001: package org.space4j.indexing;
002:
003: import java.util.*;
004: import java.io.*;
005:
006: import org.space4j.*;
007:
008: /**
009: * IndexManager will control all indexes of your space.<br>
010: * It will create Maps for each index and observe changes in your objects.<br>
011: * IndexManager is serializaded together with the space.
012: */
013: public class IndexManager implements Serializable, Observer {
014:
015: private static final boolean DEBUG = true;
016:
017: private HashMap indexes = new HashMap(); // all indexes will be here...
018: private HashMap maps = new HashMap(); // every index will have a map...
019: private HashMap keyMaps = new HashMap(); // for the old keys...
020:
021: /**
022: * Return a Map with the objects indexed.<br>
023: * You will use these maps to query your objects.
024: * @param indx The index we are talking about.
025: * @return A map with the objects indexed.
026: */
027: public Map getIndexedMap(Index indx) {
028: return (Map) maps.get(indx);
029: }
030:
031: /**
032: * Return an iterator with all indexes for a given Class.
033: * @param klass The class whose indexes we are looking for.
034: * @return Iterator The indexes of this class.
035: */
036: public Iterator getIndexes(Class klass) {
037: String name = klass.getName();
038: ArrayList al = (ArrayList) indexes.get(name);
039: if (al == null)
040: al = new ArrayList();
041:
042: ArrayList list = new ArrayList(al);
043: return list.iterator();
044: }
045:
046: /**
047: * Drop an index from the system.
048: * @param indx The index to drop
049: * @param space4j The space4j where this command will be executed.
050: * @return boolean True if the index was dropped.
051: */
052: public boolean dropIndex(Index indx, Space4J space4j)
053: throws CommandException, LoggerException {
054: Command cmd = new DropIndexCmd(indx);
055: int x = space4j.executeCommand(cmd);
056: if (x > 0)
057: return true;
058: return false;
059: }
060:
061: boolean dropIndexImpl(Index indx) {
062: String name = indx.getClassName();
063: ArrayList list = (ArrayList) indexes.get(name);
064: if (list == null)
065: return false;
066: int x = list.lastIndexOf(indx);
067: if (x != -1)
068: list.remove(x);
069: maps.remove(indx);
070: keyMaps.remove(indx);
071: if (x != -1)
072: return true;
073: return false;
074: }
075:
076: /**
077: * Find all indexes of a Class with a given attribute.
078: * @param klass The class whose indexes we are looking for.
079: * @param attribute The attribute whose indexes we are looking for.
080: * @return ArrayList The indexes found in the system.
081: */
082: public ArrayList findIndexes(Class klass, String attribute) {
083: ArrayList al = new ArrayList();
084: Iterator iter = getIndexes(klass);
085: while (iter.hasNext()) {
086: Index indx = (Index) iter.next();
087: if (indx.hasAttribute(attribute))
088: al.add(indx);
089: }
090: return al;
091: }
092:
093: /**
094: * Obsersable objects will notify their changes to the IndexManager through this method.
095: */
096: public void update(Observable o, Object arg) {
097: Object obj = null;
098: String attribute = null;
099:
100: if (o instanceof Serializable) {
101: // the object is extending Observable...
102: obj = o;
103: attribute = (String) arg;
104: } else if (arg instanceof Object[]) {
105: // the object contains Observable...
106: // you will need this when your object cannot extend observable
107: Object[] args = (Object[]) arg;
108: obj = args[0]; // the object that changed...
109: attribute = (String) args[1]; // the attribute of the object that changed....
110: } else
111: return;
112:
113: ArrayList al = findIndexes(obj.getClass(), attribute);
114: Iterator iter = al.iterator();
115: while (iter.hasNext()) {
116: Index indx = (Index) iter.next();
117: index(indx, obj);
118: }
119: }
120:
121: private boolean index(Index indx, Object obj) {
122: if (DEBUG) {
123: System.out.println("Indexing...");
124: System.out.println(indx);
125: System.out.println(obj);
126: }
127: Map map = (Map) maps.get(indx);
128: if (map == null)
129: return false;
130: Map keyMap = (Map) keyMaps.get(indx);
131: if (keyMap == null)
132: return false;
133: Key oldkey = (Key) keyMap.get(obj);
134: if (oldkey != null)
135: map.remove(oldkey);
136: Key key = indx.getKey(obj);
137: map.put(key, obj);
138: keyMap.put(obj, key);
139: return true;
140: }
141:
142: /**
143: * Insert an object in this IndexManager.
144: * @param obj The object to be inserted.
145: */
146: public void add(Object obj) {
147: Iterator iter = getIndexes(obj.getClass());
148: while (iter.hasNext()) {
149: Index indx = (Index) iter.next();
150: index(indx, obj);
151: }
152: if (obj instanceof Observable) {
153: Observable o = (Observable) obj;
154: o.addObserver(this );
155: }
156: }
157:
158: /**
159: * Remove an object from this IndexManager.
160: * @param obj The object to be removed.
161: */
162: public void remove(Object obj) {
163: Iterator iter = getIndexes(obj.getClass());
164: while (iter.hasNext()) {
165: Index indx = (Index) iter.next();
166: remove(indx, obj);
167: }
168:
169: if (obj instanceof Observable) {
170: Observable o = (Observable) obj;
171: o.deleteObserver(this );
172: }
173:
174: }
175:
176: private boolean remove(Index indx, Object obj) {
177: if (DEBUG) {
178: System.out.println("Removing...");
179: System.out.println(indx);
180: System.out.println(obj);
181: }
182: Map map = (Map) maps.get(indx);
183: if (map == null)
184: return false;
185: Map keyMap = (Map) keyMaps.get(indx);
186: if (keyMap == null)
187: return false;
188: Key oldkey = (Key) keyMap.remove(obj);
189: if (oldkey == null)
190: return false;
191: map.remove(oldkey);
192: return true;
193: }
194:
195: /**
196: * Check to see if this index exists.
197: * @param indx The index we are looking for.
198: * @return True if the index exists.
199: */
200: public boolean checkIndex(Index indx) {
201: String name = indx.getClassName();
202: ArrayList al = (ArrayList) indexes.get(name);
203: if (al == null)
204: return false;
205: return al.contains(indx);
206: }
207:
208: /**
209: * Create an index in the system.
210: * @param indx The index to be created.
211: * @param sourcemap The map where the objects are stored.
212: * @param map The new map used by this new index.
213: * @param space4j The space4j were this command will be executed.
214: * @return True if the index was created.
215: */
216: public boolean createIndex(Index indx, String sourcemap, Map map,
217: Space4J space4j) throws CommandException, LoggerException {
218: Command cmd = new CreateIndexCmd(indx, sourcemap, map);
219: int x = space4j.executeCommand(cmd);
220: if (x > 0)
221: return true;
222: return false;
223: }
224:
225: boolean createIndexImpl(Index indx, Collection list, Map map) {
226:
227: String name = indx.getClassName();
228:
229: // get all indexes for this class...
230: ArrayList al = (ArrayList) indexes.get(name);
231: if (al == null) {
232: al = new ArrayList();
233: }
234:
235: // check if index already exists...
236: if (al.contains(indx))
237: return false;
238:
239: // populate the indexed map and the keyMap...
240: HashMap keyMap = new HashMap();
241: if (list != null) {
242: Iterator iter = list.iterator();
243: while (iter.hasNext()) {
244: Object obj = iter.next();
245: Key key = indx.getKey(obj);
246: map.put(key, obj);
247: keyMap.put(obj, key);
248: }
249: }
250:
251: // all done! set everything and return...
252: maps.put(indx, map);
253: keyMaps.put(indx, keyMap);
254: al.add(indx);
255: indexes.put(name, al);
256:
257: return true;
258: }
259:
260: }
|