// ObservableProperties.java
// $Id: ObservableProperties.java,v 1.10 2013/10/18 13:42:30 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.util;
import java.io.File;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* An enhanced property class that provides support to monitor changes.
* This class extends the basic properties class of Java, by providing
* monitoring support. It also provides more type conversion.
*
* @see PropertyMonitoring
*/
public class ObservableProperties extends Properties {
private static final boolean debug = false;
private static final long serialVersionUID = 1527682518013288353L;
PropertyMonitoring observers[] = null;
int observers_count = 0;
/**
* Build an httpdProperties instance from a Properties instance.
*
* @param props The Properties instance.
*/
public ObservableProperties(Properties props) {
super(props);
this.observers = new PropertyMonitoring[5];
this.observers_count = 0;
}
/**
* Subscribe for property monitoring.
*
* @param observer The object that handles the PropertyMonitoring
* interface.
*/
public synchronized void registerObserver(PropertyMonitoring observer) {
// Try looking for an empty slot:
for (int i = 0; i < observers.length; i++) {
if (observers[i] == null) {
observers[i] = observer;
return;
}
}
// Add the observer to the registered oned, resizing array if needed
if (observers_count + 1 >= observers.length) {
PropertyMonitoring m[] = new PropertyMonitoring[observers.length * 2];
System.arraycopy(observers, 0, m, 0, observers.length);
observers = m;
}
observers[observers_count++] = observer;
}
/**
* Unsubscribe this object from the observers list.
*
* @param observer The observer to unsubscribe.
* @return A boolean <strong>true</strong> if object was succesfully
* unsubscribed, <strong>false</strong> otherwise.
*/
public synchronized boolean unregisterObserver(PropertyMonitoring observer) {
for (int i = 0; i < observers.length; i++) {
if (observers[i] == observer) {
observers[i] = null;
return true;
}
}
return false;
}
/**
* Update a property value.
* Assign a value to a property. If the property value has really changed
* notify our observers of the change.
*
* @param name The name of the property to assign.
* @param value The new value for this property, or <strong>null</strong>
* if the property setting is to be cancelled.
* @return A boolean <strong>true</strong> if change was accepted by
* our observers, <strong>false</strong> otherwise.
*/
public synchronized boolean putValue(String name, String value) {
if (debug) {
System.out.println("ObservableProperties: put " + name + "=[" + value
+ "]");
}
// If null value, remove the prop definition:
if (value == null) {
super.remove(name);
return true;
}
// Otherwise, proceed:
String old = (String) get(name);
if ((old == null) || (!old.equals(value))) {
super.put(name, value);
for (PropertyMonitoring observer : observers) {
if (debug) {
if (observer != null) {
System.out.println("ObservableProperties: notifies "
+ observer);
}
}
if (observer != null && !observer.propertyChanged(name)) {
if (old != null) {
super.put(name, old);
}
return false;
}
}
}
return true;
}
/**
* Get this property value, as a boolean.
*
* @param name The name of the property to be fetched.
* @param def The default value, if the property isn't defined.
* @return A Boolean instance.
*/
public boolean getBoolean(String name, boolean def) {
String v = getProperty(name, null);
if (v != null) {
return Boolean.parseBoolean(v);
}
return def;
}
/**
* Get this property value, as a String.
*
* @param name The name of the property to be fetched.
* @param def The default value, if the property isn't defined.
* @return An instance of String.
*/
public String getString(String name, String def) {
String v = getProperty(name, null);
return (v == null) ? def : v;
}
/**
* Get this property as a String array.
* By convention, properties that are get as string arrays should be
* encoded as a <strong>|</strong> separated list of Strings.
*
* @param name The property's name.
* @param def The default value (if undefined).
* @return A String array, or <strong>null</strong> if the property
* is undefined.
*/
public String[] getStringArray(String name, String def[]) {
String v = getProperty(name, null);
if (v == null) {
return def;
}
// Parse the property value:
StringTokenizer st = new StringTokenizer(v, "|");
int len = st.countTokens();
String ret[] = new String[len];
for (int i = 0; i < ret.length; i++) {
ret[i] = st.nextToken();
}
return ret;
}
/**
* Get this property value, as an integer.
*
* @param name The name of the property to be fetched.
* @param def The default value, if the property isn't defined.
* @return An integer value.
*/
public int getInteger(String name, int def) {
String v = getProperty(name, null);
if (v != null) {
try {
if (v.startsWith("0x")) {
return Integer.valueOf(v.substring(2), 16).intValue();
}
if (v.startsWith("#")) {
return Integer.valueOf(v.substring(1), 16).intValue();
}
return Integer.valueOf(v).intValue();
} catch (NumberFormatException e) {
}
}
return def;
}
public long getLong(String name, long def) {
String v = getProperty(name, null);
if (v != null) {
try {
return Long.valueOf(v).longValue();
} catch (NumberFormatException e) {
}
}
return def;
}
/**
* Get this property value, as a double.
*
* @param name The name of the property.
* @param def The default value if undefined.
* @return A double value.
*/
public double getDouble(String name, double def) {
String v = getProperty(name, null);
if (v != null) {
try {
return Double.valueOf(v).doubleValue();
} catch (NumberFormatException ex) {
}
}
return def;
}
/**
* Get this property value, as a File.
*
* @param name The name of the property to be fetched.
* @param def The default value, if the property isn't defined.
* @return An instance of File.
*/
public File getFile(String name, File def) {
String v = getProperty(name, null);
if (v != null)
return new File(v);
return def;
}
}
Webmaster