001: /*
002: * JavuX - Java Component Set
003: * Copyright (c) 2005-2007 Krzysztof A. Sadlocha
004: * e-mail: ksadlocha@programics.com
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package com.javujavu.javux.proptree;
022:
023: import java.util.StringTokenizer;
024: import java.util.Vector;
025: import com.javujavu.javux.util.SortMap;
026:
027: /**
028: * This class represents a single node in the document tree.<br>
029: * <br>
030: * <b>This class is NOT thread safe.</b>
031: **/
032: public class PropTree {
033:
034: protected PropTree parent;
035: protected String key;
036: protected String value;
037:
038: protected SortMap map;
039: protected Vector data;
040: protected Vector all;
041:
042: public PropTree() {
043: }
044:
045: public PropTree(String key, String value) {
046: this .key = key;
047: this .value = value;
048: }
049:
050: public String getKey() {
051: return key;
052: }
053:
054: public int childCount() {
055: return (data != null) ? data.size() : 0;
056: }
057:
058: public PropTree getChild(int i) {
059: return (PropTree) ((data != null) ? data.elementAt(i) : null);
060: }
061:
062: public PropTree getChild(String shortKey) {
063: return getLastChild(shortKey);
064: }
065:
066: private PropTree getLastChild(String shortKey) {
067: if (map == null) {
068: PropTree n;
069: return (data != null && data.size() > 0 && shortKey
070: .equalsIgnoreCase((n = (PropTree) data
071: .firstElement()).key)) ? n : null;
072: }
073: Object o = map.get(shortKey);
074: if (o instanceof Vector)
075: o = ((Vector) o).lastElement();
076: return (PropTree) o;
077: }
078:
079: private PropTree getFirstChild(String shortKey) {
080: if (map == null)
081: return getLastChild(shortKey);
082: Object o = map.get(shortKey);
083: if (o instanceof Vector)
084: o = ((Vector) o).firstElement();
085: return (PropTree) o;
086: }
087:
088: public void addChild(PropTree node) {
089: node.parent = this ;
090:
091: if (all != null)
092: all.addElement(node);
093:
094: if (data == null)
095: data = new Vector();
096: data.addElement(node);
097:
098: if (map != null || data.size() > 1) {
099: if (map == null) {
100: map = new SortMap(true);
101: PropTree n = (PropTree) data.firstElement();
102: map.set(n.key, n);
103: }
104: int i = map.find(node.key);
105: if (i == -1)
106: map.set(node.key, node);
107: else {
108: Object o = map.value(i);
109: if (o instanceof Vector)
110: ((Vector) o).addElement(node);
111: else {
112: Vector v = new Vector();
113: v.addElement(o);
114: v.addElement(node);
115: map.set(i, v);
116: }
117: }
118: }
119: }
120:
121: public PropTree[] getChilds() {
122: return getChilds(null);
123: }
124:
125: public PropTree[] getChilds(String shortKey) {
126: Object o = (shortKey == null) ? data : (map != null) ? map
127: .get(shortKey)
128: : (data != null && data.size() > 0 && shortKey
129: .equalsIgnoreCase(((PropTree) data
130: .firstElement()).key)) ? data
131: .firstElement() : null;
132: if (o == null)
133: return null;
134: else if (o instanceof Vector) {
135: Vector v = (Vector) o;
136: if (v.size() == 0)
137: return null;
138: PropTree[] r = new PropTree[v.size()];
139: v.copyInto(r);
140: return r;
141: } else {
142: PropTree[] r = new PropTree[1];
143: r[0] = (PropTree) o;
144: return r;
145: }
146: }
147:
148: // public PropTree[] getBranches(String key)
149: // {
150: // if(key==null) return null;
151: //
152: // if(key.startsWith(".."))
153: // {
154: // if(parent==null) return null;
155: // return parent.getBranches(key.substring(1));
156: // }
157: //
158: // if(key.startsWith(".")) key= key.substring(1);
159: //
160: // int fklen= key.indexOf('.');
161: // if(fklen==-1)
162: // {
163: // if(key.length()>0) return getNodes(key);
164: // else return null;
165: // }
166: // else
167: // {
168: // String firstKey= key.substring(0,fklen);
169: // String key2= key.substring(fklen+1);
170: // PropTree[] nn= getNodes(firstKey);
171: // if(nn==null) return null;
172: // Vector r= new Vector();
173: // for(int i= 0; i<nn.length; i++)
174: // {
175: // PropTree[] nn2= nn[i].getBranches(key2);
176: // if(nn2!=null)
177: // {
178: // for(int j= 0; j<nn2.length; j++)
179: // {
180: // r.addElement(nn2[j]);
181: // }
182: // }
183: // }
184: // nn= new PropTree[r.size()];
185: // r.copyInto(nn);
186: // return nn;
187: // }
188: // }
189:
190: public PropTree getLastNode(String key) {
191: if (key == null)
192: return this ;
193:
194: if (key.startsWith("..")) {
195: if (parent == null)
196: return null;
197: return parent.getLastNode(key.substring(1));
198: }
199:
200: if (key.startsWith("."))
201: key = key.substring(1);
202:
203: int fklen = key.indexOf('.');
204: if (fklen == -1) {
205: if (key.length() > 0)
206: return getLastChild(key);
207: else
208: return this ;
209: } else {
210: String firstKey = key.substring(0, fklen);
211: String key2 = key.substring(fklen + 1);
212: PropTree n;
213: Object o;
214: if (map != null) {
215: o = map.get(firstKey);
216: if (o == null)
217: return null;
218: } else if (data == null
219: || data.size() == 0
220: || !firstKey.equalsIgnoreCase(((PropTree) (o = data
221: .firstElement())).key))
222: return null;
223: if (o instanceof Vector) {
224: Vector v = (Vector) o;
225: for (int i = v.size() - 1; i >= 0; i--) {
226: n = ((PropTree) v.elementAt(i)).getLastNode(key2);
227: if (n != null)
228: return n;
229: }
230: return null;
231: } else
232: return ((PropTree) o).getLastNode(key2);
233: }
234: }
235:
236: protected PropTree addNode(String key, String value,
237: boolean insertNode, boolean continueNode) {
238: if (key.startsWith("..")) {
239: if (parent == null)
240: return null;
241: return parent.addNode(key.substring(1), value, insertNode,
242: continueNode);
243: } else {
244: if (key.startsWith("."))
245: key = key.substring(1);
246: int fklen = key.indexOf('.');
247: if (fklen == -1) {
248: PropTree n = new PropTree();
249: n.key = key;
250: n.value = value;
251: addChild(n);
252: return n;
253: } else {
254: String firstKey = key.substring(0, fklen);
255: String key2 = key.substring(fklen + 1);
256:
257: PropTree ln = null;
258: if (insertNode)
259: ln = getLastChild(firstKey);
260: else if (continueNode && data != null) {
261: ln = (PropTree) data.lastElement();
262: if (!ln.key.equalsIgnoreCase(firstKey))
263: ln = null;
264: }
265: if (ln == null) {
266: ln = new PropTree();
267: ln.key = firstKey;
268: addChild(ln);
269: }
270: return ln
271: .addNode(key2, value, insertNode, continueNode);
272: }
273: }
274: }
275:
276: public PropTree insertNode(String key, String value) {
277: return addNode(key, value, true, false);
278: }
279:
280: public PropTree continueNode(String key, String value) {
281: return addNode(key, value, false, true);
282: }
283:
284: public PropTree addNode(String key, String value) {
285: return addNode(key, value, false, false);
286: }
287:
288: public boolean removeFirstNode(String key) {
289: if (key.startsWith("..")) {
290: if (parent == null)
291: return false;
292: return parent.removeFirstNode(key.substring(1));
293: }
294:
295: if (key.startsWith("."))
296: key = key.substring(1);
297:
298: int fklen = key.indexOf('.');
299: if (fklen == -1) {
300: PropTree n = getFirstChild(key);
301: if (n == null)
302: return false;
303:
304: if (all != null)
305: all.removeElement(n);
306: data.removeElement(n);
307: if (map != null) {
308: int i = map.find(key);
309: Object o = map.value(i);
310: if (o instanceof Vector) {
311: Vector v = (Vector) o;
312: v.removeElementAt(0);
313: if (v.size() == 0)
314: map.remove(i);
315: } else
316: map.remove(i);
317: }
318: return true;
319: } else {
320: String firstKey = key.substring(0, fklen);
321: String key2 = key.substring(fklen + 1);
322:
323: Object o;
324: if (map != null) {
325: o = map.get(firstKey);
326: if (o == null)
327: return false;
328: } else if (data == null
329: || data.size() == 0
330: || !firstKey.equalsIgnoreCase(((PropTree) (o = data
331: .firstElement())).key))
332: return false;
333:
334: if (o instanceof Vector) {
335: Vector v = (Vector) o;
336: for (int i = 0; i < v.size(); i++) {
337: if (((PropTree) v.elementAt(i))
338: .removeFirstNode(key2)) {
339: return true;
340: }
341: }
342: return false;
343: } else
344: return ((PropTree) o).removeFirstNode(key2);
345: }
346: }
347:
348: public String getString() {
349: return value;
350: }
351:
352: public void setString(String value) {
353: this .value = value;
354: }
355:
356: public String getString(String key) {
357: PropTree n = getLastNode(key);
358: if (n == null)
359: return null;
360: return n.value;
361: }
362:
363: public void setString(String key, String value) {
364: PropTree n = getLastNode(key);
365: if (n != null)
366: n.value = value;
367: else
368: insertNode(key, value);
369: }
370:
371: public void addString(String key, String value) {
372: insertNode(key, value);
373: }
374:
375: public void removeAllChilds() {
376: if (all != null)
377: all.removeAllElements();
378: if (data != null)
379: data.removeAllElements();
380: if (map != null)
381: map.removeAllElements();
382: }
383:
384: public void addComment(String value) {
385: if (all == null) {
386: if (data == null)
387: all = new Vector();
388: else
389: all = (Vector) data.clone();
390: }
391: all.addElement(value);
392: }
393:
394: public boolean getBoolean(String key) {
395: return getBoolean(key, false);
396: }
397:
398: public int getInteger(String key) {
399: return getInteger(key, 0);
400: }
401:
402: public String getString(String key, String def) {
403: String r = getString(key);
404: return (r == null) ? def : r;
405: }
406:
407: public boolean getBoolean(String key, boolean def) {
408: // true when: "1", "yes", "true", "on"
409: String s = getString(key);
410: if (s == null)
411: return def;
412: if (s.equals("1") || s.equalsIgnoreCase("yes")
413: || s.equalsIgnoreCase("true")
414: || s.equalsIgnoreCase("on"))
415: return true;
416: return false;
417: }
418:
419: public int getInteger(String key, int def) {
420: String r = getString(key);
421: if (r == null)
422: return def;
423: try {
424: return Integer.parseInt(r);
425: } catch (NumberFormatException e) {
426: return 0;
427: }
428: }
429:
430: public void setBoolean(String key, boolean value) {
431: setString(key, value ? "1" : "0");
432: }
433:
434: public void setInteger(String key, int value) {
435: setString(key, String.valueOf(value));
436: }
437:
438: public void addBoolean(String key, boolean value) {
439: setBoolean(key, value);
440: }
441:
442: public void addInteger(String key, int value) {
443: setInteger(key, value);
444: }
445:
446: public void appendTree(PropTree n) {
447: Vector v = n.all;
448: if (v == null)
449: v = n.data;
450: if (v == null)
451: return;
452: PropTree m;
453: for (int i = 0; i < v.size(); i++) {
454: m = (PropTree) v.elementAt(i);
455: if (m.key == null) {
456: this .addComment(m.value);
457: } else {
458: this .addChild(m);
459: }
460: }
461: }
462:
463: public void getIntegers(String key, int[] r) {
464: String s = getString(key);
465: if (s == null || s.length() == 0)
466: return;
467: StringTokenizer st = new StringTokenizer(s, ",");
468: for (int i = 0; i < r.length && st.hasMoreTokens(); i++) {
469: s = st.nextToken().trim();
470: try {
471: r[i] = Integer.parseInt(s);
472: } catch (NumberFormatException e) {
473: }
474: }
475: }
476:
477: public void setIntegers(String key, int[] r) {
478: StringBuffer s = new StringBuffer();
479: for (int i = 0; i < r.length; i++) {
480: if (i > 0)
481: s.append(',');
482: s.append(r[i]);
483: }
484: setString(key, s.toString());
485: }
486: }
|