001: // ObservableProperties.java
002: // $Id: ObservableProperties.java,v 1.8 2000/08/16 21:37:58 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.util;
007:
008: import java.util.Hashtable;
009: import java.util.Properties;
010: import java.util.StringTokenizer;
011:
012: import java.io.File;
013:
014: /**
015: * An enhanced property class that provides support to monitor changes.
016: * This class extends the basic properties class of Java, by providing
017: * monitoring support. It also provides more type conversion.
018: * @see PropertyMonitoring
019: */
020:
021: public class ObservableProperties extends Properties {
022: private static final boolean debug = false;
023:
024: PropertyMonitoring observers[] = null;
025: int observers_count = 0;
026:
027: /**
028: * Subscribe for property monitoring.
029: * @param observer The object that handles the PropertyMonitoring
030: * interface.
031: */
032:
033: public synchronized void registerObserver(PropertyMonitoring o) {
034: // Try looking for an empty slot:
035: for (int i = 0; i < observers.length; i++) {
036: if (observers[i] == null) {
037: observers[i] = o;
038: return;
039: }
040: }
041: // Add the observer to the registered oned, resizing array if needed
042: if (observers_count + 1 >= observers.length) {
043: PropertyMonitoring m[] = new PropertyMonitoring[observers.length * 2];
044: System.arraycopy(observers, 0, m, 0, observers.length);
045: observers = m;
046: }
047: observers[observers_count++] = o;
048: }
049:
050: /**
051: * Unsubscribe this object from the observers list.
052: * @param observer The observer to unsubscribe.
053: * @return A boolean <strong>true</strong> if object was succesfully
054: * unsubscribed, <strong>false</strong> otherwise.
055: */
056:
057: public synchronized boolean unregisterObserver(PropertyMonitoring o) {
058: for (int i = 0; i < observers.length; i++) {
059: if (observers[i] == o) {
060: observers[i] = null;
061: return true;
062: }
063: }
064: return false;
065: }
066:
067: /**
068: * Update a property value.
069: * Assign a value to a property. If the property value has really changed
070: * notify our observers of the change.
071: * @param name The name of the property to assign.
072: * @param value The new value for this property, or <strong>null</strong>
073: * if the property setting is to be cancelled.
074: * @return A boolean <strong>true</strong> if change was accepted by
075: * our observers, <strong>false</strong> otherwise.
076: */
077:
078: public synchronized boolean putValue(String name, String value) {
079: if (debug)
080: System.out.println("ObservableProperties: put " + name
081: + "=[" + value + "]");
082: // If null value, remove the prop definition:
083: if (value == null) {
084: super .remove(name);
085: return true;
086: }
087: // Otherwise, proceed:
088: String old = (String) get(name);
089: if ((old == null) || (!old.equals(value))) {
090: super .put(name, value);
091: for (int i = 0; i < observers.length; i++) {
092: if (observers[i] == null)
093: continue;
094: if (debug)
095: System.out
096: .println("ObservableProperties: notifies "
097: + observers[i]);
098: if (!observers[i].propertyChanged(name)) {
099: if (old != null)
100: super .put(name, old);
101: return false;
102: }
103: }
104: }
105: return true;
106: }
107:
108: /**
109: * Get this property value, as a boolean.
110: * @param name The name of the property to be fetched.
111: * @param def The default value, if the property isn't defined.
112: * @return A Boolean instance.
113: */
114:
115: public boolean getBoolean(String name, boolean def) {
116: String v = getProperty(name, null);
117: if (v != null)
118: return "true".equalsIgnoreCase(v) ? true : false;
119: return def;
120: }
121:
122: /**
123: * Get this property value, as a String.
124: * @param name The name of the property to be fetched.
125: * @param def The default value, if the property isn't defined.
126: * @return An instance of String.
127: */
128:
129: public String getString(String name, String def) {
130: String v = getProperty(name, null);
131: if (v != null)
132: return v;
133: return def;
134: }
135:
136: /**
137: * Get this property as a String array.
138: * By convention, properties that are get as string arrays should be
139: * encoded as a <strong>|</strong> separated list of Strings.
140: * @param name The property's name.
141: * @param def The default value (if undefined).
142: * @return A String array, or <strong>null</strong> if the property
143: * is undefined.
144: */
145:
146: public String[] getStringArray(String name, String def[]) {
147: String v = getProperty(name, null);
148: if (v == null)
149: return def;
150: // Parse the property value:
151: StringTokenizer st = new StringTokenizer(v, "|");
152: int len = st.countTokens();
153: String ret[] = new String[len];
154: for (int i = 0; i < ret.length; i++) {
155: ret[i] = st.nextToken();
156: }
157: return ret;
158: }
159:
160: /**
161: * Get this property value, as an integer.
162: * @param name The name of the property to be fetched.
163: * @param def The default value, if the property isn't defined.
164: * @return An integer value.
165: */
166:
167: public int getInteger(String name, int def) {
168: String v = getProperty(name, null);
169: if (v != null) {
170: try {
171: if (v.startsWith("0x")) {
172: return Integer.valueOf(v.substring(2), 16)
173: .intValue();
174: }
175: if (v.startsWith("#")) {
176: return Integer.valueOf(v.substring(1), 16)
177: .intValue();
178: }
179: return Integer.valueOf(v).intValue();
180: } catch (NumberFormatException e) {
181: }
182: }
183: return def;
184: }
185:
186: public long getLong(String name, long def) {
187: String v = getProperty(name, null);
188: if (v != null) {
189: try {
190: return Long.valueOf(v).longValue();
191: } catch (NumberFormatException e) {
192: }
193: }
194: return def;
195: }
196:
197: /**
198: * Get this property value, as a double.
199: * @param name The name of the property.
200: * @param def The default value if undefined.
201: * @return A double value.
202: */
203:
204: public double getDouble(String name, double def) {
205: String v = getProperty(name, null);
206: if (v != null) {
207: try {
208: return Double.valueOf(v).doubleValue();
209: } catch (NumberFormatException ex) {
210: }
211: }
212: return def;
213: }
214:
215: /**
216: * Get this property value, as a File.
217: * @param name The name of the property to be fetched.
218: * @param def The default value, if the property isn't defined.
219: * @return An instance of File.
220: */
221:
222: public File getFile(String name, File def) {
223: String v = getProperty(name, null);
224: if (v != null)
225: return new File(v);
226: return def;
227: }
228:
229: /**
230: * Build an httpdProperties instance from a Properties instance.
231: * @param props The Properties instance.
232: */
233:
234: public ObservableProperties(Properties props) {
235: super (props);
236: this .observers = new PropertyMonitoring[5];
237: this .observers_count = 0;
238: }
239:
240: }
|