| /******************************************************************************* |
| * Copyright (c) 2007, 2010 Oracle. All rights reserved. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v1.0, which accompanies this distribution |
| * and is available at http://www.eclipse.org/legal/epl-v10.html. |
| * |
| * Contributors: |
| * Oracle - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.jpt.utility.internal.model; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.EventListener; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.jpt.utility.internal.ArrayTools; |
| import org.eclipse.jpt.utility.internal.CollectionTools; |
| import org.eclipse.jpt.utility.internal.HashBag; |
| import org.eclipse.jpt.utility.internal.ListenerList; |
| import org.eclipse.jpt.utility.internal.StringTools; |
| import org.eclipse.jpt.utility.internal.Tools; |
| import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; |
| import org.eclipse.jpt.utility.model.Model; |
| import org.eclipse.jpt.utility.model.event.CollectionAddEvent; |
| import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; |
| import org.eclipse.jpt.utility.model.event.CollectionClearEvent; |
| import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent; |
| import org.eclipse.jpt.utility.model.event.ListAddEvent; |
| import org.eclipse.jpt.utility.model.event.ListChangeEvent; |
| import org.eclipse.jpt.utility.model.event.ListClearEvent; |
| import org.eclipse.jpt.utility.model.event.ListMoveEvent; |
| import org.eclipse.jpt.utility.model.event.ListRemoveEvent; |
| import org.eclipse.jpt.utility.model.event.ListReplaceEvent; |
| import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; |
| import org.eclipse.jpt.utility.model.event.StateChangeEvent; |
| import org.eclipse.jpt.utility.model.event.TreeAddEvent; |
| import org.eclipse.jpt.utility.model.event.TreeChangeEvent; |
| import org.eclipse.jpt.utility.model.event.TreeClearEvent; |
| import org.eclipse.jpt.utility.model.event.TreeRemoveEvent; |
| import org.eclipse.jpt.utility.model.listener.ChangeListener; |
| import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; |
| import org.eclipse.jpt.utility.model.listener.ListChangeListener; |
| import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; |
| import org.eclipse.jpt.utility.model.listener.StateChangeListener; |
| import org.eclipse.jpt.utility.model.listener.TreeChangeListener; |
| |
| /** |
| * Support object that can be used by implementors of the {@link Model} interface. |
| * It provides for state, property, collection, list, and tree change notifications to |
| * listeners. |
| * <p> |
| * <strong>NB1:</strong> There is lots of copy-n-paste code in this class. Nearly all of this duplication |
| * is an effort to prevent the unnecessary creation of new objects (typically event |
| * objects). Since many events are fired when there are no listeners, we postpone |
| * the creation of event objects until we know we have interested listeners. |
| * Most methods have the "non-duplicated" version of the method body commented |
| * out at the top of the current method body. |
| * The hope was that this class would prove to be fairly static and the duplicated |
| * code would not prove onerous; but that has not proven to be |
| * the case, as we have added support for "state" changes, "dirty" notification, |
| * and custom "notifiers", with more to come, I'm sure.... ~bjv |
| * <p> |
| * <strong>NB2:</strong> This class will check to see if, during the firing of events, a listener |
| * on the original, cloned, list of listeners has been removed from the master |
| * list of listeners <em>before</em> it is notified. If the listener has been removed |
| * "concurrently" it will <em>not</em> be notified. |
| * <p> |
| * <strong>NB3:</strong> Any listener that is added during the firing of events will <em>not</em> be |
| * also notified. This is a bit inconsistent with NB2, but seems reasonable |
| * since any added listener should already be in synch with the model. |
| * <p> |
| * <strong>NB4:</strong> This class is serializable, but it will only write out listeners that |
| * are also serializable while silently leaving behind listeners that are not. |
| * |
| * @see Model |
| * @see AbstractModel |
| */ |
| public class ChangeSupport |
| implements Serializable |
| { |
| /** The object to be provided as the "source" for any generated events. */ |
| protected final Model source; |
| |
| /** Associate aspect names to class-specific listener lists. */ |
| private AspectListenerListPair<?>[] aspectListenerListPairs = EMPTY_ASPECT_LISTENER_LIST_PAIR_ARRAY; |
| private static final AspectListenerListPair<?>[] EMPTY_ASPECT_LISTENER_LIST_PAIR_ARRAY = new AspectListenerListPair[0]; |
| |
| private static final long serialVersionUID = 1L; |
| |
| |
| // ********** constructor ********** |
| |
| /** |
| * Construct support for the specified source of change events. |
| * The source cannot be null. |
| */ |
| public ChangeSupport(Model source) { |
| super(); |
| if (source == null) { |
| throw new NullPointerException(); |
| } |
| this.source = source; |
| } |
| |
| |
| // ********** internal implementation ********** |
| |
| /** |
| * Add a listener that listens to all the events of the specified type and |
| * carrying the specified aspect name. |
| * Neither the aspect name nor the listener can be null. |
| */ |
| protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, String aspectName, L listener) { |
| ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); |
| if (aspectListenerList == null) { |
| this.aspectListenerListPairs = ArrayTools.add(this.aspectListenerListPairs, new SimpleAspectListenerListPair<L>(listenerClass, aspectName, listener)); |
| } else { |
| aspectListenerList.add(listener); |
| } |
| } |
| |
| /** |
| * Add a listener that listens to all the events of the specified type. |
| * The listener cannot be null. |
| */ |
| protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, L listener) { |
| ListenerList<L> listenerList = this.getListenerList(listenerClass); |
| if (listenerList == null) { |
| this.aspectListenerListPairs = ArrayTools.add(this.aspectListenerListPairs, new NullAspectListenerListPair<L>(listenerClass, listener)); |
| } else { |
| listenerList.add(listener); |
| } |
| } |
| |
| /** |
| * Remove a listener that has been registered for all the |
| * events of the specified type and carrying the specified aspect name. |
| * Neither the aspect name nor the listener can be null. |
| */ |
| protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, String aspectName, L listener) { |
| ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); |
| if (aspectListenerList == null) { |
| throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$ |
| } |
| aspectListenerList.remove(listener); // leave the pair, even if the listener list is empty? |
| } |
| |
| /** |
| * Remove a listener that has been registered for all the events of the specified type. |
| * The listener cannot be null. |
| */ |
| protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, L listener) { |
| ListenerList<L> listenerList = this.getListenerList(listenerClass); |
| if (listenerList == null) { |
| throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$ |
| } |
| listenerList.remove(listener); // leave the pair, even if the listener list is empty? |
| } |
| |
| /** |
| * Return the listener list for the specified listener class and aspect name. |
| * Return null if the listener list is not present. |
| * The aspect name cannot be null. |
| */ |
| protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass, String aspectName) { |
| // put in a null check to simplify calling code |
| if (aspectName == null) { |
| throw new NullPointerException(); |
| } |
| return this.getListenerList_(listenerClass, aspectName); |
| } |
| |
| /** |
| * Return the listener list for the specified listener class. |
| * Return null if the listener list is not present. |
| */ |
| protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass) { |
| return this.getListenerList_(listenerClass, null); |
| } |
| |
| /** |
| * Return the listener list for the specified listener class and aspect name. |
| * Return null if the listener list is not present. |
| */ |
| protected synchronized <L extends EventListener> ListenerList<L> getListenerList_(Class<L> listenerClass, String aspectName) { |
| for (AspectListenerListPair<?> pair : this.aspectListenerListPairs) { |
| if (pair.matches(listenerClass, aspectName)) { |
| @SuppressWarnings("unchecked") ListenerList<L> aspectListenerList = (ListenerList<L>) pair.listenerList; |
| return aspectListenerList; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return whether there are any listeners for the specified listener class |
| * and aspect name. |
| */ |
| protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass, String aspectName) { |
| ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); |
| if ((aspectListenerList != null) && ! aspectListenerList.isEmpty()) { |
| return true; |
| } |
| return this.hasAnyChangeListeners(); // check for any general purpose listeners |
| } |
| |
| /** |
| * Return whether there are no listeners for the specified listener class |
| * and aspect name. |
| */ |
| protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass, String aspectName) { |
| return ! this.hasAnyListeners(listenerClass, aspectName); |
| } |
| |
| /** |
| * Return whether there are any listeners for the specified listener class. |
| */ |
| protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass) { |
| ListenerList<L> aspectListenerList = this.getListenerList(listenerClass); |
| if ((aspectListenerList != null) && ! aspectListenerList.isEmpty()) { |
| return true; |
| } |
| // check for any general purpose listeners (unless that's what we're already doing) |
| return (listenerClass == this.getChangeListenerClass()) ? false : this.hasAnyChangeListeners(); |
| } |
| |
| /** |
| * Return whether there are no listeners for the specified listener class. |
| */ |
| protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass) { |
| return ! this.hasAnyListeners(listenerClass); |
| } |
| |
| |
| // ********** general purpose change support ********** |
| |
| /** |
| * Subclasses that add other types of listeners should override this method |
| * to return the extension to ChangeListener that also extends whatever new |
| * listener types are supported. |
| */ |
| @SuppressWarnings("unchecked") |
| protected <L extends ChangeListener> Class<L> getChangeListenerClass() { |
| // not sure why I need to cast here... |
| return (Class<L>) CHANGE_LISTENER_CLASS; |
| } |
| |
| protected static final Class<ChangeListener> CHANGE_LISTENER_CLASS = ChangeListener.class; |
| |
| /** |
| * Add a general purpose listener that listens to all events, |
| * regardless of the aspect name associated with that event. |
| * The listener cannot be null. |
| */ |
| public void addChangeListener(ChangeListener listener) { |
| this.addListener(this.getChangeListenerClass(), listener); |
| } |
| |
| /** |
| * Remove a general purpose listener. |
| * The listener cannot be null. |
| */ |
| public void removeChangeListener(ChangeListener listener) { |
| this.removeListener(this.getChangeListenerClass(), listener); |
| } |
| |
| /** |
| * Return whether there are any general purpose listeners that will be |
| * notified of any changes. |
| */ |
| public boolean hasAnyChangeListeners() { |
| return this.hasAnyListeners(this.getChangeListenerClass()); |
| } |
| |
| private ListenerList<ChangeListener> getChangeListenerList() { |
| return this.getListenerList(CHANGE_LISTENER_CLASS); |
| } |
| |
| private Iterable<ChangeListener> getChangeListeners() { |
| ListenerList<ChangeListener> listenerList = this.getChangeListenerList(); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasChangeListener(ChangeListener listener) { |
| return CollectionTools.contains(this.getChangeListeners(), listener); |
| } |
| |
| |
| // ********** state change support ********** |
| |
| protected static final Class<StateChangeListener> STATE_CHANGE_LISTENER_CLASS = StateChangeListener.class; |
| |
| /** |
| * Add a state change listener. |
| */ |
| public void addStateChangeListener(StateChangeListener listener) { |
| this.addListener(STATE_CHANGE_LISTENER_CLASS, listener); |
| } |
| |
| /** |
| * Remove a state change listener. |
| */ |
| public void removeStateChangeListener(StateChangeListener listener) { |
| this.removeListener(STATE_CHANGE_LISTENER_CLASS, listener); |
| } |
| |
| /** |
| * Return whether there are any state change listeners. |
| */ |
| public boolean hasAnyStateChangeListeners() { |
| return this.hasAnyListeners(STATE_CHANGE_LISTENER_CLASS); |
| } |
| |
| private ListenerList<StateChangeListener> getStateChangeListenerList() { |
| return this.getListenerList(STATE_CHANGE_LISTENER_CLASS); |
| } |
| |
| private Iterable<StateChangeListener> getStateChangeListeners() { |
| ListenerList<StateChangeListener> listenerList = this.getStateChangeListenerList(); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasStateChangeListener(StateChangeListener listener) { |
| return CollectionTools.contains(this.getStateChangeListeners(), listener); |
| } |
| |
| /** |
| * Fire the specified state change event to any registered listeners. |
| */ |
| public void fireStateChanged(StateChangeEvent event) { |
| Iterable<StateChangeListener> listeners = this.getStateChangeListeners(); |
| if (listeners != null) { |
| for (StateChangeListener listener : listeners) { |
| if (this.hasStateChangeListener(listener)) { // verify listener is still listening |
| listener.stateChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.stateChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a generic state change event to any registered state change |
| * listeners. |
| */ |
| public void fireStateChanged() { |
| // this.fireStateChanged(new StateChangeEvent(this.source)); |
| StateChangeEvent event = null; |
| Iterable<StateChangeListener> listeners = this.getStateChangeListeners(); |
| if (listeners != null) { |
| for (StateChangeListener listener : listeners) { |
| if (this.hasStateChangeListener(listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new StateChangeEvent(this.source); |
| } |
| listener.stateChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new StateChangeEvent(this.source); |
| } |
| changeListener.stateChanged(event); |
| } |
| } |
| } |
| } |
| |
| |
| // ********** property change support ********** |
| |
| protected static final Class<PropertyChangeListener> PROPERTY_CHANGE_LISTENER_CLASS = PropertyChangeListener.class; |
| |
| /** |
| * Add a property change listener for the specified property. The listener |
| * will be notified only for changes to the specified property. |
| */ |
| public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { |
| this.addListener(PROPERTY_CHANGE_LISTENER_CLASS, propertyName, listener); |
| } |
| |
| /** |
| * Remove a property change listener that was registered for a specific property. |
| */ |
| public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { |
| this.removeListener(PROPERTY_CHANGE_LISTENER_CLASS, propertyName, listener); |
| } |
| |
| /** |
| * Return whether there are any property change listeners that will |
| * be notified when the specified property has changed. |
| */ |
| public boolean hasAnyPropertyChangeListeners(String propertyName) { |
| return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); |
| } |
| |
| private ListenerList<PropertyChangeListener> getPropertyChangeListenerList(String propertyName) { |
| return this.getListenerList(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); |
| } |
| |
| private Iterable<PropertyChangeListener> getPropertyChangeListeners(String propertyName) { |
| ListenerList<PropertyChangeListener> listenerList = this.getPropertyChangeListenerList(propertyName); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasPropertyChangeListener(String propertyName, PropertyChangeListener listener) { |
| return CollectionTools.contains(this.getPropertyChangeListeners(propertyName), listener); |
| } |
| |
| /** |
| * Fire the specified property change event to any registered listeners. |
| * No event is fired if the given event's old and new values are the same; |
| * this includes when both values are null. Use a state change event |
| * for general purpose notification of changes. |
| */ |
| public void firePropertyChanged(PropertyChangeEvent event) { |
| if (this.valuesAreDifferent(event.getOldValue(), event.getNewValue())) { |
| this.firePropertyChanged_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: the specified event's old and new values are different |
| */ |
| protected void firePropertyChanged_(PropertyChangeEvent event) { |
| String propertyName = event.getPropertyName(); |
| Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); |
| if (listeners != null) { |
| for (PropertyChangeListener listener : listeners) { |
| if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening |
| listener.propertyChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.propertyChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound property update to any registered property change listeners. |
| * No event is fired if the given old and new values are the same; |
| * this includes when both values are null. Use a state change event |
| * for general purpose notification of changes. |
| */ |
| public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { |
| // this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); |
| if (this.valuesAreDifferent(oldValue, newValue)) { |
| this.firePropertyChanged_(propertyName, oldValue, newValue); |
| } |
| } |
| |
| /** |
| * pre-condition: the specified old and new values are different |
| */ |
| protected void firePropertyChanged_(String propertyName, Object oldValue, Object newValue) { |
| PropertyChangeEvent event = null; |
| Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); |
| if (listeners != null) { |
| for (PropertyChangeListener listener : listeners) { |
| if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); |
| } |
| listener.propertyChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); |
| } |
| changeListener.propertyChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report an int bound property update to any registered listeners. |
| * No event is fired if old and new are equal. |
| * <p> |
| * This is merely a convenience wrapper around the more general |
| * firePropertyChange method that takes Object values. |
| */ |
| public void firePropertyChanged(String propertyName, int oldValue, int newValue) { |
| // this.firePropertyChanged(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); |
| if (oldValue != newValue) { |
| this.firePropertyChanged_(propertyName, oldValue, newValue); |
| } |
| } |
| |
| /** |
| * pre-condition: the specified old and new values are different |
| */ |
| protected void firePropertyChanged_(String propertyName, int oldValue, int newValue) { |
| PropertyChangeEvent event = null; |
| Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); |
| if (listeners != null) { |
| for (PropertyChangeListener listener : listeners) { |
| if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); |
| } |
| listener.propertyChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); |
| } |
| changeListener.propertyChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a boolean bound property update to any registered listeners. |
| * No event is fired if old and new are equal. |
| * <p> |
| * This is merely a convenience wrapper around the more general |
| * firePropertyChange method that takes Object values. |
| */ |
| public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { |
| // this.firePropertyChanged(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); |
| if (oldValue != newValue) { |
| this.firePropertyChanged_(propertyName, oldValue, newValue); |
| } |
| } |
| |
| /** |
| * pre-condition: the specified old and new values are different |
| */ |
| protected void firePropertyChanged_(String propertyName, boolean oldValue, boolean newValue) { |
| PropertyChangeEvent event = null; |
| Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); |
| if (listeners != null) { |
| for (PropertyChangeListener listener : listeners) { |
| if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); |
| } |
| listener.propertyChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); |
| } |
| changeListener.propertyChanged(event); |
| } |
| } |
| } |
| } |
| |
| |
| // ********** collection change support ********** |
| |
| protected static final Class<CollectionChangeListener> COLLECTION_CHANGE_LISTENER_CLASS = CollectionChangeListener.class; |
| |
| /** |
| * Add a collection change listener for the specified collection. The listener |
| * will be notified only for changes to the specified collection. |
| */ |
| public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { |
| this.addListener(COLLECTION_CHANGE_LISTENER_CLASS, collectionName, listener); |
| } |
| |
| /** |
| * Remove a collection change listener that was registered for a specific collection. |
| */ |
| public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { |
| this.removeListener(COLLECTION_CHANGE_LISTENER_CLASS, collectionName, listener); |
| } |
| |
| /** |
| * Return whether there are any collection change listeners that will |
| * be notified when the specified collection has changed. |
| */ |
| public boolean hasAnyCollectionChangeListeners(String collectionName) { |
| return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); |
| } |
| |
| private ListenerList<CollectionChangeListener> getCollectionChangeListenerList(String collectionName) { |
| return this.getListenerList(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); |
| } |
| |
| private Iterable<CollectionChangeListener> getCollectionChangeListeners(String collectionName) { |
| ListenerList<CollectionChangeListener> listenerList = this.getCollectionChangeListenerList(collectionName); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasCollectionChangeListener(String collectionName, CollectionChangeListener listener) { |
| return CollectionTools.contains(this.getCollectionChangeListeners(collectionName), listener); |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemsAdded(CollectionAddEvent event) { |
| if (event.getItemsSize() != 0) { |
| this.fireItemsAdded_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: items were added |
| */ |
| protected void fireItemsAdded_(CollectionAddEvent event) { |
| String collectionName = event.getCollectionName(); |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemsAdded(String collectionName, Collection<?> addedItems) { |
| // this.fireItemsAdded(new CollectionAddEvent(this.source, collectionName, addedItems)); |
| if ( ! addedItems.isEmpty()) { |
| this.fireItemsAdded_(collectionName, addedItems); |
| } |
| } |
| |
| /** |
| * pre-condition: items were added |
| */ |
| protected void fireItemsAdded_(String collectionName, Collection<?> addedItems) { |
| CollectionAddEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionAddEvent(this.source, collectionName, addedItems); |
| } |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionAddEvent(this.source, collectionName, addedItems); |
| } |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemAdded(String collectionName, Object addedItem) { |
| // this.fireItemsAdded(collectionName, Collections.singleton(addedItem)); |
| |
| CollectionAddEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionAddEvent(this.source, collectionName, addedItem); |
| } |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionAddEvent(this.source, collectionName, addedItem); |
| } |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemsRemoved(CollectionRemoveEvent event) { |
| if (event.getItemsSize() != 0) { |
| this.fireItemsRemoved_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: items were removed |
| */ |
| protected void fireItemsRemoved_(CollectionRemoveEvent event) { |
| String collectionName = event.getCollectionName(); |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemsRemoved(String collectionName, Collection<?> removedItems) { |
| // this.fireItemsRemoved(new CollectionRemoveEvent(this.source, collectionName, removedItems)); |
| if ( ! removedItems.isEmpty()) { |
| this.fireItemsRemoved_(collectionName, removedItems); |
| } |
| } |
| |
| /** |
| * pre-condition: items were removed |
| */ |
| protected void fireItemsRemoved_(String collectionName, Collection<?> removedItems) { |
| CollectionRemoveEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionRemoveEvent(this.source, collectionName, removedItems); |
| } |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionRemoveEvent(this.source, collectionName, removedItems); |
| } |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireItemRemoved(String collectionName, Object removedItem) { |
| // this.fireItemsRemoved(collectionName, Collections.singleton(removedItem)); |
| |
| CollectionRemoveEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionRemoveEvent(this.source, collectionName, removedItem); |
| } |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionRemoveEvent(this.source, collectionName, removedItem); |
| } |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireCollectionCleared(CollectionClearEvent event) { |
| String collectionName = event.getCollectionName(); |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| listener.collectionCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.collectionCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireCollectionCleared(String collectionName) { |
| // this.fireCollectionCleared(new CollectionClearEvent(this.source, collectionName)); |
| |
| CollectionClearEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionClearEvent(this.source, collectionName); |
| } |
| listener.collectionCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionClearEvent(this.source, collectionName); |
| } |
| changeListener.collectionCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireCollectionChanged(CollectionChangeEvent event) { |
| String collectionName = event.getCollectionName(); |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| listener.collectionChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.collectionChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound collection update to any registered listeners. |
| */ |
| public void fireCollectionChanged(String collectionName, Collection<?> collection) { |
| // this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName, collection)); |
| |
| CollectionChangeEvent event = null; |
| Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); |
| if (listeners != null) { |
| for (CollectionChangeListener listener : listeners) { |
| if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionChangeEvent(this.source, collectionName, collection); |
| } |
| listener.collectionChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new CollectionChangeEvent(this.source, collectionName, collection); |
| } |
| changeListener.collectionChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Add the specified item to the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#add(Object) |
| */ |
| public <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) { |
| if (collection.add(item)) { |
| this.fireItemAdded(collectionName, item); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Add the specified items to the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether collection changed. |
| * @see java.util.Collection#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) { |
| return (items.length != 0) |
| && this.addItemsToCollection_(new ArrayIterator<E>(items), collection, collectionName); |
| } |
| |
| /** |
| * Add the specified items to the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether collection changed. |
| * @see java.util.Collection#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToCollection(Collection<? extends E> items, Collection<E> collection, String collectionName) { |
| return ( ! items.isEmpty()) |
| && this.addItemsToCollection_(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Add the specified items to the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether collection changed. |
| * @see java.util.Collection#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) { |
| return this.addItemsToCollection(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Add the specified items to the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether collection changed. |
| * @see java.util.Collection#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) { |
| return items.hasNext() |
| && this.addItemsToCollection_(items, collection, collectionName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> boolean addItemsToCollection_(Iterator<? extends E> items, Collection<E> collection, String collectionName) { |
| Collection<E> addedItems = null; |
| while (items.hasNext()) { |
| E item = items.next(); |
| if (collection.add(item)) { |
| if (addedItems == null) { |
| addedItems = new ArrayList<E>(); |
| } |
| addedItems.add(item); |
| } |
| } |
| if (addedItems != null) { |
| this.fireItemsAdded(collectionName, addedItems); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Remove the specified item from the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#remove(Object) |
| */ |
| public boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) { |
| if (collection.remove(item)) { |
| this.fireItemRemoved(collectionName, item); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Remove the specified items from the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) { |
| return (items.length != 0) |
| && ( ! collection.isEmpty()) |
| && this.removeItemsFromCollection_(new ArrayIterator<Object>(items), collection, collectionName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromCollection(Collection<?> items, Collection<?> collection, String collectionName) { |
| return ( ! items.isEmpty()) |
| && ( ! collection.isEmpty()) |
| && this.removeItemsFromCollection_(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) { |
| return this.removeItemsFromCollection(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) { |
| return items.hasNext() |
| && ( ! collection.isEmpty()) |
| && this.removeItemsFromCollection_(items, collection, collectionName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected boolean removeItemsFromCollection_(Iterator<?> items, Collection<?> collection, String collectionName) { |
| HashBag<?> removedItems = CollectionTools.collection(items); |
| removedItems.retainAll(collection); |
| boolean changed = collection.removeAll(removedItems); |
| |
| if ( ! removedItems.isEmpty()) { |
| this.fireItemsRemoved(collectionName, removedItems); |
| } |
| return changed; |
| } |
| |
| /** |
| * Retain the specified items in the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) { |
| if (collection.isEmpty()) { |
| return false; |
| } |
| if (items.length == 0) { |
| return this.clearCollection_(collection, collectionName); |
| } |
| return this.retainItemsInCollection_(new ArrayIterator<Object>(items), collection, collectionName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInCollection(Collection<?> items, Collection<?> collection, String collectionName) { |
| if (collection.isEmpty()) { |
| return false; |
| } |
| if (items.isEmpty()) { |
| return this.clearCollection_(collection, collectionName); |
| } |
| return this.retainItemsInCollection_(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) { |
| return this.retainItemsInCollection(items.iterator(), collection, collectionName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) { |
| if (collection.isEmpty()) { |
| return false; |
| } |
| if ( ! items.hasNext()) { |
| return this.clearCollection_(collection, collectionName); |
| } |
| return this.retainItemsInCollection_(items, collection, collectionName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected boolean retainItemsInCollection_(Iterator<?> items, Collection<?> collection, String collectionName) { |
| HashBag<?> retainedItems = CollectionTools.collection(items); |
| HashBag<?> removedItems = CollectionTools.collection(collection); |
| removedItems.removeAll(retainedItems); |
| boolean changed = collection.retainAll(retainedItems); |
| |
| if ( ! removedItems.isEmpty()) { |
| this.fireItemsRemoved(collectionName, removedItems); |
| } |
| return changed; |
| } |
| |
| /** |
| * Clear the entire collection |
| * and fire the appropriate event if necessary. |
| * Return whether the collection changed. |
| * @see java.util.Collection#clear() |
| */ |
| public boolean clearCollection(Collection<?> collection, String collectionName) { |
| if (collection.isEmpty()) { |
| return false; |
| } |
| return this.clearCollection_(collection, collectionName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected boolean clearCollection_(Collection<?> collection, String collectionName) { |
| collection.clear(); |
| this.fireCollectionCleared(collectionName); |
| return true; |
| } |
| |
| /** |
| * Synchronize the collection with the specified new collection, |
| * making a minimum number of removes and adds. |
| * Return whether the collection changed. |
| */ |
| public <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) { |
| if (newCollection.isEmpty()) { |
| return this.clearCollection(collection, collectionName); |
| } |
| |
| if (collection.isEmpty()) { |
| return this.addItemsToCollection_(newCollection.iterator(), collection, collectionName); |
| } |
| |
| return this.synchronizeCollection_(newCollection, collection, collectionName); |
| } |
| |
| /** |
| * Synchronize the collection with the specified new collection, |
| * making a minimum number of removes and adds. |
| * Return whether the collection changed. |
| */ |
| public <E> boolean synchronizeCollection(Iterator<E> newCollection, Collection<E> collection, String collectionName) { |
| if ( ! newCollection.hasNext()) { |
| return this.clearCollection(collection, collectionName); |
| } |
| |
| if (collection.isEmpty()) { |
| return this.addItemsToCollection_(newCollection, collection, collectionName); |
| } |
| |
| return this.synchronizeCollection_(CollectionTools.collection(newCollection), collection, collectionName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected <E> boolean synchronizeCollection_(Collection<E> newCollection, Collection<E> collection, String collectionName) { |
| boolean changed = false; |
| Collection<E> removeItems = new HashBag<E>(collection); |
| removeItems.removeAll(newCollection); |
| changed |= this.removeItemsFromCollection(removeItems, collection, collectionName); |
| |
| Collection<E> addItems = new HashBag<E>(newCollection); |
| addItems.removeAll(collection); |
| changed |= this.addItemsToCollection(addItems, collection, collectionName); |
| |
| return changed; |
| } |
| |
| |
| // ********** list change support ********** |
| |
| protected static final Class<ListChangeListener> LIST_CHANGE_LISTENER_CLASS = ListChangeListener.class; |
| |
| /** |
| * Add a list change listener for the specified list. The listener |
| * will be notified only for changes to the specified list. |
| */ |
| public void addListChangeListener(String listName, ListChangeListener listener) { |
| this.addListener(LIST_CHANGE_LISTENER_CLASS, listName, listener); |
| } |
| |
| /** |
| * Remove a list change listener that was registered for a specific list. |
| */ |
| public void removeListChangeListener(String listName, ListChangeListener listener) { |
| this.removeListener(LIST_CHANGE_LISTENER_CLASS, listName, listener); |
| } |
| |
| /** |
| * Return whether there are any list change listeners that will |
| * be notified when the specified list has changed. |
| */ |
| public boolean hasAnyListChangeListeners(String listName) { |
| return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS, listName); |
| } |
| |
| private ListenerList<ListChangeListener> getListChangeListenerList(String listName) { |
| return this.getListenerList(LIST_CHANGE_LISTENER_CLASS, listName); |
| } |
| |
| private Iterable<ListChangeListener> getListChangeListeners(String listName) { |
| ListenerList<ListChangeListener> listenerList = this.getListChangeListenerList(listName); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasListChangeListener(String listName, ListChangeListener listener) { |
| return CollectionTools.contains(this.getListChangeListeners(listName), listener); |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsAdded(ListAddEvent event) { |
| if (event.getItemsSize() != 0) { |
| this.fireItemsAdded_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: items were added |
| */ |
| protected void fireItemsAdded_(ListAddEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsAdded(String listName, int index, List<?> addedItems) { |
| // this.fireItemsAdded(new ListAddEvent(this.source, listName, index, addedItems)); |
| if ( ! addedItems.isEmpty()) { |
| this.fireItemsAdded_(listName, index, addedItems); |
| } |
| } |
| |
| /** |
| * pre-condition: items were added |
| */ |
| protected void fireItemsAdded_(String listName, int index, List<?> addedItems) { |
| ListAddEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListAddEvent(this.source, listName, index, addedItems); |
| } |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListAddEvent(this.source, listName, index, addedItems); |
| } |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemAdded(String listName, int index, Object addedItem) { |
| // this.fireItemsAdded(listName, index, Collections.singletonList(addedItem)); |
| |
| ListAddEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListAddEvent(this.source, listName, index, addedItem); |
| } |
| listener.itemsAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListAddEvent(this.source, listName, index, addedItem); |
| } |
| changeListener.itemsAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsRemoved(ListRemoveEvent event) { |
| if (event.getItemsSize() != 0) { |
| this.fireItemsRemoved_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: items were removed |
| */ |
| protected void fireItemsRemoved_(ListRemoveEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsRemoved(String listName, int index, List<?> removedItems) { |
| // this.fireItemsRemoved(new ListRemoveEvent(this.source, listName, index, removedItems)); |
| if ( ! removedItems.isEmpty()) { |
| this.fireItemsRemoved_(listName, index, removedItems); |
| } |
| } |
| |
| /** |
| * pre-condition: items were removed |
| */ |
| protected void fireItemsRemoved_(String listName, int index, List<?> removedItems) { |
| ListRemoveEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListRemoveEvent(this.source, listName, index, removedItems); |
| } |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListRemoveEvent(this.source, listName, index, removedItems); |
| } |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemRemoved(String listName, int index, Object removedItem) { |
| // this.fireItemsRemoved(listName, index, Collections.singletonList(removedItem)); |
| |
| ListRemoveEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListRemoveEvent(this.source, listName, index, removedItem); |
| } |
| listener.itemsRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListRemoveEvent(this.source, listName, index, removedItem); |
| } |
| changeListener.itemsRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsReplaced(ListReplaceEvent event) { |
| if ((event.getItemsSize() != 0) && this.elementsAreDifferent(event.getNewItems(), event.getOldItems())) { |
| this.fireItemsReplaced_(event); |
| } |
| } |
| |
| /** |
| * pre-condition: items were replaced |
| */ |
| protected void fireItemsReplaced_(ListReplaceEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.itemsReplaced(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsReplaced(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> oldItems) { |
| // this.fireItemsReplaced(new ListReplaceEvent(this.source, listName, index, newItems, oldItems)); |
| if (( ! newItems.isEmpty()) && this.elementsAreDifferent(newItems, oldItems)) { |
| this.fireItemsReplaced_(listName, index, newItems, oldItems); |
| } |
| } |
| |
| /** |
| * pre-condition: items were replaced |
| */ |
| protected void fireItemsReplaced_(String listName, int index, List<?> newItems, List<?> oldItems) { |
| ListReplaceEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListReplaceEvent(this.source, listName, index, newItems, oldItems); |
| } |
| listener.itemsReplaced(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListReplaceEvent(this.source, listName, index, newItems, oldItems); |
| } |
| changeListener.itemsReplaced(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemReplaced(String listName, int index, Object newItem, Object oldItem) { |
| // this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(oldItem)); |
| if (this.valuesAreDifferent(newItem, oldItem)) { |
| this.fireItemReplaced_(listName, index, newItem, oldItem); |
| } |
| } |
| |
| /** |
| * pre-condition: items were replaced |
| */ |
| protected void fireItemReplaced_(String listName, int index, Object newItem, Object oldItem) { |
| ListReplaceEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListReplaceEvent(this.source, listName, index, newItem, oldItem); |
| } |
| listener.itemsReplaced(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListReplaceEvent(this.source, listName, index, newItem, oldItem); |
| } |
| changeListener.itemsReplaced(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsMoved(ListMoveEvent event) { |
| if (event.getTargetIndex() != event.getSourceIndex()) { |
| this.fireItemsMoved_(event); |
| } |
| // it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...) |
| } |
| |
| /** |
| * pre-condition: items were moved |
| */ |
| protected void fireItemsMoved_(ListMoveEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.itemsMoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.itemsMoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { |
| // this.fireItemsMoved(new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length)); |
| if (targetIndex != sourceIndex) { |
| this.fireItemsMoved_(listName, targetIndex, sourceIndex, length); |
| } |
| // it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...) |
| } |
| |
| /** |
| * pre-condition: items were moved |
| */ |
| protected void fireItemsMoved_(String listName, int targetIndex, int sourceIndex, int length) { |
| ListMoveEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length); |
| } |
| listener.itemsMoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length); |
| } |
| changeListener.itemsMoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireItemMoved(String listName, int targetIndex, int sourceIndex) { |
| this.fireItemsMoved(listName, targetIndex, sourceIndex, 1); |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireListCleared(ListClearEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.listCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.listCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireListCleared(String listName) { |
| // this.fireListCleared(new ListClearEvent(this.source, listName)); |
| |
| ListClearEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListClearEvent(this.source, listName); |
| } |
| listener.listCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListClearEvent(this.source, listName); |
| } |
| changeListener.listCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireListChanged(ListChangeEvent event) { |
| String listName = event.getListName(); |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| listener.listChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.listChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound list update to any registered listeners. |
| */ |
| public void fireListChanged(String listName, List<?> list) { |
| // this.fireListChanged(new ListChangeEvent(this.source, listName)); |
| |
| ListChangeEvent event = null; |
| Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); |
| if (listeners != null) { |
| for (ListChangeListener listener : listeners) { |
| if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListChangeEvent(this.source, listName, list); |
| } |
| listener.listChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new ListChangeEvent(this.source, listName, list); |
| } |
| changeListener.listChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Add the specified item to the specified bound list at the specified index |
| * and fire the appropriate event. |
| * @see java.util.List#add(int, Object) |
| */ |
| public <E> void addItemToList(int index, E item, List<E> list, String listName) { |
| list.add(index, item); |
| this.fireItemAdded(listName, index, item); |
| } |
| |
| /** |
| * Add the specified item to the end of the specified bound list |
| * and fire the appropriate event. |
| * Return whether the list changed (i.e. 'true'). |
| * @see java.util.List#add(Object) |
| */ |
| public <E> boolean addItemToList(E item, List<E> list, String listName) { |
| if (list.add(item)) { |
| this.fireItemAdded(listName, list.size() - 1, item); |
| return true; |
| } |
| return false; // List#add(Object) should always return 'true', so we should never get here... |
| } |
| |
| /** |
| * Add the specified items to the specified bound list at the specified index |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(int, java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) { |
| return (items.length != 0) |
| && this.addItemsToList_(index, Arrays.asList(items), list, listName); |
| } |
| |
| /** |
| * Add the specified items to the specified bound list at the specified index |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(int, java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(int index, Collection<? extends E> items, List<E> list, String listName) { |
| return ( ! items.isEmpty()) |
| && this.addItemsToList_(index, this.convertToList(items), list, listName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> boolean addItemsToList_(int index, List<? extends E> items, List<E> list, String listName) { |
| if (list.addAll(index, items)) { |
| this.fireItemsAdded(listName, index, items); |
| return true; |
| } |
| return false; // 'items' should not be empty, so we should never get here... |
| } |
| |
| /** |
| * Add the specified items to the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(int, java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) { |
| return this.addItemsToList(index, items.iterator(), list, listName); |
| } |
| |
| /** |
| * Add the specified items to the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(int, java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) { |
| if ( ! items.hasNext()) { |
| return false; |
| } |
| |
| ArrayList<E> addedItems = CollectionTools.list(items); |
| if (list.addAll(index, addedItems)) { |
| this.fireItemsAdded(listName, index, addedItems); |
| return true; |
| } |
| return false; // 'items' should not be empty, so we should never get here... |
| } |
| |
| /** |
| * Add the specified items to the end of to the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(E[] items, List<E> list, String listName) { |
| return (items.length != 0) |
| && this.addItemsToList_(Arrays.asList(items), list, listName); |
| } |
| |
| /** |
| * Add the specified items to the end of the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(int, java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(Collection<? extends E> items, List<E> list, String listName) { |
| return ( ! items.isEmpty()) |
| && this.addItemsToList_(this.convertToList(items), list, listName); |
| } |
| |
| protected <E> List<? extends E> convertToList(Collection<? extends E> collection) { |
| return (collection instanceof List<?>) ? (List<? extends E>) collection : new ArrayList<E>(collection); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> boolean addItemsToList_(List<? extends E> items, List<E> list, String listName) { |
| int index = list.size(); |
| if (list.addAll(items)) { |
| this.fireItemsAdded(listName, index, items); |
| return true; |
| } |
| return false; // 'items' should not be empty, so we should never get here... |
| } |
| |
| /** |
| * Add the specified items to the end of to the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) { |
| return this.addItemsToList(items.iterator(), list, listName); |
| } |
| |
| /** |
| * Add the specified items to the end of to the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#addAll(java.util.Collection) |
| */ |
| public <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) { |
| if ( ! items.hasNext()) { |
| return false; |
| } |
| return this.addItemsToList_(items, list, listName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> boolean addItemsToList_(Iterator<? extends E> items, List<E> list, String listName) { |
| ArrayList<E> addedItems = CollectionTools.list(items); |
| int index = list.size(); |
| if (list.addAll(addedItems)) { |
| this.fireItemsAdded(listName, index, addedItems); |
| return true; |
| } |
| return false; // 'items' should not be empty, so we should never get here... |
| } |
| |
| /** |
| * Remove the specified item from the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the removed item. |
| * @see java.util.List#remove(int) |
| */ |
| public <E> E removeItemFromList(int index, List<E> list, String listName) { |
| E item = list.remove(index); |
| this.fireItemRemoved(listName, index, item); |
| return item; |
| } |
| |
| /** |
| * Remove the specified item from the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#remove(Object) |
| */ |
| public boolean removeItemFromList(Object item, List<?> list, String listName) { |
| int index = list.indexOf(item); |
| if (index == -1) { |
| return false; |
| } |
| list.remove(index); |
| this.fireItemRemoved(listName, index, item); |
| return true; |
| } |
| |
| /** |
| * Remove the items from the specified index on |
| * from the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the removed items. |
| * @see java.util.List#remove(int) |
| */ |
| public <E> List<E> removeItemsFromList(int index, List<E> list, String listName) { |
| return this.removeItemsFromList(index, list.size() - index, list, listName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the removed items. |
| * @see java.util.List#remove(int) |
| */ |
| public <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) { |
| if (length == 0) { |
| return Collections.emptyList(); |
| } |
| return this.removeItemsFromList_(index, length, list, listName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> List<E> removeItemsFromList_(int index, int length, List<E> list, String listName) { |
| List<E> subList = list.subList(index, index + length); |
| List<E> removedItems = new ArrayList<E>(subList); |
| subList.clear(); |
| this.fireItemsRemoved(listName, index, removedItems); |
| return removedItems; |
| } |
| |
| /** |
| * Remove the specified items from the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromList(Object[] items, List<?> list, String listName) { |
| return (items.length != 0) |
| && ( ! list.isEmpty()) |
| && this.removeItemsFromList_(new ArrayIterator<Object>(items), list, listName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromList(Collection<?> items, List<?> list, String listName) { |
| return ( ! items.isEmpty()) |
| && ( ! list.isEmpty()) |
| && this.removeItemsFromList_(items.iterator(), list, listName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) { |
| return this.removeItemsFromList(items.iterator(), list, listName); |
| } |
| |
| /** |
| * Remove the specified items from the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#removeAll(java.util.Collection) |
| */ |
| public boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) { |
| return (items.hasNext()) |
| && ( ! list.isEmpty()) |
| && this.removeItemsFromList_(items, list, listName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected boolean removeItemsFromList_(Iterator<?> items, List<?> list, String listName) { |
| boolean changed = false; |
| while (items.hasNext()) { |
| changed |= this.removeItemFromList(items.next(), list, listName); |
| } |
| return changed; |
| } |
| |
| /** |
| * Retain the specified items in the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInList(Object[] items, List<?> list, String listName) { |
| if (list.isEmpty()) { |
| return false; |
| } |
| if (items.length == 0) { |
| return this.clearList_(list, listName); |
| } |
| return this.retainItemsInList_(new ArrayIterator<Object>(items), list, listName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInList(Collection<?> items, List<?> list, String listName) { |
| if (list.isEmpty()) { |
| return false; |
| } |
| if (items.isEmpty()) { |
| return this.clearList_(list, listName); |
| } |
| return this.retainItemsInList_(items.iterator(), list, listName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) { |
| return this.retainItemsInList(items.iterator(), list, listName); |
| } |
| |
| /** |
| * Retain the specified items in the specified bound list |
| * and fire the appropriate event(s) if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#retainAll(java.util.Collection) |
| */ |
| public boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) { |
| if (list.isEmpty()) { |
| return false; |
| } |
| if ( ! items.hasNext()) { |
| return this.clearList_(list, listName); |
| } |
| return this.retainItemsInList_(items, list, listName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected boolean retainItemsInList_(Iterator<?> items, List<?> list, String listName) { |
| HashBag<?> retainedItems = CollectionTools.collection(items); |
| HashBag<?> removedItems = CollectionTools.collection(list); |
| removedItems.removeAll(retainedItems); |
| return this.removeItemsFromList(removedItems, list, listName); |
| } |
| |
| /** |
| * Set the specified item in the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the replaced item. |
| * @see java.util.List#set(int, Object) |
| */ |
| public <E> E setItemInList(int index, E item, List<E> list, String listName) { |
| E oldItem = list.set(index, item); |
| this.fireItemReplaced(listName, index, item, oldItem); |
| return oldItem; |
| } |
| |
| /** |
| * Replace the first occurrence of the specified item |
| * in the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the index of the replaced item. |
| * Return -1 if the item was not found in the list. |
| * @see java.util.List#set(int, Object) |
| */ |
| public <E> int replaceItemInList(E oldItem, E newItem, List<E> list, String listName) { |
| if (list.isEmpty()) { |
| return -1; |
| } |
| |
| int index = list.indexOf(oldItem); |
| if ((index != -1) && this.valuesAreDifferent(oldItem, newItem)) { |
| list.set(index, newItem); |
| this.fireItemReplaced_(listName, index, newItem, oldItem); |
| } |
| return index; |
| } |
| |
| /** |
| * Set the specified items in the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the replaced items. |
| * @see java.util.List#set(int, Object) |
| */ |
| public <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) { |
| if (items.length == 0) { |
| return Collections.emptyList(); |
| } |
| return this.setItemsInList_(index, Arrays.asList(items), list, listName); |
| } |
| |
| /** |
| * Set the specified items in the specified bound list |
| * and fire the appropriate event if necessary. |
| * Return the replaced items. |
| * @see java.util.List#set(int, Object) |
| */ |
| public <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) { |
| if (items.isEmpty()) { |
| return Collections.emptyList(); |
| } |
| return this.setItemsInList_(index, items, list, listName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected <E> List<E> setItemsInList_(int index, List<? extends E> items, List<E> list, String listName) { |
| List<E> subList = list.subList(index, index + items.size()); |
| List<E> oldItems = new ArrayList<E>(subList); |
| for (int i = 0; i < items.size(); i++) { |
| E newItem = items.get(i); |
| E oldItem = subList.set(i, newItem); |
| this.fireItemReplaced(listName, index + i, newItem, oldItem); |
| } |
| return oldItems; |
| } |
| |
| /** |
| * Move items in the specified list from the specified source index to the |
| * specified target index for the specified length. |
| * Return whether the list changed. |
| */ |
| public <E> boolean moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) { |
| if ((targetIndex == sourceIndex) || (length == 0)) { |
| return false; |
| } |
| // it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...) |
| CollectionTools.move(list, targetIndex, sourceIndex, length); |
| this.fireItemsMoved(listName, targetIndex, sourceIndex, length); |
| return true; |
| } |
| |
| /** |
| * Move an item in the specified list from the specified source index to the |
| * specified target index. |
| * Return whether the list changed. |
| */ |
| public <E> boolean moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) { |
| if (targetIndex == sourceIndex) { |
| return false; |
| } |
| // it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...) |
| CollectionTools.move(list, targetIndex, sourceIndex); |
| this.fireItemMoved(listName, targetIndex, sourceIndex); |
| return true; |
| } |
| |
| /** |
| * Move an item in the specified list from the specified source index to the |
| * specified target index. |
| * Return whether the list changed. |
| */ |
| public <E> boolean moveItemInList(int targetIndex, E item, List<E> list, String listName) { |
| return this.moveItemInList(targetIndex, list.indexOf(item), list, listName); |
| } |
| |
| /** |
| * Clear the entire list |
| * and fire the appropriate event if necessary. |
| * Return whether the list changed. |
| * @see java.util.List#clear() |
| */ |
| public boolean clearList(List<?> list, String listName) { |
| if (list.isEmpty()) { |
| return false; |
| } |
| return this.clearList_(list, listName); |
| } |
| |
| /** |
| * no empty check |
| */ |
| protected boolean clearList_(List<?> list, String listName) { |
| list.clear(); |
| this.fireListCleared(listName); |
| return true; |
| } |
| |
| /** |
| * Synchronize the list with the specified new list, |
| * making a minimum number of sets, removes, and/or adds. |
| * Return whether the list changed. |
| */ |
| public <E> boolean synchronizeList(List<E> newList, List<E> list, String listName) { |
| if (newList.isEmpty()) { |
| return this.clearList(list, listName); |
| } |
| if (list.isEmpty()) { |
| return this.addItemsToList_(newList, list, listName); |
| } |
| return this.synchronizeList_(newList, list, listName); |
| } |
| |
| /** |
| * Synchronize the list with the specified new list, |
| * making a minimum number of sets, removes, and/or adds. |
| * Return whether the list changed. |
| */ |
| public <E> boolean synchronizeList(Iterator<E> newList, List<E> list, String listName) { |
| if ( ! newList.hasNext()) { |
| return this.clearList(list, listName); |
| } |
| if (list.isEmpty()) { |
| return this.addItemsToList_(newList, list, listName); |
| } |
| return this.synchronizeList_(CollectionTools.list(newList), list, listName); |
| } |
| |
| /** |
| * no empty checks |
| */ |
| protected <E> boolean synchronizeList_(List<E> newList, List<E> oldList, String listName) { |
| int newSize = newList.size(); |
| int oldSize = oldList.size(); |
| |
| boolean changed = false; |
| int min = Math.min(newSize, oldSize); |
| for (int i = 0; i < min; i++) { |
| E newItem = newList.get(i); |
| E oldItem = oldList.set(i, newItem); |
| if (this.valuesAreDifferent(newItem, oldItem)) { |
| changed = true; |
| this.fireItemReplaced_(listName, i, newItem, oldItem); |
| } |
| } |
| |
| if (newSize == oldSize) { |
| return changed; |
| } |
| |
| if (newSize < oldSize) { |
| this.removeItemsFromList_(newSize, oldSize - newSize, oldList, listName); |
| return true; |
| } |
| |
| // newSize > oldSize |
| this.addItemsToList_(newList.subList(oldSize, newSize), oldList, listName); |
| return true; |
| } |
| |
| |
| // ********** tree change support ********** |
| |
| protected static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class; |
| |
| /** |
| * Add a tree change listener for the specified tree. The listener |
| * will be notified only for changes to the specified tree. |
| */ |
| public void addTreeChangeListener(String treeName, TreeChangeListener listener) { |
| this.addListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener); |
| } |
| |
| /** |
| * Remove a tree change listener that was registered for a specific tree. |
| */ |
| public void removeTreeChangeListener(String treeName, TreeChangeListener listener) { |
| this.removeListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener); |
| } |
| |
| /** |
| * Return whether there are any tree change listeners that will |
| * be notified when the specified tree has changed. |
| */ |
| public boolean hasAnyTreeChangeListeners(String treeName) { |
| return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS, treeName); |
| } |
| |
| private ListenerList<TreeChangeListener> getTreeChangeListenerList(String treeName) { |
| return this.getListenerList(TREE_CHANGE_LISTENER_CLASS, treeName); |
| } |
| |
| private Iterable<TreeChangeListener> getTreeChangeListeners(String treeName) { |
| ListenerList<TreeChangeListener> listenerList = this.getTreeChangeListenerList(treeName); |
| return (listenerList == null) ? null : listenerList.getListeners(); |
| } |
| |
| private boolean hasTreeChangeListener(String treeName, TreeChangeListener listener) { |
| return CollectionTools.contains(this.getTreeChangeListeners(treeName), listener); |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireNodeAdded(TreeAddEvent event) { |
| String treeName = event.getTreeName(); |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| listener.nodeAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.nodeAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireNodeAdded(String treeName, List<?> path) { |
| // this.fireNodeAdded(new TreeAddEvent(this.source, treeName, path)); |
| TreeAddEvent event = null; |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeAddEvent(this.source, treeName, path); |
| } |
| listener.nodeAdded(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeAddEvent(this.source, treeName, path); |
| } |
| changeListener.nodeAdded(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireNodeRemoved(TreeRemoveEvent event) { |
| String treeName = event.getTreeName(); |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| listener.nodeRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.nodeRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireNodeRemoved(String treeName, List<?> path) { |
| // this.fireNodeRemoved(new TreeRemoveEvent(this.source, treeName, path)); |
| |
| TreeRemoveEvent event = null; |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeRemoveEvent(this.source, treeName, path); |
| } |
| listener.nodeRemoved(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeRemoveEvent(this.source, treeName, path); |
| } |
| changeListener.nodeRemoved(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireTreeCleared(TreeClearEvent event) { |
| String treeName = event.getTreeName(); |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| listener.treeCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.treeCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireTreeCleared(String treeName) { |
| // this.fireTreeCleared(new TreeClearEvent(this.source, treeName)); |
| |
| TreeClearEvent event = null; |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeClearEvent(this.source, treeName); |
| } |
| listener.treeCleared(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeClearEvent(this.source, treeName); |
| } |
| changeListener.treeCleared(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireTreeChanged(TreeChangeEvent event) { |
| String treeName = event.getTreeName(); |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| listener.treeChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| changeListener.treeChanged(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Report a bound tree update to any registered listeners. |
| */ |
| public void fireTreeChanged(String treeName, Collection<?> nodes) { |
| // this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, nodes)); |
| |
| TreeChangeEvent event = null; |
| Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); |
| if (listeners != null) { |
| for (TreeChangeListener listener : listeners) { |
| if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeChangeEvent(this.source, treeName, nodes); |
| } |
| listener.treeChanged(event); |
| } |
| } |
| } |
| |
| Iterable<ChangeListener> changeListeners = this.getChangeListeners(); |
| if (changeListeners != null) { |
| for (ChangeListener changeListener : changeListeners) { |
| if (this.hasChangeListener(changeListener)) { // verify listener is still listening |
| if (event == null) { |
| event = new TreeChangeEvent(this.source, treeName, nodes); |
| } |
| changeListener.treeChanged(event); |
| } |
| } |
| } |
| } |
| |
| |
| // ********** convenience methods ********** |
| |
| /** |
| * Return whether the specified values are equal, with the appropriate null checks. |
| * Convenience method for checking whether an attribute value has changed. |
| */ |
| public boolean valuesAreEqual(Object value1, Object value2) { |
| return Tools.valuesAreEqual(value1, value2); |
| } |
| |
| /** |
| * Return whether the specified values are different, with the appropriate null checks. |
| * Convenience method for checking whether an attribute value has changed. |
| */ |
| public boolean valuesAreDifferent(Object value1, Object value2) { |
| return Tools.valuesAreDifferent(value1, value2); |
| } |
| |
| /** |
| * Return whether the specified iterables return the same elements |
| * in the same order. |
| */ |
| public boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) { |
| return CollectionTools.elementsAreEqual(iterable1, iterable2); |
| } |
| |
| /** |
| * Return whether the specified iterables do not return the same elements |
| * in the same order. |
| */ |
| public boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) { |
| return CollectionTools.elementsAreDifferent(iterable1, iterable2); |
| } |
| |
| |
| // ********** standard methods ********** |
| |
| @Override |
| public String toString() { |
| return StringTools.buildToStringFor(this, this.source); |
| } |
| |
| |
| // ********** member classes ********** |
| |
| /** |
| * Pair an aspect name with its associated listeners. |
| */ |
| static abstract class AspectListenerListPair<L extends EventListener> |
| implements Serializable |
| { |
| final ListenerList<L> listenerList; |
| |
| private static final long serialVersionUID = 1L; |
| |
| AspectListenerListPair(Class<L> listenerClass, L listener) { |
| super(); |
| this.listenerList = new ListenerList<L>(listenerClass, listener); |
| } |
| |
| boolean matches(Class<? extends EventListener> listenerClass, @SuppressWarnings("unused") String aspectName) { |
| return this.listenerList.getListenerType() == listenerClass; |
| } |
| |
| boolean matches(Class<? extends EventListener> listenerClass) { |
| return this.matches(listenerClass, null); |
| } |
| |
| @Override |
| public String toString() { |
| return StringTools.buildToStringFor(this, this.getAspectName()); |
| } |
| |
| abstract String getAspectName(); |
| |
| } |
| |
| /** |
| * Pair an aspect name with its associated listeners. |
| */ |
| static class SimpleAspectListenerListPair<L extends EventListener> |
| extends AspectListenerListPair<L> |
| { |
| final String aspectName; |
| |
| private static final long serialVersionUID = 1L; |
| |
| SimpleAspectListenerListPair(Class<L> listenerClass, String aspectName, L listener) { |
| super(listenerClass, listener); |
| if (aspectName == null) { |
| throw new NullPointerException(); |
| } |
| this.aspectName = aspectName; |
| } |
| |
| @Override |
| boolean matches(Class<? extends EventListener> listenerClass, @SuppressWarnings("hiding") String aspectName) { |
| return this.aspectName.equals(aspectName) |
| && super.matches(listenerClass, aspectName); |
| } |
| |
| @Override |
| String getAspectName() { |
| return this.aspectName; |
| } |
| |
| } |
| |
| /** |
| * Pair a null aspect name with its associated listeners. |
| */ |
| static class NullAspectListenerListPair<L extends EventListener> |
| extends AspectListenerListPair<L> |
| { |
| private static final long serialVersionUID = 1L; |
| |
| NullAspectListenerListPair(Class<L> listenerClass, L listener) { |
| super(listenerClass, listener); |
| } |
| |
| @Override |
| boolean matches(Class<? extends EventListener> listenerClass, String aspectName) { |
| return (aspectName == null) |
| && super.matches(listenerClass, null); |
| } |
| |
| @Override |
| String getAspectName() { |
| return null; |
| } |
| |
| } |
| |
| } |