diff options
author | bvosburgh | 2007-11-07 05:15:34 +0000 |
---|---|---|
committer | bvosburgh | 2007-11-07 05:15:34 +0000 |
commit | ad871d9537424d01464398b07979905d8bc01887 (patch) | |
tree | 8d5d4e048d6fbdc55ccf02d0e31a35bb75279c4d /jpa/plugins/org.eclipse.jpt.utility/src | |
parent | d04fb34d8100ed8a25b27269475c80dec6817e16 (diff) | |
download | webtools.dali-ad871d9537424d01464398b07979905d8bc01887.tar.gz webtools.dali-ad871d9537424d01464398b07979905d8bc01887.tar.xz webtools.dali-ad871d9537424d01464398b07979905d8bc01887.zip |
[201159] model rework: CollectionValueModel
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src')
23 files changed, 543 insertions, 649 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java index 63409420fd..4015998afa 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import org.eclipse.jpt.utility.internal.ClassTools; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.StringTools; import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent; @@ -49,17 +50,17 @@ import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener; * and custom "notifiers", with more to come, I'm sure.... ~bjv * * NB2: This class will check to see if, during the firing of events, a listener - * on the original list of listeners has been removed from the mast list of - * listeners *before* it is notified. If the listener has been removed + * on the original, cloned, list of listeners has been removed from the master + * list of listeners *before* it is notified. If the listener has been removed * "concurrently" it will *not* be notified. (See the code that uses the * 'stillListening' local boolean flag.) * * NB3: This class is serializable, but it will only write out listeners that * are also serializable while silently leaving behind listeners that are not. * - * TODO support a dispatcher per listener - * TODO fire a STATE change event with *every* change? - * TODO use objects (IDs?) instead of strings to identify aspects + * TODO support a dispatcher per listener? + * TODO fire a state change event with *every* change? + * TODO use objects (IDs?) instead of strings to identify aspects? */ public class ChangeSupport implements Serializable @@ -68,11 +69,11 @@ public class ChangeSupport /** The object to be provided as the "source" for any generated events. */ protected final Model source; - /** Maps a listener class to a collection of "generic" listeners for that class. */ + /** Associate a listener class to a collection of "generic" listeners for that class. */ transient private GenericListenerList[] genericListeners = EMPTY_GENERIC_LISTENERS; private static final GenericListenerList[] EMPTY_GENERIC_LISTENERS = new GenericListenerList[0]; - /** Maps aspect names to child change support objects. */ + /** Associate aspect names to child change support objects. */ private AspectChild[] aspectChildren = EMPTY_ASPECT_CHILDREN; private static final AspectChild[] EMPTY_ASPECT_CHILDREN = new AspectChild[0]; @@ -97,8 +98,8 @@ public class ChangeSupport // ********** internal behavior ********** /** - * Add a listener that listens to all events appropriate to that listener, - * regardless of the aspect name associated with that event. + * Add a "generic" listener that listens to all events appropriate to that + * listener, regardless of the aspect name associated with that event. * The listener cannot be null. */ protected <T extends ChangeListener> void addListener(Class<T> listenerClass, T listener) { @@ -116,7 +117,7 @@ public class ChangeSupport } /** - * Return the generic listener list for the specified listener class. + * Return the "generic" listener list for the specified listener class. * Return null if the list is not present. */ protected GenericListenerList genericListenerList(Class<? extends ChangeListener> listenerClass) { @@ -129,7 +130,7 @@ public class ChangeSupport } /** - * Add the generic listener list for the specified listener class. + * Add the "generic" listener list for the specified listener class. * Return the newly-built generic listener list. */ protected <T extends ChangeListener> GenericListenerList addGenericListenerList(Class<T> listenerClass, T listener) { @@ -166,7 +167,7 @@ public class ChangeSupport return null; } for (AspectChild aspectChild : this.aspectChildren) { - if (aspectChild.aspectName.equals(aspectName)) { + if (aspectChild.aspectName == aspectName) { return aspectChild.child; } } @@ -191,7 +192,8 @@ public class ChangeSupport } /** - * Removes a listener that has been registered for all events appropriate to that listener. + * Removes a "generic" listener that has been registered for all events + * appropriate to that listener. */ protected <T extends ChangeListener> void removeListener(Class<T> listenerClass, T listener) { synchronized (this) { @@ -230,7 +232,7 @@ public class ChangeSupport } /** - * Return the listeners for the specified listener class. + * Return the "generic" listeners for the specified listener class. * Return null if there are no listeners. */ protected ChangeListener[] listeners(Class<? extends ChangeListener> listenerClass) { @@ -248,6 +250,14 @@ public class ChangeSupport } /** + * Return whether there are no "generic" listeners for the specified + * listener class. + */ + protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass) { + return ! this.hasAnyListeners(listenerClass); + } + + /** * Return whether there are any listeners for the specified * listener class and aspect name. */ @@ -260,6 +270,14 @@ public class ChangeSupport child.hasAnyListeners(listenerClass); } + /** + * Return whether there are no "generic" listeners for the specified + * listener class and aspect name. + */ + protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass, String aspectName) { + return ! this.hasAnyListeners(listenerClass, aspectName); + } + // ********** behavior ********** @@ -308,11 +326,10 @@ public class ChangeSupport */ public void fireStateChanged(StateChangeEvent event) { - StateChangeListener[] stateChangeListeners = null; StateChangeListener[] targets = null; synchronized (this) { - stateChangeListeners = this.stateChangeListeners(); + StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); if (stateChangeListeners != null) { targets = stateChangeListeners.clone(); } @@ -334,16 +351,16 @@ public class ChangeSupport } /** - * Report a generic state change event to any registered state change listeners. + * Report a generic state change event to any registered state change + * listeners. */ public void fireStateChanged() { // this.fireStateChange(new StateChangeEvent(this.source)); - StateChangeListener[] stateChangeListeners = null; StateChangeListener[] targets = null; synchronized (this) { - stateChangeListeners = this.stateChangeListeners(); + StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); if (stateChangeListeners != null) { targets = stateChangeListeners.clone(); } @@ -458,12 +475,11 @@ public class ChangeSupport String propertyName = event.propertyName(); - PropertyChangeListener[] propertyChangeListeners = null; PropertyChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - propertyChangeListeners = this.propertyChangeListeners(); + PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); if (propertyChangeListeners != null) { targets = propertyChangeListeners.clone(); } @@ -500,12 +516,11 @@ public class ChangeSupport return; } - PropertyChangeListener[] propertyChangeListeners = null; PropertyChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - propertyChangeListeners = this.propertyChangeListeners(); + PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); if (propertyChangeListeners != null) { targets = propertyChangeListeners.clone(); } @@ -553,12 +568,11 @@ public class ChangeSupport return; } - PropertyChangeListener[] propertyChangeListeners = null; PropertyChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - propertyChangeListeners = this.propertyChangeListeners(); + PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); if (propertyChangeListeners != null) { targets = propertyChangeListeners.clone(); } @@ -606,12 +620,11 @@ public class ChangeSupport return; } - PropertyChangeListener[] propertyChangeListeners = null; PropertyChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - propertyChangeListeners = this.propertyChangeListeners(); + PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); if (propertyChangeListeners != null) { targets = propertyChangeListeners.clone(); } @@ -710,12 +723,11 @@ public class ChangeSupport String collectionName = event.collectionName(); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -749,12 +761,11 @@ public class ChangeSupport return; } - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -795,12 +806,11 @@ public class ChangeSupport public void fireItemAdded(String collectionName, Object addedItem) { // this.fireItemsAdded(collectionName, Collections.singleton(addedItem)); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -845,12 +855,11 @@ public class ChangeSupport String collectionName = event.collectionName(); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -884,12 +893,11 @@ public class ChangeSupport return; } - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -930,12 +938,11 @@ public class ChangeSupport public void fireItemRemoved(String collectionName, Object removedItem) { // this.fireItemsRemoved(collectionName, Collections.singleton(removedItem)); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -976,12 +983,11 @@ public class ChangeSupport public void fireCollectionCleared(CollectionChangeEvent event) { String collectionName = event.collectionName(); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -1012,12 +1018,11 @@ public class ChangeSupport public void fireCollectionCleared(String collectionName) { // this.fireCollectionCleared(new CollectionChangeEvent(this.source, collectionName)); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -1058,12 +1063,11 @@ public class ChangeSupport public void fireCollectionChanged(CollectionChangeEvent event) { String collectionName = event.collectionName(); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -1094,12 +1098,11 @@ public class ChangeSupport public void fireCollectionChanged(String collectionName) { // this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName)); - CollectionChangeListener[] collectionChangeListeners = null; CollectionChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - collectionChangeListeners = this.collectionChangeListeners(); + CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); if (collectionChangeListeners != null) { targets = collectionChangeListeners.clone(); } @@ -1198,12 +1201,11 @@ public class ChangeSupport String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1237,12 +1239,11 @@ public class ChangeSupport return; } - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1283,12 +1284,11 @@ public class ChangeSupport public void fireItemAdded(String listName, int index, Object addedItem) { // this.fireItemsAdded(listName, index, Collections.singletonList(addedItem)); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1333,12 +1333,11 @@ public class ChangeSupport String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1372,12 +1371,11 @@ public class ChangeSupport return; } - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1418,12 +1416,11 @@ public class ChangeSupport public void fireItemRemoved(String listName, int index, Object removedItem) { // this.fireItemsRemoved(listName, index, Collections.singletonList(removedItem)); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1468,12 +1465,11 @@ public class ChangeSupport String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1507,12 +1503,11 @@ public class ChangeSupport return; } - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1553,12 +1548,11 @@ public class ChangeSupport public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { // this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem)); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1603,12 +1597,11 @@ public class ChangeSupport String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1642,12 +1635,11 @@ public class ChangeSupport return; } - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1695,12 +1687,11 @@ public class ChangeSupport public void fireListCleared(ListChangeEvent event) { String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1731,12 +1722,11 @@ public class ChangeSupport public void fireListCleared(String listName) { // this.fireListCleared(new ListChangeEvent(this.source, listName)); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1777,12 +1767,11 @@ public class ChangeSupport public void fireListChanged(ListChangeEvent event) { String listName = event.listName(); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1813,12 +1802,11 @@ public class ChangeSupport public void fireListChanged(String listName) { // this.fireListChanged(new ListChangeEvent(this.source, listName)); - ListChangeListener[] listChangeListeners = null; ListChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - listChangeListeners = this.listChangeListeners(); + ListChangeListener[] listChangeListeners = this.listChangeListeners(); if (listChangeListeners != null) { targets = listChangeListeners.clone(); } @@ -1914,12 +1902,11 @@ public class ChangeSupport public void fireNodeAdded(TreeChangeEvent event) { String treeName = event.treeName(); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -1950,12 +1937,11 @@ public class ChangeSupport public void fireNodeAdded(String treeName, Object[] path) { // this.fireNodeAdded(new TreeChangeEvent(this.source, treeName, path)); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -1996,12 +1982,11 @@ public class ChangeSupport public void fireNodeRemoved(TreeChangeEvent event) { String treeName = event.treeName(); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2032,12 +2017,11 @@ public class ChangeSupport public void fireNodeRemoved(String treeName, Object[] path) { // this.fireNodeRemoved(new TreeChangeEvent(this.source, treeName, path)); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2078,12 +2062,11 @@ public class ChangeSupport public void fireTreeCleared(TreeChangeEvent event) { String treeName = event.treeName(); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2114,12 +2097,11 @@ public class ChangeSupport public void fireTreeCleared(String treeName, Object[] path) { // this.fireTreeCleared(new TreeChangeEvent(this.source, treeName, path)); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2167,12 +2149,11 @@ public class ChangeSupport public void fireTreeChanged(TreeChangeEvent event) { String treeName = event.treeName(); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2203,12 +2184,11 @@ public class ChangeSupport public void fireTreeChanged(String treeName, Object[] path) { // this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, path)); - TreeChangeListener[] treeChangeListeners = null; TreeChangeListener[] targets = null; ChangeSupport child = null; synchronized (this) { - treeChangeListeners = this.treeChangeListeners(); + TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); if (treeChangeListeners != null) { targets = treeChangeListeners.clone(); } @@ -2321,20 +2301,23 @@ public class ChangeSupport // ********** member classes ********** /** - * Pair a listener class with its generic listeners. + * Pair a listener class with its "generic" listeners. */ private static class GenericListenerList { final Class<? extends ChangeListener> listenerClass; ChangeListener[] listeners; + <T extends ChangeListener> GenericListenerList(Class<T> listenerClass, T listener) { super(); this.listenerClass = listenerClass; this.listeners = (ChangeListener[]) Array.newInstance(listenerClass, 1); this.listeners[0] = listener; } + void addListener(ChangeListener listener) { this.listeners = CollectionTools.add(this.listeners, listener); } + boolean removeListener(ChangeListener listener) { int len = this.listeners.length; if (len == 0) { @@ -2347,9 +2330,16 @@ public class ChangeSupport } return (this.listeners.length + 1) == len; } + boolean hasListeners() { return this.listeners.length > 0; } + + @Override + public String toString() { + return StringTools.buildToStringFor(this, ClassTools.shortNameFor(this.listenerClass)); + } + } /** @@ -2360,11 +2350,18 @@ public class ChangeSupport final String aspectName; final ChangeSupport child; private static final long serialVersionUID = 1L; + AspectChild(String aspectName, ChangeSupport child) { super(); this.aspectName = aspectName; this.child = child; } + + @Override + public String toString() { + return StringTools.buildToStringFor(this, this.aspectName); + } + } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java index d7544a2805..af226f4bca 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/************************************************* * Copyright (c) 2007 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 @@ -6,7 +6,7 @@ * * Contributors: * Oracle - initial API and implementation - ******************************************************************************/ + ************************************************/ package org.eclipse.jpt.utility.internal.model; import java.util.Collection; @@ -20,62 +20,63 @@ import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent; import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; /** - * This support class changes the behavior of the standard + * This change support class changes the behavior of the standard * ChangeSupport in several ways: - * - All events fired by the source must specify the expected aspect name. + * - All events fired by the source must specify the single aspect name. * - Listeners are required to be either "generic" listeners or - * listeners of the aspect name. - * - The "aspect-specific" listeners are stored alongside the "generic" - * listeners, improving performance a bit (in terms of both time and space) + * listeners of the single aspect name. */ -public class SingleAspectChangeSupport extends ChangeSupport { +public class SingleAspectChangeSupport + extends ChangeSupport +{ private final String aspectName; + private static final long serialVersionUID = 1L; + + // ********** constructor ********** + public SingleAspectChangeSupport(Model source, String aspectName) { super(source); this.aspectName = aspectName; } - // ******************** internal behavior ******************** + // ********** internal behavior ********** private UnsupportedOperationException unsupportedOperationException() { return new UnsupportedOperationException("This Model supports only changes for the aspect \"" + this.aspectName + "\""); } - private void checkAspectName(String aName) { - if (aName != this.aspectName) { - throw new IllegalArgumentException("This Model supports only changes for the aspect \"" + this.aspectName + "\" : \"" + aName + "\""); + private void checkAspectName(String listenerAspectName) { + if (listenerAspectName != this.aspectName) { + throw new IllegalArgumentException("This Model supports only changes for the aspect \"" + this.aspectName + "\" : \"" + listenerAspectName + "\""); } } @Override - protected <T extends ChangeListener> void addListener(String aName, Class<T> listenerClass, T listener) { - this.checkAspectName(aName); - // redirect to "generic" listeners collection - this.addListener(listenerClass, listener); + protected <T extends ChangeListener> void addListener(String listenerAspectName, Class<T> listenerClass, T listener) { + this.checkAspectName(listenerAspectName); + super.addListener(listenerAspectName, listenerClass, listener); } @Override - protected <T extends ChangeListener> void removeListener(String aName, Class<T> listenerClass, T listener) { - this.checkAspectName(aName); - // redirect to "generic" listeners collection - this.removeListener(listenerClass, listener); + protected <T extends ChangeListener> void removeListener(String listenerAspectName, Class<T> listenerClass, T listener) { + this.checkAspectName(listenerAspectName); + super.removeListener(listenerAspectName, listenerClass, listener); } - // ******************** internal queries ******************** + // ********** internal queries ********** @Override - protected boolean hasAnyListeners(Class<? extends ChangeListener> listenerClass, String aName) { - this.checkAspectName(aName); - // redirect to "generic" listeners collection - return this.hasAnyListeners(listenerClass); + protected boolean hasAnyListeners(Class<? extends ChangeListener> listenerClass, String listenerAspectName) { + this.checkAspectName(listenerAspectName); + return super.hasAnyListeners(listenerClass, listenerAspectName); } - // ******************** state change support ******************** + // ********** state change support ********** @Override public void fireStateChanged(StateChangeEvent event) { @@ -88,7 +89,7 @@ public class SingleAspectChangeSupport extends ChangeSupport { } - // ******************** property change support ******************** + // ********** property change support ********** @Override public void firePropertyChanged(PropertyChangeEvent event) { @@ -115,7 +116,7 @@ public class SingleAspectChangeSupport extends ChangeSupport { } - // ******************** collection change support ******************** + // ********** collection change support ********** @Override public void fireItemsAdded(CollectionChangeEvent event) { @@ -178,7 +179,7 @@ public class SingleAspectChangeSupport extends ChangeSupport { } - // ******************** list change support ******************** + // ********** list change support ********** @Override public void fireItemsAdded(ListChangeEvent event) { @@ -271,7 +272,7 @@ public class SingleAspectChangeSupport extends ChangeSupport { } - // ******************** tree change support ******************** + // ********** tree change support ********** @Override public void fireNodeAdded(TreeChangeEvent event) { diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractReadOnlyCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractReadOnlyCollectionValueModel.java index f8dd691623..a2838845d4 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractReadOnlyCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractReadOnlyCollectionValueModel.java @@ -51,24 +51,24 @@ public abstract class AbstractReadOnlyCollectionValueModel // ********** CollectionValueModel implementation ********** - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } - public void addItems(Collection items) { + public void addAll(Collection items) { throw new UnsupportedOperationException(); } - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } - public void removeItems(Collection items) { + public void removeAll(Collection items) { throw new UnsupportedOperationException(); } public int size() { - return CollectionTools.size((Iterator) this.value()); + return CollectionTools.size((Iterator) this.values()); } @@ -76,7 +76,7 @@ public abstract class AbstractReadOnlyCollectionValueModel @Override public String toString() { - return StringTools.buildToStringFor(this, CollectionTools.collection((Iterator) this.value())); + return StringTools.buildToStringFor(this, CollectionTools.collection((Iterator) this.values())); } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java index 5e4c6df31c..45aef0c618 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java @@ -13,17 +13,14 @@ import org.eclipse.jpt.utility.internal.model.AbstractModel; import org.eclipse.jpt.utility.internal.model.ChangeSupport; import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener; /** * This abstract extension of AbstractModel provides a base for adding * change listeners (PropertyChange, CollectionChange, ListChange, TreeChange) * to a subject and converting the subject's change notifications into a single - * set of change notifications for the aspect VALUE. + * set of change notifications for a common aspect (e.g. VALUE). * * The adapter will only listen to the subject (and subject holder) when the * adapter itself actually has listeners. This will allow the adapter to be @@ -31,7 +28,6 @@ import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener; */ public abstract class AspectAdapter extends AbstractModel - implements ValueModel { /** * The subject that holds the aspect and fires @@ -50,10 +46,10 @@ public abstract class AspectAdapter * For now, this is can only be set upon construction and is * immutable. */ - protected ValueModel subjectHolder; + protected final ValueModel subjectHolder; /** A listener that keeps us in synch with the subjectHolder. */ - protected PropertyChangeListener subjectChangeListener; + protected final PropertyChangeListener subjectChangeListener; // ********** constructors ********** @@ -75,6 +71,7 @@ public abstract class AspectAdapter throw new NullPointerException(); } this.subjectHolder = subjectHolder; + this.subjectChangeListener = this.buildSubjectChangeListener(); // the subject is null when we are not listening to it // this will typically result in our value being null this.subject = null; @@ -82,16 +79,10 @@ public abstract class AspectAdapter // ********** initialization ********** - - @Override - protected void initialize() { - super.initialize(); - this.subjectChangeListener = this.buildSubjectChangeListener(); - } @Override protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, VALUE); + return new LocalChangeSupport(this, this.listenerAspectName()); } /** @@ -129,12 +120,30 @@ public abstract class AspectAdapter } /** + * Return the aspect's current value. + */ + protected abstract Object value(); + + /** + * Return the class of listener that is interested in the aspect adapter's + * changes. + */ + protected abstract Class<? extends ChangeListener> listenerClass(); + + /** + * Return the name of the aspect adapter's aspect (e.g. VALUE). + * This is the name of the aspect adapter's single aspect, not the + * name of the subject's aspect the aspect adapter is adapting. + */ + protected abstract String listenerAspectName(); + + /** * Return whether there are any listeners for the aspect. */ protected abstract boolean hasListeners(); /** - * Return whether there are any listeners for the aspect. + * Return whether there are no listeners for the aspect. */ protected boolean hasNoListeners() { return ! this.hasListeners(); @@ -170,14 +179,14 @@ public abstract class AspectAdapter } protected void engageSubjectHolder() { - this.subjectHolder.addPropertyChangeListener(VALUE, this.subjectChangeListener); + this.subjectHolder.addPropertyChangeListener(ValueModel.VALUE, this.subjectChangeListener); // synch our subject *after* we start listening to the subject holder, // since its value might change when a listener is added this.subject = this.subjectHolder.value(); } protected void disengageSubjectHolder() { - this.subjectHolder.removePropertyChangeListener(VALUE, this.subjectChangeListener); + this.subjectHolder.removePropertyChangeListener(ValueModel.VALUE, this.subjectChangeListener); // clear out the subject when we are not listening to its holder this.subject = null; } @@ -193,204 +202,77 @@ public abstract class AspectAdapter } - // ********** extend change support ********** - - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModels(); - } - super.addStateChangeListener(listener); - } - - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModels(); - } - } - - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModels(); - } - super.addPropertyChangeListener(listener); - } - - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName == VALUE && this.hasNoListeners()) { - this.engageModels(); - } - super.addPropertyChangeListener(propertyName, listener); - } + // ********** local change support ********** /** - * Extend to stop listening to the models if appropriate. + * Extend change support to start listening to the aspect adapter's + * models (the subject holder and the subject itself) when the first + * relevant listener is added. + * Conversely, stop listening to the aspect adapter's models when the + * last relevant listener is removed. + * A relevant listener is a listener of the relevant type. */ - @Override - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - super.removePropertyChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModels(); - } - } + protected class LocalChangeSupport extends SingleAspectChangeSupport { + private static final long serialVersionUID = 1L; - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName == VALUE && this.hasNoListeners()) { - this.disengageModels(); + public LocalChangeSupport(AspectAdapter source, String aspectName) { + super(source, aspectName); } - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModels(); + protected boolean listenerIsRelevant(Class<? extends ChangeListener> listenerClass) { + return listenerClass == AspectAdapter.this.listenerClass(); } - super.addCollectionChangeListener(listener); - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUE && this.hasNoListeners()) { - this.engageModels(); + protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> listenerClass) { + return this.listenerIsRelevant(listenerClass) + && this.hasNoListeners(listenerClass); } - super.addCollectionChangeListener(collectionName, listener); - } - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModels(); - } - } - - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUE && this.hasNoListeners()) { - this.disengageModels(); + protected boolean listenerIsRelevant(Class<? extends ChangeListener> listenerClass, String listenerAspectName) { + return this.listenerIsRelevant(listenerClass) + && (listenerAspectName == AspectAdapter.this.listenerAspectName()); } - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModels(); + protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> listenerClass, String listenerAspectName) { + return this.listenerIsRelevant(listenerClass, listenerAspectName) + && this.hasNoListeners(listenerClass, listenerAspectName); } - super.addListChangeListener(listener); - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == VALUE && this.hasNoListeners()) { - this.engageModels(); - } - super.addListChangeListener(listName, listener); - } - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModels(); - } - } + // ********** overrides ********** - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == VALUE && this.hasNoListeners()) { - this.disengageModels(); + @Override + protected <T extends ChangeListener> void addListener(Class<T> listenerClass, T listener) { + if (this.hasNoRelevantListeners(listenerClass)) { + AspectAdapter.this.engageModels(); + } + super.addListener(listenerClass, listener); } - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addTreeChangeListener(TreeChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModels(); + @Override + protected <T extends ChangeListener> void addListener(String listenerAspectName, Class<T> listenerClass, T listener) { + if (this.hasNoRelevantListeners(listenerClass, listenerAspectName)) { + AspectAdapter.this.engageModels(); + } + super.addListener(listenerAspectName, listenerClass, listener); } - super.addTreeChangeListener(listener); - } - /** - * Extend to start listening to the models if necessary. - */ - @Override - public synchronized void addTreeChangeListener(String treeName, TreeChangeListener listener) { - if (treeName == VALUE && this.hasNoListeners()) { - this.engageModels(); + @Override + protected <T extends ChangeListener> void removeListener(Class<T> listenerClass, T listener) { + super.removeListener(listenerClass, listener); + if (this.hasNoRelevantListeners(listenerClass)) { + AspectAdapter.this.disengageModels(); + } } - super.addTreeChangeListener(treeName, listener); - } - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeTreeChangeListener(TreeChangeListener listener) { - super.removeTreeChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModels(); + @Override + protected <T extends ChangeListener> void removeListener(String listenerAspectName, Class<T> listenerClass, T listener) { + super.removeListener(listenerAspectName, listenerClass, listener); + if (this.hasNoRelevantListeners(listenerClass, listenerAspectName)) { + AspectAdapter.this.disengageModels(); + } } - } - /** - * Extend to stop listening to the models if appropriate. - */ - @Override - public synchronized void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - super.removeTreeChangeListener(treeName, listener); - if (treeName == VALUE && this.hasNoListeners()) { - this.disengageModels(); - } } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java index 0aaa8e7bd2..a5d6744158 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java @@ -16,6 +16,7 @@ import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.model.Model; import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener; /** @@ -35,7 +36,7 @@ import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener; * (e.g. UI) will need only to *get* the value * #addItems(Collection) and #removeItems(Collection) * override these methods to improve performance, if necessary - * #value() + * #values() * override this method only if returning an empty iterator when the * subject is null is unacceptable * #size() @@ -49,10 +50,10 @@ public abstract class CollectionAspectAdapter /** * The name of the subject's collection that we use for the value. */ - protected String collectionName; + protected final String collectionName; /** A listener that listens to the subject's collection aspect. */ - protected CollectionChangeListener collectionChangeListener; + protected final CollectionChangeListener collectionChangeListener; // ********** constructors ********** @@ -62,17 +63,7 @@ public abstract class CollectionAspectAdapter * and collection. */ protected CollectionAspectAdapter(String collectionName, Model subject) { - super(subject); - this.collectionName = collectionName; - } - - /** - * Construct a CollectionAspectAdapter for the specified subject holder - * and collection. - */ - protected CollectionAspectAdapter(ValueModel subjectHolder, String collectionName) { - super(subjectHolder); - this.collectionName = collectionName; + this(new ReadOnlyPropertyValueModel(subject), collectionName); } /** @@ -85,15 +76,19 @@ public abstract class CollectionAspectAdapter this(subjectHolder, null); } - - // ********** initialization ********** - - @Override - protected void initialize() { - super.initialize(); + /** + * Construct a CollectionAspectAdapter for the specified subject holder + * and collection. + */ + protected CollectionAspectAdapter(ValueModel subjectHolder, String collectionName) { + super(subjectHolder); + this.collectionName = collectionName; this.collectionChangeListener = this.buildCollectionChangeListener(); } + + // ********** initialization ********** + /** * The subject's collection aspect has changed, notify the listeners. */ @@ -120,13 +115,13 @@ public abstract class CollectionAspectAdapter } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** /** * Return the value of the subject's collection aspect. * This should be an *iterator* on the collection. */ - public Object value() { + public Iterator values() { if (this.subject == null) { return EmptyIterator.instance(); } @@ -137,44 +132,41 @@ public abstract class CollectionAspectAdapter * Return the value of the subject's collection aspect. * This should be an *iterator* on the collection. * At this point we can be sure that the subject is not null. - * @see #value() + * @see #values() */ protected Iterator getValueFromSubject() { throw new UnsupportedOperationException(); } - - // ********** CollectionValueModel implementation ********** - /** * Add the specified item to the subject's collection aspect. */ - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } /** * Add the specified items to the subject's collection aspect. */ - public void addItems(Collection items) { + public void addAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.addItem(stream.next()); + this.add(stream.next()); } } /** * Remove the specified item from the subject's collection aspect. */ - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } /** * Remove the specified items from the subject's collection aspect. */ - public void removeItems(Collection items) { + public void removeAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.removeItem(stream.next()); + this.remove(stream.next()); } } @@ -191,20 +183,35 @@ public abstract class CollectionAspectAdapter * @see #size() */ protected int sizeFromSubject() { - return CollectionTools.size((Iterator) this.value()); + return CollectionTools.size((Iterator) this.values()); } // ********** AspectAdapter implementation ********** @Override + protected Object value() { + return this.values(); + } + + @Override + protected Class<? extends ChangeListener> listenerClass() { + return CollectionChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUES; + } + + @Override protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUE); + return this.hasAnyCollectionChangeListeners(VALUES); } @Override protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUE); + this.fireCollectionChanged(VALUES); } @Override @@ -230,19 +237,19 @@ public abstract class CollectionAspectAdapter // ********** behavior ********** protected void itemsAdded(CollectionChangeEvent e) { - this.fireItemsAdded(e.cloneWithSource(this, VALUE)); + this.fireItemsAdded(e.cloneWithSource(this, VALUES)); } protected void itemsRemoved(CollectionChangeEvent e) { - this.fireItemsRemoved(e.cloneWithSource(this, VALUE)); + this.fireItemsRemoved(e.cloneWithSource(this, VALUES)); } protected void collectionCleared(CollectionChangeEvent e) { - this.fireCollectionCleared(VALUE); + this.fireCollectionCleared(VALUES); } protected void collectionChanged(CollectionChangeEvent e) { - this.fireCollectionChanged(VALUE); + this.fireCollectionChanged(VALUES); } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java index d6ef0a1aa3..b73b1aa48c 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java @@ -235,7 +235,7 @@ public class CollectionListValueModelAdapter // ********** behavior ********** protected void buildList() { - Iterator stream = (Iterator) this.collectionHolder.value(); + Iterator stream = (Iterator) this.collectionHolder.values(); // if the new collection is empty, do nothing if (stream.hasNext()) { this.list.ensureCapacity(this.collectionHolder.size()); @@ -255,14 +255,14 @@ public class CollectionListValueModelAdapter } protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); // synch our list *after* we start listening to the collection holder, // since its value might change when a listener is added this.buildList(); } protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); // clear out the list when we are not listening to the collection holder this.list.clear(); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java index b827a51120..3228f4a0a0 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java @@ -188,7 +188,7 @@ public abstract class CollectionPropertyValueModelAdapter * Start listening to the collection holder. */ protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); // synch our value *after* we start listening to the collection, // since the collection's value might change when a listener is added this.value = this.buildValue(); @@ -204,7 +204,7 @@ public abstract class CollectionPropertyValueModelAdapter * Stop listening to the collection holder. */ protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); // clear out our value when we are not listening to the collection this.value = null; } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModel.java index acc3034ae3..79ce454cf5 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModel.java @@ -10,34 +10,41 @@ package org.eclipse.jpt.utility.internal.model.value; import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.jpt.utility.internal.model.Model; /** - * Extend ValueModel to allow the adding and - * removing of items in a collection value. - * Typically the value returned from #value() - * will be an Iterator. + * Interface used to abstract collection accessing and + * change notification and make it more pluggable. */ -public interface CollectionValueModel extends ValueModel { +public interface CollectionValueModel extends Model { + + /** + * Return the collection's values. + */ + Iterator values(); + String VALUES = "values"; /** - * Add the specified item to the collection value. + * Add the specified item to the collection. */ - void addItem(Object item); + void add(Object item); /** - * Add the specified items to the collection value. + * Add the specified items to the collection. */ - void addItems(Collection items); + void addAll(Collection items); /** - * Remove the specified item from the collection value. + * Remove the specified item from the collection. */ - void removeItem(Object item); + void remove(Object item); /** - * Remove the specified items from the collection value. + * Remove the specified items from the collection. */ - void removeItems(Collection items); + void removeAll(Collection items); /** * Return the size of the collection value. diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java index a75cfea75e..3045ee481b 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java @@ -58,7 +58,7 @@ public abstract class CollectionValueModelWrapper @Override protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, VALUE); + return new SingleAspectChangeSupport(this, VALUES); } protected CollectionChangeListener buildCollectionChangeListener() { @@ -90,7 +90,7 @@ public abstract class CollectionValueModelWrapper */ @Override public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoCollectionChangeListeners(VALUE)) { + if (this.hasNoCollectionChangeListeners(VALUES)) { this.engageModel(); } super.addCollectionChangeListener(listener); @@ -101,7 +101,7 @@ public abstract class CollectionValueModelWrapper */ @Override public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUE && this.hasNoCollectionChangeListeners(VALUE)) { + if (collectionName == VALUES && this.hasNoCollectionChangeListeners(VALUES)) { this.engageModel(); } super.addCollectionChangeListener(collectionName, listener); @@ -113,7 +113,7 @@ public abstract class CollectionValueModelWrapper @Override public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { super.removeCollectionChangeListener(listener); - if (this.hasNoCollectionChangeListeners(VALUE)) { + if (this.hasNoCollectionChangeListeners(VALUES)) { this.disengageModel(); } } @@ -124,7 +124,7 @@ public abstract class CollectionValueModelWrapper @Override public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUE && this.hasNoCollectionChangeListeners(VALUE)) { + if (collectionName == VALUES && this.hasNoCollectionChangeListeners(VALUES)) { this.disengageModel(); } } @@ -135,26 +135,26 @@ public abstract class CollectionValueModelWrapper /** * wrappers cannot be modified - the underlying model must be modified directly */ - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } - public void addItems(Collection items) { + public void addAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.addItem(stream.next()); + this.add(stream.next()); } } /** * wrappers cannot be modified - the underlying model must be modified directly */ - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } - public void removeItems(Collection items) { + public void removeAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.removeItem(stream.next()); + this.remove(stream.next()); } } @@ -165,14 +165,14 @@ public abstract class CollectionValueModelWrapper * Start listening to the collection holder. */ protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.addCollectionChangeListener(VALUES, this.collectionChangeListener); } /** * Stop listening to the collection holder. */ protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(VALUE, this.collectionChangeListener); + this.collectionHolder.removeCollectionChangeListener(VALUES, this.collectionChangeListener); } @Override diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java index 1d12858258..9be509a43d 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java @@ -138,9 +138,9 @@ public class CompositeCollectionValueModel } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** - public Object value() { + public Iterator values() { return new CompositeIterator(this.buildCollectionsIterators()); } @@ -152,9 +152,6 @@ public class CompositeCollectionValueModel }; } - - // ********** CollectionValueModel implementation ********** - public int size() { return this.size; } @@ -170,7 +167,7 @@ public class CompositeCollectionValueModel // the following will trigger the firing of a number of unnecessary events // (since we don't have any listeners yet), // but it reduces the amount of duplicate code - this.addComponentSources((Iterator) this.collectionHolder.value()); + this.addComponentSources((Iterator) this.collectionHolder.values()); } @Override @@ -178,7 +175,7 @@ public class CompositeCollectionValueModel super.disengageModel(); // stop listening to the components... for (Iterator stream = this.components.values().iterator(); stream.hasNext(); ) { - ((CollectionValueModel) stream.next()).removeCollectionChangeListener(ValueModel.VALUE, this.componentListener); + ((CollectionValueModel) stream.next()).removeCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener); } // ...and clear the cache this.components.clear(); @@ -214,7 +211,7 @@ public class CompositeCollectionValueModel if (this.components.put(source, component) != null) { throw new IllegalStateException("duplicate component: " + source); } - component.addCollectionChangeListener(ValueModel.VALUE, this.componentListener); + component.addCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener); ArrayList componentCollection = new ArrayList(component.size()); if (this.collections.put(component, componentCollection) != null) { throw new IllegalStateException("duplicate collection: " + source); @@ -250,7 +247,7 @@ public class CompositeCollectionValueModel if (component == null) { throw new IllegalStateException("missing component: " + source); } - component.removeCollectionChangeListener(VALUE, this.componentListener); + component.removeCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener); ArrayList componentCollection = (ArrayList) this.collections.remove(component); if (componentCollection == null) { throw new IllegalStateException("missing collection: " + source); @@ -276,7 +273,7 @@ public class CompositeCollectionValueModel protected void collectionChanged(CollectionChangeEvent e) { // copy the keys so we don't eat our own tail this.removeComponentSources(new ArrayList(this.components.keySet()).iterator()); - this.addComponentSources((Iterator) this.collectionHolder.value()); + this.addComponentSources((Iterator) this.collectionHolder.values()); } @@ -323,7 +320,7 @@ public class CompositeCollectionValueModel * Update our cache. */ protected void addComponentItems(CollectionValueModel itemsHolder, ArrayList componentCollection) { - this.addComponentItems((Iterator) itemsHolder.value(), itemsHolder.size(), componentCollection); + this.addComponentItems((Iterator) itemsHolder.values(), itemsHolder.size(), componentCollection); } /** @@ -332,7 +329,7 @@ public class CompositeCollectionValueModel protected void addComponentItems(Iterator items, int itemsSize, ArrayList componentCollection) { this.size += itemsSize; componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - this.addItemsToCollection(items, componentCollection, VALUE); + this.addItemsToCollection(items, componentCollection, CollectionValueModel.VALUES); } /** @@ -363,7 +360,7 @@ public class CompositeCollectionValueModel */ protected void removeComponentItems(Iterator items, int itemsSize, ArrayList componentCollection) { this.size -= itemsSize; - this.removeItemsFromCollection(items, componentCollection, VALUE); + this.removeItemsFromCollection(items, componentCollection, CollectionValueModel.VALUES); } /** diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java index e4d046aff3..fe6c6c250f 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java @@ -117,15 +117,12 @@ public class FilteringCollectionValueModel } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** - public Object value() { + public Iterator values() { return this.filteredItems.iterator(); } - - // ********** CollectionValueModel implementation ********** - public int size() { return this.filteredItems.size(); } @@ -151,7 +148,7 @@ public class FilteringCollectionValueModel @Override protected void itemsAdded(CollectionChangeEvent e) { // filter the values before propagating the change event - this.addItemsToCollection(this.filter(e.items()), this.filteredItems, VALUE); + this.addItemsToCollection(this.filter(e.items()), this.filteredItems, VALUES); } @Override @@ -159,18 +156,18 @@ public class FilteringCollectionValueModel // do *not* filter the values, because they may no longer be // "accepted" and that might be why they were removed in the first place; // anyway, any extraneous items are harmless - this.removeItemsFromCollection(e.items(), this.filteredItems, VALUE); + this.removeItemsFromCollection(e.items(), this.filteredItems, VALUES); } @Override protected void collectionCleared(CollectionChangeEvent e) { - this.clearCollection(this.filteredItems, VALUE); + this.clearCollection(this.filteredItems, VALUES); } @Override protected void collectionChanged(CollectionChangeEvent e) { this.synchFilteredItems(); - this.fireCollectionChanged(VALUE); + this.fireCollectionChanged(VALUES); } @@ -204,7 +201,7 @@ public class FilteringCollectionValueModel */ protected void synchFilteredItems() { this.filteredItems.clear(); - CollectionTools.addAll(this.filteredItems, this.filter((Iterator) this.collectionHolder.value())); + CollectionTools.addAll(this.filteredItems, this.filter((Iterator) this.collectionHolder.values())); } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java index 3786fa3720..c4ea16741b 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java @@ -17,6 +17,7 @@ import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; import org.eclipse.jpt.utility.internal.model.Model; import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener; /** @@ -52,10 +53,10 @@ public abstract class ListAspectAdapter /** * The name of the subject's list that we use for the value. */ - protected String listName; + protected final String listName; /** A listener that listens to the subject's list aspect. */ - protected ListChangeListener listChangeListener; + protected final ListChangeListener listChangeListener; // ********** constructors ********** @@ -65,17 +66,7 @@ public abstract class ListAspectAdapter * and list. */ protected ListAspectAdapter(String listName, Model subject) { - super(subject); - this.listName = listName; - } - - /** - * Construct a ListAspectAdapter for the specified subject holder - * and list. - */ - protected ListAspectAdapter(ValueModel subjectHolder, String listName) { - super(subjectHolder); - this.listName = listName; + this(new ReadOnlyPropertyValueModel(subject), listName); } /** @@ -88,15 +79,19 @@ public abstract class ListAspectAdapter this(subjectHolder, null); } - - // ********** initialization ********** - - @Override - protected void initialize() { - super.initialize(); + /** + * Construct a ListAspectAdapter for the specified subject holder + * and list. + */ + protected ListAspectAdapter(ValueModel subjectHolder, String listName) { + super(subjectHolder); + this.listName = listName; this.listChangeListener = this.buildListChangeListener(); } + + // ********** initialization ********** + /** * The subject's list aspect has changed, notify the listeners. */ @@ -135,6 +130,7 @@ public abstract class ListAspectAdapter * Return the value of the subject's list aspect. * This should be a *list iterator* on the list. */ + @Override public Object value() { if (this.subject == null) { return EmptyListIterator.instance(); @@ -234,6 +230,16 @@ public abstract class ListAspectAdapter // ********** AspectAdapter implementation ********** @Override + protected Class<? extends ChangeListener> listenerClass() { + return ListChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUE; + } + + @Override protected boolean hasListeners() { return this.hasAnyListChangeListeners(VALUE); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java index 0b679c57d8..aa39a47ad4 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java @@ -76,7 +76,7 @@ public class ListCollectionValueModelAdapter @Override protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, VALUE); + return new SingleAspectChangeSupport(this, VALUES); } /** @@ -111,29 +111,26 @@ public class ListCollectionValueModelAdapter } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** - public Object value() { + public Iterator values() { // try to prevent backdoor modification of the list return new ReadOnlyIterator(this.collection); } - - // ********** CollectionValueModel implementation ********** - - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } - public void addItems(Collection items) { + public void addAll(Collection items) { throw new UnsupportedOperationException(); } - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } - public void removeItems(Collection items) { + public void removeAll(Collection items) { throw new UnsupportedOperationException(); } @@ -160,7 +157,7 @@ public class ListCollectionValueModelAdapter */ @Override public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUE && this.hasNoListeners()) { + if (collectionName == VALUES && this.hasNoListeners()) { this.engageModel(); } super.addCollectionChangeListener(collectionName, listener); @@ -183,7 +180,7 @@ public class ListCollectionValueModelAdapter @Override public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUE && this.hasNoListeners()) { + if (collectionName == VALUES && this.hasNoListeners()) { this.disengageModel(); } } @@ -192,7 +189,7 @@ public class ListCollectionValueModelAdapter // ********** queries ********** protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUE); + return this.hasAnyCollectionChangeListeners(VALUES); } protected boolean hasNoListeners() { @@ -235,20 +232,20 @@ public class ListCollectionValueModelAdapter } protected void engageModel() { - this.listHolder.addListChangeListener(VALUE, this.listChangeListener); + this.listHolder.addListChangeListener(ValueModel.VALUE, this.listChangeListener); // synch our collection *after* we start listening to the list holder, // since its value might change when a listener is added this.buildCollection(); } protected void disengageModel() { - this.listHolder.removeListChangeListener(VALUE, this.listChangeListener); + this.listHolder.removeListChangeListener(ValueModel.VALUE, this.listChangeListener); // clear out the collection when we are not listening to the list holder this.collection.clear(); } protected void itemsAdded(ListChangeEvent e) { - this.addItemsToCollection(e.items(), this.collection, VALUE); + this.addItemsToCollection(e.items(), this.collection, VALUES); } protected void removeInternalItems(Iterator items) { @@ -258,7 +255,7 @@ public class ListCollectionValueModelAdapter Object removedItem = items.next(); int index = this.lastIdentityIndexOf(removedItem); this.collection.remove(index); - this.fireItemRemoved(VALUE, removedItem); + this.fireItemRemoved(VALUES, removedItem); } } @@ -268,7 +265,7 @@ public class ListCollectionValueModelAdapter protected void itemsReplaced(ListChangeEvent e) { this.removeInternalItems(e.replacedItems()); - this.addItemsToCollection(e.items(), this.collection, VALUE); + this.addItemsToCollection(e.items(), this.collection, VALUES); } protected void itemsMoved(ListChangeEvent e) { @@ -279,7 +276,7 @@ public class ListCollectionValueModelAdapter // put in empty check so we don't fire events unnecessarily if ( ! this.collection.isEmpty()) { this.collection.clear(); - this.fireCollectionCleared(VALUE); + this.fireCollectionCleared(VALUES); } } @@ -294,13 +291,13 @@ public class ListCollectionValueModelAdapter Collection removedItems = this.collection; // ...or we create a new one here (which is what we do) this.collection = new ArrayList(); - this.fireItemsRemoved(VALUE, removedItems); + this.fireItemsRemoved(VALUES, removedItems); } this.buildCollection(); // put in empty check so we don't fire events unnecessarily if ( ! this.collection.isEmpty()) { - this.fireItemsAdded(VALUE, this.collection); + this.fireItemsAdded(VALUES, this.collection); } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java index 7af76872f3..5e329bf289 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java @@ -17,6 +17,8 @@ import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; import org.eclipse.jpt.utility.internal.model.Model; import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; +import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener; import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener; /** @@ -33,41 +35,36 @@ import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener; public abstract class ListCurator extends AspectAdapter implements ListValueModel -{ +{ /** How the list looked before the last state change */ - private List record; - + private final ArrayList record; + /** A listener that listens for the subject's state to change */ - private StateChangeListener stateChangeListener; - - - // **************** Constructors ****************************************** - + private final StateChangeListener stateChangeListener; + + + // ********** constructors ********** + /** * Construct a Curator for the specified subject. */ protected ListCurator(Model subject) { - super(subject); + this(new ReadOnlyPropertyValueModel(subject)); } - + /** * Construct a curator for the specified subject holder. * The subject holder cannot be null. */ protected ListCurator(ValueModel subjectHolder) { super(subjectHolder); - } - - - // **************** Initialization **************************************** - - @Override - protected void initialize() { - super.initialize(); this.record = new ArrayList(); this.stateChangeListener = this.buildStateChangeListener(); } - + + + // ********** initialization ********** + /** * The subject's state has changed, do inventory and report to listeners. */ @@ -82,38 +79,39 @@ public abstract class ListCurator } }; } - - - // **************** ValueModel contract *********************************** - + + + // ********** ValueModel implementation ********** + + @Override public Object value() { return new ReadOnlyListIterator(this.record); } - - - // **************** ListValueModel contract ******************************* - + + + // ********** ListValueModel implementation ********** + /** * Return the item at the specified index of the subject's list aspect. */ public Object getItem(int index) { return this.record.get(index); } - + /** * Return the size of the subject's list aspect. */ public int size() { return this.record.size(); } - + /** * Unsupported in this implementation */ public void addItem(int index, Object item) { throw new UnsupportedOperationException(); } - + /** * Unsupported in this implementation */ @@ -122,14 +120,14 @@ public abstract class ListCurator this.addItem(index + i, items.get(i)); } } - + /** * Unsupported in this implementation */ public Object removeItem(int index) { throw new UnsupportedOperationException(); } - + /** * Unsupported in this implementation */ @@ -140,14 +138,14 @@ public abstract class ListCurator } return removedItems; } - + /** * Unsupported in this implementation */ public Object replaceItem(int index, Object item) { throw new UnsupportedOperationException(); } - + /** * Unsupported in this implementation */ @@ -158,18 +156,25 @@ public abstract class ListCurator } return replacedItems; } - - - // ***************** AspectAdapter contract ******************************* - - /** - * Return whether there are any listeners. - */ + + + // ********** AspectAdapter implementation ********** + + @Override + protected Class<? extends ChangeListener> listenerClass() { + return ListChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUE; + } + @Override protected boolean hasListeners() { return this.hasAnyListChangeListeners(VALUE); } - + /** * The aspect has changed, notify listeners appropriately. */ @@ -177,7 +182,7 @@ public abstract class ListCurator protected void fireAspectChange(Object oldValue, Object newValue) { this.fireListChanged(VALUE); } - + /** * The subject is not null - add our listener. */ @@ -188,7 +193,7 @@ public abstract class ListCurator // since its value might change when a listener is added CollectionTools.addAll(this.record, this.getValueForRecord()); } - + /** * The subject is not null - remove our listener. */ @@ -198,33 +203,33 @@ public abstract class ListCurator // clear out the list when we are not listening to the subject this.record.clear(); } - - // **************** ListCurator contract ********************************** - + + // ********** ListCurator contract ********** + /** * This is intended to be different from #ValueModel.getValue(). * It is intended to be used only when the subject changes or the subject's state changes. */ protected abstract Iterator getValueForRecord(); - - - // **************** Behavior ********************************************** - + + + // ********** behavior ********** + void submitInventoryReport() { List newRecord = CollectionTools.list(this.getValueForRecord()); int recordIndex = 0; - + // add items from the new record for (Iterator newItems = newRecord.iterator(); newItems.hasNext(); ) { this.inventoryNewItem(recordIndex, newItems.next()); recordIndex ++; } - + // clean out items that are no longer in the new record for (recordIndex = 0; recordIndex < this.record.size(); ) { Object item = this.record.get(recordIndex); - + if (! newRecord.contains(item)) { this.removeItemFromInventory(recordIndex, item); } @@ -233,10 +238,10 @@ public abstract class ListCurator } } } - + private void inventoryNewItem(int recordIndex, Object newItem) { List rec = new ArrayList(this.record); - + if (recordIndex < rec.size() && rec.get(recordIndex).equals(newItem)) { return; } @@ -248,11 +253,11 @@ public abstract class ListCurator this.inventoryNewItem(recordIndex, newItem); } } - + private void addItemToInventory(int index, Object item) { this.addItemToList(index, item, this.record, VALUE); } - + private void removeItemFromInventory(int index, Object item) { this.removeItemFromList(index, this.record, VALUE); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java index 505518aa1c..441bb5278f 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java @@ -9,6 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.utility.internal.model.value; +import java.util.Iterator; + import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; @@ -51,7 +53,7 @@ public final class NullCollectionValueModel return 0; } - public Object value() { + public Iterator values() { return EmptyIterator.instance(); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java index 8d0fd79516..1b4d206abb 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java @@ -14,6 +14,7 @@ import java.util.Collection; import org.eclipse.jpt.utility.internal.model.Model; import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener; /** @@ -52,10 +53,11 @@ public abstract class PropertyAspectAdapter protected Object value; /** The name of the subject's properties that we use for the value. */ - protected String[] propertyNames; + protected final String[] propertyNames; + private static final String[] EMPTY_PROPERTY_NAMES = new String[0]; /** A listener that listens to the appropriate properties of the subject. */ - protected PropertyChangeListener propertyChangeListener; + protected final PropertyChangeListener propertyChangeListener; // ********** constructors ********** @@ -73,41 +75,19 @@ public abstract class PropertyAspectAdapter * and properties. */ protected PropertyAspectAdapter(String[] propertyNames, Model subject) { - super(subject); - this.propertyNames = propertyNames; - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and property. - */ - protected PropertyAspectAdapter(ValueModel subjectHolder, String propertyName) { - this(subjectHolder, new String[] {propertyName}); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(ValueModel subjectHolder, String propertyName1, String propertyName2) { - this(subjectHolder, new String[] {propertyName1, propertyName2}); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(ValueModel subjectHolder, String propertyName1, String propertyName2, String propertyName3) { - this(subjectHolder, new String[] {propertyName1, propertyName2, propertyName3}); + this(new ReadOnlyPropertyValueModel(subject), propertyNames); } /** * Construct a PropertyAspectAdapter for the specified subject holder * and properties. */ - protected PropertyAspectAdapter(ValueModel subjectHolder, String[] propertyNames) { + protected PropertyAspectAdapter(ValueModel subjectHolder, String... propertyNames) { super(subjectHolder); this.propertyNames = propertyNames; + this.propertyChangeListener = this.buildPropertyChangeListener(); + // our value is null when we are not listening to the subject + this.value = null; } /** @@ -125,20 +105,12 @@ public abstract class PropertyAspectAdapter * a new property. */ protected PropertyAspectAdapter(ValueModel subjectHolder) { - this(subjectHolder, new String[0]); + this(subjectHolder, EMPTY_PROPERTY_NAMES); } // ********** initialization ********** - @Override - protected void initialize() { - super.initialize(); - // our value is null when we are not listening to the subject - this.value = null; - this.propertyChangeListener = this.buildPropertyChangeListener(); - } - /** * The subject's property has changed, notify the listeners. */ @@ -161,6 +133,7 @@ public abstract class PropertyAspectAdapter /** * Return the value of the subject's property. */ + @Override public final Object value() { return this.value; } @@ -189,6 +162,16 @@ public abstract class PropertyAspectAdapter // ********** AspectAdapter implementation ********** + @Override + protected Class<? extends ChangeListener> listenerClass() { + return PropertyChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUE; + } + @Override protected boolean hasListeners() { return this.hasAnyPropertyChangeListeners(VALUE); @@ -242,7 +225,7 @@ public abstract class PropertyAspectAdapter } - // ********** queries ********** + // ********** behavior ********** /** * Return the aspect's value. @@ -264,9 +247,6 @@ public abstract class PropertyAspectAdapter throw new UnsupportedOperationException(); } - - // ********** behavior ********** - protected void propertyChanged() { Object old = this.value; this.value = this.buildValue(); diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java index d12426ad1b..ee28f98e1e 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java @@ -10,6 +10,7 @@ package org.eclipse.jpt.utility.internal.model.value; import java.util.Collection; +import java.util.Iterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator; @@ -64,7 +65,7 @@ public class PropertyCollectionValueModelAdapter @Override protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, VALUE); + return new SingleAspectChangeSupport(this, VALUES); } /** @@ -84,31 +85,28 @@ public class PropertyCollectionValueModelAdapter } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** - public Object value() { - if (this.value == null) { - return EmptyIterator.instance(); - } - return new SingleElementIterator(this.value); + public Iterator values() { + return (this.value == null) ? + EmptyIterator.instance() + : + new SingleElementIterator(this.value); } - - // ********** CollectionValueModel implementation ********** - - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } - public void addItems(Collection items) { + public void addAll(Collection items) { throw new UnsupportedOperationException(); } - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } - public void removeItems(Collection items) { + public void removeAll(Collection items) { throw new UnsupportedOperationException(); } @@ -135,7 +133,7 @@ public class PropertyCollectionValueModelAdapter */ @Override public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUE && this.hasNoListeners()) { + if (collectionName == VALUES && this.hasNoListeners()) { this.engageModel(); } super.addCollectionChangeListener(collectionName, listener); @@ -158,7 +156,7 @@ public class PropertyCollectionValueModelAdapter @Override public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUE && this.hasNoListeners()) { + if (collectionName == VALUES && this.hasNoListeners()) { this.disengageModel(); } } @@ -167,7 +165,7 @@ public class PropertyCollectionValueModelAdapter // ********** queries ********** protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUE); + return this.hasAnyCollectionChangeListeners(VALUES); } protected boolean hasNoListeners() { @@ -178,14 +176,14 @@ public class PropertyCollectionValueModelAdapter // ********** behavior ********** protected void engageModel() { - this.valueHolder.addPropertyChangeListener(VALUE, this.propertyChangeListener); + this.valueHolder.addPropertyChangeListener(ValueModel.VALUE, this.propertyChangeListener); // synch our value *after* we start listening to the value holder, // since its value might change when a listener is added this.value = this.valueHolder.value(); } protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(VALUE, this.propertyChangeListener); + this.valueHolder.removePropertyChangeListener(ValueModel.VALUE, this.propertyChangeListener); // clear out the value when we are not listening to the value holder this.value = null; } @@ -199,12 +197,12 @@ public class PropertyCollectionValueModelAdapter if (this.value != null) { Object oldValue = this.value; this.value = null; - this.fireItemRemoved(VALUE, oldValue); + this.fireItemRemoved(VALUES, oldValue); } this.value = newValue; // put in "empty" check so we don't fire events unnecessarily if (this.value != null) { - this.fireItemAdded(VALUE, this.value); + this.fireItemAdded(VALUES, this.value); } } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ReadOnlyCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ReadOnlyCollectionValueModel.java index 4f1988ebde..8e1d02b2b0 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ReadOnlyCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ReadOnlyCollectionValueModel.java @@ -10,6 +10,7 @@ package org.eclipse.jpt.utility.internal.model.value; import java.util.Collection; +import java.util.Iterator; /** * Implementation of CollectionValueModel that can be used for @@ -43,10 +44,7 @@ public class ReadOnlyCollectionValueModel return this.value.size(); } - - // ********** ValueModel implementation ********** - - public Object value() { + public Iterator values() { return this.value.iterator(); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java index 723c01d905..bfd6441cc0 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java @@ -11,6 +11,7 @@ package org.eclipse.jpt.utility.internal.model.value; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import org.eclipse.jpt.utility.internal.HashBag; import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; @@ -48,34 +49,31 @@ public class SimpleCollectionValueModel @Override protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, VALUE); + return new SingleAspectChangeSupport(this, VALUES); } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** - public Object value() { + public Iterator values() { // try to prevent backdoor modification of the collection return new ReadOnlyIterator(this.value); } - - // ********** CollectionValueModel implementation ********** - - public void addItem(Object item) { - this.addItemToCollection(item, this.value, VALUE); + public void add(Object item) { + this.addItemToCollection(item, this.value, VALUES); } - public void addItems(Collection items) { - this.addItemsToCollection(items, this.value, VALUE); + public void addAll(Collection items) { + this.addItemsToCollection(items, this.value, VALUES); } - public void removeItem(Object item) { - this.removeItemFromCollection(item, this.value, VALUE); + public void remove(Object item) { + this.removeItemFromCollection(item, this.value, VALUES); } - public void removeItems(Collection items) { - this.removeItemsFromCollection(items, this.value, VALUE); + public void removeAll(Collection items) { + this.removeItemsFromCollection(items, this.value, VALUES); } public int size() { @@ -90,7 +88,7 @@ public class SimpleCollectionValueModel */ public void setValue(Collection value) { this.value = ((value == null) ? new HashBag() : value); - this.fireCollectionChanged(VALUE); + this.fireCollectionChanged(VALUES); } /** @@ -102,7 +100,7 @@ public class SimpleCollectionValueModel } Collection items = new ArrayList(this.value); this.value.clear(); - this.fireItemsRemoved(VALUE, items); + this.fireItemsRemoved(VALUES, items); } @Override diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java index 44b96fd8a0..f3fe043e42 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java @@ -14,6 +14,7 @@ import java.util.Iterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.model.Model; import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener; /** @@ -39,10 +40,10 @@ public abstract class TreeAspectAdapter /** * The name of the subject's tree that we use for the value. */ - protected String treeName; + protected final String treeName; /** A listener that listens to the subject's tree aspect. */ - protected TreeChangeListener treeChangeListener; + protected final TreeChangeListener treeChangeListener; // ********** constructors ********** @@ -52,8 +53,7 @@ public abstract class TreeAspectAdapter * and tree. */ protected TreeAspectAdapter(String treeName, Model subject) { - super(subject); - this.treeName = treeName; + this(new ReadOnlyPropertyValueModel(subject), treeName); } /** @@ -63,17 +63,12 @@ public abstract class TreeAspectAdapter protected TreeAspectAdapter(ValueModel subjectHolder, String treeName) { super(subjectHolder); this.treeName = treeName; + this.treeChangeListener = this.buildTreeChangeListener(); } // ********** initialization ********** - @Override - protected void initialize() { - super.initialize(); - this.treeChangeListener = this.buildTreeChangeListener(); - } - /** * The subject's tree aspect has changed, notify the listeners. */ @@ -143,6 +138,16 @@ public abstract class TreeAspectAdapter // ********** AspectAdapter implementation ********** + @Override + protected Class<? extends ChangeListener> listenerClass() { + return TreeChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUE; + } + @Override protected boolean hasListeners() { return this.hasAnyTreeChangeListeners(VALUE); diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueModel.java index fb85042e8c..0c2494773f 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueModel.java @@ -12,13 +12,13 @@ package org.eclipse.jpt.utility.internal.model.value; import org.eclipse.jpt.utility.internal.model.Model; /** - * Interface used to abstract attribute accessing and + * Interface used to abstract property accessing and * change notification and make it more pluggable. */ public interface ValueModel extends Model { /** - * Return the value. + * Return the property's value. */ Object value(); String VALUE = "value"; diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java index 1190eb371a..2d7b69308b 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java @@ -14,8 +14,11 @@ import java.util.prefs.PreferenceChangeListener; import java.util.prefs.Preferences; import org.eclipse.jpt.utility.internal.BidiStringConverter; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; +import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener; import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; import org.eclipse.jpt.utility.internal.model.value.PropertyValueModel; +import org.eclipse.jpt.utility.internal.model.value.ReadOnlyPropertyValueModel; import org.eclipse.jpt.utility.internal.model.value.ValueModel; /** @@ -45,7 +48,7 @@ public class PreferencePropertyValueModel implements PropertyValueModel { /** The key to the preference we use for the value. */ - protected String key; + protected final String key; /** * Cache the current (object) value of the preference so we @@ -57,7 +60,7 @@ public class PreferencePropertyValueModel * The default (object) value returned if there is no value * associated with the preference. */ - protected Object defaultValue; + protected final Object defaultValue; /** * This converter is used to convert the preference's @@ -66,7 +69,7 @@ public class PreferencePropertyValueModel protected BidiStringConverter converter; /** A listener that listens to the appropriate preference. */ - protected PreferenceChangeListener preferenceChangeListener; + protected final PreferenceChangeListener preferenceChangeListener; // ********** constructors ********** @@ -84,9 +87,7 @@ public class PreferencePropertyValueModel * the specified default value for the preference. */ public PreferencePropertyValueModel(Preferences preferences, String key, Object defaultValue) { - super(preferences); - this.key = key; - this.defaultValue = defaultValue; + this(new ReadOnlyPropertyValueModel(preferences), key, defaultValue); } /** @@ -121,20 +122,15 @@ public class PreferencePropertyValueModel super(preferencesHolder); this.key = key; this.defaultValue = defaultValue; + this.converter = BidiStringConverter.Default.instance(); + this.preferenceChangeListener = this.buildPreferenceChangeListener(); + // our value is null when we are not listening to the preference + this.value = null; } // ********** initialization ********** - @Override - protected void initialize() { - super.initialize(); - // our value is null when we are not listening to the preference - this.value = null; - this.converter = BidiStringConverter.Default.instance(); - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - } - /** * A preference has changed, notify the listeners if necessary. */ @@ -157,6 +153,7 @@ public class PreferencePropertyValueModel /** * Return the cached (converted) value. */ + @Override public synchronized Object value() { return this.value; } @@ -185,6 +182,16 @@ public class PreferencePropertyValueModel // ********** AspectAdapter implementation ********** @Override + protected Class<? extends ChangeListener> listenerClass() { + return PropertyChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUE; + } + + @Override protected boolean hasListeners() { return this.hasAnyPropertyChangeListeners(VALUE); } diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java index c67d351f34..52cdddaf62 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java @@ -20,8 +20,11 @@ import java.util.prefs.Preferences; import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; +import org.eclipse.jpt.utility.internal.model.listener.ChangeListener; +import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener; import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; import org.eclipse.jpt.utility.internal.model.value.CollectionValueModel; +import org.eclipse.jpt.utility.internal.model.value.ReadOnlyPropertyValueModel; import org.eclipse.jpt.utility.internal.model.value.ValueModel; /** @@ -35,10 +38,10 @@ public class PreferencesCollectionValueModel { /** Cache the current preferences, stored in models and keyed by name. */ - protected Map preferences; + protected final Map preferences; /** A listener that listens to the preferences node for added or removed preferences. */ - protected PreferenceChangeListener preferenceChangeListener; + protected final PreferenceChangeListener preferenceChangeListener; // ********** constructors ********** @@ -47,7 +50,7 @@ public class PreferencesCollectionValueModel * Construct an adapter for the specified preferences node. */ public PreferencesCollectionValueModel(Preferences preferences) { - super(preferences); + this(new ReadOnlyPropertyValueModel(preferences)); } /** @@ -55,18 +58,13 @@ public class PreferencesCollectionValueModel */ public PreferencesCollectionValueModel(ValueModel preferencesHolder) { super(preferencesHolder); + this.preferences = new HashMap(); + this.preferenceChangeListener = this.buildPreferenceChangeListener(); } // ********** initialization ********** - @Override - protected void initialize() { - super.initialize(); - this.preferences = new HashMap(); - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - } - /** * A preferences have changed, notify the listeners. */ @@ -84,35 +82,32 @@ public class PreferencesCollectionValueModel } - // ********** ValueModel implementation ********** + // ********** CollectionValueModel implementation ********** /** * Return an iterator on the preference models. */ - public synchronized Object value() { + public synchronized Iterator values() { return this.preferences.values().iterator(); } - - // ********** CollectionValueModel implementation ********** - - public void addItem(Object item) { + public void add(Object item) { throw new UnsupportedOperationException(); } - public void addItems(Collection items) { + public void addAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.addItem(stream.next()); + this.add(stream.next()); } } - public void removeItem(Object item) { + public void remove(Object item) { throw new UnsupportedOperationException(); } - public void removeItems(Collection items) { + public void removeAll(Collection items) { for (Iterator stream = items.iterator(); stream.hasNext(); ) { - this.removeItem(stream.next()); + this.remove(stream.next()); } } @@ -123,14 +118,29 @@ public class PreferencesCollectionValueModel // ********** AspectAdapter implementation ********** + @Override + protected Object value() { + return this.values(); + } + + @Override + protected Class<? extends ChangeListener> listenerClass() { + return CollectionChangeListener.class; + } + + @Override + protected String listenerAspectName() { + return VALUES; + } + @Override protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUE); + return this.hasAnyCollectionChangeListeners(VALUES); } @Override protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUE); + this.fireCollectionChanged(VALUES); } @Override @@ -198,12 +208,12 @@ public class PreferencesCollectionValueModel if (newValue == null) { // a preference was removed PreferencePropertyValueModel preferenceModel = (PreferencePropertyValueModel) this.preferences.remove(key); - this.fireItemRemoved(VALUE, preferenceModel); + this.fireItemRemoved(VALUES, preferenceModel); } else if ( ! this.preferences.containsKey(key)) { // a preference was added PreferencePropertyValueModel preferenceModel = this.buildPreferenceModel(key); this.preferences.put(key, preferenceModel); - this.fireItemAdded(VALUE, preferenceModel); + this.fireItemAdded(VALUES, preferenceModel); } else { // a preference's value changed - do nothing } |