/* * DiscovererDataModel.java * * Created on July 2, 2001, 3:27 PM */ package context.arch.discoverer.component.dataModel; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import context.arch.discoverer.ComponentDescription; /** * This class stores the ComponentDescriptions of the CTK object * that register to the discoverer. * It stores the complete ComponentDescription in a Hashtable and * maintain a set of IndexTableIF that allows to search more quickly for * particular CTK objects. They are index on each of the description element. * * TODO: this seems to maintain redundant info with the widget Storage mechanism! So there is an unnaturally tight coupling --Brian * * @author Agathe * @author Brian Y. Lim */ public class DiscovererDataModel extends AbstractDataModel { /** * Stores the whole ComponentDescription objects * key = String(component.id) => value=ComponentDescription */ private Map<String, ComponentDescription> components; /** * Creates new DiscovererDataModel */ public DiscovererDataModel () { super(); components = new ConcurrentHashMap<String, ComponentDescription>(); // nameToIndexTableIF is inherited from the AbstractDataModel class // Here a put the index tables : the key is the name of the table addIndexTable(new IdIndexTable()); addIndexTable(new ClassnameIndexTable()); addIndexTable(new HostnameIndexTable()); addIndexTable(new TypeIndexTable()); addIndexTable(new PortIndexTable()); addIndexTable(new CstAttributeIndexTable()); addIndexTable(new NonCstAttributeIndexTable()); addIndexTable(new NonCstAttributeNameIndexTable()); addIndexTable(new CallbackIndexTable()); addIndexTable(new ServiceIndexTable()); addIndexTable(new SubscriberIndexTable()); //nameToIndexTableIF.put(LOCATION_INDEX, new LocationIndexTable(LOCATION_INDEX)); } /** * Convenience method to put IndexTable associated with its name. */ public void addIndexTable(IndexTable<?> table) { indexTables.put(table.getName(), table); } @Override public String add(ComponentDescription component) { components.put(component.id, component); addToIndexTables(component); return component.id; } @Override public int size() { return components.size(); } /** * Update all hashtables (general and index tables) to add a new component * * @param component The new component to add * @return the Integer corresponding to the index of the component */ @Override public String update(ComponentDescription component) { /* * Essential to synchronize to this lookup table * Since we are adding and removing it; many other threads may call this method simultaneously, * and we don't want to encounter a state mid-update when the index was just removed */ synchronized (components) { remove(component.id); // delete old index to this component add(component); // replace with new index return component.id; } } @Override public ComponentDescription getComponent(String componentId) { return components.get(componentId); } @Override public Collection<ComponentDescription> getComponents() { return components.values(); } /** * * @param integer Integer * @return Object The removed object (ComponentDescription) */ @Override public ComponentDescription remove(String componentId) { if (!components.containsKey(componentId)) { return null; } // remove from the all component descriptions ComponentDescription removed = components.remove(componentId); // remove from the index tables removeFromIndexTables(removed); return removed; } /** * Add the reference to a component description to all IndexTable tables. */ private void addToIndexTables(ComponentDescription component) { for (IndexTable<?> table : indexTables.values()) { table.addComponent(component); } } /** * Remove the reference to a component description from all IndexTable tables. */ private void removeFromIndexTables(ComponentDescription component) { for (IndexTable<?> table : indexTables.values()) { table.removeComponent(component); } } /** * */ public String toString() { return "DiscovererDataModel - " + "Nb Elements=" + size() + "\n\n" + indexTables; } }