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}