File:  [Public] / java / classes / org / w3c / util / ObservableProperties.java
Revision 1.10: download - view: text, annotated - select for diffs
Fri Oct 18 13:42:30 2013 UTC (11 years, 11 months ago) by ylafon
Branches: MAIN
CVS tags: HEAD
generics + raw types + serializer

// 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