001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.util;
024:
025: import java.util.Collection;
026: import java.util.Iterator;
027: import java.util.Map;
028: import java.util.Properties;
029:
030: /**
031: * TODO Add UserProperties Overview JavaDoc.
032: * <p>
033: *
034: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
035: * @version 1.0
036: */
037: public class UserProperties extends Properties {
038:
039: private static final long serialVersionUID = 6738010317137968113L;
040:
041: /**
042: * Creates new properties object with given defaults.
043: * <p>
044: *
045: * @see Properties#Properties(java.util.Properties)
046: * @param defaults default properties object to use.
047: */
048: public UserProperties(Properties defaults) {
049:
050: super (defaults);
051: }
052:
053: /**
054: * Creates new properties object with no defaults.
055: * <p>
056: *
057: * @see Properties#Properties()
058: */
059: public UserProperties() {
060:
061: super ();
062: }
063:
064: /**
065: * Removes a property from current mapping.
066: * <p>
067: *
068: * @param property property name to remove.
069: * @return property as a string, null if the property does not exist.
070: */
071: public String removeProperty(String property) {
072:
073: try {
074: return super .remove(property.toLowerCase().trim())
075: .toString();
076: } catch (NullPointerException npe) {
077: return null;
078: }
079: }
080:
081: /**
082: * Renames an existing property to a new name.
083: * <p>
084: *
085: * @param oldName the old property name to change.
086: * @param newName property name to change the oldName to.
087: */
088: public synchronized final void renameProperty(String oldName,
089: String newName) {
090:
091: if (containsKey(oldName)) {
092: Object value = getObjectProperty(oldName);
093: if (value == null) {
094: throw new NullPointerException(
095: "Cannot rename non-existent property.");
096: }
097: remove(oldName);
098: put(newName, value);
099: rehash();
100: } else if (!containsKey(newName)) {
101: put(newName, "");
102: }
103: }
104:
105: /**
106: * Takes the a list of keys then iterators through the list and validates that all keys are contained as keys with
107: * the UserProperties.
108: *
109: * @param keySet the keyset to validate againist
110: * @return false if the key is not contained
111: */
112: public boolean containsAllKeys(Collection keySet) {
113:
114: if (keySet == null || keySet.isEmpty()) {
115: return isEmpty();
116: }
117:
118: synchronized (keySet) {
119: Iterator itr = keySet.iterator();
120: while (itr.hasNext()) {
121: if (!containsKey(itr.next())) {
122: return false;
123: }
124: }
125: }
126: return true;
127: }
128:
129: /**
130: * Removes all keys from map.
131: * <p>
132: * Takes the keys from map and removes them from this object. In terms of set theory the properties are removed by
133: * the intersection of the given map and this object.
134: *
135: * @param map map that contains the keys to removes.
136: */
137: public synchronized final void removeAll(Map map) {
138:
139: Iterator i = map.keySet().iterator();
140: synchronized (this ) {
141: while (i.hasNext()) {
142: remove(i.next());
143: }
144: }
145: }
146:
147: /**
148: * Associates a string representing the specified boolean value.
149: * <p>
150: *
151: * @param key key with which the string form of value is to be associated.
152: * @param value value whose boolean form is to be associated with key.
153: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
154: * @see #getBoolean(String, boolean)
155: */
156: public final void putBoolean(String key, boolean value) {
157:
158: setObjectProperty(key, Boolean.toString(value));
159: }
160:
161: /**
162: * Associates a string representing the specified int value.
163: * <p>
164: *
165: * @param key key with which the string form of value is to be associated.
166: * @param value value whose int form is to be associated with key.
167: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
168: * @see #getInt(String, int)
169: */
170: public final void putInt(String key, int value) {
171:
172: setObjectProperty(key, Integer.toString(value));
173: }
174:
175: /**
176: * Associates a string representing the specified double value.
177: * <p>
178: *
179: * @param key key with which the string form of value is to be associated.
180: * @param value value whose double form is to be associated with key.
181: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
182: * @see #getDouble(String, double)
183: */
184:
185: public final void putDouble(String key, double value) {
186:
187: setObjectProperty(key, Double.toString(value));
188: }
189:
190: /**
191: * Associates a string representing the specified float value.
192: * <p>
193: *
194: * @param key key with which the string form of value is to be associated.
195: * @param value value whose float form is to be associated with key.
196: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
197: * @see #getFloat(String, float)
198: */
199: public final void putFloat(String key, float value) {
200:
201: setObjectProperty(key, Float.toString(value));
202: }
203:
204: /**
205: * Associates a string representing the specified long value.
206: * <p>
207: *
208: * @param key key with which the string form of value is to be associated.
209: * @param value value whose long form is to be associated with key.
210: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
211: * @see #getLong(String, long)
212: */
213: public final void putLong(String key, long value) {
214:
215: setObjectProperty(key, Long.toString(value));
216: }
217:
218: /**
219: * Sets the short property with the given key name.
220: * <p>
221: *
222: * @param key key with which the string form of value is to be associated.
223: * @param value value whose long form is to be associated with key.
224: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
225: * @see #getShort(String, short)
226: */
227:
228: public final void putShort(String key, short value) {
229:
230: setObjectProperty(key, Short.toString(value));
231: }
232:
233: /**
234: * Sets the byte property with the given key name.
235: * <p>
236: *
237: * @param key key with which the string form of value is to be associated.
238: * @param value value whose byte form is to be associated with key.
239: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
240: * @see #getShort(String, short)
241: */
242: public final void putByte(String key, byte value) {
243:
244: setObjectProperty(key, Byte.toString(value));
245: }
246:
247: /**
248: * Associates a string representing the specified String value.
249: * <p>
250: *
251: * @param key key with which the string form of value is to be associated.
252: * @param value value whose String form is to be associated with key.
253: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
254: * @see #get(String, String)
255: */
256: public final void put(String key, String value) {
257:
258: setObjectProperty(key, value);
259: }
260:
261: /**
262: * Returns the boolean value of the string associated with the specified key.
263: * <p>
264: *
265: * @param key key whose associated value is to be returned as a double.
266: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
267: * the associated value cannot be interpreted as a boolean.
268: * @return the boolean value represented by the string associated with <tt>key</tt> in this object, or
269: * <tt>def</tt> if the associated value does not exist or cannot be interpreted as a boolean.
270: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
271: * @see #putBoolean(String, boolean)
272: * @see #get(String,String)
273: */
274: public final boolean getBoolean(String key, boolean def) {
275:
276: Object value = getObjectProperty(key);
277: if (value != null) {
278: if (value instanceof Boolean) {
279: return ((Boolean) value).booleanValue();
280: } else if (value instanceof String) {
281: return Boolean.valueOf((String) value).booleanValue();
282: } else {
283: return def;
284: }
285: }
286: return def;
287: }
288:
289: /**
290: * Returns the boolean value of the string associated with the specified key.
291: * <p>
292: * This returns false as the default value.
293: *
294: * @param key key whose associated value is to be returned as a boolean.
295: * @return the boolean value represented by the string associated with <tt>key</tt> in this object.
296: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
297: * @see #putBoolean(String, boolean)
298: * @see #get(String,String)
299: */
300: public final boolean getBoolean(String key) {
301:
302: return getBoolean(key, false);
303: }
304:
305: /**
306: * Returns the int value of the string associated with the specified key.
307: * <p>
308: *
309: * @param key key whose associated value is to be returned as a int.
310: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
311: * the associated value cannot be interpreted as an int.
312: * @return the boolean value represented by the string associated with <tt>key</tt> in this object, or
313: * <tt>def</tt> if the associated value does not exist or cannot be interpreted as an int.
314: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
315: * @see #putInt(String, int)
316: * @see #get(String,String)
317: */
318:
319: public final int getInt(String key, int def) {
320:
321: Object value = getObjectProperty(key);
322: if (value != null) {
323: if (value instanceof Integer) {
324: return ((Integer) value).intValue();
325: } else if (value instanceof Long) {
326: return ((Long) value).intValue();
327: } else if (value instanceof String) {
328: return Integer.decode((String) value).intValue();
329: } else {
330: return def;
331: }
332: }
333: return def;
334: }
335:
336: /**
337: * Returns the int value of the string associated with the specified key.
338: * <p>
339: * This returns Integer.MIN_VALUE as the default value.
340: *
341: * @param key key whose associated value is to be returned as a double.
342: * @return the int value represented by the string associated with <tt>key</tt> in this object.
343: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
344: * @see #putInt(String, int)
345: * @see #get(String,String)
346: */
347: public final int getInt(String key) {
348:
349: return getInt(key, Integer.MIN_VALUE);
350: }
351:
352: /**
353: * Returns the double value of the string associated with the specified key.
354: * <p>
355: *
356: * @param key key whose associated value is to be returned as a double.
357: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
358: * the associated value cannot be interpreted as a float.
359: * @return the double value represented by the string associated with <tt>key</tt> in this object, or <tt>def</tt>
360: * if the associated value does not exist or cannot be interpreted as a double.
361: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
362: * @see #putDouble(String, double)
363: * @see #get(String,String)
364: */
365: public final double getDouble(String key, double def) {
366:
367: Object value = getObjectProperty(key);
368: if (value != null) {
369: if (value instanceof Double) {
370: return ((Double) value).doubleValue();
371: } else if (value instanceof String) {
372: return Double.parseDouble((String) value);
373: } else {
374: return def;
375: }
376: }
377: return def;
378: }
379:
380: /**
381: * Returns the double value of the string associated with the specified key.
382: * <p>
383: * This will use the constant Double.NaN as the default value.
384: *
385: * @param key key whose associated value is to be returned as a double.
386: * @return the double value represented by the string associated with <tt>key</tt> in this object.
387: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
388: * @see #putDouble(String,double)
389: * @see #get(String,String)
390: */
391: public final double getDouble(String key) {
392:
393: return getDouble(key, Double.NaN);
394: }
395:
396: /**
397: * Returns the float value of the string associated with the specified key.
398: * <p>
399: *
400: * @param key key whose associated value is to be returned as a float.
401: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
402: * the associated value cannot be interpreted as a float.
403: * @return the float value represented by the string associated with <tt>key</tt> in this object, or <tt>def</tt>
404: * if the associated value does not exist or cannot be interpreted as a float.
405: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
406: * @see #putFloat(String, float)
407: * @see #get(String,String)
408: */
409: public final float getFloat(String key, float def) {
410:
411: Object value = getObjectProperty(key);
412: if (value != null) {
413: if (value instanceof Float) {
414: return ((Float) value).floatValue();
415: } else if (value instanceof Double) {
416: return ((Double) value).floatValue();
417: } else if (value instanceof String) {
418: return Float.parseFloat((String) value);
419: } else {
420: return def;
421: }
422: }
423: return def;
424: }
425:
426: /**
427: * Returns the float value of the string associated with the specified key.
428: * <p>
429: * This returns Float.NaN as the default value.
430: *
431: * @param key key whose associated value is to be returned as a float.
432: * @return the float value represented by the string associated with <tt>key</tt> in this object.
433: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
434: * @see #putFloat(String, float)
435: * @see #get(String,String)
436: */
437: public final float getFloat(String key) {
438:
439: return getFloat(key, Float.NaN);
440: }
441:
442: /**
443: * Returns the long value of the string associated with the specified key.
444: * <p>
445: * This returns Long.MIN_VALUE as the default value.
446: *
447: * @param key key whose associated value is to be returned as a long.
448: * @return the long value represented by the string associated with <tt>key</tt> in this object.
449: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
450: * @see #putLong(String, long)
451: * @see #get(String,String)
452: */
453: public final long getLong(String key) {
454:
455: return getLong(key, Long.MIN_VALUE);
456: }
457:
458: /**
459: * Returns the long value of the string associated with the specified key.
460: * <p>
461: *
462: * @param key key whose associated value is to be returned as a long.
463: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
464: * the associated value cannot be interpreted as a long.
465: * @return the long value represented by the string associated with <tt>key</tt> in this object, or <tt>def</tt>
466: * if the associated value does not exist or cannot be interpreted as a long.
467: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
468: * @see #putLong(String, long)
469: * @see #get(String,String)
470: */
471: public final long getLong(String key, long def) {
472:
473: Object value = getObjectProperty(key);
474: if (value != null) {
475: if (value instanceof Long) {
476: return ((Long) value).longValue();
477: } else if (value instanceof String) {
478: return Long.decode((String) value).longValue();
479: } else {
480: return def;
481: }
482: }
483: return def;
484: }
485:
486: /**
487: * Returns the short value of the string associated with the specified key.
488: * <p>
489: * This returns Short.MIN_VALUE as the default value.
490: *
491: * @param key key whose associated value is to be returned as a long.
492: * @return the short value represented by the string associated with <tt>key</tt> in this object.
493: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
494: * @see #putShort(String, short)
495: * @see #get(String,String)
496: */
497: public final short getShort(String key) {
498:
499: return getShort(key, Short.MIN_VALUE);
500: }
501:
502: /**
503: * Returns the short value of the string associated with the specified key.
504: * <p>
505: *
506: * @param key key whose associated value is to be returned as a short.
507: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt> or
508: * the associated value cannot be interpreted as a short.
509: * @return the long value represented by the string associated with <tt>key</tt> in this object, or <tt>def</tt>
510: * if the associated value does not exist or cannot be interpreted as a short.
511: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
512: * @see #putShort(String, short)
513: * @see #get(String,String)
514: */
515: public final short getShort(String key, short def) {
516:
517: Object value = getObjectProperty(key);
518: if (value != null) {
519: if (value instanceof Short) {
520: return ((Short) value).shortValue();
521: } else if (value instanceof Byte) {
522: return ((Byte) value).shortValue();
523: } else if (value instanceof String) {
524: return Short.decode((String) value).shortValue();
525: } else {
526: return def;
527: }
528: }
529: return def;
530: }
531:
532: /**
533: * Returns the String value of the string associated with the specified key.
534: * <p>
535: *
536: * @param key key whose associated value is to be returned as a char.
537: * @param def the value to be returned in the event that this object has no value associated with <tt>key</tt>.
538: * @return the String value represented by the string associated with <tt>key</tt> in this object, or <tt>def</tt>
539: * if the associated value does not exist.
540: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
541: * @see #put(String, String)
542: * @see Properties#getProperty(java.lang.String, java.lang.String)
543: */
544: public final String get(String key, String def) {
545:
546: Object value = getObjectProperty(key.toLowerCase().trim());
547: if (value != null) {
548: return value.toString();
549: }
550: return def;
551: }
552:
553: @Override
554: public final boolean containsKey(Object key) {
555:
556: if (key == null) {
557: return false;
558: } else if (key instanceof String) {
559: return super .containsKey(((String) key).toLowerCase()
560: .trim());
561: }
562: throw new IllegalArgumentException(
563: "Keys for this map must be of type String.");
564: }
565:
566: /**
567: * Returns the String value of the string associated with the specified key.
568: * <p>
569: * This returns <tt>null</tt> as the default value.
570: *
571: * @param key key whose associated value is to be returned as a String.
572: * @return the String value represented by the string associated with <tt>key</tt> in this object.
573: * @throws NullPointerException if <tt>key</tt> is <tt>null</tt>.
574: * @see #put(String, String)
575: */
576: public final String get(String key) {
577:
578: return get(key, null);
579: }
580:
581: @Override
582: public final Object put(Object key, Object value) {
583:
584: if (key instanceof String) {
585: return setObjectProperty((String) key, value);
586: }
587: throw new IllegalArgumentException(
588: "Keys for this map must be of type String.");
589: }
590:
591: @Override
592: public final Object get(Object key) {
593:
594: if (key instanceof String) {
595: return getObjectProperty((String) key);
596: }
597: throw new IllegalArgumentException(
598: "Keys for this map must be of type String.");
599: }
600:
601: @Override
602: public String getProperty(String key, String defaultValue) {
603:
604: return get(key, defaultValue);
605: }
606:
607: @Override
608: public String getProperty(String key) {
609:
610: return get(key, null);
611: }
612:
613: protected Object getObjectProperty(String key) {
614:
615: checkKey(key);
616: String normalized = key.toLowerCase().trim();
617: Object object = super .get(normalized);
618: if (object == null && defaults != null) {
619: return defaults.get(normalized);
620: }
621: return object;
622: }
623:
624: protected Object setObjectProperty(String key, Object value) {
625:
626: checkKey(key);
627: Class clazz = value.getClass();
628: if (isPrimative(clazz) || value instanceof String) {
629: String newKey = key.toLowerCase().trim();
630: return super .put(newKey, value);
631: }
632: throw new IllegalArgumentException(
633: "Invaild Object given only primatives and strings are allowed.");
634: }
635:
636: private boolean isPrimative(Class clazz) {
637:
638: if (clazz.isPrimitive()) {
639: return true;
640: }
641: return (clazz == Boolean.class || clazz == Integer.class
642: || clazz == Long.class || clazz == Short.class
643: || clazz == Byte.class || clazz == Float.class || clazz == Double.class);
644:
645: }
646:
647: // method for validating keys for this object.
648: private static void checkKey(String key) {
649:
650: if (key == null) {
651: throw new NullPointerException("Null Keys are not allowed.");
652: }
653: }
654: }
|