All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jitsi.impl.configuration.ChangeEventDispatcher Maven / Gradle / Ivy

/*
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jitsi.impl.configuration;

import java.beans.*;
import java.util.*;

import org.jitsi.service.configuration.*;

/**
 * This is a utility class that can be used by objects that support constrained
 * properties.  You can use an instance of this class as a member field and
 * delegate various work to it.
 *
 * @author Emil Ivov
 */
public class ChangeEventDispatcher
{

    /**
     * All property change listeners registered so far.
     */
    private List propertyChangeListeners;

    /**
     * All listeners registered for vetoable change events.
     */
    private List vetoableChangeListeners;

    /**
     * Hashtable for managing property change listeners registered for specific
     * properties. Maps property names to PropertyChangeSupport objects.
     */
    private Map propertyChangeChildren;

    /**
     * Hashtable for managing vetoable change listeners registered for specific
     * properties. Maps property names to PropertyChangeSupport objects.
     */
    private Map vetoableChangeChildren;

    /**
     * The object to be provided as the "source" for any generated events.
     */
    private final Object source;

    /**
     * Constructs a VetoableChangeSupport object.
     *
     * @param sourceObject  The object to be given as the source for any events.
     */
    public ChangeEventDispatcher(Object sourceObject)
    {
        if (sourceObject == null)
            throw new NullPointerException("sourceObject");

        source = sourceObject;
    }

    /**
     * Add a PropertyChangeListener to the listener list.
     * The listener is registered for all properties.
     *
     * @param listener  The PropertyChangeChangeListener to be added
     */
    public synchronized void addPropertyChangeListener(
        PropertyChangeListener listener)
    {
        if (propertyChangeListeners == null)
            propertyChangeListeners = new Vector();

        propertyChangeListeners.add(listener);
    }

