View Javadoc

1   package org.catacomb.interlish.content;
2   
3   import org.catacomb.interlish.structure.*;
4   import org.catacomb.report.E;
5   
6   import java.util.ArrayList;
7   import java.util.HashMap;
8   import java.util.HashSet;
9   
10  
11  public class KeyedList<V> implements ElementWriter {
12  
13      ArrayList<V> items;
14      HashMap<String, V> itemHM;
15  
16      Class itemClass;
17  
18      ArrayList<String> keyCache;
19  
20      HashMap<String, String> shortToFullHM;
21  
22      HashSet<String> duplicateShorts;
23  
24      int inewid = 0;
25  
26      ArrayList<ListWatcher> listWatchers;
27  
28      public KeyedList() {
29          items = new ArrayList<V>();
30          itemHM = new HashMap<String, V>();
31          shortToFullHM = new HashMap<String, String>();
32      }
33  
34  
35      public KeyedList(String s) {
36          this();
37          try {
38              itemClass = Class.forName(s);
39          } catch (Exception ex) {
40              E.error("cant find class " + s + " " + ex);
41          }
42      }
43  
44  
45      public KeyedList(Class c) {
46          this();
47          itemClass = c;
48      }
49  
50  
51      public KeyedList(ArrayList<V> elts) {
52          this();
53          addAll(elts);
54      }
55  
56      public void add(V v) {
57          addItem(v);
58      }
59  
60  
61      public void addAll(ArrayList<V> elts) {
62          for (V v : elts) {
63              addItem(v);
64          }
65      }
66  
67      public ArrayList<V> getItems(String[] ks) {
68          ArrayList<V> ret = new ArrayList<V>();
69          if (ks != null) {
70              for (String s : ks) {
71                  if (hasItem(s)) {
72                      ret.add(get(s));
73                  }
74              }
75          }
76          return ret;
77      }
78  
79      public ArrayList<V> getItems(ArrayList<String> ks) {
80          ArrayList<V> ret = new ArrayList<V>();
81          for (String s : ks) {
82              ret.add(get(s));
83          }
84          return ret;
85      }
86  
87  
88      public ArrayList<V> getItems() {
89          return items;
90      }
91  
92      public void silentAddItem(V obj) {
93          items.add(obj);
94          String sid = addToHM(obj);
95          addKey(sid);
96          reportChange();
97      }
98  
99  
100     public void addItem(V obj) {
101         silentAddItem(obj);
102         reportChange();
103     }
104 
105     private String addToHM(V obj) {
106         String sid = "";
107         if (obj instanceof IDd) {
108             sid = ((IDd)obj).getID();
109         } else {
110             sid = obj.toString();
111         }
112         itemHM.put(sid, obj);
113         keyCache = null;
114         return sid;
115     }
116 
117 
118     public void remove(V obj) {
119         String sid = "";
120         if (obj instanceof IDd) {
121             sid = ((IDd)obj).getID();
122         } else {
123             sid = obj.toString();
124         }
125         items.remove(obj);
126         itemHM.remove(sid);
127         removeKey(sid);
128         reportChange();
129     }
130 
131 
132     public void put(String s, V v) {
133         items.add(v);
134         itemHM.put(s, v);
135         keyCache = null;
136         addKey(s);
137     }
138 
139 
140     public void putNew(String sid, V psc) {
141         if (itemHM.containsKey(sid)) {
142             E.warning("put new tried to override existing item " + sid);
143         } else {
144             put(sid, psc);
145         }
146     }
147 
148 
149     public boolean hasItem(String s) {
150         return (shortToFullHM.containsKey(s) || itemHM.containsKey(s));
151     }
152 
153 
154     public V get(String s) {
155         V ret = null;
156         if (itemHM.containsKey(s)) {
157             ret = itemHM.get(s);
158         } else {
159             String sf = getFullID(s);
160             if (itemHM.containsKey(sf)) {
161                 ret = itemHM.get(sf);
162             } else {
163                 E.error("cant get " + s + " from keyed list");
164             }
165 
166         }
167         return ret;
168     }
169 
170 
171     @SuppressWarnings( { "unchecked" })
172     public V getOrMake(String s) {
173         V ret = null;
174         if (hasItem(s)) {
175             ret = get(s);
176 
177         } else if (itemClass != null) {
178             try {
179                 Object obj = itemClass.newInstance();
180                 ret = (V)obj;
181 
182                 if (ret instanceof IDable) {
183                     ((IDable)ret).setID(s);
184                 } else {
185                     E.warning("autogenerated items should be IDable " + itemClass);
186                 }
187 
188                 addItem(ret);
189 
190             } catch (Exception ex) {
191                 E.error("cant make item of type " + itemClass + " " + ex);
192             }
193 
194 
195         } else {
196             E.error("cant make new item - null classs");
197         }
198 
199 
200         return ret;
201 
202     }
203 
204 
205     @SuppressWarnings( { "unchecked" })
206     public void superceded(V old) {
207         if (old instanceof Supercedable) {
208             V repl = (V)((Supercedable)old).getSupercessor();
209 
210             if (items.contains(old)) {
211                 items.remove(old);
212                 items.add(repl);
213             } else {
214                 E.error("supercedee isnt in list " + old + " " + old.hashCode());
215                 for (Object obj : items) {
216                     E.info("is in: " + obj + " " + obj.hashCode());
217                 }
218             }
219 
220             addToHM(repl);
221 
222         } else {
223             E.error(" cant supercede non supercedable: " + old);
224         }
225     }
226 
227     public void quietSuperceded(V old) {
228         if (items.contains(old)) {
229             superceded(old);
230         }
231         // else do nothing, and dont complain;
232     }
233 
234 
235 
236     public V getFirst() {
237         return items.get(0);
238     }
239 
240 
241 
242     public Element makeElement(ElementFactory ef, Elementizer eltz) {
243         Element elt = ef.makeElement("KeyedList");
244         for (V obj : getItems()) {
245 
246             Element chld = eltz.elementize(obj);
247             ef.addElement(elt, chld);
248         }
249         return elt;
250     }
251 
252 
253     public ArrayList<String> getKeys() {
254         if (keyCache == null) {
255             keyCache = new ArrayList<String>();
256             keyCache.addAll(itemHM.keySet());
257         }
258         return keyCache;
259     }
260 
261 
262     public ArrayList<String> getShortKeys() {
263         ArrayList<String> al = new ArrayList<String>();
264         al.addAll(shortToFullHM.keySet());
265         return al;
266     }
267 
268 
269     public void remove(String s) {
270         if (hasItem(s)) {
271             V val = get(s);
272             items.remove(val);
273             itemHM.remove(s);
274             removeKey(s);
275             reportChange();
276         }
277     }
278 
279     private void removeKey(String s) {
280         String ss = s.substring(s.lastIndexOf(".") + 1, s.length());
281         shortToFullHM.remove(ss);
282         keyCache = null;
283     }
284 
285 
286 
287     private void addKey(String s) {
288         String ss = s.substring(s.lastIndexOf(".") + 1, s.length());
289         if (shortToFullHM.containsKey(ss)) {
290 
291             E.shortWarning("duplicate items - deleted " +
292                            shortToFullHM.get(ss) + " and " + s);
293 
294             shortToFullHM.remove(ss);
295             if (duplicateShorts == null) {
296                 duplicateShorts = new HashSet<String>();
297             }
298             duplicateShorts.add(ss);
299 
300         } else {
301             shortToFullHM.put(ss, s);
302         }
303     }
304 
305 
306     public boolean hasFullID(String sid) {
307         boolean ret = false;
308         if (sid.indexOf(".") > 0) {
309             ret = itemHM.containsKey(sid);
310         } else {
311             ret = shortToFullHM.containsKey(sid);
312         }
313         return ret;
314     }
315 
316 
317     public String getFullID(String sid) {
318         String ret = null;
319         if (sid == null) {
320             // just leave fro null return;
321         } else {
322             if (sid.indexOf(".") > 0) {
323                 ret = sid;
324             } else {
325                 if (shortToFullHM.containsKey(sid)) {
326                     String s = shortToFullHM.get(sid);
327                     if (s.equals("_duplicate_")) {
328                         E.shortError("Duplicate short ID - must use full ID " + sid);
329                     } else {
330                         ret = s;
331                     }
332 
333                 } else {
334                     E.error("no such key " + sid);
335                 }
336             }
337         }
338         return ret;
339     }
340 
341 
342     public String printIDs() {
343         StringBuffer sb = new StringBuffer();
344         int iel = 0;
345         for (String s : itemHM.keySet()) {
346             sb.append(s);
347             sb.append(", ");
348             iel += 1;
349             if (iel % 4 == 0) {
350                 sb.append("\n");
351             }
352         }
353         return sb.toString();
354     }
355 
356 
357     public void dump() {
358         for (String s : itemHM.keySet()) {
359             E.info("kl item " + s + " " + itemHM.get(s));
360         }
361         for (String s : shortToFullHM.keySet()) {
362             E.info("short key " + s + " " + shortToFullHM.get(s));
363         }
364     }
365 
366 
367     public String[] getKeysArray() {
368         return getKeys().toArray(new String[0]);
369     }
370 
371     public String[] getShortKeysArray() {
372         return getShortKeys().toArray(new String[0]);
373     }
374 
375 
376     public ArrayList<V> getDescendants(String rtid) {
377         ArrayList<V> ret = new ArrayList<V>();
378         String fr = rtid + ".";
379         for (String sk : itemHM.keySet()) {
380             if (sk.startsWith(fr)) {
381                 ret.add(itemHM.get(sk));
382             }
383         }
384         return ret;
385     }
386 
387 
388     public String newName(String root) {
389         while (itemHM.containsKey(root + "_" + inewid)) {
390             inewid += 1;
391         }
392         return root + "_" + inewid;
393     }
394 
395 
396     public void removeListWatcher(ListWatcher lw) {
397         listWatchers.remove(lw);
398     }
399 
400 
401     public void reportChange() {
402         if (listWatchers != null) {
403             for (ListWatcher lw : listWatchers) {
404                 lw.listChanged(this);
405             }
406         }
407     }
408 
409     public void addListWatcher(ListWatcher lw) {
410         if (listWatchers == null) {
411             listWatchers = new ArrayList<ListWatcher>();
412         }
413         listWatchers.add(lw);
414     }
415 
416 
417     public int size() {
418         return items.size();
419     }
420 
421 
422 
423 
424 }