package ecologylab.generic; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; /** * 1-3 * 420-450; :3 * * A class that indexes inserted objects by a set of multiple criteria. implementors provide the critera in the form of * ItemIndexer predicates, marshalling happens via .by(); * @author tom * */ public abstract class MultiIndexer<IndexedObject> { public final class InnerIndexer<IndexedObject>{ Map<String, IndexedObject> ourMap; public InnerIndexer(Map<String, IndexedObject> theMap) { this.ourMap = theMap; } public IndexedObject get(String indexString) { return this.ourMap.get(indexString); } } private HashMap<String, HashMap<String, IndexedObject>> allmaps; private List<IndexedObject> allitems; public MultiIndexer() { this.allitems = new ArrayList<IndexedObject>(); // Not sure about this one... may revise. // This is probably better as a set, but I can't decide at the moment. this.allmaps = new HashMap<String, HashMap<String, IndexedObject>>(); // Initialize all of the maps in the allmaps. for(ItemIndexPredicate<IndexedObject> index : this.getIndexPredicates()) { String indexID = index.GetIndexIdentifier(); if(this.allmaps.containsKey(indexID)) { throw new RuntimeException("Should not have multiple indexers of the same identifer, please check your indexers and try again."); }else{ // Put a new map at the approrpiate index. this.allmaps.put(indexID, new HashMap<String, IndexedObject>()); } } } /** * Obtains the list of index predicates that implementors of the MultiIndexer desire. * Guides the indexing process.. * @return */ public abstract List<ItemIndexPredicate<IndexedObject>> getIndexPredicates(); /** * Inserts an item into the MultiIndexer * @param object */ public void Insert(IndexedObject object) { this.allitems.add(object); for(ItemIndexPredicate<IndexedObject> index : this.getIndexPredicates()) { String indexID = index.GetIndexIdentifier(); String indexValue = index.ObtainIndex(object); this.allmaps.get(indexID).put(indexValue, object); } } /** * Removes a given item from the Multiindexer * @param object */ public void Remove(IndexedObject object) { this.allitems.remove(object); for(ItemIndexPredicate<IndexedObject> index : this.getIndexPredicates()) { String indexID = index.GetIndexIdentifier(); String indexValue = index.ObtainIndex(object); this.allmaps.get(indexID).remove(indexValue); } } public InnerIndexer<IndexedObject> by(String indexID) { return new InnerIndexer<IndexedObject>(this.allmaps.get(indexID)); } public Integer size() { return this.allitems.size(); } }