    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;
    008import java.util.ServiceLoader;
    009
    010import com.hammurapi.extract.And;
    011import com.hammurapi.extract.Predicate;
    012
    013/**
    014 * Default context uses ServiceLoader to find services in
    015 * a given classloader and map of bindings.
    016 * @author Pavel Vlasov
    017 *
    018 */
    019public class DefaultContext implements Context {
    020
    021        private ClassLoader classLoader;
    022        private Map<String, Object> bindings;
    023
    024        /**
    025         * @param classLoader ClassLoader for services. Can be null.
    026         * @param bindings Name bindings. Can be null.
    027         */
    028        public DefaultContext(ClassLoader classLoader, Map<String, Object> bindings) {
    029                this.classLoader = classLoader==null ? this.getClass().getClassLoader() : classLoader;
    030                this.bindings = bindings;
    031        }
    032
    033        public Object lookup(String name) {
    034                return bindings==null ? null : bindings.get(name);
    035        }
    036
    037        public <T> T lookup(Class<T> serviceClass, Predicate<T, Context>... selectors) {
    038                ServiceLoader<T> sl = ServiceLoader.load(serviceClass, classLoader);
    039                Iterator<T> sit = sl.iterator();
    040                And<T, Context> and = new And<T, Context>(0, null, selectors);
    041                while (sit.hasNext()) {
    042                        T service = sit.next();
    043                        if (and.extract(this, null, service)) {
    044                                return service;
    045                        }
    046                }
    047                return null;
    048        }
    049
    050        public <T> Iterator<T> lookupAll(Class<T> serviceClass, Predicate<T, Context>... selectors) {
    051                ServiceLoader<T> sl = ServiceLoader.load(serviceClass, classLoader);
    052                And<T, Context> and = new And<T, Context>(0, null, selectors);
    053                Collection<T> ret = new ArrayList<T>();
    054                Iterator<T> sit = sl.iterator();
    055                while (sit.hasNext()) {
    056                        T service = sit.next();
    057                        if (and.extract(this, null, service)) {
    058                                ret.add(service);
    059                        }
    060                }
    061                return Collections.unmodifiableCollection(ret).iterator();
    062        }
    063
    064}