package gueei.binding.utility; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import gueei.binding.IObservable; import gueei.binding.Observer; public class ObservableMultiplexer<T> { private Hashtable<T, List<ObservableEntry>> parentHT = new Hashtable<T, List<ObservableEntry>>(); private Observer childChangedObserver = null; private static class ObservableEntry { public Observer observer = null; public IObservable<?> observable = null; } public ObservableMultiplexer(Observer childChangedObserver) { this.childChangedObserver = childChangedObserver; } public void add(IObservable<?> observable, T parent) { if( observable == null || parent == null ) return; List<ObservableEntry> parentList = null; if( parentHT.containsKey(parent)) { parentList = parentHT.get(parent); } else { parentList = new ArrayList<ObservableEntry>(); parentHT.put(parent,parentList); } Observer observer = new Observer() { @Override public void onPropertyChanged(IObservable<?> prop, Collection<Object> initiators) { T parent = getParentFromObserver(this); if( parent != null && childChangedObserver != null ) childChangedObserver.onPropertyChanged(prop,Arrays.asList(new Object[]{parent})); } }; ObservableEntry entry = new ObservableEntry(); entry.observable = observable; entry.observer = observer; entry.observable.subscribe(entry.observer); parentList.add(entry); } public void removeParent(T parent) { if( !parentHT.containsKey(parent) ) return; List<ObservableEntry> list = parentHT.get(parent); for(ObservableEntry entry :list ) { if( entry.observable == null || entry.observer == null ) continue; entry.observable.unsubscribe(entry.observer); } list.clear(); } public void clear() { for (Iterator<Entry<T, List<ObservableEntry>>> iter = parentHT.entrySet().iterator(); iter.hasNext();) { Entry<T, List<ObservableEntry>> entry = iter.next(); removeParent(entry.getKey()); iter.remove(); } } private T getParentFromObserver(Observer observer) { for (Iterator<Entry<T, List<ObservableEntry>>> iter = parentHT.entrySet().iterator(); iter.hasNext();) { Entry<T, List<ObservableEntry>> entry = iter.next(); List<ObservableEntry> list = entry.getValue(); for(ObservableEntry e : list) { if( e.observer != null && e.observer.equals(observer)) return entry.getKey(); } } return null; } }