Source code: com/aendvari/common/properties/Properties.java
1 /*
2 * Properties.java
3 *
4 * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5 *
6 * See the file LICENSE for terms of use.
7 *
8 */
9
10 package com.aendvari.common.properties;
11
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.Map;
16
17 import com.aendvari.common.osm.Osm;
18 import com.aendvari.common.osm.OsmNode;
19 import com.aendvari.common.osm.SimpleOsmPath;
20 import com.aendvari.common.osm.QueryOsmPath;
21
22 /**
23 * <p>Provides the ability to store property values in a hierarchy.</p>
24 *
25 * <p>This class extends the Object Space Model ({@link Osm}) class.</p>
26 *
27 * <p>Native types may be stored using the accessors provided. The methods will translate
28 * to and from their Object class equivalents.</p>
29 *
30 * @author Trevor Milne
31 *
32 */
33
34 public class Properties extends Osm
35 {
36 /* Constructors. */
37
38
39 /**
40 * Constructs a <code>Properties</code> instance.
41 *
42 */
43
44 public Properties()
45 {
46 super();
47 }
48
49 /**
50 * Constructs a <code>Properties</code> instance from another <code>Properties</code>.
51 * Only the references to the objects stored in this <code>Properties</code> are
52 * copied, the objects themselves are not copied.
53 *
54 * @param source The <code>Properties</code> to copy.
55 *
56 */
57
58 public Properties(Properties source)
59 {
60 super(source);
61 }
62
63
64 /* Management. */
65
66
67 /**
68 * Clears (removes) all properties.
69 *
70 */
71
72 public void clearProperties()
73 {
74 // remove all child nodes
75 this.removeChildNodes();
76 }
77
78 /**
79 * Removes the specified property and all of its children.
80 *
81 * @param path Path of the property.
82 *
83 */
84
85 public void removeProperty(String path)
86 {
87 // get node for property
88 OsmNode node = SimpleOsmPath.getNode(this, path, false);
89
90 // check if the node exists
91 if (node == null) return;
92
93 // remove the node from its parent
94 node.getParentNode().removeChild(node);
95 }
96
97 /**
98 * Returns true if the specified property exists.
99 *
100 * @param path Path of the property.
101 *
102 * @return True if the property exists, false otherwise.
103 *
104 */
105
106 public boolean propertyExists(String path)
107 {
108 // get node for property
109 OsmNode node = SimpleOsmPath.getNode(this, path, false);
110
111 // if node is null, then propery does not exist
112 return (node != null);
113 }
114
115 /**
116 * Returns a duplicate of this <code>Properties</code>.
117 *
118 * Only the references to the objects stored in this <code>Properties</code> are
119 * copied, the objects themselves are not copied.
120 *
121 * @return A new <code>Properties</code> object.
122 *
123 */
124
125 public Properties cloneProperties()
126 {
127 return new Properties(this);
128 }
129
130 /**
131 * Duplicates the supplied <code>Properties</code>. Existing values stored in
132 * this properties will be overridden.
133 *
134 * Only the references to the objects stored in this <code>Properties</code> are
135 * copied, the objects themselves are not copied.
136 *
137 * @param source The <code>Properties</code> object to duplicate.
138 *
139 */
140
141 public void cloneProperties(Properties source)
142 {
143 super.cloneOsm(source);
144 }
145
146
147 /* Value access. */
148
149
150 /**
151 * Returns the <code>Object</code> value of the specified property.
152 *
153 * @param path Path of the property.
154 *
155 * @return The <code>Object</code> value of the property.
156 *
157 */
158
159 public Object getObject(String path)
160 {
161 // get node for property
162 OsmNode node = SimpleOsmPath.getNode(this, path, false);
163
164 // check for non existant property
165 if (node == null) return null;
166
167 // get value of node
168 return node.getNodeValue();
169 }
170
171 /**
172 * Sets the <code>Object</code> value of the specified property.
173 *
174 * @param path Path of the object.
175 * @param value The <code>Object</code> value of the property.
176 *
177 */
178
179 public void setObject(String path, Object value)
180 {
181 // get node for property
182 OsmNode node = SimpleOsmPath.getNode(this, path, true);
183
184 // set value of node
185 node.setNodeValue(value);
186 }
187
188 /**
189 * Returns the <code>String value of the specified property.
190 *
191 * @param path Path of the property.
192 *
193 * @return The <code>String</code> value of the property.
194 *
195 */
196
197 public String getString(String path)
198 {
199 // get node for property
200 OsmNode node = SimpleOsmPath.getNode(this, path, false);
201
202 // check for non existant property
203 if (node == null) return null;
204
205 // check for value
206 if (node.getNodeValue() == null) return null;
207
208 // get value of node
209 return node.getNodeValue().toString();
210 }
211
212 /**
213 * Sets the <code>String</code> value of the specified property.
214 *
215 * @param path Path of the object.
216 * @param value The <code>String</code> value of the property.
217 *
218 */
219
220 public void setString(String path, String value)
221 {
222 // get node for property
223 OsmNode node = SimpleOsmPath.getNode(this, path, true);
224
225 // set value of node
226 node.setNodeValue(value);
227 }
228
229 /**
230 * Returns the <code>boolean</code> value of the specified property.
231 *
232 * @param path Path of the property.
233 *
234 * @return The <code>boolean</code> value of the property.
235 *
236 */
237
238 public boolean getBoolean(String path)
239 {
240 // get node for property
241 OsmNode node = SimpleOsmPath.getNode(this, path, false);
242
243 // check for non existant property
244 if (node == null) return false;
245
246 // check for value
247 if (node.getNodeValue() == null) return false;
248
249 // get value of node
250 return ((Boolean)node.getNodeValue()).booleanValue();
251 }
252
253 /**
254 * Sets the <code>boolean</code> value of the specified property.
255 *
256 * @param path Path of the object.
257 * @param value The <code>boolean</code> value of the property.
258 *
259 */
260
261 public void setBoolean(String path, boolean value)
262 {
263 // get node for property
264 OsmNode node = SimpleOsmPath.getNode(this, path, true);
265
266 // set value of node
267 node.setNodeValue(new Boolean(value));
268 }
269
270 /**
271 * Returns the <code>byte</code> value of the specified property.
272 *
273 * @param path Path of the property.
274 *
275 * @return The <code>byte</code> value of the property.
276 *
277 */
278
279 public byte getByte(String path)
280 {
281 // get node for property
282 OsmNode node = SimpleOsmPath.getNode(this, path, false);
283
284 // check for non existant property
285 if (node == null) return 0;
286
287 // check for value
288 if (node.getNodeValue() == null) return 0;
289
290 // check for String value conversion
291 if (node.getNodeValue() instanceof String)
292 {
293 try
294 {
295 return Byte.parseByte((String)node.getNodeValue());
296 }
297 catch (NumberFormatException exception)
298 {
299 return 0;
300 }
301 }
302
303 // get value of node
304 return ((Number)node.getNodeValue()).byteValue();
305 }
306
307 /**
308 * Sets the <code>byte</code> value of the specified property.
309 *
310 * @param path Path of the object.
311 * @param value The <code>byte</code> value of the property.
312 *
313 */
314
315 public void setByte(String path, byte value)
316 {
317 // get node for property
318 OsmNode node = SimpleOsmPath.getNode(this, path, true);
319
320 // set value of node
321 node.setNodeValue(new Byte(value));
322 }
323
324 /**
325 * Returns the <code>short</code> value of the specified property.
326 *
327 * @param path Path of the property.
328 *
329 * @return The <code>short</code> value of the property.
330 *
331 */
332
333 public short getShort(String path)
334 {
335 // get node for property
336 OsmNode node = SimpleOsmPath.getNode(this, path, false);
337
338 // check for non existant property
339 if (node == null) return 0;
340
341 // check for value
342 if (node.getNodeValue() == null) return 0;
343
344 // check for String value conversion
345 if (node.getNodeValue() instanceof String)
346 {
347 try
348 {
349 return Short.parseShort((String)node.getNodeValue());
350 }
351 catch (NumberFormatException exception)
352 {
353 return 0;
354 }
355 }
356
357 // get value of node
358 return ((Number)node.getNodeValue()).shortValue();
359 }
360
361 /**
362 * Sets the <code>short</code> value of the specified property.
363 *
364 * @param path Path of the object.
365 * @param value The <code>short</code> value of the property.
366 *
367 */
368
369 public void setShort(String path, short value)
370 {
371 // get node for property
372 OsmNode node = SimpleOsmPath.getNode(this, path, true);
373
374 // set value of node
375 node.setNodeValue(new Short(value));
376 }
377
378 /**
379 * Returns the <code>int</code> value of the specified property.
380 *
381 * @param path Path of the property.
382 *
383 * @return The <code>int</code> value of the property.
384 *
385 */
386
387 public int getInt(String path)
388 {
389 // get node for property
390 OsmNode node = SimpleOsmPath.getNode(this, path, false);
391
392 // check for non existant property
393 if (node == null) return 0;
394
395 // check for value
396 if (node.getNodeValue() == null) return 0;
397
398 // check for String value conversion
399 if (node.getNodeValue() instanceof String)
400 {
401 try
402 {
403 return Integer.parseInt((String)node.getNodeValue());
404 }
405 catch (NumberFormatException exception)
406 {
407 return 0;
408 }
409 }
410
411 // get value of node
412 return ((Number)node.getNodeValue()).intValue();
413 }
414
415 /**
416 * Sets the <code>int</code> value of the specified property.
417 *
418 * @param path Path of the object.
419 * @param value The <code>int</code> value of the property.
420 *
421 */
422
423 public void setInt(String path, int value)
424 {
425 // get node for property
426 OsmNode node = SimpleOsmPath.getNode(this, path, true);
427
428 // set value of node
429 node.setNodeValue(new Integer(value));
430 }
431
432 /**
433 * Returns the <code>long</code> value of the specified property.
434 *
435 * @param path Path of the property.
436 *
437 * @return The <code>long</code> value of the property.
438 *
439 */
440
441 public long getLong(String path)
442 {
443 // get node for property
444 OsmNode node = SimpleOsmPath.getNode(this, path, false);
445
446 // check for non existant property
447 if (node == null) return 0;
448
449 // check for value
450 if (node.getNodeValue() == null) return 0;
451
452 // check for String value conversion
453 if (node.getNodeValue() instanceof String)
454 {
455 try
456 {
457 return Long.parseLong((String)node.getNodeValue());
458 }
459 catch (NumberFormatException exception)
460 {
461 return 0;
462 }
463 }
464
465 // get value of node
466 return ((Number)node.getNodeValue()).longValue();
467 }
468
469 /**
470 * Sets the <code>long</code> value of the specified property.
471 *
472 * @param path Path of the object.
473 * @param value The <code>long</code> value of the property.
474 *
475 */
476
477 public void setLong(String path, long value)
478 {
479 // get node for property
480 OsmNode node = SimpleOsmPath.getNode(this, path, true);
481
482 // set value of node
483 node.setNodeValue(new Long(value));
484 }
485
486 /**
487 * Returns the <code>float</code> value of the specified property.
488 *
489 * @param path Path of the property.
490 *
491 * @return The <code>float</code> value of the property.
492 *
493 */
494
495 public float getFloat(String path)
496 {
497 // get node for property
498 OsmNode node = SimpleOsmPath.getNode(this, path, false);
499
500 // check for non existant property
501 if (node == null) return 0.0f;
502
503 // check for value
504 if (node.getNodeValue() == null) return 0.0f;
505
506 // check for String value conversion
507 if (node.getNodeValue() instanceof String)
508 {
509 try
510 {
511 return Float.parseFloat((String)node.getNodeValue());
512 }
513 catch (NumberFormatException exception)
514 {
515 return 0.0f;
516 }
517 }
518
519 // get value of node
520 return ((Number)node.getNodeValue()).floatValue();
521 }
522
523 /**
524 * Sets the <code>float</code> value of the specified property.
525 *
526 * @param path Path of the object.
527 * @param value The <code>float</code> value of the property.
528 *
529 */
530
531 public void setFloat(String path, float value)
532 {
533 // get node for property
534 OsmNode node = SimpleOsmPath.getNode(this, path, true);
535
536 // set value of node
537 node.setNodeValue(new Float(value));
538 }
539
540 /**
541 * Returns the <code>double</code> value of the specified property.
542 *
543 * @param path Path of the property.
544 *
545 * @return The <code>double</code> value of the property.
546 *
547 */
548
549 public double getDouble(String path)
550 {
551 // get node for property
552 OsmNode node = SimpleOsmPath.getNode(this, path, false);
553
554 // check for non existant property
555 if (node == null) return 0.0;
556
557 // check for value
558 if (node.getNodeValue() == null) return 0.0;
559
560 // check for String value conversion
561 if (node.getNodeValue() instanceof String)
562 {
563 try
564 {
565 return Double.parseDouble((String)node.getNodeValue());
566 }
567 catch (NumberFormatException exception)
568 {
569 return 0.0;
570 }
571 }
572
573 // get value of node
574 return ((Number)node.getNodeValue()).doubleValue();
575 }
576
577 /**
578 * Sets the <code>double</code> value of the specified property.
579 *
580 * @param path Path of the object.
581 * @param value The <code>double</code> value of the property.
582 *
583 */
584
585 public void setDouble(String path, double value)
586 {
587 // get node for property
588 OsmNode node = SimpleOsmPath.getNode(this, path, true);
589
590 // set value of node
591 node.setNodeValue(new Double(value));
592 }
593
594
595 /* Querying. */
596
597
598 /**
599 * Selects the properties specified by the query expression. A <code>Map</code>
600 * of property path/value pairs are returned.
601 *
602 * @param expression Query expression to select properties.
603 * @param includeChildren Should child nodes be selected.
604 *
605 * @return A <code>Map</code> of property path/value pairs.
606 *
607 */
608
609 public Map getProperties(String expression, boolean includeChildren)
610 {
611 HashMap result = new HashMap();
612
613 // select nodes
614 Collection nodes = QueryOsmPath.selectNodes(this, expression);
615
616 // collect values
617 getProperties(nodes, includeChildren, result);
618
619 return result;
620 }
621
622 /**
623 * Selects the properties specified by the query expression. The selected properties
624 * are stored in the supplied <code>Map</code>.
625 *
626 * @param nodes The {@link OsmNode OsmNodes} to retrieve values from.
627 * @param includeChildren Should child nodes be selected.
628 * @param result The <code>Map</code> to store the selected path/value pairs.
629 *
630 */
631
632 protected void getProperties(Collection nodes, boolean includeChildren, Map result)
633 {
634 Iterator valueIterator = nodes.iterator();
635
636 // retrieve values from each node
637 while (valueIterator.hasNext())
638 {
639 OsmNode node = (OsmNode)valueIterator.next();
640
641 // only add the list if there a valid value
642 if (node.getNodeValue() != null)
643 {
644 // place path/value into result
645 result.put(node.getNodePath(), node.getNodeValue());
646 }
647
648 // if children are wanted, get them now
649 if (includeChildren)
650 {
651 // visit children
652 getProperties(node.getChildNodes(), includeChildren, result);
653 }
654 }
655 }
656 }
657