ObservableProperties.java Source code

Java tutorial

Introduction

Here is the source code for ObservableProperties.java

Source

// ObservableProperties.java
// $Id: ObservableProperties.java,v 1.8 2000/08/16 21:37:58 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

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;

    PropertyMonitoring observers[] = null;

    int observers_count = 0;

    /**
     * Subscribe for property monitoring.
     * 
     * @param observer
     *          The object that handles the PropertyMonitoring interface.
     */

    public synchronized void registerObserver(PropertyMonitoring o) {
        // Try looking for an empty slot:
        for (int i = 0; i < observers.length; i++) {
            if (observers[i] == null) {
                observers[i] = o;
                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++] = o;
    }

    /**
     * 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 o) {
        for (int i = 0; i < observers.length; i++) {
            if (observers[i] == o) {
                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 (int i = 0; i < observers.length; i++) {
                if (observers[i] == null)
                    continue;
                if (debug)
                    System.out.println("ObservableProperties: notifies " + observers[i]);
                if (!observers[i].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 "true".equalsIgnoreCase(v) ? true : false;
        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);
        if (v != null)
            return v;
        return def;
    }

    /**
     * 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;
    }

    /**
     * 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;
    }

}

// PropertyMonitoring.java
// $Id: PropertyMonitoring.java,v 1.3 2000/08/16 21:37:58 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
interface PropertyMonitoring {

    /**
     * The callback method, invoked when any property change occurs.
     * 
     * @param name
     *          The name of the property that changed.
     * @return A boolean, if <strong>true</strong>, accept the new property
     *         value, otherwise, reject it and reset the property to its old
     *         value.
     */

    public boolean propertyChanged(String name);
}