/*
 * @(#)PropertyModel.java  1.1  2005-01-02
 *
 * Copyright (c) 1998-2005 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package ch.randelshofer.util;

import java.util.Properties;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
/**
 * This subclass of java.util.Properties informs registered
 * PropertyChange listeners about changes of the properties.
 *
 * @author  Werner Randelshofer, Hausmatt 10, CH-6405 Immensee, Switzerland
 *
 * @version  1.1 2005-01-02 Method setForwardTarget added.
 * <p>1.0 1998-10-19 Created.
 */
public class PropertyModel
extends Properties {
    /** The list of listeners. */
    private PropertyChangeSupport listeners_ = new PropertyChangeSupport(this);
    private PropertyModel forwardTarget;
    
    /** Add a PropertyChangeListener to the listener list. */
    public void addPropertyChangeListener(PropertyChangeListener l) { 
        listeners_.addPropertyChangeListener(l); 
    }
    /** Remove a PropertyChangeListener to the listener list. */
    public void removePropertyChangeListener(PropertyChangeListener l) { 
        listeners_.removePropertyChangeListener(l); 
    }
    
    /** Puts a property. All registered listeners are informed about
     * the change.
     *
     * @exception  ClassCastException When the key supplied is not an instance
     * of String.
     */
    public Object put(Object key, Object newValue) {
        if (newValue == null) {
            remove(key);
            }
        Object oldValue = super.put(key,newValue);
        listeners_.firePropertyChange( (String)key, oldValue, newValue);
        if (forwardTarget != null) {
            forwardTarget.put(key, newValue);
        }
        return oldValue;
    }
    /** Puts a property. All registered listeners are informed about
     * the change.
     *
     * @exception  ClassCastException When the key supplied is not an instance
     * of String.
     */
    public Object remove(Object key) {
        Object oldValue = super.remove(key);
        listeners_.firePropertyChange( (String)key, oldValue, null);
        if (forwardTarget != null) {
            forwardTarget.remove(key);
        }
        return oldValue;
    }
    /**
     * All putted values are also putted to the forward target.
     *
     * @value target Forward target. Set this to null, if no forwarding shall
     * be done.
     */
    public void setForwardTarget(PropertyModel target) {
        this.forwardTarget = target;
    }
    
    public synchronized Object clone() {
        PropertyModel clone = (PropertyModel)super.clone();
        // don't clone listeners
        clone.listeners_ = new PropertyChangeSupport(clone);
        return clone;
    }
}
