001package com.hammurapi.common;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.Collections;
006import java.util.Iterator;
007import java.util.Map;
008
009import com.hammurapi.extract.And;
010import com.hammurapi.extract.Predicate;
011
012/**
013 * Simple context implementation.
014 * @author Pavel Vlasov
015 *
016 */
017public class FacadeContext implements Context {
018        
019        private Map<String, ?> bindings;
020        private Map<Class<?>, Iterable<?>> services;
021        
022        /**
023         * @param classLoader ClassLoader for services. Can be null.
024         * @param bindings Name bindings. Can be null.
025         */
026        public FacadeContext(Map<Class<?>, Iterable<?>> services, Map<String, ?> bindings) {
027                this.services = services;
028                this.bindings = bindings;
029        }
030                
031        public Object lookup(String name) {
032                return bindings==null ? null : bindings.get(name);
033        }
034
035        @SuppressWarnings("unchecked")
036        public <T> T lookup(Class<T> serviceClass, Predicate<T, Context>... selectors) {
037                if (services==null) { 
038                        return null;
039                }
040                
041                Iterable<?> sl = services.get(serviceClass);
042                if (sl==null) {
043                        return null;
044                }
045                                
046                Iterator<?> sit = sl.iterator();
047                And<T, Context> and = new And<T, Context>(0, null, selectors);
048                while (sit.hasNext()) {
049                        T service = (T) sit.next();
050                        if (and.extract(this, null, service)) {
051                                return service;
052                        }
053                }
054                return null;
055        }
056
057        @SuppressWarnings("unchecked")
058        public <T> Iterator<T> lookupAll(Class<T> serviceClass, Predicate<T, Context>... selectors) {
059                if (services==null) {
060                        return (Iterator<T>) Collections.emptyList().iterator();
061                }
062                
063                Iterable<?> sl = services.get(serviceClass);
064                And<T, Context> and = new And<T, Context>(0, null, selectors);
065                Collection<T> ret = new ArrayList<T>();
066                Iterator<?> sit = sl.iterator();          
067                while (sit.hasNext()) {
068                        T service = (T) sit.next();
069                        if (and.extract(this, null, service)) {
070                                ret.add(service);
071                        }
072                }
073                return Collections.unmodifiableCollection(ret).iterator();
074        }
075
076}