001    /**
002     * Copyright (C) 2009-2011 the original author or authors.
003     * See the notice.md file distributed with this work for additional
004     * information regarding copyright ownership.
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.fusesource.restygwt.client.dispatcher;
020    
021    import java.util.ArrayList;
022    import java.util.List;
023    import java.util.logging.Logger;
024    
025    import org.fusesource.restygwt.client.Method;
026    import org.fusesource.restygwt.client.cache.QueueableCacheStorage;
027    import org.fusesource.restygwt.client.callback.DefaultFilterawareRequestCallback;
028    
029    import com.google.gwt.http.client.Request;
030    import com.google.gwt.http.client.RequestBuilder;
031    import com.google.gwt.http.client.RequestException;
032    import com.google.gwt.logging.client.LogConfiguration;
033    
034    /**
035     * Some valuable ideas came from:
036     * http://turbomanage.wordpress.com/2010/07/12/caching-batching-dispatcher-for-gwt-dispatch/
037     * <p/>
038     * Thanks David!
039     * <p/>
040     * Especially: - Waiting if a particular request is already on the way
041     * (otherwise you end up having many requests on the same source.
042     *
043     * @author <a href="mailto:mail@raphaelbauer.com">rEyez</<a>
044     * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
045     */
046    public class DefaultFilterawareDispatcher implements FilterawareDispatcher {
047    
048        public static DefaultFilterawareDispatcher INSTANCE;
049        
050        /**
051         * list of dispatcherfilters to be performed when an request is done
052         */
053        final protected List<DispatcherFilter> dispatcherFilters =
054                new ArrayList<DispatcherFilter>();
055    
056        /**
057         * get one instance of this class
058         *
059         * @param cacheStorage the one and only {@link QueueableCacheStorage} for this instance
060         * @param cf CallbackFactory to be able to use {@link DefaultFilterawareRequestCallback}
061         * @return
062         */
063        public static DefaultFilterawareDispatcher singleton() {
064            if (null != INSTANCE) return INSTANCE;
065    
066            INSTANCE = new DefaultFilterawareDispatcher();
067            return INSTANCE;
068        }
069        
070        public DefaultFilterawareDispatcher(){    
071        }
072        
073        public DefaultFilterawareDispatcher(DispatcherFilter... filters){
074            for(DispatcherFilter filter: filters){
075                addFilter(filter);
076            }
077        }
078        
079        public Request send(Method method, RequestBuilder builder) throws RequestException {
080            for (DispatcherFilter f : dispatcherFilters) {
081                if (!f.filter(method, builder)) {
082                    // filter returned false, no continue
083                    if (LogConfiguration.loggingIsEnabled()) {
084                        Logger.getLogger(DefaultFilterawareDispatcher.class.getName())
085                                .fine(f.getClass() + " told me not to continue filtering for: "
086                                        + builder.getHTTPMethod() + " " + builder.getUrl());
087                    }
088                    return null;
089                }
090            }
091    
092            return builder.send();
093        }
094    
095        /**
096         * well, add one more dispatcherfilter
097         */
098        @Override
099        public void addFilter(DispatcherFilter filter) {
100            this.dispatcherFilters.add(filter);
101        }
102    }