001package com.hammurapi.common; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Collections; 006import java.util.Iterator; 007 008import com.hammurapi.extract.And; 009import com.hammurapi.extract.Predicate; 010 011public class SingletonChainingContext<ST> implements MutableContext { 012 013 private Class<ST> type; 014 private ST service; 015 private Context chain; 016 017 public SingletonChainingContext(Class<ST> type, ST service, Context chain) { 018 this.type = type; 019 this.service = service; 020 this.chain = chain; 021 } 022 023 public void bind(String name, Object obj) { 024 if (chain instanceof MutableContext) { 025 ((MutableContext) chain).bind(name, obj); 026 } else { 027 throw new IllegalStateException("Chain context is not mutable"); 028 } 029 } 030 031 public <T> void register(Class<? super T> type, T service) { 032 if (chain instanceof MutableContext) { 033 ((MutableContext) chain).register(type, service); 034 } else { 035 throw new IllegalStateException("Chain context is not mutable"); 036 } 037 } 038 039 public Object unbind(String name) { 040 if (chain instanceof MutableContext) { 041 return ((MutableContext) chain).unbind(name); 042 } else { 043 throw new IllegalStateException("Chain context is not mutable"); 044 } 045 } 046 047 public <T> void unregister(Class<? super T> type, T service) { 048 if (chain instanceof MutableContext) { 049 ((MutableContext) chain).unregister(type, service); 050 } else { 051 throw new IllegalStateException("Chain context is not mutable"); 052 } 053 } 054 055 public Object lookup(String name) { 056 return chain==null ? null : chain.lookup(name); 057 } 058 059 @SuppressWarnings("unchecked") 060 public <T> T lookup(Class<T> serviceClass, Predicate<T, Context>... selectors) { 061 And<T, Context> and = new And<T, Context>(0, null, selectors); 062 if (serviceClass.equals(type) && and.extract(this, null, (T) service)) { 063 return (T) service; 064 } 065 066 return chain==null ? null : chain.lookup(serviceClass, selectors); 067 } 068 069 @SuppressWarnings("unchecked") 070 public <T> Iterator<T> lookupAll(Class<T> serviceClass, Predicate<T, Context>... selectors) { 071 And<T, Context> and = new And<T, Context>(0, null, selectors); 072 if (serviceClass.equals(type) && and.extract(this, null, (T) service)) { 073 Collection<T> c = new ArrayList<T>(); 074 c.add((T) service); 075 if (chain!=null) { 076 Iterator<T> it = chain.lookupAll(serviceClass, selectors); 077 while (it.hasNext()) { 078 c.add(it.next()); 079 } 080 } 081 return c.iterator(); 082 } 083 return (Iterator<T>) (chain==null ? Collections.emptyList().iterator() : chain.lookupAll(serviceClass, selectors)); 084 } 085 086}