    /**
     * Add a PropertyChangeListener for a specific property.  The listener
     * will be invoked only when a call on firePropertyChange names that
     * specific property.
     *
     * @param propertyName  The name of the property to listen on.
     * @param listener  The ConfigurationChangeListener to be added
     */
    public synchronized void addPropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener)
    {
        if (propertyChangeChildren == null)
        {
            propertyChangeChildren =
                new Hashtable();
        }
        ChangeEventDispatcher child = propertyChangeChildren.get(
            propertyName);
        if (child == null)
        {
            child = new ChangeEventDispatcher(source);
            propertyChangeChildren.put(propertyName, child);
        }
        child.addPropertyChangeListener(listener);
    }

    /**
     * Remove a PropertyChangeListener from the listener list.
     * This removes a ConfigurationChangeListener that was registered
     * for all properties.
     *
     * @param listener The PropertyChangeListener to be removed
     */
    public synchronized void removePropertyChangeListener(
        PropertyChangeListener listener)
    {
        if (propertyChangeListeners != null)
            propertyChangeListeners.remove(listener);
    }

    /**
     * Remove a PropertyChangeListener for a specific property.
     *
     * @param propertyName  The name of the property that was listened on.
     * @param listener  The VetoableChangeListener to be removed
     */
    public synchronized void removePropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener)
    {
        if (propertyChangeChildren != null)
        {
            ChangeEventDispatcher child
                = propertyChangeChildren.get(propertyName);

            if (child != null)
                child.removePropertyChangeListener(listener);
        }
    }

    /**
     * Add a VetoableChangeListener to the listener list.
     * The listener is registered for all properties.
     *
     * @param listener  The VetoableChangeListener to be added
     */
    public synchronized void addVetoableChangeListener(
            ConfigVetoableChangeListener listener)
    {
        if (vetoableChangeListeners == null)
        {
            vetoableChangeListeners
                = new Vector();
        }

        vetoableChangeListeners.add(listener);
    }

    /**
     * Remove a VetoableChangeListener from the listener list.
     * This removes a VetoableChangeListener that was registered
     * for all properties.
     *
     * @param listener  The VetoableChangeListener to be removed
     */
    public synchronized void removeVetoableChangeListener(
        ConfigVetoableChangeListener listener)
    {
        if (vetoableChangeListeners != null)
            vetoableChangeListeners.remove(listener);
    }

    /**
     * Add a VetoableChangeListener for a specific property.  The listener
     * will be invoked only when a call on fireVetoableChange names that
     * specific property.
     *
     * @param propertyName  The name of the property to listen on.
     * @param listener  The ConfigurationChangeListener to be added
     */

    public synchronized void addVetoableChangeListener(
        String propertyName,
        ConfigVetoableChangeListener listener)
    {
        if (vetoableChangeChildren == null)
        {
            vetoableChangeChildren
                = new Hashtable();
        }
        ChangeEventDispatcher child = vetoableChangeChildren.get(propertyName);
        if (child == null)
        {
            child = new ChangeEventDispatcher(source);
            vetoableChangeChildren.put(propertyName, child);
        }
        child.addVetoableChangeListener(listener);
    }

    /**
     * Remove a VetoableChangeListener for a specific property.
     *
     * @param propertyName  The name of the property that was listened on.
     * @param listener  The VetoableChangeListener to be removed
     */
    public synchronized void removeVetoableChangeListener(
        String propertyName,
        ConfigVetoableChangeListener listener)
    {
        if (vetoableChangeChildren != null)
        {
            ChangeEventDispatcher child
                = vetoableChangeChildren.get( propertyName );

            if (child != null)
                child.removeVetoableChangeListener(listener);
        }
    }

    /**
     * Report a vetoable property update to any registered listeners.  If
     * no one vetos the change, then fire a new ConfigurationChangeEvent
     * indicating that the change has been accepted. In the case of a
     * PropertyVetoException, end eventdispatch and rethrow the exception
     * 

* No event is fired if old and new are equal and non-null. * * @param propertyName The programmatic name of the property * that is about to change.. * @param oldValue The old value of the property. * @param newValue The new value of the property. */ public void fireVetoableChange(String propertyName, Object oldValue, Object newValue) { if (vetoableChangeListeners != null || vetoableChangeChildren != null) { fireVetoableChange( new PropertyChangeEvent( source, propertyName, oldValue, newValue)); } } /** * Fire a vetoable property update to any registered listeners. If anyone * vetos the change, then the exception will be rethrown by this method. *

* No event is fired if old and new are equal and non-null. * * @param evt The PropertyChangeEvent to be fired. */ public void fireVetoableChange(PropertyChangeEvent evt) { Object oldValue = evt.getOldValue(); Object newValue = evt.getNewValue(); String propertyName = evt.getPropertyName(); if (oldValue != null && newValue != null && oldValue.equals(newValue)) return; ConfigVetoableChangeListener[] targets = null; ChangeEventDispatcher child = null; synchronized (this) { if (vetoableChangeListeners != null) { targets = vetoableChangeListeners.toArray( new ConfigVetoableChangeListener[ vetoableChangeListeners.size()]); } if (vetoableChangeChildren != null && propertyName != null) child = vetoableChangeChildren.get(propertyName); } if (vetoableChangeListeners != null && targets != null) { for (ConfigVetoableChangeListener target : targets) target.vetoableChange(evt); } if (child != null) child.fireVetoableChange(evt); } /** * Report a bound property update to any registered listeners. * No event is fired if old and new are equal and non-null. * * @param propertyName The programmatic name of the property * that was changed. * @param oldValue The old value of the property. * @param newValue The new value of the property. */ public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { firePropertyChange( new PropertyChangeEvent( source, propertyName, oldValue, newValue)); } } /** * Fire an existing PropertyChangeEvent to any registered listeners. * No event is fired if the given event's old and new values are * equal and non-null. * @param evt The PropertyChangeEvent object. */ public void firePropertyChange(PropertyChangeEvent evt) { Object oldValue = evt.getOldValue(); Object newValue = evt.getNewValue(); String propertyName = evt.getPropertyName(); if (oldValue != null && newValue != null && oldValue.equals(newValue)) return; if (propertyChangeListeners != null) { for (PropertyChangeListener target : propertyChangeListeners) target.propertyChange(evt); } if (propertyChangeChildren != null && propertyName != null) { ChangeEventDispatcher child = propertyChangeChildren.get(propertyName); if (child != null) child.firePropertyChange(evt); } } /** * Check if there are any listeners for a specific property. (Generic * listeners count as well) * * @param propertyName the property name. * @return true if there are one or more listeners for the given property */ public synchronized boolean hasPropertyChangeListeners(String propertyName) { if(propertyChangeListeners != null && !propertyChangeListeners.isEmpty()) { // there is a generic listener return true; } if (propertyChangeChildren != null) { ChangeEventDispatcher child = propertyChangeChildren.get(propertyName); if (child != null && child.propertyChangeListeners != null) return!child.propertyChangeListeners.isEmpty(); } return false; } /** * Check if there are any vetoable change listeners for a specific property. * (Generic vetoable change listeners count as well) * * @param propertyName the property name. * @return true if there are one or more listeners for the given property */ public synchronized boolean hasVetoableChangeListeners(String propertyName) { if(vetoableChangeListeners != null && !vetoableChangeListeners.isEmpty()) { // there is a generic listener return true; } if (vetoableChangeChildren != null) { ChangeEventDispatcher child = vetoableChangeChildren.get(propertyName); if (child != null && child.vetoableChangeListeners != null) return!child.vetoableChangeListeners.isEmpty(); } return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy