diff options
Diffstat (limited to 'common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model')
100 files changed, 0 insertions, 21707 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AbstractModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AbstractModel.java deleted file mode 100644 index c8d1dc690b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AbstractModel.java +++ /dev/null @@ -1,1007 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model; - -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; - -/** - * Reasonable implementation of the {@link Model} protocol - * with numerous convenience methods. - * - * @see ChangeSupport - */ -public abstract class AbstractModel - implements Model -{ - /** - * Delegate state/property/collection/list/tree change support to this - * helper object. The change support object is <em>lazily-initialized</em>; - * so it may be <code>null</code>. The method {@link #getChangeSupport()} - * will initialize this field if it is <code>null</code>. - * <p> - * <strong>NB:</strong> We instantiate this when we fire events, even when - * we do not have any listeners (which is be implied if this is <code>null</code>). - * This allows the change support to have behavior tied to events even when - * we have no listeners. - * - * @see AspectChangeSupport#aspectChanged(String) - */ - protected ChangeSupport changeSupport; - - - // ********** constructors/initialization ********** - - /** - * Default constructor. - */ - protected AbstractModel() { - super(); - } - - /** - * This accessor will build the change support when required. - * This only helps reduce the footprint of a model that neither has any - * listeners added to it nor ever changes (fires any events). - */ - protected synchronized ChangeSupport getChangeSupport() { - if (this.changeSupport == null) { - this.changeSupport = this.buildChangeSupport(); - } - return this.changeSupport; - } - - /** - * Allow subclasses to tweak the change support used. - */ - protected ChangeSupport buildChangeSupport() { - return new ChangeSupport(this); - } - - - // ********** change support ********** - - /** - * @see ChangeSupport#addChangeListener(ChangeListener) - */ - public void addChangeListener(ChangeListener listener) { - this.getChangeSupport().addChangeListener(listener); - } - - /** - * @see ChangeSupport#removeChangeListener(ChangeListener) - */ - public void removeChangeListener(ChangeListener listener) { - this.getChangeSupport().removeChangeListener(listener); - } - - /** - * @see ChangeSupport#hasAnyChangeListeners() - */ - public boolean hasAnyChangeListeners() { - return (this.changeSupport != null) && this.changeSupport.hasAnyChangeListeners(); - } - - /** - * Return whether the model has no change listeners. - */ - public boolean hasNoChangeListeners() { - return ! this.hasAnyChangeListeners(); - } - - - // ********** state change support ********** - - /** - * @see ChangeSupport#addStateChangeListener(StateChangeListener) - */ - public void addStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().addStateChangeListener(listener); - } - - /** - * @see ChangeSupport#removeStateChangeListener(StateChangeListener) - */ - public void removeStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().removeStateChangeListener(listener); - } - - /** - * @see ChangeSupport#hasAnyStateChangeListeners() - */ - public boolean hasAnyStateChangeListeners() { - return (this.changeSupport != null) && this.changeSupport.hasAnyStateChangeListeners(); - } - - /** - * Return whether the model has no state change listeners. - */ - public boolean hasNoStateChangeListeners() { - return ! this.hasAnyStateChangeListeners(); - } - - /** - * @see ChangeSupport#fireStateChanged(StateChangeEvent) - */ - protected final void fireStateChanged(StateChangeEvent event) { - this.getChangeSupport().fireStateChanged(event); - } - - /** - * @see ChangeSupport#fireStateChanged() - */ - protected final void fireStateChanged() { - this.getChangeSupport().fireStateChanged(); - } - - - // ********** property change support ********** - - /** - * @see ChangeSupport#addPropertyChangeListener(String, PropertyChangeListener) - */ - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().addPropertyChangeListener(propertyName, listener); - } - - /** - * @see ChangeSupport#removePropertyChangeListener(String, PropertyChangeListener) - */ - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().removePropertyChangeListener(propertyName, listener); - } - - /** - * @see ChangeSupport#hasAnyPropertyChangeListeners(String) - */ - public boolean hasAnyPropertyChangeListeners(String propertyName) { - return (this.changeSupport != null) && this.changeSupport.hasAnyPropertyChangeListeners(propertyName); - } - - /** - * Return whether the model has no property change listeners that will - * be notified when the specified property has changed. - */ - public boolean hasNoPropertyChangeListeners(String propertyName) { - return ! this.hasAnyPropertyChangeListeners(propertyName); - } - - /** - * @see ChangeSupport#firePropertyChanged(PropertyChangeEvent) - */ - protected final boolean firePropertyChanged(PropertyChangeEvent event) { - return this.getChangeSupport().firePropertyChanged(event); - } - - /** - * @see ChangeSupport#firePropertyChanged(String, Object, Object) - */ - protected final boolean firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - return this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - /** - * @see ChangeSupport#firePropertyChanged(String, int, int) - */ - protected final boolean firePropertyChanged(String propertyName, int oldValue, int newValue) { - return this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - /** - * @see ChangeSupport#firePropertyChanged(String, boolean, boolean) - */ - protected final boolean firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - return this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - /** - * Implied <code>null</code> "old" value. - * @see #firePropertyChanged(String, Object, Object) - */ - protected final boolean firePropertyChanged(String propertyName, Object newValue) { - return this.firePropertyChanged(propertyName, null, newValue); - } - - - // ********** collection change support ********** - - /** - * @see ChangeSupport#addCollectionChangeListener(String, CollectionChangeListener) - */ - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().addCollectionChangeListener(collectionName, listener); - } - - /** - * @see ChangeSupport#removeCollectionChangeListener(String, CollectionChangeListener) - */ - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().removeCollectionChangeListener(collectionName, listener); - } - - /** - * @see ChangeSupport#hasAnyCollectionChangeListeners(String) - */ - public boolean hasAnyCollectionChangeListeners(String collectionName) { - return (this.changeSupport != null) && this.changeSupport.hasAnyCollectionChangeListeners(collectionName); - } - - /** - * Return whether the model has no collection change listeners that will - * be notified when the specified collection has changed. - */ - public boolean hasNoCollectionChangeListeners(String collectionName) { - return ! this.hasAnyCollectionChangeListeners(collectionName); - } - - /** - * @see ChangeSupport#fireItemsAdded(CollectionAddEvent) - */ - protected final boolean fireItemsAdded(CollectionAddEvent event) { - return this.getChangeSupport().fireItemsAdded(event); - } - - /** - * @see ChangeSupport#fireItemsAdded(String, Collection) - */ - protected final boolean fireItemsAdded(String collectionName, Collection<?> addedItems) { - return this.getChangeSupport().fireItemsAdded(collectionName, addedItems); - } - - /** - * @see ChangeSupport#fireItemAdded(String, Object) - */ - protected final void fireItemAdded(String collectionName, Object addedItem) { - this.getChangeSupport().fireItemAdded(collectionName, addedItem); - } - - /** - * @see ChangeSupport#fireItemsRemoved(CollectionRemoveEvent) - */ - protected final boolean fireItemsRemoved(CollectionRemoveEvent event) { - return this.getChangeSupport().fireItemsRemoved(event); - } - - /** - * @see ChangeSupport#fireItemsRemoved(String, Collection) - */ - protected final boolean fireItemsRemoved(String collectionName, Collection<?> removedItems) { - return this.getChangeSupport().fireItemsRemoved(collectionName, removedItems); - } - - /** - * @see ChangeSupport#fireItemRemoved(String, Object) - */ - protected final void fireItemRemoved(String collectionName, Object removedItem) { - this.getChangeSupport().fireItemRemoved(collectionName, removedItem); - } - - /** - * @see ChangeSupport#fireCollectionCleared(CollectionClearEvent) - */ - protected final void fireCollectionCleared(CollectionClearEvent event) { - this.getChangeSupport().fireCollectionCleared(event); - } - - /** - * @see ChangeSupport#fireCollectionCleared(String) - */ - protected final void fireCollectionCleared(String collectionName) { - this.getChangeSupport().fireCollectionCleared(collectionName); - } - - protected final void fireCollectionChanged(CollectionChangeEvent event) { - this.getChangeSupport().fireCollectionChanged(event); - } - - protected final void fireCollectionChanged(String collectionName, Collection<?> collection) { - this.getChangeSupport().fireCollectionChanged(collectionName, collection); - } - - /** - * @see ChangeSupport#addItemToCollection(Object, Collection, String) - */ - protected <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) { - return this.getChangeSupport().addItemToCollection(item, collection, collectionName); - } - - /** - * @see ChangeSupport#addItemsToCollection(Object[], Collection, String) - */ - protected <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) { - return this.getChangeSupport().addItemsToCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#addItemsToCollection(Collection, Collection, String) - */ - protected <E> boolean addItemsToCollection(Collection<? extends E> items, Collection<E> collection, String collectionName) { - return this.getChangeSupport().addItemsToCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#addItemsToCollection(Iterable, Collection, String) - */ - protected <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) { - return this.getChangeSupport().addItemsToCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#addItemsToCollection(Iterator, Collection, String) - */ - protected <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) { - return this.getChangeSupport().addItemsToCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#removeItemFromCollection(Object, Collection, String) - */ - protected boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) { - return this.getChangeSupport().removeItemFromCollection(item, collection, collectionName); - } - - /** - * @see ChangeSupport#removeItemsFromCollection(Object[], Collection, String) - */ - protected boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().removeItemsFromCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#removeItemsFromCollection(Collection, Collection, String) - */ - protected boolean removeItemsFromCollection(Collection<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().removeItemsFromCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#removeItemsFromCollection(Iterable, Collection, String) - */ - protected boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().removeItemsFromCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#removeItemsFromCollection(Iterator, Collection, String) - */ - protected boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().removeItemsFromCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#retainItemsInCollection(Object[], Collection, String) - */ - protected boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().retainItemsInCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#retainItemsInCollection(Collection, Collection, String) - */ - protected boolean retainItemsInCollection(Collection<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().retainItemsInCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#retainItemsInCollection(Iterable, Collection, String) - */ - protected boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().retainItemsInCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#retainItemsInCollection(Iterator, Collection, String) - */ - protected boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - return this.getChangeSupport().retainItemsInCollection(items, collection, collectionName); - } - - /** - * @see ChangeSupport#clearCollection(Collection, String) - */ - protected boolean clearCollection(Collection<?> collection, String collectionName) { - return this.getChangeSupport().clearCollection(collection, collectionName); - } - - /** - * @see ChangeSupport#synchronizeCollection(Collection, Collection, String) - */ - protected <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) { - return this.getChangeSupport().synchronizeCollection(newCollection, collection, collectionName); - } - - /** - * @see ChangeSupport#synchronizeCollection(Iterable, Collection, String) - */ - protected <E> boolean synchronizeCollection(Iterable<E> newCollection, Collection<E> collection, String collectionName) { - return this.getChangeSupport().synchronizeCollection(newCollection, collection, collectionName); - } - - /** - * @see ChangeSupport#synchronizeCollection(Iterator, Collection, String) - */ - protected <E> boolean synchronizeCollection(Iterator<E> newCollection, Collection<E> collection, String collectionName) { - return this.getChangeSupport().synchronizeCollection(newCollection, collection, collectionName); - } - - - // ********** list change support ********** - - /** - * @see ChangeSupport#addListChangeListener(String, ListChangeListener) - */ - public void addListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().addListChangeListener(listName, listener); - } - - /** - * @see ChangeSupport#removeListChangeListener(String, ListChangeListener) - */ - public void removeListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().removeListChangeListener(listName, listener); - } - - /** - * @see ChangeSupport#hasAnyListChangeListeners(String) - */ - public boolean hasAnyListChangeListeners(String listName) { - return (this.changeSupport != null) && this.changeSupport.hasAnyListChangeListeners(listName); - } - - /** - * Return whether the model has no list change listeners that will - * be notified when the specified list has changed. - */ - public boolean hasNoListChangeListeners(String listName) { - return ! this.hasAnyListChangeListeners(listName); - } - - /** - * @see ChangeSupport#fireItemsAdded(ListAddEvent) - */ - protected final boolean fireItemsAdded(ListAddEvent event) { - return this.getChangeSupport().fireItemsAdded(event); - } - - /** - * @see ChangeSupport#fireItemsAdded(String, int, List) - */ - protected final boolean fireItemsAdded(String listName, int index, List<?> addedItems) { - return this.getChangeSupport().fireItemsAdded(listName, index, addedItems); - } - - /** - * @see ChangeSupport#fireItemAdded(String, int, Object) - */ - protected final void fireItemAdded(String listName, int index, Object addedItem) { - this.getChangeSupport().fireItemAdded(listName, index, addedItem); - } - - /** - * @see ChangeSupport#fireItemsRemoved(ListRemoveEvent) - */ - protected final boolean fireItemsRemoved(ListRemoveEvent event) { - return this.getChangeSupport().fireItemsRemoved(event); - } - - /** - * @see ChangeSupport#fireItemsRemoved(String, int, List) - */ - protected final boolean fireItemsRemoved(String listName, int index, List<?> removedItems) { - return this.getChangeSupport().fireItemsRemoved(listName, index, removedItems); - } - - /** - * @see ChangeSupport#fireItemRemoved(String, int, Object) - */ - protected final void fireItemRemoved(String listName, int index, Object removedItem) { - this.getChangeSupport().fireItemRemoved(listName, index, removedItem); - } - - /** - * @see ChangeSupport#fireItemsReplaced(ListReplaceEvent) - */ - protected final boolean fireItemsReplaced(ListReplaceEvent event) { - return this.getChangeSupport().fireItemsReplaced(event); - } - - /** - * @see ChangeSupport#fireItemsReplaced(String, int, List, List) - */ - protected final <E> boolean fireItemsReplaced(String listName, int index, List<? extends E> newItems, List<E> replacedItems) { - return this.getChangeSupport().fireItemsReplaced(listName, index, newItems, replacedItems); - } - - /** - * @see ChangeSupport#fireItemReplaced(String, int, Object, Object) - */ - protected final boolean fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - return this.getChangeSupport().fireItemReplaced(listName, index, newItem, replacedItem); - } - - /** - * @see ChangeSupport#fireItemsMoved(ListMoveEvent) - */ - protected final boolean fireItemsMoved(ListMoveEvent event) { - return this.getChangeSupport().fireItemsMoved(event); - } - - /** - * @see ChangeSupport#fireItemsMoved(String, int, int, int) - */ - protected final <E> boolean fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - return this.getChangeSupport().fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - /** - * @see ChangeSupport#fireItemMoved(String, int, int) - */ - protected final boolean fireItemMoved(String listName, int targetIndex, int sourceIndex) { - return this.getChangeSupport().fireItemMoved(listName, targetIndex, sourceIndex); - } - - /** - * @see ChangeSupport#fireListCleared(ListClearEvent) - */ - protected final void fireListCleared(ListClearEvent event) { - this.getChangeSupport().fireListCleared(event); - } - - /** - * @see ChangeSupport#fireListCleared(String) - */ - protected final void fireListCleared(String listName) { - this.getChangeSupport().fireListCleared(listName); - } - - protected final void fireListChanged(ListChangeEvent event) { - this.getChangeSupport().fireListChanged(event); - } - - protected final void fireListChanged(String listName, List<?> list) { - this.getChangeSupport().fireListChanged(listName, list); - } - - /** - * @see ChangeSupport#addItemToList(int, Object, List, String) - */ - protected <E> void addItemToList(int index, E item, List<E> list, String listName) { - this.getChangeSupport().addItemToList(index, item, list, listName); - } - - /** - * @see ChangeSupport#addItemToList(Object, List, String) - */ - protected <E> boolean addItemToList(E item, List<E> list, String listName) { - return this.getChangeSupport().addItemToList(item, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(int, Object[], List, String) - */ - protected <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(index, items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(int, Collection, List, String) - */ - protected <E> boolean addItemsToList(int index, Collection<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(index, items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(int, Iterable, List, String) - */ - protected <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(index, items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(int, Iterator, List, String) - */ - protected <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(index, items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(Object[], List, String) - */ - protected <E> boolean addItemsToList(E[] items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(Collection, List, String) - */ - protected <E> boolean addItemsToList(Collection<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(Iterable, List, String) - */ - protected <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(items, list, listName); - } - - /** - * @see ChangeSupport#addItemsToList(Iterator, List, String) - */ - protected <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().addItemsToList(items, list, listName); - } - - /** - * @see ChangeSupport#removeItemFromList(int, List, String) - */ - protected <E> E removeItemFromList(int index, List<E> list, String listName) { - return this.getChangeSupport().removeItemFromList(index, list, listName); - } - - /** - * @see ChangeSupport#removeItemFromList(Object, List, String) - */ - protected boolean removeItemFromList(Object item, List<?> list, String listName) { - return this.getChangeSupport().removeItemFromList(item, list, listName); - } - - /** - * @see ChangeSupport#removeRangeFromList(int, int, List, String) - */ - protected <E> List<E> removeRangeFromList(int beginIndex, int endIndex, List<E> list, String listName) { - return this.getChangeSupport().removeRangeFromList(beginIndex, endIndex, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(int, List, String) - */ - protected <E> List<E> removeItemsFromList(int index, List<E> list, String listName) { - return this.getChangeSupport().removeItemsFromList(index, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(int, int, List, String) - */ - protected <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) { - return this.getChangeSupport().removeItemsFromList(index, length, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(Object[], List, String) - */ - protected boolean removeItemsFromList(Object[] items, List<?> list, String listName) { - return this.getChangeSupport().removeItemsFromList(items, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(Collection, List, String) - */ - protected boolean removeItemsFromList(Collection<?> items, List<?> list, String listName) { - return this.getChangeSupport().removeItemsFromList(items, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(Iterable, List, String) - */ - protected boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) { - return this.getChangeSupport().removeItemsFromList(items, list, listName); - } - - /** - * @see ChangeSupport#removeItemsFromList(Iterator, List, String) - */ - protected boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) { - return this.getChangeSupport().removeItemsFromList(items, list, listName); - } - - /** - * @see ChangeSupport#retainItemsInList(Object[], List, String) - */ - protected boolean retainItemsInList(Object[] items, List<?> list, String listName) { - return this.getChangeSupport().retainItemsInList(items, list, listName); - } - - /** - * @see ChangeSupport#retainItemsInList(Collection, List, String) - */ - protected boolean retainItemsInList(Collection<?> items, List<?> list, String listName) { - return this.getChangeSupport().retainItemsInList(items, list, listName); - } - - /** - * @see ChangeSupport#retainItemsInList(Iterable, List, String) - */ - protected boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) { - return this.getChangeSupport().retainItemsInList(items, list, listName); - } - - /** - * @see ChangeSupport#retainItemsInList(Iterator, List, String) - */ - protected boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) { - return this.getChangeSupport().retainItemsInList(items, list, listName); - } - - /** - * @see ChangeSupport#setItemInList(int, Object, List, String) - */ - protected <E> E setItemInList(int index, E item, List<E> list, String listName) { - return this.getChangeSupport().setItemInList(index, item, list, listName); - } - - /** - * @see ChangeSupport#replaceItemInList(Object, Object, List, String) - */ - protected <E> int replaceItemInList(E oldItem, E newItem, List<E> list, String listName) { - return this.getChangeSupport().replaceItemInList(oldItem, newItem, list, listName); - } - - /** - * @see ChangeSupport#setItemsInList(int, Object[], List, String) - */ - protected <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) { - return this.getChangeSupport().setItemsInList(index, items, list, listName); - } - - /** - * @see ChangeSupport#setItemsInList(int, List, List, String) - */ - protected <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) { - return this.getChangeSupport().setItemsInList(index, items, list, listName); - } - - /** - * @see ChangeSupport#moveItemsInList(int, int, int, List, String) - */ - protected <E> void moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) { - this.getChangeSupport().moveItemsInList(targetIndex, sourceIndex, length, list, listName); - } - - /** - * @see ChangeSupport#moveItemInList(int, int, List, String) - */ - protected <E> void moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) { - this.getChangeSupport().moveItemInList(targetIndex, sourceIndex, list, listName); - } - - /** - * @see ChangeSupport#moveItemInList(int, Object, List, String) - */ - protected <E> void moveItemInList(int targetIndex, E item, List<E> list, String listName) { - this.getChangeSupport().moveItemInList(targetIndex, item, list, listName); - } - - /** - * @see ChangeSupport#clearList(List, String) - */ - protected boolean clearList(List<?> list, String listName) { - return this.getChangeSupport().clearList(list, listName); - } - - /** - * @see ChangeSupport#synchronizeList(List, List, String) - */ - protected <E> boolean synchronizeList(List<? extends E> newList, List<E> list, String listName) { - return this.getChangeSupport().synchronizeList(newList, list, listName); - } - - /** - * @see ChangeSupport#synchronizeList(Iterable, List, String) - */ - protected <E> boolean synchronizeList(Iterable<? extends E> newList, List<E> list, String listName) { - return this.getChangeSupport().synchronizeList(newList, list, listName); - } - - /** - * @see ChangeSupport#synchronizeList(Iterator, List, String) - */ - protected <E> boolean synchronizeList(Iterator<? extends E> newList, List<E> list, String listName) { - return this.getChangeSupport().synchronizeList(newList, list, listName); - } - - - // ********** tree change support ********** - - /** - * @see ChangeSupport#addTreeChangeListener(String, TreeChangeListener) - */ - public void addTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().addTreeChangeListener(treeName, listener); - } - - /** - * @see ChangeSupport#removeTreeChangeListener(String, TreeChangeListener) - */ - public void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().removeTreeChangeListener(treeName, listener); - } - - /** - * @see ChangeSupport#hasAnyTreeChangeListeners(String) - */ - public boolean hasAnyTreeChangeListeners(String treeName) { - return (this.changeSupport != null) && this.changeSupport.hasAnyTreeChangeListeners(treeName); - } - - /** - * Return whether the model has no tree change listeners that will - * be notified when the specified tree has changed. - */ - public boolean hasNoTreeChangeListeners(String treeName) { - return ! this.hasAnyTreeChangeListeners(treeName); - } - - /** - * @see ChangeSupport#fireNodeAdded(TreeAddEvent) - */ - protected final void fireNodeAdded(TreeAddEvent event) { - this.getChangeSupport().fireNodeAdded(event); - } - - /** - * @see ChangeSupport#fireNodeAdded(String, List) - */ - protected final void fireNodeAdded(String treeName, List<?> path) { - this.getChangeSupport().fireNodeAdded(treeName, path); - } - - /** - * @see ChangeSupport#fireNodeRemoved(TreeRemoveEvent) - */ - protected final void fireNodeRemoved(TreeRemoveEvent event) { - this.getChangeSupport().fireNodeRemoved(event); - } - - /** - * @see ChangeSupport#fireNodeRemoved(String, List) - */ - protected final void fireNodeRemoved(String treeName, List<?> path) { - this.getChangeSupport().fireNodeRemoved(treeName, path); - } - - /** - * @see ChangeSupport#fireTreeCleared(TreeClearEvent) - */ - protected final void fireTreeCleared(TreeClearEvent event) { - this.getChangeSupport().fireTreeCleared(event); - } - - /** - * @see ChangeSupport#fireTreeCleared(String) - */ - protected final void fireTreeCleared(String treeName) { - this.getChangeSupport().fireTreeCleared(treeName); - } - - /** - * @see ChangeSupport#fireTreeChanged(TreeChangeEvent) - */ - protected final void fireTreeChanged(TreeChangeEvent event) { - this.getChangeSupport().fireTreeChanged(event); - } - - /** - * @see ChangeSupport#fireTreeChanged(String, Collection) - */ - protected final void fireTreeChanged(String treeName, Collection<?> nodes) { - this.getChangeSupport().fireTreeChanged(treeName, nodes); - } - - - // ********** convenience methods ********** - - /** - * Return whether the specified values are equal, with the appropriate <code>null</code> checks. - * Convenience method for checking whether an attribute value has changed. - * <p> - * <em>Do not</em> use this to determine whether to fire a change notification, - * {@link ChangeSupport} already does that. - */ - protected final boolean valuesAreEqual(Object value1, Object value2) { - return this.getChangeSupport().valuesAreEqual(value1, value2); - } - - /** - * @see #valuesAreEqual(Object, Object) - */ - protected final boolean attributeValueHasNotChanged(Object oldValue, Object newValue) { - return this.valuesAreEqual(oldValue, newValue); - } - - - /** - * <em>Do not</em> use this to determine whether to fire a change notification, - * {@link ChangeSupport} already does that. - * <p> - * For example, after firing the change notification, you can use this method - * to decide if some other, related, piece of state needs to be synchronized - * with the state that just changed. - * - * @see ChangeSupport#valuesAreDifferent(Object, Object) - */ - protected final boolean valuesAreDifferent(Object value1, Object value2) { - return this.getChangeSupport().valuesAreDifferent(value1, value2); - } - - /** - * @see #valuesAreDifferent(Object, Object) - */ - protected final boolean attributeValueHasChanged(Object oldValue, Object newValue) { - return this.valuesAreDifferent(oldValue, newValue); - } - - - // ********** Object overrides ********** - - /** - * Although cloning models is usually not a Good Idea, - * we should at least support it properly. - */ - @Override - protected AbstractModel clone() throws CloneNotSupportedException { - AbstractModel clone = (AbstractModel) super.clone(); - // clear out change support - models do not share listeners - clone.changeSupport = null; - return clone; - } - - /** - * e.g. <code>"ClassName[00-F3-EE-42](add'l info)"</code> - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - StringTools.appendSimpleToString(sb, this); - sb.append('('); - int len = sb.length(); - this.toString(sb); - if (sb.length() == len) { - sb.deleteCharAt(len - 1); - } else { - sb.append(')'); - } - return sb.toString(); - } - - /** - * This method is public so one model can call a nested abstract model's - * <code>#toString(StringBuilder)</code>. - */ - public void toString(@SuppressWarnings("unused") StringBuilder sb) { - // subclasses should override this to do something a bit more helpful - } -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AspectChangeSupport.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AspectChangeSupport.java deleted file mode 100644 index d98f4438fd..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/AspectChangeSupport.java +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model; - -import java.util.Collection; -import java.util.EventListener; -import java.util.List; -import org.eclipse.jpt.common.utility.internal.ListenerList; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; - -/** - * This change support class will notify listeners whenever one of the source's - * aspects has changed. Only the aspect name is passed to the listener; no - * event is generated. This allows the listeners to delegate to the change - * support object verification that an aspect as actually changed. This is - * useful for simple things like setting dirty flags, blanket validation, and - * blanket sychronization; i.e. things that might be interested in the <em>name</em> - * of the aspect that changed but not so much <em>how</em> the aspect changed. - */ -public class AspectChangeSupport - extends ChangeSupport -{ - private static final long serialVersionUID = 1L; - protected static final Class<Listener> LISTENER_CLASS = Listener.class; - - - public AspectChangeSupport(Model source, Listener listener) { - this(source); - this.addListener(listener); - } - - public AspectChangeSupport(Model source) { - super(source); - } - - protected void aspectChanged(String aspectName) { - Iterable<Listener> listeners = this.getListeners(); - if (listeners != null) { - for (Listener listener : listeners) { - listener.aspectChanged(aspectName); - } - } - } - - public void addListener(Listener listener) { - this.addListener(LISTENER_CLASS, listener); - } - - public void removeListener(Listener listener) { - this.removeListener(LISTENER_CLASS, listener); - } - - private Iterable<Listener> getListeners() { - ListenerList<Listener> listenerList = this.getListenerList(); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private ListenerList<Listener> getListenerList() { - return this.getListenerList(LISTENER_CLASS); - } - - - // ********** listener interface ********** - - /** - * Listener that will be notified of any aspect changes. - */ - public interface Listener extends EventListener { - - /** - * The specified aspect changed. - */ - void aspectChanged(String aspectName); - - } - - - // ********** state change support ********** - - @Override - public void fireStateChanged(StateChangeEvent event) { - super.fireStateChanged(event); - this.aspectChanged(null); - } - - @Override - public void fireStateChanged() { - super.fireStateChanged(); - this.aspectChanged(null); - } - - - // ********** property change support ********** - - @Override - protected void firePropertyChanged_(PropertyChangeEvent event) { - super.firePropertyChanged_(event); - this.aspectChanged(event.getPropertyName()); - } - - @Override - protected void firePropertyChanged_(String propertyName, Object oldValue, Object newValue) { - super.firePropertyChanged_(propertyName, oldValue, newValue); - this.aspectChanged(propertyName); - } - - @Override - protected void firePropertyChanged_(String propertyName, int oldValue, int newValue) { - super.firePropertyChanged_(propertyName, oldValue, newValue); - this.aspectChanged(propertyName); - } - - @Override - protected void firePropertyChanged_(String propertyName, boolean oldValue, boolean newValue) { - super.firePropertyChanged_(propertyName, oldValue, newValue); - this.aspectChanged(propertyName); - } - - - // ********** collection change support ********** - - @Override - protected void fireItemsAdded_(CollectionAddEvent event) { - super.fireItemsAdded_(event); - this.aspectChanged(event.getCollectionName()); - } - - @Override - protected void fireItemsAdded_(String collectionName, Collection<?> addedItems) { - super.fireItemsAdded_(collectionName, addedItems); - this.aspectChanged(collectionName); - } - - @Override - public void fireItemAdded(String collectionName, Object addedItem) { - super.fireItemAdded(collectionName, addedItem); - this.aspectChanged(collectionName); - } - - @Override - protected void fireItemsRemoved_(CollectionRemoveEvent event) { - super.fireItemsRemoved_(event); - this.aspectChanged(event.getCollectionName()); - } - - @Override - protected void fireItemsRemoved_(String collectionName, Collection<?> removedItems) { - super.fireItemsRemoved_(collectionName, removedItems); - this.aspectChanged(collectionName); - } - - @Override - public void fireItemRemoved(String collectionName, Object removedItem) { - super.fireItemRemoved(collectionName, removedItem); - this.aspectChanged(collectionName); - } - - @Override - public void fireCollectionCleared(CollectionClearEvent event) { - super.fireCollectionCleared(event); - this.aspectChanged(event.getCollectionName()); - } - - @Override - public void fireCollectionCleared(String collectionName) { - super.fireCollectionCleared(collectionName); - this.aspectChanged(collectionName); - } - - @Override - public void fireCollectionChanged(CollectionChangeEvent event) { - super.fireCollectionChanged(event); - this.aspectChanged(event.getCollectionName()); - } - - @Override - public void fireCollectionChanged(String collectionName, Collection<?> collection) { - super.fireCollectionChanged(collectionName, collection); - this.aspectChanged(collectionName); - } - - - // ********** list change support ********** - - @Override - protected void fireItemsAdded_(ListAddEvent event) { - super.fireItemsAdded_(event); - this.aspectChanged(event.getListName()); - } - - @Override - protected void fireItemsAdded_(String listName, int index, List<?> addedItems) { - super.fireItemsAdded_(listName, index, addedItems); - this.aspectChanged(listName); - } - - @Override - public void fireItemAdded(String listName, int index, Object addedItem) { - super.fireItemAdded(listName, index, addedItem); - this.aspectChanged(listName); - } - - @Override - protected void fireItemsRemoved_(ListRemoveEvent event) { - super.fireItemsRemoved_(event); - this.aspectChanged(event.getListName()); - } - - @Override - protected void fireItemsRemoved_(String listName, int index, List<?> removedItems) { - super.fireItemsRemoved_(listName, index, removedItems); - this.aspectChanged(listName); - } - - @Override - public void fireItemRemoved(String listName, int index, Object removedItem) { - super.fireItemRemoved(listName, index, removedItem); - this.aspectChanged(listName); - } - - @Override - protected void fireItemsReplaced_(ListReplaceEvent event) { - super.fireItemsReplaced_(event); - this.aspectChanged(event.getListName()); - } - - @Override - protected void fireItemsReplaced_(String listName, int index, List<?> newItems, List<?> replacedItems) { - super.fireItemsReplaced_(listName, index, newItems, replacedItems); - this.aspectChanged(listName); - } - - @Override - protected void fireItemReplaced_(String listName, int index, Object newItem, Object replacedItem) { - super.fireItemReplaced_(listName, index, newItem, replacedItem); - this.aspectChanged(listName); - } - - @Override - protected void fireItemsMoved_(ListMoveEvent event) { - super.fireItemsMoved_(event); - this.aspectChanged(event.getListName()); - } - - @Override - protected void fireItemsMoved_(String listName, int targetIndex, int sourceIndex, int length) { - super.fireItemsMoved_(listName, targetIndex, sourceIndex, length); - this.aspectChanged(listName); - } - - @Override - public void fireListCleared(ListClearEvent event) { - super.fireListCleared(event); - this.aspectChanged(event.getListName()); - } - - @Override - public void fireListCleared(String listName) { - super.fireListCleared(listName); - this.aspectChanged(listName); - } - - @Override - public void fireListChanged(ListChangeEvent event) { - super.fireListChanged(event); - this.aspectChanged(event.getListName()); - } - - @Override - public void fireListChanged(String listName, List<?> list) { - super.fireListChanged(listName, list); - this.aspectChanged(listName); - } - - - // ********** tree change support ********** - - @Override - public void fireNodeAdded(TreeAddEvent event) { - super.fireNodeAdded(event); - this.aspectChanged(event.getTreeName()); - } - - @Override - public void fireNodeAdded(String treeName, List<?> path) { - super.fireNodeAdded(treeName, path); - this.aspectChanged(treeName); - } - - @Override - public void fireNodeRemoved(TreeRemoveEvent event) { - super.fireNodeRemoved(event); - this.aspectChanged(event.getTreeName()); - } - - @Override - public void fireNodeRemoved(String treeName, List<?> path) { - super.fireNodeRemoved(treeName, path); - this.aspectChanged(treeName); - } - - @Override - public void fireTreeCleared(TreeClearEvent event) { - super.fireTreeCleared(event); - this.aspectChanged(event.getTreeName()); - } - - @Override - public void fireTreeCleared(String treeName) { - super.fireTreeCleared(treeName); - this.aspectChanged(treeName); - } - - @Override - public void fireTreeChanged(TreeChangeEvent event) { - super.fireTreeChanged(event); - this.aspectChanged(event.getTreeName()); - } - - @Override - public void fireTreeChanged(String treeName, Collection<?> nodes) { - super.fireTreeChanged(treeName, nodes); - this.aspectChanged(treeName); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/ChangeSupport.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/ChangeSupport.java deleted file mode 100644 index af4b952a2b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/ChangeSupport.java +++ /dev/null @@ -1,2844 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EventListener; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jpt.common.utility.internal.ArrayTools; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.HashBag; -import org.eclipse.jpt.common.utility.internal.ListenerList; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.Tools; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; - -/** - * Support object that can be used by implementors of the {@link Model} interface. - * It provides for state, property, collection, list, and tree change notifications to - * listeners. - * <p> - * <strong>NB1:</strong> There is lots of copy-n-paste code in this class. Nearly all of this duplication - * is an effort to prevent the unnecessary creation of new objects (typically event - * objects). Since many events are fired when there are no listeners, we postpone - * the creation of event objects until we know we have interested listeners. - * Most methods have the "non-duplicated" version of the method body commented - * out at the top of the current method body. - * The hope was that this class would prove to be fairly static and the duplicated - * code would not prove onerous; but that has not proven to be - * the case, as we have added support for "state" changes, "dirty" notification, - * and custom "notifiers", with more to come, I'm sure.... ~bjv - * <p> - * <strong>NB2:</strong> This class will check to see if, during the firing of events, a listener - * on the original, cloned, list of listeners has been removed from the master - * list of listeners <em>before</em> it is notified. If the listener has been removed - * "concurrently" it will <em>not</em> be notified. - * <p> - * <strong>NB3:</strong> Any listener that is added during the firing of events will <em>not</em> be - * also notified. This is a bit inconsistent with NB2, but seems reasonable - * since any added listener should already be in synch with the model. - * <p> - * <strong>NB4:</strong> This class is serializable, but it will only write out listeners that - * are also serializable while silently leaving behind listeners that are not. - * - * @see Model - * @see AbstractModel - */ -public class ChangeSupport - implements Serializable -{ - /** The object to be provided as the "source" for any generated events. */ - protected final Model source; - - /** Associate aspect names to class-specific listener lists. */ - private AspectListenerListPair<?>[] aspectListenerListPairs = EMPTY_ASPECT_LISTENER_LIST_PAIR_ARRAY; - private static final AspectListenerListPair<?>[] EMPTY_ASPECT_LISTENER_LIST_PAIR_ARRAY = new AspectListenerListPair[0]; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - /** - * Construct support for the specified source of change events. - * The source cannot be <code>null</code>. - */ - public ChangeSupport(Model source) { - super(); - if (source == null) { - throw new NullPointerException(); - } - this.source = source; - } - - - // ********** internal implementation ********** - - /** - * Add a listener that listens to all the events of the specified type and - * carrying the specified aspect name. - * Neither the aspect name nor the listener can be <code>null</code>. - */ - protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, String aspectName, L listener) { - ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); - if (aspectListenerList == null) { - this.aspectListenerListPairs = ArrayTools.add(this.aspectListenerListPairs, new SimpleAspectListenerListPair<L>(listenerClass, aspectName, listener)); - } else { - aspectListenerList.add(listener); - } - } - - /** - * Add a listener that listens to all the events of the specified type. - * The listener cannot be <code>null</code>. - */ - protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, L listener) { - ListenerList<L> listenerList = this.getListenerList(listenerClass); - if (listenerList == null) { - this.aspectListenerListPairs = ArrayTools.add(this.aspectListenerListPairs, new NullAspectListenerListPair<L>(listenerClass, listener)); - } else { - listenerList.add(listener); - } - } - - /** - * Remove a listener that has been registered for all the - * events of the specified type and carrying the specified aspect name. - * Neither the aspect name nor the listener can be <code>null</code>. - */ - protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, String aspectName, L listener) { - ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); - if (aspectListenerList == null) { - throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$ - } - aspectListenerList.remove(listener); // leave the pair, even if the listener list is empty? - } - - /** - * Remove a listener that has been registered for all the events of the specified type. - * The listener cannot be <code>null</code>. - */ - protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, L listener) { - ListenerList<L> listenerList = this.getListenerList(listenerClass); - if (listenerList == null) { - throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$ - } - listenerList.remove(listener); // leave the pair, even if the listener list is empty? - } - - /** - * Return the listener list for the specified listener class and aspect name. - * Return <code>null</code> if the listener list is not present. - * The aspect name cannot be <code>null</code>. - */ - protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass, String aspectName) { - // put in a null check to simplify calling code - if (aspectName == null) { - throw new NullPointerException(); - } - return this.getListenerList_(listenerClass, aspectName); - } - - /** - * Return the listener list for the specified listener class. - * Return <code>null</code> if the listener list is not present. - */ - protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass) { - return this.getListenerList_(listenerClass, null); - } - - /** - * Return the listener list for the specified listener class and aspect name. - * Return <code>null</code> if the listener list is not present. - */ - protected synchronized <L extends EventListener> ListenerList<L> getListenerList_(Class<L> listenerClass, String aspectName) { - for (AspectListenerListPair<?> pair : this.aspectListenerListPairs) { - if (pair.matches(listenerClass, aspectName)) { - @SuppressWarnings("unchecked") ListenerList<L> aspectListenerList = (ListenerList<L>) pair.listenerList; - return aspectListenerList; - } - } - return null; - } - - /** - * Return whether there are any listeners for the specified listener class - * and aspect name. - */ - protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass, String aspectName) { - ListenerList<L> aspectListenerList = this.getListenerList(listenerClass, aspectName); - if ((aspectListenerList != null) && ! aspectListenerList.isEmpty()) { - return true; - } - return this.hasAnyChangeListeners(); // check for any general purpose listeners - } - - /** - * Return whether there are no listeners for the specified listener class - * and aspect name. - */ - protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass, String aspectName) { - return ! this.hasAnyListeners(listenerClass, aspectName); - } - - /** - * Return whether there are any listeners for the specified listener class. - */ - protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass) { - ListenerList<L> aspectListenerList = this.getListenerList(listenerClass); - if ((aspectListenerList != null) && ! aspectListenerList.isEmpty()) { - return true; - } - // check for any general purpose listeners (unless that's what we're already doing) - return (listenerClass == this.getChangeListenerClass()) ? false : this.hasAnyChangeListeners(); - } - - /** - * Return whether there are no listeners for the specified listener class. - */ - protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass) { - return ! this.hasAnyListeners(listenerClass); - } - - - // ********** general purpose change support ********** - - /** - * Subclasses that add other types of listeners should override this method - * to return the extension to ChangeListener that also extends whatever new - * listener types are supported. - */ - @SuppressWarnings("unchecked") - protected <L extends ChangeListener> Class<L> getChangeListenerClass() { - // not sure why I need to cast here... - return (Class<L>) CHANGE_LISTENER_CLASS; - } - - protected static final Class<ChangeListener> CHANGE_LISTENER_CLASS = ChangeListener.class; - - /** - * Add a general purpose listener that listens to all events, - * regardless of the aspect name associated with that event. - * The listener cannot be null. - */ - public void addChangeListener(ChangeListener listener) { - this.addListener(this.getChangeListenerClass(), listener); - } - - /** - * Remove a general purpose listener. - * The listener cannot be null. - */ - public void removeChangeListener(ChangeListener listener) { - this.removeListener(this.getChangeListenerClass(), listener); - } - - /** - * Return whether there are any general purpose listeners that will be - * notified of any changes. - */ - public boolean hasAnyChangeListeners() { - return this.hasAnyListeners(this.getChangeListenerClass()); - } - - private ListenerList<ChangeListener> getChangeListenerList() { - return this.getListenerList(CHANGE_LISTENER_CLASS); - } - - private Iterable<ChangeListener> getChangeListeners() { - ListenerList<ChangeListener> listenerList = this.getChangeListenerList(); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasChangeListener(ChangeListener listener) { - return CollectionTools.contains(this.getChangeListeners(), listener); - } - - - // ********** state change support ********** - - protected static final Class<StateChangeListener> STATE_CHANGE_LISTENER_CLASS = StateChangeListener.class; - - /** - * Add a state change listener. - */ - public void addStateChangeListener(StateChangeListener listener) { - this.addListener(STATE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a state change listener. - */ - public void removeStateChangeListener(StateChangeListener listener) { - this.removeListener(STATE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any state change listeners. - */ - public boolean hasAnyStateChangeListeners() { - return this.hasAnyListeners(STATE_CHANGE_LISTENER_CLASS); - } - - private ListenerList<StateChangeListener> getStateChangeListenerList() { - return this.getListenerList(STATE_CHANGE_LISTENER_CLASS); - } - - private Iterable<StateChangeListener> getStateChangeListeners() { - ListenerList<StateChangeListener> listenerList = this.getStateChangeListenerList(); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasStateChangeListener(StateChangeListener listener) { - return CollectionTools.contains(this.getStateChangeListeners(), listener); - } - - /** - * Fire the specified state change event to any registered listeners. - */ - public void fireStateChanged(StateChangeEvent event) { - Iterable<StateChangeListener> listeners = this.getStateChangeListeners(); - if (listeners != null) { - for (StateChangeListener listener : listeners) { - if (this.hasStateChangeListener(listener)) { // verify listener is still listening - listener.stateChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.stateChanged(event); - } - } - } - } - - /** - * Report a generic state change event to any registered state change - * listeners. - */ - public void fireStateChanged() { -// this.fireStateChanged(new StateChangeEvent(this.source)); - StateChangeEvent event = null; - Iterable<StateChangeListener> listeners = this.getStateChangeListeners(); - if (listeners != null) { - for (StateChangeListener listener : listeners) { - if (this.hasStateChangeListener(listener)) { // verify listener is still listening - if (event == null) { - event = new StateChangeEvent(this.source); - } - listener.stateChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new StateChangeEvent(this.source); - } - changeListener.stateChanged(event); - } - } - } - } - - - // ********** property change support ********** - - protected static final Class<PropertyChangeListener> PROPERTY_CHANGE_LISTENER_CLASS = PropertyChangeListener.class; - - /** - * Add a property change listener for the specified property. The listener - * will be notified only for changes to the specified property. - */ - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.addListener(PROPERTY_CHANGE_LISTENER_CLASS, propertyName, listener); - } - - /** - * Remove a property change listener that was registered for a specific property. - */ - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.removeListener(PROPERTY_CHANGE_LISTENER_CLASS, propertyName, listener); - } - - /** - * Return whether there are any property change listeners that will - * be notified when the specified property has changed. - */ - public boolean hasAnyPropertyChangeListeners(String propertyName) { - return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - } - - private ListenerList<PropertyChangeListener> getPropertyChangeListenerList(String propertyName) { - return this.getListenerList(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - } - - private Iterable<PropertyChangeListener> getPropertyChangeListeners(String propertyName) { - ListenerList<PropertyChangeListener> listenerList = this.getPropertyChangeListenerList(propertyName); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - return CollectionTools.contains(this.getPropertyChangeListeners(propertyName), listener); - } - - /** - * Fire the specified property change event to any registered listeners. - * No event is fired if the specified event's old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - * Return whether the old and new values are different. - */ - public boolean firePropertyChanged(PropertyChangeEvent event) { - if (this.valuesAreDifferent(event.getOldValue(), event.getNewValue())) { - this.firePropertyChanged_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event's old and new values are different - */ - protected void firePropertyChanged_(PropertyChangeEvent event) { - String propertyName = event.getPropertyName(); - Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); - if (listeners != null) { - for (PropertyChangeListener listener : listeners) { - if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening - listener.propertyChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.propertyChanged(event); - } - } - } - } - - /** - * Report a bound property update to any registered property change listeners. - * No event is fired if the specified old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - * Return whether the old and new values are different. - */ - public boolean firePropertyChanged(String propertyName, Object oldValue, Object newValue) { -// return this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); - if (this.valuesAreDifferent(oldValue, newValue)) { - this.firePropertyChanged_(propertyName, oldValue, newValue); - return true; - } - return false; - } - - /** - * pre-condition: the specified old and new values are different - */ - protected void firePropertyChanged_(String propertyName, Object oldValue, Object newValue) { - PropertyChangeEvent event = null; - Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); - if (listeners != null) { - for (PropertyChangeListener listener : listeners) { - if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); - } - listener.propertyChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); - } - changeListener.propertyChanged(event); - } - } - } - } - - /** - * Report an <code>int</code> bound property update to any registered listeners. - * No event is fired if the specified old and new values are equal. - * Return whether the old and new values are different. - * <p> - * This is merely a convenience wrapper around the more general method - * {@link #firePropertyChanged(String, Object, Object)}. - */ - public boolean firePropertyChanged(String propertyName, int oldValue, int newValue) { -// return this.firePropertyChanged(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); - if (oldValue != newValue) { - this.firePropertyChanged_(propertyName, oldValue, newValue); - return true; - } - return false; - } - - /** - * pre-condition: the specified old and new values are different - */ - protected void firePropertyChanged_(String propertyName, int oldValue, int newValue) { - PropertyChangeEvent event = null; - Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); - if (listeners != null) { - for (PropertyChangeListener listener : listeners) { - if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); - } - listener.propertyChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); - } - changeListener.propertyChanged(event); - } - } - } - } - - /** - * Report a <code>boolean</code> bound property update to any registered listeners. - * No event is fired if the specified old and new values are equal. - * Return whether the old and new values are different. - * <p> - * This is merely a convenience wrapper around the more general method - * {@link #firePropertyChanged(String, Object, Object)}. - */ - public boolean firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { -// return this.firePropertyChanged(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - if (oldValue != newValue) { - this.firePropertyChanged_(propertyName, oldValue, newValue); - return true; - } - return false; - } - - /** - * pre-condition: the specified old and new values are different - */ - protected void firePropertyChanged_(String propertyName, boolean oldValue, boolean newValue) { - PropertyChangeEvent event = null; - Iterable<PropertyChangeListener> listeners = this.getPropertyChangeListeners(propertyName); - if (listeners != null) { - for (PropertyChangeListener listener : listeners) { - if (this.hasPropertyChangeListener(propertyName, listener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - } - listener.propertyChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - } - changeListener.propertyChanged(event); - } - } - } - } - - - // ********** collection change support ********** - - protected static final Class<CollectionChangeListener> COLLECTION_CHANGE_LISTENER_CLASS = CollectionChangeListener.class; - - /** - * Add a collection change listener for the specified collection. The listener - * will be notified only for changes to the specified collection. - */ - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.addListener(COLLECTION_CHANGE_LISTENER_CLASS, collectionName, listener); - } - - /** - * Remove a collection change listener that was registered for a specific collection. - */ - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.removeListener(COLLECTION_CHANGE_LISTENER_CLASS, collectionName, listener); - } - - /** - * Return whether there are any collection change listeners that will - * be notified when the specified collection has changed. - */ - public boolean hasAnyCollectionChangeListeners(String collectionName) { - return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - } - - private ListenerList<CollectionChangeListener> getCollectionChangeListenerList(String collectionName) { - return this.getListenerList(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - } - - private Iterable<CollectionChangeListener> getCollectionChangeListeners(String collectionName) { - ListenerList<CollectionChangeListener> listenerList = this.getCollectionChangeListenerList(collectionName); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - return CollectionTools.contains(this.getCollectionChangeListeners(collectionName), listener); - } - - /** - * Report a bound collection update to any registered listeners. - * Return whether the event has any items. - */ - public boolean fireItemsAdded(CollectionAddEvent event) { - if (event.getItemsSize() != 0) { - this.fireItemsAdded_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event contains items - */ - protected void fireItemsAdded_(CollectionAddEvent event) { - String collectionName = event.getCollectionName(); - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - * Return whether there are any added items. - */ - public boolean fireItemsAdded(String collectionName, Collection<?> addedItems) { -// return this.fireItemsAdded(new CollectionAddEvent(this.source, collectionName, addedItems)); - if ( ! addedItems.isEmpty()) { - this.fireItemsAdded_(collectionName, addedItems); - return true; - } - return false; - } - - /** - * pre-condition: 'addedItems' is not empty - */ - protected void fireItemsAdded_(String collectionName, Collection<?> addedItems) { - CollectionAddEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionAddEvent(this.source, collectionName, addedItems); - } - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionAddEvent(this.source, collectionName, addedItems); - } - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemAdded(String collectionName, Object addedItem) { -// this.fireItemsAdded(collectionName, Collections.singleton(addedItem)); - - CollectionAddEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionAddEvent(this.source, collectionName, addedItem); - } - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionAddEvent(this.source, collectionName, addedItem); - } - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - * Return whether the event has any items. - */ - public boolean fireItemsRemoved(CollectionRemoveEvent event) { - if (event.getItemsSize() != 0) { - this.fireItemsRemoved_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event contains items - */ - protected void fireItemsRemoved_(CollectionRemoveEvent event) { - String collectionName = event.getCollectionName(); - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - * Return whether there are any removed items. - */ - public boolean fireItemsRemoved(String collectionName, Collection<?> removedItems) { -// return this.fireItemsRemoved(new CollectionRemoveEvent(this.source, collectionName, removedItems)); - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved_(collectionName, removedItems); - return true; - } - return false; - } - - /** - * pre-condition: 'removedItems' is not empty - */ - protected void fireItemsRemoved_(String collectionName, Collection<?> removedItems) { - CollectionRemoveEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionRemoveEvent(this.source, collectionName, removedItems); - } - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionRemoveEvent(this.source, collectionName, removedItems); - } - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemRemoved(String collectionName, Object removedItem) { -// this.fireItemsRemoved(collectionName, Collections.singleton(removedItem)); - - CollectionRemoveEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionRemoveEvent(this.source, collectionName, removedItem); - } - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionRemoveEvent(this.source, collectionName, removedItem); - } - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(CollectionClearEvent event) { - String collectionName = event.getCollectionName(); - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - listener.collectionCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.collectionCleared(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(String collectionName) { -// this.fireCollectionCleared(new CollectionClearEvent(this.source, collectionName)); - - CollectionClearEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionClearEvent(this.source, collectionName); - } - listener.collectionCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionClearEvent(this.source, collectionName); - } - changeListener.collectionCleared(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(CollectionChangeEvent event) { - String collectionName = event.getCollectionName(); - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - listener.collectionChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.collectionChanged(event); - } - } - } - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(String collectionName, Collection<?> collection) { -// this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName, collection)); - - CollectionChangeEvent event = null; - Iterable<CollectionChangeListener> listeners = this.getCollectionChangeListeners(collectionName); - if (listeners != null) { - for (CollectionChangeListener listener : listeners) { - if (this.hasCollectionChangeListener(collectionName, listener)) { // verify listener is still listening - if (event == null) { - event = new CollectionChangeEvent(this.source, collectionName, collection); - } - listener.collectionChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new CollectionChangeEvent(this.source, collectionName, collection); - } - changeListener.collectionChanged(event); - } - } - } - } - - /** - * Add the specified item to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#add(Object) - */ - public <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) { - if (collection.add(item)) { - this.fireItemAdded(collectionName, item); - return true; - } - return false; - } - - /** - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see Collection#addAll(Collection) - */ - public <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) { - return (items.length != 0) - && this.addItemsToCollection_(new ArrayIterator<E>(items), collection, collectionName); - } - - /** - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see Collection#addAll(Collection) - */ - public <E> boolean addItemsToCollection(Collection<? extends E> items, Collection<E> collection, String collectionName) { - return ( ! items.isEmpty()) - && this.addItemsToCollection_(items.iterator(), collection, collectionName); - } - - /** - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see Collection#addAll(Collection) - */ - public <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) { - return this.addItemsToCollection(items.iterator(), collection, collectionName); - } - - /** - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see Collection#addAll(Collection) - */ - public <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) { - return items.hasNext() - && this.addItemsToCollection_(items, collection, collectionName); - } - - /** - * no empty check - */ - protected <E> boolean addItemsToCollection_(Iterator<? extends E> items, Collection<E> collection, String collectionName) { - Collection<E> addedItems = null; - while (items.hasNext()) { - E item = items.next(); - if (collection.add(item)) { - if (addedItems == null) { - addedItems = new ArrayList<E>(); - } - addedItems.add(item); - } - } - if (addedItems != null) { - this.fireItemsAdded_(collectionName, addedItems); - return true; - } - return false; - } - - /** - * Remove the specified item from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#remove(Object) - */ - public boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) { - if (collection.remove(item)) { - this.fireItemRemoved(collectionName, item); - return true; - } - return false; - } - - /** - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#removeAll(Collection) - */ - public boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) { - return (items.length != 0) - && ( ! collection.isEmpty()) - && this.removeItemsFromCollection_(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#removeAll(Collection) - */ - public boolean removeItemsFromCollection(Collection<?> items, Collection<?> collection, String collectionName) { - return ( ! items.isEmpty()) - && ( ! collection.isEmpty()) - && this.removeItemsFromCollection_(items.iterator(), collection, collectionName); - } - - /** - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#removeAll(Collection) - */ - public boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.removeItemsFromCollection(items.iterator(), collection, collectionName); - } - - /** - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#removeAll(Collection) - */ - public boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - return items.hasNext() - && ( ! collection.isEmpty()) - && this.removeItemsFromCollection_(items, collection, collectionName); - } - - /** - * no empty checks - */ - protected boolean removeItemsFromCollection_(Iterator<?> items, Collection<?> collection, String collectionName) { - HashBag<?> removedItems = CollectionTools.collection(items); - removedItems.retainAll(collection); - boolean changed = collection.removeAll(removedItems); - - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved_(collectionName, removedItems); - } - return changed; - } - - /** - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#retainAll(Collection) - */ - public boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - if (items.length == 0) { - return this.clearCollection_(collection, collectionName); - } - return this.retainItemsInCollection_(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#retainAll(Collection) - */ - public boolean retainItemsInCollection(Collection<?> items, Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - if (items.isEmpty()) { - return this.clearCollection_(collection, collectionName); - } - return this.retainItemsInCollection_(items.iterator(), collection, collectionName); - } - - /** - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#retainAll(Collection) - */ - public boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.retainItemsInCollection(items.iterator(), collection, collectionName); - } - - /** - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#retainAll(Collection) - */ - public boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - if ( ! items.hasNext()) { - return this.clearCollection_(collection, collectionName); - } - return this.retainItemsInCollection_(items, collection, collectionName); - } - - /** - * no empty checks - */ - protected boolean retainItemsInCollection_(Iterator<?> items, Collection<?> collection, String collectionName) { - HashBag<?> retainedItems = CollectionTools.collection(items); - HashBag<?> removedItems = CollectionTools.collection(collection); - removedItems.removeAll(retainedItems); - boolean changed = collection.retainAll(retainedItems); - - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved_(collectionName, removedItems); - } - return changed; - } - - /** - * Clear the entire collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see Collection#clear() - */ - public boolean clearCollection(Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - return this.clearCollection_(collection, collectionName); - } - - /** - * no empty check - */ - protected boolean clearCollection_(Collection<?> collection, String collectionName) { - collection.clear(); - this.fireCollectionCleared(collectionName); - return true; - } - - /** - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - public <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) { - if (newCollection.isEmpty()) { - return this.clearCollection(collection, collectionName); - } - - if (collection.isEmpty()) { - return this.addItemsToCollection_(newCollection.iterator(), collection, collectionName); - } - - return this.synchronizeCollection_(newCollection, collection, collectionName); - } - - /** - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - public <E> boolean synchronizeCollection(Iterable<E> newCollection, Collection<E> collection, String collectionName) { - return this.synchronizeCollection(newCollection.iterator(), collection, collectionName); - } - - /** - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - public <E> boolean synchronizeCollection(Iterator<E> newCollection, Collection<E> collection, String collectionName) { - if ( ! newCollection.hasNext()) { - return this.clearCollection(collection, collectionName); - } - - if (collection.isEmpty()) { - return this.addItemsToCollection_(newCollection, collection, collectionName); - } - - return this.synchronizeCollection_(CollectionTools.collection(newCollection), collection, collectionName); - } - - /** - * no empty checks - */ - protected <E> boolean synchronizeCollection_(Collection<E> newCollection, Collection<E> collection, String collectionName) { - boolean changed = false; - Collection<E> removeItems = new HashBag<E>(collection); - removeItems.removeAll(newCollection); - changed |= this.removeItemsFromCollection(removeItems, collection, collectionName); - - Collection<E> addItems = new HashBag<E>(newCollection); - addItems.removeAll(collection); - changed |= this.addItemsToCollection(addItems, collection, collectionName); - - return changed; - } - - - // ********** list change support ********** - - protected static final Class<ListChangeListener> LIST_CHANGE_LISTENER_CLASS = ListChangeListener.class; - - /** - * Add a list change listener for the specified list. The listener - * will be notified only for changes to the specified list. - */ - public void addListChangeListener(String listName, ListChangeListener listener) { - this.addListener(LIST_CHANGE_LISTENER_CLASS, listName, listener); - } - - /** - * Remove a list change listener that was registered for a specific list. - */ - public void removeListChangeListener(String listName, ListChangeListener listener) { - this.removeListener(LIST_CHANGE_LISTENER_CLASS, listName, listener); - } - - /** - * Return whether there are any list change listeners that will - * be notified when the specified list has changed. - */ - public boolean hasAnyListChangeListeners(String listName) { - return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS, listName); - } - - private ListenerList<ListChangeListener> getListChangeListenerList(String listName) { - return this.getListenerList(LIST_CHANGE_LISTENER_CLASS, listName); - } - - private Iterable<ListChangeListener> getListChangeListeners(String listName) { - ListenerList<ListChangeListener> listenerList = this.getListChangeListenerList(listName); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasListChangeListener(String listName, ListChangeListener listener) { - return CollectionTools.contains(this.getListChangeListeners(listName), listener); - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any added items. - */ - public boolean fireItemsAdded(ListAddEvent event) { - if (event.getItemsSize() != 0) { - this.fireItemsAdded_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event contains items - */ - protected void fireItemsAdded_(ListAddEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any added items. - */ - public boolean fireItemsAdded(String listName, int index, List<?> addedItems) { -// return this.fireItemsAdded(new ListAddEvent(this.source, listName, index, addedItems)); - if ( ! addedItems.isEmpty()) { - this.fireItemsAdded_(listName, index, addedItems); - return true; - } - return false; - } - - /** - * pre-condition: 'addedItems' is not empty - */ - protected void fireItemsAdded_(String listName, int index, List<?> addedItems) { - ListAddEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListAddEvent(this.source, listName, index, addedItems); - } - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListAddEvent(this.source, listName, index, addedItems); - } - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemAdded(String listName, int index, Object addedItem) { -// this.fireItemsAdded(listName, index, Collections.singletonList(addedItem)); - - ListAddEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListAddEvent(this.source, listName, index, addedItem); - } - listener.itemsAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListAddEvent(this.source, listName, index, addedItem); - } - changeListener.itemsAdded(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any removed items. - */ - public boolean fireItemsRemoved(ListRemoveEvent event) { - if (event.getItemsSize() != 0) { - this.fireItemsRemoved_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event contains items - */ - protected void fireItemsRemoved_(ListRemoveEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any removed items. - */ - public boolean fireItemsRemoved(String listName, int index, List<?> removedItems) { -// return this.fireItemsRemoved(new ListRemoveEvent(this.source, listName, index, removedItems)); - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved_(listName, index, removedItems); - return true; - } - return false; - } - - /** - * pre-condition: 'removedItems' is not empty - */ - protected void fireItemsRemoved_(String listName, int index, List<?> removedItems) { - ListRemoveEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListRemoveEvent(this.source, listName, index, removedItems); - } - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListRemoveEvent(this.source, listName, index, removedItems); - } - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemRemoved(String listName, int index, Object removedItem) { -// this.fireItemsRemoved(listName, index, Collections.singletonList(removedItem)); - - ListRemoveEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListRemoveEvent(this.source, listName, index, removedItem); - } - listener.itemsRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListRemoveEvent(this.source, listName, index, removedItem); - } - changeListener.itemsRemoved(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any replaced items. - */ - public boolean fireItemsReplaced(ListReplaceEvent event) { - if ((event.getItemsSize() != 0) && this.elementsAreDifferent(event.getNewItems(), event.getOldItems())) { - this.fireItemsReplaced_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event contains new items - */ - protected void fireItemsReplaced_(ListReplaceEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.itemsReplaced(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsReplaced(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any replaced items. - */ - public boolean fireItemsReplaced(String listName, int index, List<?> newItems, List<?> oldItems) { -// return this.fireItemsReplaced(new ListReplaceEvent(this.source, listName, index, newItems, oldItems)); - if (( ! newItems.isEmpty()) && this.elementsAreDifferent(newItems, oldItems)) { - this.fireItemsReplaced_(listName, index, newItems, oldItems); - return true; - } - return false; - } - - /** - * pre-condition: 'newItems' is not empty and unequal to 'oldItems' - */ - protected void fireItemsReplaced_(String listName, int index, List<?> newItems, List<?> oldItems) { - ListReplaceEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListReplaceEvent(this.source, listName, index, newItems, oldItems); - } - listener.itemsReplaced(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListReplaceEvent(this.source, listName, index, newItems, oldItems); - } - changeListener.itemsReplaced(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether the item changed. - */ - public boolean fireItemReplaced(String listName, int index, Object newItem, Object oldItem) { -// return this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(oldItem)); - if (this.valuesAreDifferent(newItem, oldItem)) { - this.fireItemReplaced_(listName, index, newItem, oldItem); - return true; - } - return false; - } - - /** - * pre-condition: the specified old and new items are different - */ - protected void fireItemReplaced_(String listName, int index, Object newItem, Object oldItem) { - ListReplaceEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListReplaceEvent(this.source, listName, index, newItem, oldItem); - } - listener.itemsReplaced(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListReplaceEvent(this.source, listName, index, newItem, oldItem); - } - changeListener.itemsReplaced(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any moved items. - */ - // it's unlikely but possible the list is unchanged by the move... - // e.g. any moves within ["foo", "foo", "foo"] - public boolean fireItemsMoved(ListMoveEvent event) { - if (event.getTargetIndex() != event.getSourceIndex()) { - this.fireItemsMoved_(event); - return true; - } - return false; - } - - /** - * pre-condition: the specified event indicates a move - */ - protected void fireItemsMoved_(ListMoveEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.itemsMoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.itemsMoved(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any moved items. - */ - // it's unlikely but possible the list is unchanged by the move... - // e.g. any moves within ["foo", "foo", "foo"] - public boolean fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { -// return this.fireItemsMoved(new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length)); - if (targetIndex != sourceIndex) { - this.fireItemsMoved_(listName, targetIndex, sourceIndex, length); - return true; - } - return false; - } - - /** - * pre-condition: the specified indices indicate a move - */ - protected void fireItemsMoved_(String listName, int targetIndex, int sourceIndex, int length) { - ListMoveEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length); - } - listener.itemsMoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListMoveEvent(this.source, listName, targetIndex, sourceIndex, length); - } - changeListener.itemsMoved(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - * Return whether there are any moved items. - */ - // it's unlikely but possible the list is unchanged by the move... - // e.g. any moves within ["foo", "foo", "foo"] - public boolean fireItemMoved(String listName, int targetIndex, int sourceIndex) { - if (targetIndex != sourceIndex) { - this.fireItemMoved_(listName, targetIndex, sourceIndex); - return true; - } - return false; - } - - /** - * pre-condition: the specified indices indicate a move - */ - protected void fireItemMoved_(String listName, int targetIndex, int sourceIndex) { - this.fireItemsMoved_(listName, targetIndex, sourceIndex, 1); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(ListClearEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.listCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.listCleared(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(String listName) { -// this.fireListCleared(new ListClearEvent(this.source, listName)); - - ListClearEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListClearEvent(this.source, listName); - } - listener.listCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListClearEvent(this.source, listName); - } - changeListener.listCleared(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(ListChangeEvent event) { - String listName = event.getListName(); - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - listener.listChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.listChanged(event); - } - } - } - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(String listName, List<?> list) { -// this.fireListChanged(new ListChangeEvent(this.source, listName)); - - ListChangeEvent event = null; - Iterable<ListChangeListener> listeners = this.getListChangeListeners(listName); - if (listeners != null) { - for (ListChangeListener listener : listeners) { - if (this.hasListChangeListener(listName, listener)) { // verify listener is still listening - if (event == null) { - event = new ListChangeEvent(this.source, listName, list); - } - listener.listChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new ListChangeEvent(this.source, listName, list); - } - changeListener.listChanged(event); - } - } - } - } - - /** - * Add the specified item to the specified bound list at the specified index - * and fire the appropriate event. - * @see List#add(int, Object) - */ - public <E> void addItemToList(int index, E item, List<E> list, String listName) { - list.add(index, item); - this.fireItemAdded(listName, index, item); - } - - /** - * Add the specified item to the end of the specified bound list - * and fire the appropriate event. - * Return whether the list changed (i.e. 'true'). - * @see List#add(Object) - */ - public <E> boolean addItemToList(E item, List<E> list, String listName) { - if (list.add(item)) { - this.fireItemAdded(listName, list.size() - 1, item); - return true; - } - return false; // List#add(Object) should always return 'true', so we should never get here... - } - - /** - * Add the specified items to the specified bound list at the specified index - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(int, Collection) - */ - public <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) { - return (items.length != 0) - && this.addItemsToList_(index, Arrays.asList(items), list, listName); - } - - /** - * Add the specified items to the specified bound list at the specified index - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(int, Collection) - */ - public <E> boolean addItemsToList(int index, Collection<? extends E> items, List<E> list, String listName) { - return ( ! items.isEmpty()) - && this.addItemsToList_(index, this.convertToList(items), list, listName); - } - - /** - * no empty check - */ - protected <E> boolean addItemsToList_(int index, List<? extends E> items, List<E> list, String listName) { - if (list.addAll(index, items)) { - this.fireItemsAdded(listName, index, items); - return true; - } - return false; // 'items' should not be empty, so we should never get here... - } - - /** - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(int, Collection) - */ - public <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(index, items.iterator(), list, listName); - } - - /** - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(int, Collection) - */ - public <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) { - if ( ! items.hasNext()) { - return false; - } - - ArrayList<E> addedItems = CollectionTools.list(items); - if (list.addAll(index, addedItems)) { - this.fireItemsAdded(listName, index, addedItems); - return true; - } - return false; // 'items' should not be empty, so we should never get here... - } - - /** - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(Collection) - */ - public <E> boolean addItemsToList(E[] items, List<E> list, String listName) { - return (items.length != 0) - && this.addItemsToList_(Arrays.asList(items), list, listName); - } - - /** - * Add the specified items to the end of the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(int, Collection) - */ - public <E> boolean addItemsToList(Collection<? extends E> items, List<E> list, String listName) { - return ( ! items.isEmpty()) - && this.addItemsToList_(this.convertToList(items), list, listName); - } - - protected <E> List<? extends E> convertToList(Collection<? extends E> collection) { - return (collection instanceof List<?>) ? (List<? extends E>) collection : new ArrayList<E>(collection); - } - - /** - * no empty check - */ - protected <E> boolean addItemsToList_(List<? extends E> items, List<E> list, String listName) { - int index = list.size(); - if (list.addAll(items)) { - this.fireItemsAdded(listName, index, items); - return true; - } - return false; // 'items' should not be empty, so we should never get here... - } - - /** - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(Collection) - */ - public <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(items.iterator(), list, listName); - } - - /** - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#addAll(Collection) - */ - public <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) { - if ( ! items.hasNext()) { - return false; - } - return this.addItemsToList_(items, list, listName); - } - - /** - * no empty check - */ - protected <E> boolean addItemsToList_(Iterator<? extends E> items, List<E> list, String listName) { - ArrayList<E> addedItems = CollectionTools.list(items); - int index = list.size(); - if (list.addAll(addedItems)) { - this.fireItemsAdded(listName, index, addedItems); - return true; - } - return false; // 'items' should not be empty, so we should never get here... - } - - /** - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed item. - * @see List#remove(int) - */ - public <E> E removeItemFromList(int index, List<E> list, String listName) { - E item = list.remove(index); - this.fireItemRemoved(listName, index, item); - return item; - } - - /** - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#remove(Object) - */ - public boolean removeItemFromList(Object item, List<?> list, String listName) { - int index = list.indexOf(item); - if (index == -1) { - return false; - } - list.remove(index); - this.fireItemRemoved(listName, index, item); - return true; - } - - /** - * Remove the items from the specified index to the end of the list - * from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see List#remove(int) - */ - public <E> List<E> removeItemsFromList(int index, List<E> list, String listName) { - return this.removeRangeFromList(index, list.size(), list, listName); - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see List#remove(int) - */ - public <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) { - return this.removeRangeFromList(index, index + length, list, listName); - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. The begin index - * is inclusive, while the end index is exclusive. - * Return the removed items. - * @see List#remove(int) - * @see List#subList(int, int) - */ - public <E> List<E> removeRangeFromList(int beginIndex, int endIndex, List<E> list, String listName) { - if (beginIndex == endIndex) { - return Collections.emptyList(); - } - return this.removeRangeFromList_(beginIndex, endIndex, list, listName); - } - - /** - * no empty check - */ - protected <E> List<E> removeRangeFromList_(int beginIndex, int endIndex, List<E> list, String listName) { - List<E> subList = list.subList(beginIndex, endIndex); - List<E> removedItems = new ArrayList<E>(subList); - subList.clear(); - this.fireItemsRemoved(listName, beginIndex, removedItems); - return removedItems; - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#removeAll(Collection) - */ - public boolean removeItemsFromList(Object[] items, List<?> list, String listName) { - return (items.length != 0) - && ( ! list.isEmpty()) - && this.removeItemsFromList_(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#removeAll(Collection) - */ - public boolean removeItemsFromList(Collection<?> items, List<?> list, String listName) { - return ( ! items.isEmpty()) - && ( ! list.isEmpty()) - && this.removeItemsFromList_(items.iterator(), list, listName); - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#removeAll(Collection) - */ - public boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) { - return this.removeItemsFromList(items.iterator(), list, listName); - } - - /** - * Remove the specified items from the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#removeAll(Collection) - */ - public boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) { - return (items.hasNext()) - && ( ! list.isEmpty()) - && this.removeItemsFromList_(items, list, listName); - } - - /** - * no empty checks - */ - protected boolean removeItemsFromList_(Iterator<?> items, List<?> list, String listName) { - boolean changed = false; - while (items.hasNext()) { - changed |= this.removeItemFromList(items.next(), list, listName); - } - return changed; - } - - /** - * Retain the specified items in the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#retainAll(Collection) - */ - public boolean retainItemsInList(Object[] items, List<?> list, String listName) { - if (list.isEmpty()) { - return false; - } - if (items.length == 0) { - return this.clearList_(list, listName); - } - return this.retainItemsInList_(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Retain the specified items in the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#retainAll(Collection) - */ - public boolean retainItemsInList(Collection<?> items, List<?> list, String listName) { - if (list.isEmpty()) { - return false; - } - if (items.isEmpty()) { - return this.clearList_(list, listName); - } - return this.retainItemsInList_(items.iterator(), list, listName); - } - - /** - * Retain the specified items in the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#retainAll(Collection) - */ - public boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) { - return this.retainItemsInList(items.iterator(), list, listName); - } - - /** - * Retain the specified items in the specified bound list - * and fire the appropriate event(s) if necessary. - * Return whether the list changed. - * @see List#retainAll(Collection) - */ - public boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) { - if (list.isEmpty()) { - return false; - } - if ( ! items.hasNext()) { - return this.clearList_(list, listName); - } - return this.retainItemsInList_(items, list, listName); - } - - /** - * no empty checks - */ - protected boolean retainItemsInList_(Iterator<?> items, List<?> list, String listName) { - HashBag<?> retainedItems = CollectionTools.collection(items); - HashBag<?> removedItems = CollectionTools.collection(list); - removedItems.removeAll(retainedItems); - return this.removeItemsFromList(removedItems, list, listName); - } - - /** - * Set the specified item in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced item. - * @see List#set(int, Object) - */ - public <E> E setItemInList(int index, E item, List<E> list, String listName) { - E oldItem = list.set(index, item); - this.fireItemReplaced(listName, index, item, oldItem); - return oldItem; - } - - /** - * Replace the first occurrence of the specified item - * in the specified bound list - * and fire the appropriate event if necessary. - * Return the index of the replaced item. - * Return -1 if the item was not found in the list. - * @see List#set(int, Object) - */ - public <E> int replaceItemInList(E oldItem, E newItem, List<E> list, String listName) { - if (list.isEmpty()) { - return -1; - } - - int index = list.indexOf(oldItem); - if ((index != -1) && this.valuesAreDifferent(oldItem, newItem)) { - list.set(index, newItem); - this.fireItemReplaced_(listName, index, newItem, oldItem); - } - return index; - } - - /** - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see List#set(int, Object) - */ - public <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) { - if (items.length == 0) { - return Collections.emptyList(); - } - return this.setItemsInList_(index, Arrays.asList(items), list, listName); - } - - /** - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see List#set(int, Object) - */ - public <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) { - if (items.isEmpty()) { - return Collections.emptyList(); - } - return this.setItemsInList_(index, items, list, listName); - } - - /** - * no empty check - */ - protected <E> List<E> setItemsInList_(int index, List<? extends E> items, List<E> list, String listName) { - List<E> subList = list.subList(index, index + items.size()); - List<E> oldItems = new ArrayList<E>(subList); - for (int i = 0; i < items.size(); i++) { - E newItem = items.get(i); - E oldItem = subList.set(i, newItem); - this.fireItemReplaced(listName, index + i, newItem, oldItem); - } - return oldItems; - } - - /** - * Move items in the specified list from the specified source index to the - * specified target index for the specified length. - * Return whether the list changed. - */ - public <E> boolean moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) { - if ((targetIndex == sourceIndex) || (length == 0)) { - return false; - } - // it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...) - CollectionTools.move(list, targetIndex, sourceIndex, length); - this.fireItemsMoved(listName, targetIndex, sourceIndex, length); - return true; - } - - /** - * Move the specified item in the specified list to the - * specified target index. - * Return whether the list changed. - */ - public <E> boolean moveItemInList(int targetIndex, E item, List<E> list, String listName) { - return this.moveItemInList(targetIndex, list.indexOf(item), list, listName); - } - - /** - * Move an item in the specified list from the specified source index to the - * specified target index. - * Return whether the list changed. - */ - public <E> boolean moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) { - if (targetIndex == sourceIndex) { - return false; - } - if (this.valuesAreEqual(list.get(targetIndex), list.get(sourceIndex))) { - return false; - } - CollectionTools.move(list, targetIndex, sourceIndex); - this.fireItemMoved_(listName, targetIndex, sourceIndex); - return true; - } - - /** - * Clear the entire list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see List#clear() - */ - public boolean clearList(List<?> list, String listName) { - return ( ! list.isEmpty()) && this.clearList_(list, listName); - } - - /** - * no empty check - */ - protected boolean clearList_(List<?> list, String listName) { - list.clear(); - this.fireListCleared(listName); - return true; - } - - /** - * Synchronize the list with the specified new list, - * making a minimum number of sets, removes, and/or adds. - * Return whether the list changed. - */ - public <E> boolean synchronizeList(List<E> newList, List<E> list, String listName) { - if (newList.isEmpty()) { - return this.clearList(list, listName); - } - if (list.isEmpty()) { - return this.addItemsToList_(newList, list, listName); - } - return this.synchronizeList_(newList, list, listName); - } - - /** - * Synchronize the list with the specified new list, - * making a minimum number of sets, removes, and/or adds. - * Return whether the list changed. - */ - public <E> boolean synchronizeList(Iterable<? extends E> newList, List<E> list, String listName) { - return this.synchronizeList(newList.iterator(), list, listName); - } - - /** - * Synchronize the list with the specified new list, - * making a minimum number of sets, removes, and/or adds. - * Return whether the list changed. - */ - public <E> boolean synchronizeList(Iterator<? extends E> newList, List<E> list, String listName) { - if ( ! newList.hasNext()) { - return this.clearList(list, listName); - } - if (list.isEmpty()) { - return this.addItemsToList_(newList, list, listName); - } - return this.synchronizeList_(CollectionTools.list(newList), list, listName); - } - - /** - * no empty checks - */ - protected <E> boolean synchronizeList_(List<? extends E> newList, List<E> oldList, String listName) { - int newSize = newList.size(); - int oldSize = oldList.size(); - - boolean changed = false; - // TODO check for RandomAccess - int min = Math.min(newSize, oldSize); - for (int i = 0; i < min; i++) { - E newItem = newList.get(i); - E oldItem = oldList.set(i, newItem); - if (this.valuesAreDifferent(newItem, oldItem)) { - changed = true; - this.fireItemReplaced_(listName, i, newItem, oldItem); - } - } - - if (newSize == oldSize) { - return changed; - } - - if (newSize < oldSize) { - this.removeRangeFromList_(newSize, oldSize, oldList, listName); - return true; - } - - // newSize > oldSize - this.addItemsToList_(newList.subList(oldSize, newSize), oldList, listName); - return true; - } - - - // ********** tree change support ********** - - protected static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class; - - /** - * Add a tree change listener for the specified tree. The listener - * will be notified only for changes to the specified tree. - */ - public void addTreeChangeListener(String treeName, TreeChangeListener listener) { - this.addListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener); - } - - /** - * Remove a tree change listener that was registered for a specific tree. - */ - public void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.removeListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener); - } - - /** - * Return whether there are any tree change listeners that will - * be notified when the specified tree has changed. - */ - public boolean hasAnyTreeChangeListeners(String treeName) { - return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS, treeName); - } - - private ListenerList<TreeChangeListener> getTreeChangeListenerList(String treeName) { - return this.getListenerList(TREE_CHANGE_LISTENER_CLASS, treeName); - } - - private Iterable<TreeChangeListener> getTreeChangeListeners(String treeName) { - ListenerList<TreeChangeListener> listenerList = this.getTreeChangeListenerList(treeName); - return (listenerList == null) ? null : listenerList.getListeners(); - } - - private boolean hasTreeChangeListener(String treeName, TreeChangeListener listener) { - return CollectionTools.contains(this.getTreeChangeListeners(treeName), listener); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(TreeAddEvent event) { - String treeName = event.getTreeName(); - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - listener.nodeAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.nodeAdded(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(String treeName, List<?> path) { -// this.fireNodeAdded(new TreeAddEvent(this.source, treeName, path)); - TreeAddEvent event = null; - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - if (event == null) { - event = new TreeAddEvent(this.source, treeName, path); - } - listener.nodeAdded(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new TreeAddEvent(this.source, treeName, path); - } - changeListener.nodeAdded(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(TreeRemoveEvent event) { - String treeName = event.getTreeName(); - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - listener.nodeRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.nodeRemoved(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(String treeName, List<?> path) { -// this.fireNodeRemoved(new TreeRemoveEvent(this.source, treeName, path)); - - TreeRemoveEvent event = null; - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - if (event == null) { - event = new TreeRemoveEvent(this.source, treeName, path); - } - listener.nodeRemoved(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new TreeRemoveEvent(this.source, treeName, path); - } - changeListener.nodeRemoved(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(TreeClearEvent event) { - String treeName = event.getTreeName(); - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - listener.treeCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.treeCleared(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(String treeName) { -// this.fireTreeCleared(new TreeClearEvent(this.source, treeName)); - - TreeClearEvent event = null; - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - if (event == null) { - event = new TreeClearEvent(this.source, treeName); - } - listener.treeCleared(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new TreeClearEvent(this.source, treeName); - } - changeListener.treeCleared(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(TreeChangeEvent event) { - String treeName = event.getTreeName(); - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - listener.treeChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - changeListener.treeChanged(event); - } - } - } - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(String treeName, Collection<?> nodes) { -// this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, nodes)); - - TreeChangeEvent event = null; - Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName); - if (listeners != null) { - for (TreeChangeListener listener : listeners) { - if (this.hasTreeChangeListener(treeName, listener)) { // verify listener is still listening - if (event == null) { - event = new TreeChangeEvent(this.source, treeName, nodes); - } - listener.treeChanged(event); - } - } - } - - Iterable<ChangeListener> changeListeners = this.getChangeListeners(); - if (changeListeners != null) { - for (ChangeListener changeListener : changeListeners) { - if (this.hasChangeListener(changeListener)) { // verify listener is still listening - if (event == null) { - event = new TreeChangeEvent(this.source, treeName, nodes); - } - changeListener.treeChanged(event); - } - } - } - } - - - // ********** misc ********** - - /** - * Convenience method for checking whether an attribute value has changed. - * @see Tools#valuesAreEqual(Object, Object) - */ - public boolean valuesAreEqual(Object value1, Object value2) { - return Tools.valuesAreEqual(value1, value2); - } - - /** - * Convenience method for checking whether an attribute value has changed. - * @see Tools#valuesAreDifferent(Object, Object) - */ - public boolean valuesAreDifferent(Object value1, Object value2) { - return Tools.valuesAreDifferent(value1, value2); - } - - /** - * @see CollectionTools#elementsAreEqual(Iterable, Iterable) - */ - public boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) { - return CollectionTools.elementsAreEqual(iterable1, iterable2); - } - - /** - * @see CollectionTools#elementsAreDifferent(Iterable, Iterable) - */ - public boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) { - return CollectionTools.elementsAreDifferent(iterable1, iterable2); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.source); - } - - - // ********** member classes ********** - - /** - * Pair a possibly <code>null</code> aspect name with its associated - * listeners. - */ - static abstract class AspectListenerListPair<L extends EventListener> - implements Serializable - { - final ListenerList<L> listenerList; - - private static final long serialVersionUID = 1L; - - AspectListenerListPair(Class<L> listenerClass, L listener) { - super(); - this.listenerList = new ListenerList<L>(listenerClass, listener); - } - - boolean matches(Class<? extends EventListener> listenerClass, @SuppressWarnings("unused") String aspectName) { - return this.listenerList.getListenerType() == listenerClass; - } - - boolean matches(Class<? extends EventListener> listenerClass) { - return this.matches(listenerClass, null); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.getAspectName()); - } - - abstract String getAspectName(); - } - - /** - * Pair a non-<code>null</code> aspect name with its associated listeners. - */ - static class SimpleAspectListenerListPair<L extends EventListener> - extends AspectListenerListPair<L> - { - final String aspectName; - - private static final long serialVersionUID = 1L; - - SimpleAspectListenerListPair(Class<L> listenerClass, String aspectName, L listener) { - super(listenerClass, listener); - if (aspectName == null) { - throw new NullPointerException(); - } - this.aspectName = aspectName; - } - - @Override - boolean matches(Class<? extends EventListener> listenerClass, @SuppressWarnings("hiding") String aspectName) { - return this.aspectName.equals(aspectName) - && super.matches(listenerClass, aspectName); - } - - @Override - String getAspectName() { - return this.aspectName; - } - } - - /** - * Pair a <code>null</code> aspect name with its associated listeners. - */ - static class NullAspectListenerListPair<L extends EventListener> - extends AspectListenerListPair<L> - { - private static final long serialVersionUID = 1L; - - NullAspectListenerListPair(Class<L> listenerClass, L listener) { - super(listenerClass, listener); - } - - @Override - boolean matches(Class<? extends EventListener> listenerClass, String aspectName) { - return (aspectName == null) - && super.matches(listenerClass, null); - } - - @Override - String getAspectName() { - return null; - } - } -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/SingleAspectChangeSupport.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/SingleAspectChangeSupport.java deleted file mode 100644 index ef13a67927..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/SingleAspectChangeSupport.java +++ /dev/null @@ -1,380 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model; - -import java.util.Collection; -import java.util.EventListener; -import java.util.List; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; - -/** - * This change support class changes the behavior of the standard - * change support in several ways:<ul> - * <li>All events fired by the source must specify the single aspect. - * <li>Listeners are required to be either "general purpose" listeners or - * listeners of the single aspect. - * </ul> - */ -public class SingleAspectChangeSupport - extends ChangeSupport -{ - protected final Class<? extends EventListener> validListenerClass; - protected final String validAspectName; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - public SingleAspectChangeSupport(Model source, Class<? extends EventListener> validListenerClass, String validAspectName) { - super(source); - if ( ! validListenerClass.isAssignableFrom(this.getChangeListenerClass())) { - throw new IllegalArgumentException("The change support's change listener class (" + this.getChangeListenerClass().getName() + //$NON-NLS-1$ - ") does not extend the valid listener class: " + validListenerClass.getName()); //$NON-NLS-1$ - } - this.validListenerClass = validListenerClass; - this.validAspectName = validAspectName; - } - - - // ********** internal implementation ********** - - private UnsupportedOperationException buildUnsupportedOperationException() { - return new UnsupportedOperationException( - "This Model supports only changes for the listener type \"" + this.validListenerClass.getName() //$NON-NLS-1$ - + "\" and the aspect \"" + this.validAspectName + '"' //$NON-NLS-1$ - ); - } - - /** - * The listener can be either an instance of the valid listener class or - * the "general-purpose" change listener class (which should extend the - * the valid listener class). - */ - private void check(Class<? extends EventListener> listenerClass) { - if ((listenerClass != this.getChangeListenerClass()) && (listenerClass != this.validListenerClass)) { - throw new IllegalArgumentException( - "This Model supports only changes for the listener type \"" + this.validListenerClass.getName() //$NON-NLS-1$ - + "\" : \"" + listenerClass.getName() + '"' //$NON-NLS-1$ - ); - } - } - - private void check(Class<? extends EventListener> listenerClass, String aspectName) { - this.check(listenerClass); - if ( ! aspectName.equals(this.validAspectName)) { - throw new IllegalArgumentException( - "This Model supports only changes for the aspect \"" + this.validAspectName //$NON-NLS-1$ - + "\" : \"" + aspectName + '"' //$NON-NLS-1$ - ); - } - } - - @Override - protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, String aspectName, L listener) { - this.check(listenerClass, aspectName); - super.addListener(listenerClass, aspectName, listener); - } - - @Override - protected synchronized <L extends EventListener> void addListener(Class<L> listenerClass, L listener) { - this.check(listenerClass); - super.addListener(listenerClass, listener); - } - - @Override - protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, String aspectName, L listener) { - this.check(listenerClass, aspectName); - super.removeListener(listenerClass, aspectName, listener); - } - - @Override - protected synchronized <L extends EventListener> void removeListener(Class<L> listenerClass, L listener) { - this.check(listenerClass); - super.removeListener(listenerClass, listener); - } - - @Override - protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass, String aspectName) { - this.check(listenerClass, aspectName); - return super.hasAnyListeners(listenerClass, aspectName); - } - - @Override - protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass) { - this.check(listenerClass); - return super.hasAnyListeners(listenerClass); - } - - - // ********** state change support ********** - - @Override - public void fireStateChanged(StateChangeEvent event) { - throw this.buildUnsupportedOperationException(); - } - - @Override - public void fireStateChanged() { - throw this.buildUnsupportedOperationException(); - } - - - // ********** property change support ********** - - @Override - public boolean firePropertyChanged(PropertyChangeEvent event) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, event.getPropertyName()); - return super.firePropertyChanged(event); - } - - @Override - public boolean firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - return super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public boolean firePropertyChanged(String propertyName, int oldValue, int newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - return super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public boolean firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - return super.firePropertyChanged(propertyName, oldValue, newValue); - } - - - // ********** collection change support ********** - - @Override - public boolean fireItemsAdded(CollectionAddEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - return super.fireItemsAdded(event); - } - - @Override - public boolean fireItemsAdded(String collectionName, Collection<?> addedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - return super.fireItemsAdded(collectionName, addedItems); - } - - @Override - public void fireItemAdded(String collectionName, Object addedItem) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemAdded(collectionName, addedItem); - } - - @Override - public boolean fireItemsRemoved(CollectionRemoveEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - return super.fireItemsRemoved(event); - } - - @Override - public boolean fireItemsRemoved(String collectionName, Collection<?> removedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - return super.fireItemsRemoved(collectionName, removedItems); - } - - @Override - public void fireItemRemoved(String collectionName, Object removedItem) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemRemoved(collectionName, removedItem); - } - - @Override - public void fireCollectionCleared(CollectionClearEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireCollectionCleared(event); - } - - @Override - public void fireCollectionCleared(String collectionName) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireCollectionCleared(collectionName); - } - - @Override - public void fireCollectionChanged(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireCollectionChanged(event); - } - - @Override - public void fireCollectionChanged(String collectionName, Collection<?> collection) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireCollectionChanged(collectionName, collection); - } - - - // ********** list change support ********** - - @Override - public boolean fireItemsAdded(ListAddEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - return super.fireItemsAdded(event); - } - - @Override - public boolean fireItemsAdded(String listName, int index, List<?> addedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - return super.fireItemsAdded(listName, index, addedItems); - } - - @Override - public void fireItemAdded(String listName, int index, Object addedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemAdded(listName, index, addedItem); - } - - @Override - public boolean fireItemsRemoved(ListRemoveEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - return super.fireItemsRemoved(event); - } - - @Override - public boolean fireItemsRemoved(String listName, int index, List<?> removedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - return super.fireItemsRemoved(listName, index, removedItems); - } - - @Override - public void fireItemRemoved(String listName, int index, Object removedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemRemoved(listName, index, removedItem); - } - - @Override - public boolean fireItemsReplaced(ListReplaceEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - return super.fireItemsReplaced(event); - } - - @Override - public boolean fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - return super.fireItemsReplaced(listName, index, newItems, replacedItems); - } - - @Override - public boolean fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - return super.fireItemReplaced(listName, index, newItem, replacedItem); - } - - @Override - public boolean fireItemsMoved(ListMoveEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - return super.fireItemsMoved(event); - } - - @Override - public boolean fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - return super.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - @Override - public void fireListCleared(ListClearEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireListCleared(event); - } - - @Override - public void fireListCleared(String listName) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireListCleared(listName); - } - - @Override - public void fireListChanged(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireListChanged(event); - } - - @Override - public void fireListChanged(String listName, List<?> list) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireListChanged(listName, list); - } - - - // ********** tree change support ********** - - @Override - public void fireNodeAdded(TreeAddEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeAdded(event); - } - - @Override - public void fireNodeAdded(String treeName, List<?> path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeAdded(treeName, path); - } - - @Override - public void fireNodeRemoved(TreeRemoveEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeRemoved(event); - } - - @Override - public void fireNodeRemoved(String treeName, List<?> path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeRemoved(treeName, path); - } - - @Override - public void fireTreeCleared(TreeClearEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeCleared(event); - } - - @Override - public void fireTreeCleared(String treeName) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeCleared(treeName); - } - - @Override - public void fireTreeChanged(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeChanged(event); - } - - @Override - public void fireTreeChanged(String treeName, Collection<?> nodes) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeChanged(treeName, nodes); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTChangeListenerWrapper.java deleted file mode 100644 index 5f16ea4650..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTChangeListenerWrapper.java +++ /dev/null @@ -1,454 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; - -/** - * Wrap another change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTChangeListenerWrapper - implements ChangeListener -{ - private final ChangeListener listener; - - - public AWTChangeListenerWrapper(ChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void stateChanged(StateChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.stateChanged_(event); - } else { - this.executeOnEventQueue(this.buildStateChangedRunnable(event)); - } - } - - public void propertyChanged(PropertyChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.propertyChanged_(event); - } else { - this.executeOnEventQueue(this.buildPropertyChangedRunnable(event)); - } - } - - public void itemsAdded(CollectionAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(CollectionRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void collectionCleared(CollectionClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.collectionCleared_(event); - } else { - this.executeOnEventQueue(this.buildCollectionClearedRunnable(event)); - } - } - - public void collectionChanged(CollectionChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.collectionChanged_(event); - } else { - this.executeOnEventQueue(this.buildCollectionChangedRunnable(event)); - } - } - - public void itemsAdded(ListAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(ListRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void itemsMoved(ListMoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsMoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsMovedRunnable(event)); - } - } - - public void itemsReplaced(ListReplaceEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsReplaced_(event); - } else { - this.executeOnEventQueue(this.buildItemsReplacedRunnable(event)); - } - } - - public void listCleared(ListClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.listCleared_(event); - } else { - this.executeOnEventQueue(this.buildListClearedRunnable(event)); - } - } - - public void listChanged(ListChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.listChanged_(event); - } else { - this.executeOnEventQueue(this.buildListChangedRunnable(event)); - } - } - - public void nodeAdded(TreeAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.nodeAdded_(event); - } else { - this.executeOnEventQueue(this.buildNodeAddedRunnable(event)); - } - } - - public void nodeRemoved(TreeRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.nodeRemoved_(event); - } else { - this.executeOnEventQueue(this.buildNodeRemovedRunnable(event)); - } - } - - public void treeCleared(TreeClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.treeCleared_(event); - } else { - this.executeOnEventQueue(this.buildTreeClearedRunnable(event)); - } - } - - public void treeChanged(TreeChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.treeChanged_(event); - } else { - this.executeOnEventQueue(this.buildTreeChangedRunnable(event)); - } - } - - private Runnable buildStateChangedRunnable(final StateChangeEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.stateChanged_(event); - } - }; - } - - private Runnable buildPropertyChangedRunnable(final PropertyChangeEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.propertyChanged_(event); - } - }; - } - - private Runnable buildItemsAddedRunnable(final CollectionAddEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsRemovedRunnable(final CollectionRemoveEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildCollectionClearedRunnable(final CollectionClearEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.collectionCleared_(event); - } - @Override - public String toString() { - return "collection cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.collectionChanged_(event); - } - @Override - public String toString() { - return "collection changed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsAddedRunnable(final ListAddEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsRemovedRunnable(final ListRemoveEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsMovedRunnable(final ListMoveEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsMoved_(event); - } - @Override - public String toString() { - return "items moved runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsReplacedRunnable(final ListReplaceEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.itemsReplaced_(event); - } - @Override - public String toString() { - return "items replaced runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildListClearedRunnable(final ListClearEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.listCleared_(event); - } - @Override - public String toString() { - return "list cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildListChangedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.listChanged_(event); - } - @Override - public String toString() { - return "list changed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildNodeAddedRunnable(final TreeAddEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.nodeAdded_(event); - } - @Override - public String toString() { - return "node added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildNodeRemovedRunnable(final TreeRemoveEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.nodeRemoved_(event); - } - @Override - public String toString() { - return "node removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildTreeClearedRunnable(final TreeClearEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.treeCleared_(event); - } - @Override - public String toString() { - return "tree cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildTreeChangedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTChangeListenerWrapper.this.treeChanged_(event); - } - @Override - public String toString() { - return "tree changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void stateChanged_(StateChangeEvent event) { - this.listener.stateChanged(event); - } - - void propertyChanged_(PropertyChangeEvent event) { - this.listener.propertyChanged(event); - } - - void itemsAdded_(CollectionAddEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(CollectionRemoveEvent event) { - this.listener.itemsRemoved(event); - } - - void collectionCleared_(CollectionClearEvent event) { - this.listener.collectionCleared(event); - } - - void collectionChanged_(CollectionChangeEvent event) { - this.listener.collectionChanged(event); - } - - void itemsAdded_(ListAddEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(ListRemoveEvent event) { - this.listener.itemsRemoved(event); - } - - void itemsMoved_(ListMoveEvent event) { - this.listener.itemsMoved(event); - } - - void itemsReplaced_(ListReplaceEvent event) { - this.listener.itemsReplaced(event); - } - - void listCleared_(ListClearEvent event) { - this.listener.listCleared(event); - } - - void listChanged_(ListChangeEvent event) { - this.listener.listChanged(event); - } - - void nodeAdded_(TreeAddEvent event) { - this.listener.nodeAdded(event); - } - - void nodeRemoved_(TreeRemoveEvent event) { - this.listener.nodeRemoved(event); - } - - void treeCleared_(TreeClearEvent event) { - this.listener.treeCleared(event); - } - - void treeChanged_(TreeChangeEvent event) { - this.listener.treeChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java deleted file mode 100644 index b8af52a34e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; - -/** - * Wrap another collection change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTCollectionChangeListenerWrapper - implements CollectionChangeListener -{ - private final CollectionChangeListener listener; - - public AWTCollectionChangeListenerWrapper(CollectionChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void itemsAdded(CollectionAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(CollectionRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void collectionCleared(CollectionClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.collectionCleared_(event); - } else { - this.executeOnEventQueue(this.buildCollectionClearedRunnable(event)); - } - } - - public void collectionChanged(CollectionChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.collectionChanged_(event); - } else { - this.executeOnEventQueue(this.buildCollectionChangedRunnable(event)); - } - } - - private Runnable buildItemsAddedRunnable(final CollectionAddEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsRemovedRunnable(final CollectionRemoveEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildCollectionClearedRunnable(final CollectionClearEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionCleared_(event); - } - @Override - public String toString() { - return "collection cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionChanged_(event); - } - @Override - public String toString() { - return "collection changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void itemsAdded_(CollectionAddEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(CollectionRemoveEvent event) { - this.listener.itemsRemoved(event); - } - - void collectionCleared_(CollectionClearEvent event) { - this.listener.collectionCleared(event); - } - - void collectionChanged_(CollectionChangeEvent event) { - this.listener.collectionChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java deleted file mode 100644 index bc477f4f7a..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; - -/** - * Wrap another list change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTListChangeListenerWrapper - implements ListChangeListener -{ - private final ListChangeListener listener; - - public AWTListChangeListenerWrapper(ListChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void itemsAdded(ListAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(ListRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void itemsMoved(ListMoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsMoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsMovedRunnable(event)); - } - } - - public void itemsReplaced(ListReplaceEvent event) { - if (this.isExecutingOnUIThread()) { - this.itemsReplaced_(event); - } else { - this.executeOnEventQueue(this.buildItemsReplacedRunnable(event)); - } - } - - public void listCleared(ListClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.listCleared_(event); - } else { - this.executeOnEventQueue(this.buildListClearedRunnable(event)); - } - } - - public void listChanged(ListChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.listChanged_(event); - } else { - this.executeOnEventQueue(this.buildListChangedRunnable(event)); - } - } - - private Runnable buildItemsAddedRunnable(final ListAddEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsRemovedRunnable(final ListRemoveEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsMovedRunnable(final ListMoveEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsMoved_(event); - } - @Override - public String toString() { - return "items moved runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildItemsReplacedRunnable(final ListReplaceEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsReplaced_(event); - } - @Override - public String toString() { - return "items replaced runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildListClearedRunnable(final ListClearEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listCleared_(event); - } - @Override - public String toString() { - return "list cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildListChangedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listChanged_(event); - } - @Override - public String toString() { - return "list changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void itemsAdded_(ListAddEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(ListRemoveEvent event) { - this.listener.itemsRemoved(event); - } - - void itemsMoved_(ListMoveEvent event) { - this.listener.itemsMoved(event); - } - - void itemsReplaced_(ListReplaceEvent event) { - this.listener.itemsReplaced(event); - } - - void listCleared_(ListClearEvent event) { - this.listener.listCleared(event); - } - - void listChanged_(ListChangeEvent event) { - this.listener.listChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java deleted file mode 100644 index a46bd8bc64..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; - -/** - * Wrap another property change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTPropertyChangeListenerWrapper - implements PropertyChangeListener -{ - private final PropertyChangeListener listener; - - - public AWTPropertyChangeListenerWrapper(PropertyChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void propertyChanged(PropertyChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.propertyChanged_(event); - } else { - this.executeOnEventQueue(this.buildPropertyChangedRunnable(event)); - } - } - - private Runnable buildPropertyChangedRunnable(final PropertyChangeEvent event) { - return new Runnable() { - public void run() { - AWTPropertyChangeListenerWrapper.this.propertyChanged_(event); - } - @Override - public String toString() { - return "property changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void propertyChanged_(PropertyChangeEvent event) { - this.listener.propertyChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java deleted file mode 100644 index c1ecf2b2ee..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; - -/** - * Wrap another state change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTStateChangeListenerWrapper - implements StateChangeListener -{ - private final StateChangeListener listener; - - public AWTStateChangeListenerWrapper(StateChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void stateChanged(StateChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.stateChanged_(event); - } else { - this.executeOnEventQueue(this.buildStateChangedRunnable(event)); - } - } - - private Runnable buildStateChangedRunnable(final StateChangeEvent event) { - return new Runnable() { - public void run() { - AWTStateChangeListenerWrapper.this.stateChanged_(event); - } - @Override - public String toString() { - return "state changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void stateChanged_(StateChangeEvent event) { - this.listener.stateChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java deleted file mode 100644 index ea60469d1a..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; - -/** - * Wrap another tree change listener and forward events to it on the AWT - * event queue, asynchronously if necessary. If the event arrived on the UI - * thread that is probably because it was initiated by a UI widget; as a - * result, we want to loop back synchronously so the events can be - * short-circuited. - */ -public final class AWTTreeChangeListenerWrapper - implements TreeChangeListener -{ - private final TreeChangeListener listener; - - public AWTTreeChangeListenerWrapper(TreeChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void nodeAdded(TreeAddEvent event) { - if (this.isExecutingOnUIThread()) { - this.nodeAdded_(event); - } else { - this.executeOnEventQueue(this.buildNodeAddedRunnable(event)); - } - } - - public void nodeRemoved(TreeRemoveEvent event) { - if (this.isExecutingOnUIThread()) { - this.nodeRemoved_(event); - } else { - this.executeOnEventQueue(this.buildNodeRemovedRunnable(event)); - } - } - - public void treeCleared(TreeClearEvent event) { - if (this.isExecutingOnUIThread()) { - this.treeCleared_(event); - } else { - this.executeOnEventQueue(this.buildTreeClearedRunnable(event)); - } - } - - public void treeChanged(TreeChangeEvent event) { - if (this.isExecutingOnUIThread()) { - this.treeChanged_(event); - } else { - this.executeOnEventQueue(this.buildTreeChangedRunnable(event)); - } - } - - private Runnable buildNodeAddedRunnable(final TreeAddEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeAdded_(event); - } - @Override - public String toString() { - return "node added runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildNodeRemovedRunnable(final TreeRemoveEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeRemoved_(event); - } - @Override - public String toString() { - return "node removed runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildTreeClearedRunnable(final TreeClearEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeCleared_(event); - } - @Override - public String toString() { - return "tree cleared runnable"; //$NON-NLS-1$ - } - }; - } - - private Runnable buildTreeChangedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeChanged_(event); - } - @Override - public String toString() { - return "tree changed runnable"; //$NON-NLS-1$ - } - }; - } - - private boolean isExecutingOnUIThread() { - return EventQueue.isDispatchThread(); - } - - /** - * {@link EventQueue#invokeLater(Runnable)} seems to work OK; - * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make - * things more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void nodeAdded_(TreeAddEvent event) { - this.listener.nodeAdded(event); - } - - void nodeRemoved_(TreeRemoveEvent event) { - this.listener.nodeRemoved(event); - } - - void treeCleared_(TreeClearEvent event) { - this.listener.treeCleared(event); - } - - void treeChanged_(TreeChangeEvent event) { - this.listener.treeChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ')'; //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractCollectionValueModel.java deleted file mode 100644 index 31aad85651..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractCollectionValueModel.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * This abstract class provides the infrastructure for "lazily" adding listeners - * to an underlying model as necessary. Subclasses will need to engage and - * disegage the underlying model and fire the appropriate collection change - * events. Subclasses must implement the appropriate {@link CollectionValueModel}. - * <p> - * Subclasses must implement the following methods:<ul> - * <li>{@link #engageModel()}<p> - * implement this method to add the appropriate listener to the underlying model - * <li>{@link #disengageModel()}<p> - * implement this method to remove the appropriate listener from the underlying model - * </ul> - */ -public abstract class AbstractCollectionValueModel - extends AbstractModel -{ - - // ********** constructor/initialization ********** - - protected AbstractCollectionValueModel() { - super(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, CollectionValueModel.VALUES); - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public synchronized void addChangeListener(ChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addChangeListener(listener); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName.equals(CollectionValueModel.VALUES) && this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public synchronized void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName.equals(CollectionValueModel.VALUES) && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether the model has no collection value listeners. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return whether the model has any collection value listeners. - */ - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES); - } - - - // ********** behavior ********** - - /** - * Engage the underlying model. - */ - protected abstract void engageModel(); - - /** - * Stop listening to the underlying model. - */ - protected abstract void disengageModel(); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractListValueModel.java deleted file mode 100644 index b182a52764..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractListValueModel.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This abstract class provides the infrastructure for "lazily" adding listeners - * to an underlying model as necessary. Subclasses will need to engage and - * disegage the underlying model and fire the appropriate list change - * events. Subclasses must implement the appropriate {@link ListValueModel}. - * <p> - * Subclasses must implement the following methods:<ul> - * <li>{@link #engageModel()}<p> - * implement this method to add the appropriate listener to the underlying model - * <li>{@link #disengageModel()}<p> - * implement this method to remove the appropriate listener from the underlying model - * </ul> - */ -public abstract class AbstractListValueModel - extends AbstractModel -{ - - // ********** constructor/initialization ********** - - protected AbstractListValueModel() { - super(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES); - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addChangeListener(listener); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addListChangeListener(String listName, ListChangeListener listener) { - if (listName.equals(ListValueModel.LIST_VALUES) && this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName.equals(ListValueModel.LIST_VALUES) && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether the model has no collection value listeners. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return whether the model has any collection value listeners. - */ - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(ListValueModel.LIST_VALUES); - } - - - // ********** behavior ********** - - /** - * Engage the underlying model. - */ - protected abstract void engageModel(); - - /** - * Stop listening to the underlying model. - */ - protected abstract void disengageModel(); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModel.java deleted file mode 100644 index af624292d6..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModel.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure for "lazily" adding listeners - * to an underlying model as necessary. Subclasses will need to engage and - * disegage the underlying model and fire the appropriate property change - * events. Subclasses must implement the appropriate {@link PropertyValueModel}. - * <p> - * Subclasses must implement the following methods:<ul> - * <li>{@link #engageModel()}<p> - * implement this method to add the appropriate listener to the underlying model - * <li>{@link #disengageModel()}<p> - * implement this method to remove the appropriate listener from the underlying model - * </ul> - */ -public abstract class AbstractPropertyValueModel - extends AbstractModel -{ - - // ********** constructor/initialization ********** - - protected AbstractPropertyValueModel() { - super(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE); - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public synchronized void addChangeListener(ChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public synchronized void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName.equals(PropertyValueModel.VALUE) && this.hasNoListeners()) { - this.engageModel(); - } - super.addPropertyChangeListener(propertyName, listener); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName.equals(PropertyValueModel.VALUE) && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether the model has no property value listeners. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return whether the model has any property value listeners. - */ - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE); - } - - - // ********** behavior ********** - - /** - * Engage the underlying model. - */ - protected abstract void engageModel(); - - /** - * Stop listening to the underlying model. - */ - protected abstract void disengageModel(); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModelAdapter.java deleted file mode 100644 index b2dde293a2..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractPropertyValueModelAdapter.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * <p> - * Subclasses must implement:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current model - * <li>{@link #engageModel_()}<p> - * to start listening to the adapted model - * <li>{@link #disengageModel_()}<p> - * to stop listening to the adapted model - * </ul> - * Subclasses can call {@link #propertyChanged()} whenever the calculated - * value of the property changes (as determined by the subclass). - */ -public abstract class AbstractPropertyValueModelAdapter<V> - extends AbstractPropertyValueModel - implements PropertyValueModel<V> -{ - /** - * Cache the current value so we can pass an "old value" when - * we fire a property change event. - * We need this because the value may be calculated and we may - * not able to derive the "old value" from any fired events. - */ - protected V value; - - - // ********** constructor/initialization ********** - - protected AbstractPropertyValueModelAdapter() { - super(); - // our value is null when we are not listening to the model - this.value = null; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the cached value. - */ - public V getValue() { - return this.value; - } - - - // ********** behavior ********** - - /** - * Start listening to the model and build the value. - */ - @Override - protected void engageModel() { - this.engageModel_(); - // synch our value *after* we start listening to the model, - // since the model's value might change when a listener is added - this.value = this.buildValue(); - } - - /** - * Start listening to the model. - */ - protected abstract void engageModel_(); - - /** - * Build and return the current value, as derived from the - * current state of the underlying model. - */ - protected abstract V buildValue(); - - /** - * Stop listening to the model and clear the value. - */ - @Override - protected void disengageModel() { - this.disengageModel_(); - // clear out our value when we are not listening to the model - this.value = null; - } - - /** - * Stop listening to the model. - */ - protected abstract void disengageModel_(); - - /** - * The underlying model changed in some fashion. - * Recalculate the value and notify any listeners. - */ - protected void propertyChanged() { - Object old = this.value; - this.firePropertyChanged(VALUE, old, this.value = this.buildValue()); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.value); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractTreeNodeValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractTreeNodeValueModel.java deleted file mode 100644 index 657676e34d..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AbstractTreeNodeValueModel.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; -import java.util.List; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterators.ChainIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.TreeNodeValueModel; - -/** - * Subclasses need only implement the following methods: - * - * #value() - * return the user-determined "value" of the node, - * i.e. the object "wrapped" by the node - * - * #setValue(Object) - * set the user-determined "value" of the node, - * i.e. the object "wrapped" by the node; - * typically only overridden for nodes with "primitive" values - * - * #parent() - * return the parent of the node, which should be another - * TreeNodeValueModel - * - * #childrenModel() - * return a ListValueModel for the node's children - * - * #engageValue() and #disengageValue() - * override these methods to listen to the node's value if - * it can change in a way that should be reflected in the tree - */ -public abstract class AbstractTreeNodeValueModel<T> - extends AbstractModel - implements TreeNodeValueModel<T> -{ - - - // ********** constructors ********** - - /** - * Default constructor. - */ - protected AbstractTreeNodeValueModel() { - super(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - // this model fires *both* "value property change" and "state change" events... -// return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE); - return super.buildChangeSupport(); - } - - - // ********** extend AbstractModel implementation ********** - - /** - * Clients should be adding both "state change" and "value property change" - * listeners. - */ - @Override - public void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoStateChangeListeners()) { - this.engageValue(); - } - super.addStateChangeListener(listener); - } - - /** - * Begin listening to the node's value's state. If the state of the node changes - * in a way that should be reflected in the tree, fire a "state change" event. - */ - protected abstract void engageValue(); - - /** - * @see #addStateChangeListener(StateChangeListener) - */ - @Override - public void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoStateChangeListeners()) { - this.disengageValue(); - } - } - - /** - * Stop listening to the node's value. - * @see #engageValue() - */ - protected abstract void disengageValue(); - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - throw new UnsupportedOperationException(); - } - - - // ********** TreeNodeValueModel implementation ********** - - @SuppressWarnings("unchecked") - public TreeNodeValueModel<T>[] path() { - List<TreeNodeValueModel<T>> path = CollectionTools.reverseList(this.backPath()); - return path.toArray(new TreeNodeValueModel[path.size()]); - } - - /** - * Return an iterator that climbs up the node's path, - * starting with, and including, the node - * and up to, and including, the root node. - */ - protected Iterator<TreeNodeValueModel<T>> backPath() { - return new ChainIterator<TreeNodeValueModel<T>>(this) { - @Override - protected TreeNodeValueModel<T> nextLink(TreeNodeValueModel<T> currentLink) { - return currentLink.parent(); - } - }; - } - - public TreeNodeValueModel<T> child(int index) { - return this.childrenModel().get(index); - } - - public int childrenSize() { - return this.childrenModel().size(); - } - - public int indexOfChild(TreeNodeValueModel<T> child) { - ListValueModel<TreeNodeValueModel<T>> children = this.childrenModel(); - int size = children.size(); - for (int i = 0; i < size; i++) { - if (children.get(i) == child) { - return i; - } - } - return -1; - } - - public boolean isLeaf() { - return this.childrenModel().size() == 0; - } - - - // ********** standard methods ********** - - /** - * We implement #equals(Object) so that TreePaths containing these nodes - * will resolve properly when the nodes contain the same values. This is - * necessary because nodes are dropped and rebuilt willy-nilly when dealing - * with a sorted list of children; and this allows us to save and restore - * a tree's expanded paths. The nodes in the expanded paths that are - * saved before any modification (e.g. renaming a node) will be different - * from the nodes in the tree's paths after the modification, if the modification - * results in a possible change in the node sort order. ~bjv - */ - @Override - public boolean equals(Object o) { - if (o == null) { - return false; - } - if (o.getClass() != this.getClass()) { - return false; - } - @SuppressWarnings("unchecked") - AbstractTreeNodeValueModel<T> other = (AbstractTreeNodeValueModel<T>) o; - return this.getValue().equals(other.getValue()); - } - - @Override - public int hashCode() { - return this.getValue().hashCode(); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectAdapter.java deleted file mode 100644 index 99f17918c3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectAdapter.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.EventListener; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This abstract extension of {@link AbstractModel} provides a base for adding - * change listeners (property change, collection change, list change, tree change) - * to a subject and converting the subject's change notifications into a single - * set of change notifications for a common aspect (e.g. <code>VALUE</code>). - * <p> - * 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 - * garbage collected when appropriate - */ -public abstract class AspectAdapter<S> - extends AbstractModel -{ - /** - * The subject that holds the aspect and fires - * change notification when the aspect changes. - * We need to hold on to this directly so we can - * disengage it when it changes. - */ - protected S subject; - - /** - * A value model that holds the subject - * that holds the aspect and provides change notification. - * This is useful when there are a number of aspect adapters - * that have the same subject and that subject can change. - * All the aspect adapters should share the same subject holder. - * For now, this is can only be set upon construction and is - * immutable. - */ - protected final PropertyValueModel<? extends S> subjectHolder; - - /** A listener that keeps us in synch with the subject holder. */ - protected final PropertyChangeListener subjectChangeListener; - - - // ********** constructors ********** - - /** - * Construct an aspect adapter for the specified subject. - */ - protected AspectAdapter(S subject) { - this(new StaticPropertyValueModel<S>(subject)); - } - - /** - * Construct an aspect adapter for the specified subject holder. - * The subject holder cannot be null. - */ - protected AspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(); - if (subjectHolder == null) { - 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; - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new LocalChangeSupport(this, this.getListenerClass(), this.getListenerAspectName()); - } - - /** - * The subject holder's value has changed, keep our subject in synch. - */ - protected PropertyChangeListener buildSubjectChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - AspectAdapter.this.subjectChanged(); - } - @Override - public String toString() { - return "subject change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * The subject has changed. Notify listeners that the value has changed. - */ - protected synchronized void subjectChanged() { - Object oldValue = this.getValue(); - boolean hasListeners = this.hasListeners(); - if (hasListeners) { - this.disengageSubject(); - } - this.subject = this.subjectHolder.getValue(); - if (hasListeners) { - this.engageSubject(); - this.fireAspectChanged(oldValue, this.getValue()); - } - } - - /** - * Return the aspect's current value. - */ - protected abstract Object getValue(); - - /** - * Return the class of listener that is interested in the aspect adapter's - * changes. - */ - protected abstract Class<? extends EventListener> getListenerClass(); - - /** - * 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 getListenerAspectName(); - - /** - * Return whether there are any listeners for the aspect. - */ - protected abstract boolean hasListeners(); - - /** - * Return whether there are no listeners for the aspect. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * The aspect has changed, notify listeners appropriately. - */ - protected abstract void fireAspectChanged(Object oldValue, Object newValue); - - protected void engageSubject() { - // check for nothing to listen to - if (this.subject != null) { - this.engageSubject_(); - } - } - - /** - * The subject is not null - add our listener. - */ - protected abstract void engageSubject_(); - - protected void disengageSubject() { - // check for nothing to listen to - if (this.subject != null) { - this.disengageSubject_(); - } - } - - /** - * The subject is not null - remove our listener. - */ - protected abstract void disengageSubject_(); - - protected void engageSubjectHolder() { - this.subjectHolder.addPropertyChangeListener(PropertyValueModel.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.getValue(); - } - - protected void disengageSubjectHolder() { - this.subjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener); - // clear out the subject when we are not listening to its holder - this.subject = null; - } - - protected void engageModels() { - this.engageSubjectHolder(); - this.engageSubject(); - } - - protected void disengageModels() { - this.disengageSubject(); - this.disengageSubjectHolder(); - } - - - // ********** local change support ********** - - /** - * 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 and aspect or a - * general-purpose listener. - */ - protected class LocalChangeSupport extends SingleAspectChangeSupport { - private static final long serialVersionUID = 1L; - - public LocalChangeSupport(AspectAdapter<S> source, Class<? extends EventListener> validListenerClass, String validAspectName) { - super(source, validListenerClass, validAspectName); - } - - protected boolean hasNoListeners() { - return this.hasNoListeners(this.validListenerClass, this.validAspectName); - } - - - // ********** overrides ********** - - @Override - protected synchronized <T extends EventListener> void addListener(Class<T> listenerClass, T listener) { - if (this.hasNoListeners()) { - AspectAdapter.this.engageModels(); - } - super.addListener(listenerClass, listener); - } - - @Override - protected synchronized <T extends EventListener> void addListener(Class<T> listenerClass, String aspectName, T listener) { - if (this.hasNoListeners()) { - AspectAdapter.this.engageModels(); - } - super.addListener(listenerClass, aspectName, listener); - } - - @Override - protected synchronized <T extends EventListener> void removeListener(Class<T> listenerClass, T listener) { - super.removeListener(listenerClass, listener); - if (this.hasNoListeners()) { - AspectAdapter.this.disengageModels(); - } - } - - @Override - protected synchronized <T extends EventListener> void removeListener(Class<T> listenerClass, String aspectName, T listener) { - super.removeListener(listenerClass, aspectName, listener); - if (this.hasNoListeners()) { - AspectAdapter.this.disengageModels(); - } - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectCollectionValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectCollectionValueModelAdapter.java deleted file mode 100644 index 9c7f316629..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectCollectionValueModelAdapter.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Collection; -import java.util.EventListener; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This {@link AspectAdapter} provides basic collection change support. - * This converts an "aspect" (as defined by subclasses) into - * a single {@link #VALUES} collection. - * <p> - * The typical subclass will override the following methods:<ul> - * <li>{@link #engageSubject_()}<p> - * implement this method to add the appropriate listener to the subject - * <li>{@link #disengageSubject_()}<p> - * implement this method to remove the appropriate listener from the subject - * <li>{@link #getIterable()}<p> - * at the very minimum, override this method to return an iterable containing the - * subject's collection aspect; it does not need to be overridden if either - * {@link #iterator_()} or {@link #iterator()} is overridden and its behavior changed - * <li>{@link #size_()}<p> - * override this method to improve performance; it does not need to be overridden if - * {@link #size()} is overridden and its behavior changed - * <li>{@link #iterator_()}<p> - * override this method to return an iterator on the - * subject's collection aspect if it is not possible to implement {@link #getIterable()}; - * it does not need to be overridden if - * {@link #iterator()} is overridden and its behavior changed - * <li>{@link #iterator()}<p> - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - * <li>{@link #size()}<p> - * override this method only if returning a zero when the - * subject is null is unacceptable - * </ul> - * To notify listeners, subclasses can call {@link #collectionChanged()} - * whenever the aspect has changed. - */ -public abstract class AspectCollectionValueModelAdapter<S, E> - extends AspectAdapter<S> - implements CollectionValueModel<E> -{ - - // ********** constructors ********** - - /** - * Construct a collection value model adapter for an aspect of the - * specified subject. - */ - protected AspectCollectionValueModelAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - } - - - // ********** CollectionValueModel implementation ********** - - /** - * Return the elements of the subject's collection aspect. - */ - public Iterator<E> iterator() { - return (this.subject == null) ? EmptyIterator.<E>instance() : this.iterator_(); - } - - /** - * Return the elements of the subject's collection aspect. - * At this point we can be sure the subject is not null. - * @see #iterator() - */ - protected Iterator<E> iterator_() { - return this.getIterable().iterator(); - } - - /** - * Return the elements of the subject's collection aspect. - * At this point we can be sure the subject is not null. - * @see #iterator_() - */ - protected Iterable<E> getIterable() { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - /** - * Return the size of the subject's collection aspect. - */ - public int size() { - return (this.subject == null) ? 0 : this.size_(); - } - - /** - * Return the size of the subject's collection aspect. - * At this point we can be sure the subject is not null. - * @see #size() - */ - protected int size_() { - return CollectionTools.size(this.iterator()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.buildValueCollection(); - } - - @Override - protected Class<? extends EventListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - @SuppressWarnings("unchecked") Collection<E> newCollection = (Collection<E>) newValue; - this.fireCollectionChanged(VALUES, newCollection); - } - - protected void collectionChanged() { - this.fireCollectionChanged(VALUES, this.buildValueCollection()); - } - - protected Collection<E> buildValueCollection() { - return CollectionTools.collection(this.iterator()); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.buildValueCollection()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectListValueModelAdapter.java deleted file mode 100644 index 41d36a066c..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectListValueModelAdapter.java +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.EventListener; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.ArrayTools; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This {@link AspectAdapter} provides basic list change support. - * This converts an "aspect" (as defined by subclasses) into - * a single {@link #LIST_VALUES} list. - * <p> - * The typical subclass will override the following methods:<ul> - * <li>{@link #engageSubject_()}<p> - * implement this method to add the appropriate listener to the subject - * <li>{@link #disengageSubject_()}<p> - * implement this method to remove the appropriate listener from the subject - * <li>{@link #getListIterable()}<p> - * at the very minimum, override this method to return a list iterable containing the - * subject's list aspect; it does not need to be overridden if either - * {@link #listIterator_()} or {@link #listIterator()} is overridden and its behavior changed - * <li>{@link #get(int)}<p> - * override this method to improve performance - * <li>{@link #size_()}<p> - * override this method to improve performance; it does not need to be overridden if - * {@link #size()} is overridden and its behavior changed - * <li>{@link #toArray_()}<p> - * override this method to improve performance; it does not need to be overridden if - * {@link #toArray()} is overridden and its behavior changed - * <li>{@link #listIterator_()}<p> - * override this method to return a list iterator on the subject's list - * aspect if it is not possible to implement {@link #getListIterable()}; - * it does not need to be overridden if - * {@link #listIterator()} is overridden and its behavior changed - * <li>{@link #listIterator()}<p> - * override this method only if returning an empty list iterator when the - * subject is null is unacceptable - * <li>{@link #size()}<p> - * override this method only if returning a zero when the - * subject is null is unacceptable - * <li>{@link #toArray()}<p> - * override this method only if returning an empty array when the - * subject is null is unacceptable - * </ul> - * To notify listeners, subclasses can call {@link #listChanged()} - * whenever the aspect has changed. - */ -public abstract class AspectListValueModelAdapter<S, E> - extends AspectAdapter<S> - implements ListValueModel<E> -{ - private static final Object[] EMPTY_ARRAY = new Object[0]; - - - // ********** constructors ********** - - /** - * Construct a list value model adapter for an aspect of the - * specified subject. - */ - protected AspectListValueModelAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - } - - - // ********** ListValueModel implementation ********** - - /** - * Return the elements of the subject's list aspect. - */ - public ListIterator<E> iterator() { - return this.listIterator(); - } - - /** - * Return the elements of the subject's list aspect. - */ - public ListIterator<E> listIterator() { - return (this.subject == null) ? EmptyListIterator.<E>instance() : this.listIterator_(); - } - - /** - * Return the elements of the subject's list aspect. - * At this point we can be sure the subject is not null. - * @see #listIterator() - */ - protected ListIterator<E> listIterator_() { - return this.getListIterable().iterator(); - } - - /** - * Return the elements of the subject's list aspect. - * At this point we can be sure the subject is not null. - * @see #listIterator_() - */ - protected ListIterable<E> getListIterable() { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - /** - * Return the element at the specified index of the subject's list aspect. - */ - public E get(int index) { - return CollectionTools.get(this.listIterator(), index); - } - - /** - * Return the size of the subject's list aspect. - */ - public int size() { - return this.subject == null ? 0 : this.size_(); - } - - /** - * Return the size of the subject's list aspect. - * At this point we can be sure the subject is not null. - * @see #size() - */ - protected int size_() { - return CollectionTools.size(this.listIterator()); - } - - /** - * Return an array manifestation of the subject's list aspect. - */ - public Object[] toArray() { - return this.subject == null ? EMPTY_ARRAY : this.toArray_(); - } - - /** - * Return an array manifestation of the subject's list aspect. - * At this point we can be sure the subject is not null. - * @see #toArray() - */ - protected Object[] toArray_() { - return ArrayTools.array(this.listIterator(), this.size()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected List<E> getValue() { - return this.buildValueList(); - } - - @Override - protected Class<? extends EventListener> getListenerClass() { - return ListChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return LIST_VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - @SuppressWarnings("unchecked") List<E> newList = (List<E>) newValue; - this.fireListChanged(LIST_VALUES, newList); - } - - protected void listChanged() { - this.fireListChanged(LIST_VALUES, this.buildValueList()); - } - - protected List<E> buildValueList() { - return CollectionTools.list(this.iterator()); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.buildValueList()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectPropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectPropertyValueModelAdapter.java deleted file mode 100644 index 180153a586..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectPropertyValueModelAdapter.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.EventListener; - -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This {@link AspectAdapter} provides basic property change support. - * This converts an "aspect" (as defined by subclasses) into - * a single {@link #VALUE} property. - * <p> - * The typical subclass will override the following methods:<ul> - * <li>{@link #engageSubject_()}<p> - * implement this method to add the appropriate listener to the subject - * <li>{@link #disengageSubject_()}<p> - * implement this method to remove the appropriate listener from the subject - * <li>{@link #buildValue_()}<p> - * at the very minimum, override this method to return the value of the - * subject's aspect (or "virtual" aspect); it does not need to be - * overridden if {@link #buildValue()} is overridden and its behavior changed - * <li>{@link #setValue_(Object)}<p> - * override this method if the client code needs to <em>set</em> the value of - * the subject's aspect; oftentimes, though, the client code (e.g. UI) - * will need only to <em>get</em> the value; it does not need to be - * overridden if {@link #setValue(Object)} is overridden and its behavior changed - * <li>{@link #buildValue()}<p> - * override this method only if returning a <code>null</code> value when - * the subject is <code>null</code> is unacceptable - * <li>{@link #setValue(Object)}<p> - * override this method only if something must be done when the subject - * is <code>null</code> (e.g. throw an exception) - * </ul> - * To notify listeners, subclasses can call {@link #propertyChanged()} - * whenever the aspect has changed. - */ -public abstract class AspectPropertyValueModelAdapter<S, V> - extends AspectAdapter<S> - implements WritablePropertyValueModel<V> -{ - /** - * Cache the current value of the aspect so we - * can pass an "old value" when we fire a property change event. - * We need this because the value may be calculated and may - * not be in the property change event fired by the subject, - * especially when dealing with multiple aspects. - */ - protected V value; - - - // ********** constructors ********** - - /** - * Construct a property value model adapter for an aspect of the - * specified subject. - */ - protected AspectPropertyValueModelAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - // our value is null when we are not listening to the subject - this.value = null; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the value of the subject's aspect. - */ - @Override - public final V getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - /** - * Set the value of the subject's aspect. - */ - public void setValue(V value) { - if (this.subject != null) { - this.setValue_(value); - } - } - - /** - * Set the value of the subject's aspect. - * At this point we can be sure the subject is not null. - * @see #setValue(Object) - */ - protected void setValue_(@SuppressWarnings("unused") V value) { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends EventListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - @Override - protected void engageSubject() { - super.engageSubject(); - // synch our value *after* we start listening to the subject, - // since its value might change when a listener is added - this.value = this.buildValue(); - } - - @Override - protected void disengageSubject() { - super.disengageSubject(); - // clear out our value when we are not listening to the subject - this.value = null; - } - - - // ********** behavior ********** - - /** - * Return the aspect's value. - * At this point the subject may be null. - */ - protected V buildValue() { - return (this.subject == null) ? null : this.buildValue_(); - } - - /** - * Return the value of the subject's aspect. - * At this point we can be sure the subject is not null. - * @see #buildValue() - */ - protected V buildValue_() { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - /** - * This method can be called by subclasses whenever the subject's aspect - * has changed; listeners will be notified appropriately. - */ - protected void propertyChanged() { - V old = this.value; - this.value = this.buildValue(); - this.fireAspectChanged(old, this.value); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.value); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectTreeValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectTreeValueModelAdapter.java deleted file mode 100644 index 6989991744..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/AspectTreeValueModelAdapter.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Collection; -import java.util.EventListener; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.TreeValueModel; - -/** - * This {@link AspectAdapter} provides basic tree change support. - * This converts an "aspect" (as defined by subclasses) into - * a single {@link #NODES} tree. - * <p> - * The typical subclass will override the following methods:<ul> - * <li>{@link #engageSubject_()}<p> - * implement this method to add the appropriate listener to the subject - * <li>{@link #disengageSubject_()}<p> - * implement this method to remove the appropriate listener from the subject - * <li>{@link #nodes_()}<p> - * at the very minimum, override this method to return an iterator - * on the subject's tree aspect; it does not need to be overridden if - * {@link #nodes()} is overridden and its behavior changed - * <li>{@link #nodes()}<p> - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - * </ul> - * To notify listeners, subclasses can call {@link #treeChanged()} - * whenever the aspect has changed. - */ -public abstract class AspectTreeValueModelAdapter<S, E> - extends AspectAdapter<S> - implements TreeValueModel<E> -{ - - // ********** constructors ********** - - /** - * Construct a tree value model adapter for an aspect of the - * specified subject. - */ - protected AspectTreeValueModelAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - } - - - // ********** TreeValueModel implementation ********** - - /** - * Return the nodes of the subject's tree aspect. - */ - public Iterator<E> nodes() { - return (this.subject == null) ? EmptyIterator.<E>instance() : this.nodes_(); - } - - /** - * Return the nodes of the subject's tree aspect. - * At this point we can be sure the subject is not null. - * @see #nodes() - */ - protected Iterator<E> nodes_() { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.buildValueCollection(); - } - - @Override - protected Class<? extends EventListener> getListenerClass() { - return TreeChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return NODES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyTreeChangeListeners(NODES); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - @SuppressWarnings("unchecked") Collection<E> newNodes = (Collection<E>) newValue; - this.fireTreeChanged(NODES, newNodes); - } - - protected void treeChanged() { - this.fireTreeChanged(NODES, this.buildValueCollection()); - } - - protected Collection<E> buildValueCollection() { - return CollectionTools.collection(this.nodes()); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.buildValueCollection()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BufferedWritablePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BufferedWritablePropertyValueModel.java deleted file mode 100644 index 87d191ca6a..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BufferedWritablePropertyValueModel.java +++ /dev/null @@ -1,392 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>BufferedWritablePropertyValueModel</code> is used to hold a temporary copy of the value - * in another property value model (the "wrapped" value holder). The application - * can modify this temporary copy, ad nauseam; but the temporary copy is only - * passed through to the "wrapped" value holder when the trigger "accepts" the - * buffered value. Alternatively, the application can "reset" the buffered value - * to the original, "wrapped" value. - * <p> - * The trigger is another {@link PropertyValueModel} that holds a {@link Boolean} - * and the application changes the trigger's value to true on "accept", false on "reset". - * Typically, in a dialog:<ul> - * <li>pressing the "OK" button will trigger an "accept" and close the dialog - * <li>pressing the "Cancel" button will simply close the dialog, - * dropping the "buffered" values into the bit bucket - * <li>pressing the "Apply" button will trigger an "accept" and leave the dialog open - * <li>pressing the "Restore" button will trigger a "reset" and leave the dialog open - * </ul> - * <p> - * A number of buffered property value models can wrap another set of - * property aspect adapters that adapt the various aspects of a single - * domain model. All the bufferd property value models can be hooked to the - * same trigger, and that trigger is controlled by the application, typically - * via the OK button in a dialog. - * - * @see PropertyAspectAdapter - */ -public class BufferedWritablePropertyValueModel<T> - extends PropertyValueModelWrapper<T> - implements WritablePropertyValueModel<T> -{ - - /** - * We cache the value here until it is accepted and passed - * through to the wrapped value holder. - */ - protected T bufferedValue; - - /** - * This is set to true when we are "accepting" the buffered value - * and passing it through to the wrapped value holder. This allows - * us to ignore the property change event fired by the wrapped - * value holder. - * (We can't stop listening to the wrapped value holder, because - * if we are the only listener that could "deactivate" the wrapped - * value holder.) - */ - protected boolean accepting; - - /** - * This is the trigger that indicates whether the buffered value - * should be accepted or reset. - */ - protected final PropertyValueModel<Boolean> triggerHolder; - - /** This listens to the trigger holder. */ - protected final PropertyChangeListener triggerChangeListener; - - /** - * This flag indicates whether our buffered value has been assigned - * a value and is possibly out of synch with the wrapped value. - */ - protected boolean buffering; - - - // ********** constructors ********** - - /** - * Construct a buffered property value model with the specified wrapped - * property value model and trigger holder. - */ - public BufferedWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, PropertyValueModel<Boolean> triggerHolder) { - super(valueHolder); - if (triggerHolder == null) { - throw new NullPointerException(); - } - this.triggerHolder = triggerHolder; - this.bufferedValue = null; - this.buffering = false; - this.accepting = false; - this.triggerChangeListener = this.buildTriggerChangeListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildTriggerChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - BufferedWritablePropertyValueModel.this.triggerChanged(event); - } - @Override - public String toString() { - return "trigger change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ValueModel implementation ********** - - /** - * If we are currently "buffering" a value, return that; - * otherwise, return the wrapped value. - */ - public T getValue() { - return this.buffering ? this.bufferedValue : this.valueHolder.getValue(); - } - - /** - * Assign the new value to our "buffered" value. - * It will be pushed to the wrapped value holder - * when the trigger is "accepted". - */ - public void setValue(T value) { - if (this.buffering) { - if (this.valuesAreEqual(value, this.valueHolder.getValue())) { - // the buffered value is being set back to the original value - this.reset(); - } else { - // the buffered value is being changed - Object old = this.bufferedValue; - this.bufferedValue = value; - this.firePropertyChanged(VALUE, old, value); - } - } else { - if (this.valuesAreEqual(value, this.valueHolder.getValue())) { - // the buffered value is being set to the same value as the original value - ignore - } else { - // the buffered value is being set for the first time - Object old = this.valueHolder.getValue(); - this.bufferedValue = value; - this.buffering = true; - this.firePropertyChanged(VALUE, old, value); - } - } - } - - - // ********** PropertyValueModelWrapper extensions ********** - - /** - * extend to engage the trigger holder also - */ - @Override - protected void engageModel() { - super.engageModel(); - this.triggerHolder.addPropertyChangeListener(VALUE, this.triggerChangeListener); - } - - /** - * extend to disengage the trigger holder also - */ - @Override - protected void disengageModel() { - this.triggerHolder.removePropertyChangeListener(VALUE, this.triggerChangeListener); - super.disengageModel(); - } - - - // ********** behavior ********** - - /** - * If we are currently "accepting" the value (i.e passing it on to the - * "wrapped" model), ignore change notifications, since we caused - * them and our own listeners are already aware of the change. - */ - @Override - protected void valueChanged(PropertyChangeEvent event) { - if ( ! this.accepting) { - this.valueChanged_(event); - } - } - - /** - * If we have a "buffered" value, check whether the "wrapped" value has - * changed to be the same as the "buffered" value. If it has, stop "buffering"; - * if not, do nothing. - * If we do not yet have a "buffered" value, simply propagate the - * change notification with the buffered model as the source. - */ - protected void valueChanged_(PropertyChangeEvent event) { - if (this.buffering) { - if (this.valuesAreEqual(event.getNewValue(), this.bufferedValue)) { - // the buffered value is being set back to the original value - this.reset(); - } else { - this.handleChangeConflict(event); - } - } else { - this.firePropertyChanged(event.clone(this)); - } - } - - /** - * By default, if we have a "buffered" value and the "wrapped" value changes, - * we simply ignore the new "wrapped" value and simply overlay it with the - * "buffered" value if it is "accepted". ("Last One In Wins" concurrency model) - * Subclasses can override this method to change that behavior with a - * different concurrency model. For example, you could drop the "buffered" value - * and replace it with the new "wrapped" value, or you could throw an - * exception. - */ - protected void handleChangeConflict(@SuppressWarnings("unused") PropertyChangeEvent event) { - // the default is to do nothing - } - - /** - * The trigger changed:<ul> - * <li>If it is now true, "accept" the buffered value and push - * it to the wrapped value holder. - * <li>If it is now false, "reset" the buffered value to its original value. - * </ul> - */ - protected void triggerChanged(PropertyChangeEvent event) { - // if nothing has been "buffered", we don't need to do anything: - // nothing needs to be passed through; nothing needs to be reset; - if (this.buffering) { - if (((Boolean) event.getNewValue()).booleanValue()) { - this.accept(); - } else { - this.reset(); - } - } - } - - protected void accept() { - // set the accepting flag so we ignore any events - // fired by the wrapped value holder - this.accepting = true; - try { - this.getValueHolder().setValue(this.bufferedValue); - } finally { - this.bufferedValue = null; - this.buffering = false; - // clear the flag once the "accept" is complete - this.accepting = false; - } - } - - protected void reset() { - // notify our listeners that our value has been reset - Object old = this.bufferedValue; - this.bufferedValue = null; - this.buffering = false; - this.firePropertyChanged(VALUE, old, this.valueHolder.getValue()); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - - - // ********** convenience methods ********** - - /** - * Return whether the buffered model is currently "buffering" - * a value. - */ - public boolean isBuffering() { - return this.buffering; - } - - /** - * Our constructor accepts only a {@link WritablePropertyValueModel}{@code<T>}. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> getValueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - - // ********** inner class ********** - - /** - * <code>Trigger</code> is a special property value model that only maintains its - * value (of <code>true</code> or <code>false</code>) during the change notification caused by - * {@link #setValue(T)}. In other words, a <code>Trigger</code> - * only has a valid value when it is being set. - */ - public static class Trigger extends SimplePropertyValueModel<Boolean> { - - - // ********** constructor ********** - - /** - * Construct a trigger with a null value. - */ - public Trigger() { - super(); - } - - - // ********** ValueModel implementation ********** - - /** - * Extend so that this method can only be invoked during - * change notification triggered by {@link #setValue(Object)}. - */ - @Override - public Boolean getValue() { - if (this.value == null) { - throw new IllegalStateException("The method Trigger.getValue() may only be called during change notification."); //$NON-NLS-1$ - } - return this.value; - } - - /** - * Extend to reset the value to <code>null</code> once all the - * listeners have been notified. - */ - @Override - public void setValue(Boolean value) { - super.setValue(value); - this.value = null; - } - - - // ********** convenience methods ********** - - /** - * Set the trigger's value:<ul> - * <li><code>true</code> indicates "accept" - * <li><code>false</code> indicates "reset" - * </ul> - */ - public void setValue(boolean value) { - this.setValue(Boolean.valueOf(value)); - } - - /** - * Return the trigger's value:<ul> - * <li><code>true</code> indicates "accept" - * <li><code>false</code> indicates "reset" - * </ul> - * This method can only be invoked during change notification. - */ - public boolean booleanValue() { - return this.getValue().booleanValue(); - } - - /** - * Accept the trigger (i.e. set its value to <code>true</code>). - */ - public void accept() { - this.setValue(true); - } - - /** - * Return whether the trigger has been accepted - * (i.e. its value was changed to <code>true</code>). - * This method can only be invoked during change notification. - */ - public boolean isAccepted() { - return this.booleanValue(); - } - - /** - * Reset the trigger (i.e. set its value to <code>false</code>). - */ - public void reset() { - this.setValue(false); - } - - /** - * Return whether the trigger has been reset - * (i.e. its value was changed to <code>false</code>). - * This method can only be invoked during change notification. - */ - public boolean isReset() { - return ! this.booleanValue(); - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationPropertyValueModel.java deleted file mode 100644 index c62e6853bf..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationPropertyValueModel.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.Transformer; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A <code>CachingTransformationPropertyValueModel</code> wraps another - * {@link PropertyValueModel} and uses a {@link Transformer} - * to transform the wrapped value before it is returned by {@link #getValue()}. - * The transformed value is calculated and cached during initialization and every - * time the wrapped value changes. This can be useful when the old value - * passed in to {@link #valueChanged(org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent)} - * can no longer be "transformed" because its state is no longer valid. - * This caching can also improve time performance in some situations. - * <p> - * As an alternative to building a {@link Transformer}, - * a subclass of <code>CachingTransformationPropertyValueModel</code> can - * either override {@link #transform_(Object)} or, - * if something other than null should be returned when the wrapped value - * is null, override {@link #transform(Object)}. - */ -public class CachingTransformationPropertyValueModel<T1, T2> - extends TransformationPropertyValueModel<T1, T2> -{ - /** - * Cache the transformed value so that during property change event notification - * we do not have to transform the old value. The old value could no longer be valid in - * the model; as a result, transforming it would not be valid. - */ - protected T2 cachedValue; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified nested - * property value model and the default transformer. - * Use this constructor if you want to override - * {@link #transform_(Object)} or {@link #transform(Object)} - * instead of building a {@link Transformer}. - */ - public CachingTransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct an property value model with the specified nested - * property value model and transformer. - */ - public CachingTransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder, Transformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - - // ********** behavior ********** - - /** - * We have listeners, transform the nested value and cache the result. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.cachedValue = this.transform(this.valueHolder.getValue()); - } - - /** - * We have no more listeners, clear the cached value. - */ - @Override - protected void disengageModel() { - this.cachedValue = null; - super.disengageModel(); - } - - /** - * No need to transform the nested value, simply return the cached value, - * which is already transformed. - */ - @Override - public T2 getValue() { - return this.cachedValue; - } - - /** - * Transform the specified new value, caching it before returning it. - * A bit of a side-effect, but it seems reasonable. - */ - @Override - protected T2 transformNew(T1 value) { - this.cachedValue = super.transformNew(value); - return this.cachedValue; - } - - /** - * No need to transform the old value, simply return the cached value, - * which is already transformed. - */ - @Override - protected T2 transformOld(T1 value) { - return this.cachedValue; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java deleted file mode 100644 index 1560367c3e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.BidiTransformer; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>CachingTransformationWritablePropertyValueModel<code> augments the - * behavior of a {@link TransformationWritablePropertyValueModel} by caching - * the transformed value. - * The transformed value is calculated and cached during initialization and every - * time the wrapped value changes. This can be useful when the old value - * passed in to {@link #valueChanged(org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent)} - * can no longer be "transformed" because its state is no longer valid. - * This caching can also improve time performance in some situations. - */ -public class CachingTransformationWritablePropertyValueModel<T1, T2> - extends TransformationWritablePropertyValueModel<T1, T2> -{ - /** - * Cache the transformed value so that during property change event notification - * we do not have to transform the old value. The old value could no longer be valid in - * the model; as a result, transforming it would not be valid. - */ - protected T2 cachedValue; - - - // ********** constructors/initialization ********** - - /** - * Construct a writable property value model with the specified nested - * writable property value model and the default bidi transformer. - * Use this constructor if you want to override - * {@link #transform_(Object)} and {@link reverseTransform_(Object)} - * (or {@link #transform(Object)} and {@link #reverseTransform(Object)}) - * methods instead of building a {@link BidiTransformer}. - */ - public CachingTransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct a writable property value model with the specified nested - * writable property value model and bidi transformer. - */ - public CachingTransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder, BidiTransformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - - // ********** behavior ********** - - /** - * We have listeners, transform the nested value and cache the result. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.cachedValue = this.transform(this.valueHolder.getValue()); - } - - /** - * We have no more listeners, clear the cached value. - */ - @Override - protected void disengageModel() { - this.cachedValue = null; - super.disengageModel(); - } - - /** - * No need to transform the nested value, simply return the cached value, - * which is already transformed. - */ - @Override - public T2 getValue() { - return this.cachedValue; - } - - /** - * Transform the specified new value, caching it before returning it. - * A bit of a side-effect, but it seems reasonable. - */ - @Override - protected T2 transformNew(T1 value) { - this.cachedValue = super.transformNew(value); - return this.cachedValue; - } - - /** - * No need to transform the old value, simply return the cached value, - * which is already transformed. - */ - @Override - protected T2 transformOld(T1 value) { - return this.cachedValue; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ChangePropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ChangePropertyValueModelAdapter.java deleted file mode 100644 index 56d8ddd85e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ChangePropertyValueModelAdapter.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.SimpleChangeListener; - -/** - * This abstract class provides the infrastructure needed to wrap - * a model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * <p> - * Subclasses must override:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current model - * </ul> - * Subclasses might want to override the following methods - * to improve performance (by not recalculating the value, if possible):<ul> - * <li>{@link #modelChanged(ChangeEvent event)} - * <li>{@link #buildChangeListener()} - * </ul> - */ -public abstract class ChangePropertyValueModelAdapter<T> - extends AbstractPropertyValueModelAdapter<T> -{ - /** The wrapped model. */ - protected final Model model; - - /** A listener that allows us to synch with changes to the wrapped collection holder. */ - protected final ChangeListener changeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped model. - */ - protected ChangePropertyValueModelAdapter(Model model) { - super(); - this.model = model; - this.changeListener = this.buildChangeListener(); - } - - protected ChangeListener buildChangeListener() { - return new SimpleChangeListener() { - @Override - protected void modelChanged(ChangeEvent event) { - ChangePropertyValueModelAdapter.this.modelChanged(event); - } - @Override - public String toString() { - return "change listener command"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the model. - */ - @Override - protected void engageModel_() { - this.model.addChangeListener(this.changeListener); - } - - /** - * Stop listening to the model. - */ - @Override - protected void disengageModel_() { - this.model.removeChangeListener(this.changeListener); - } - - - // ********** change support ********** - - /** - * The wrapped model has changed; - * propagate the change notification appropriately. - */ - protected void modelChanged(@SuppressWarnings("unused") ChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionAspectAdapter.java deleted file mode 100644 index b9a0cf9362..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionAspectAdapter.java +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This extension of {@link AspectCollectionValueModelAdapter} provides - * basic collection change support. - * This converts a set of one or more collections into - * a single {@link #VALUES} collection. - * <p> - * The typical subclass will override the following methods (see the descriptions - * in {@link AspectCollectionValueModelAdapter}):<ul> - * <li>{@link #getIterable()} - * <li>{@link #size_()} - * <li>{@link #iterator_()} - * <li>{@link #iterator()} - * <li>{@link #size()} - * </ul> - */ -public abstract class CollectionAspectAdapter<S extends Model, E> - extends AspectCollectionValueModelAdapter<S, E> -{ - /** - * The name of the subject's collections that we use for the value. - */ - protected final String[] collectionNames; - protected static final String[] EMPTY_COLLECTION_NAMES = new String[0]; - - /** A listener that listens to the subject's collection aspects. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructors ********** - - /** - * Construct a collection aspect adapter for the specified subject - * and collection. - */ - protected CollectionAspectAdapter(String collectionName, S subject) { - this(new String[] {collectionName}, subject); - } - - /** - * Construct a collection aspect adapter for the specified subject - * and collections. - */ - protected CollectionAspectAdapter(String[] collectionNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), collectionNames); - } - - /** - * Construct a collection aspect adapter for the specified subject holder - * and collections. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... collectionNames) { - super(subjectHolder); - this.collectionNames = collectionNames; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - /** - * Construct a collection aspect adapter for the specified subject holder - * and collections. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> collectionNames) { - this(subjectHolder, collectionNames.toArray(new String[collectionNames.size()])); - } - - /** - * Construct a collection aspect adapter for an "unchanging" collection in - * the specified subject. This is useful for a collection aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new collection. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_COLLECTION_NAMES); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildCollectionChangeListener() { - // transform the subject's collection change events into VALUES collection change events - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - CollectionAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - CollectionAspectAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - CollectionAspectAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionAspectAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener: " + Arrays.asList(CollectionAspectAdapter.this.collectionNames); //$NON-NLS-1$ - } - }; - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected void engageSubject_() { - for (String collectionName : this.collectionNames) { - ((Model) this.subject).addCollectionChangeListener(collectionName, this.collectionChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String collectionName : this.collectionNames) { - ((Model) this.subject).removeCollectionChangeListener(collectionName, this.collectionChangeListener); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(CollectionAddEvent event) { - this.fireItemsAdded(event.clone(this, VALUES)); - } - - protected void itemsRemoved(CollectionRemoveEvent event) { - this.fireItemsRemoved(event.clone(this, VALUES)); - } - - protected void collectionCleared(CollectionClearEvent event) { - this.fireCollectionCleared(event.clone(this, VALUES)); - } - - protected void collectionChanged(CollectionChangeEvent event) { - this.fireCollectionChanged(event.clone(this, VALUES)); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionListValueModelAdapter.java deleted file mode 100644 index 4c3d8b4cca..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionListValueModelAdapter.java +++ /dev/null @@ -1,217 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a {@link CollectionValueModel} behave like - * a read-only {@link ListValueModel}, sorta. - * <p> - * To maintain a reasonably consistent appearance to client code, we - * keep an internal list somewhat in synch with the wrapped collection. - * <p> - * <strong>NB:</strong> Since we only listen to the wrapped collection when we have - * listeners ourselves and we can only stay in synch with the wrapped - * collection while we are listening to it, results to various methods - * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, clients will also be listeners. - */ -public class CollectionListValueModelAdapter<E> - extends AbstractListValueModel - implements ListValueModel<E> -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<? extends E> collectionHolder; - - /** A listener that forwards any events fired by the collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - /** - * Our internal list, which holds the same elements as - * the wrapped collection, but keeps them in order. - */ - // we declare this an ArrayList so we can use #clone() and #ensureCapacity(int) - protected final ArrayList<E> list; - - - // ********** constructors ********** - - /** - * Wrap the specified collection value model. - */ - public CollectionListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - super(); - if (collectionHolder == null) { - throw new NullPointerException(); - } - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - this.list = new ArrayList<E>(collectionHolder.size()); - // postpone building the list and listening to the underlying collection - // until we have listeners ourselves... - } - - - // ********** initialization ********** - - /** - * The wrapped collection has changed, forward an equivalent - * list change event to our listeners. - */ - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - CollectionListValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - CollectionListValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - CollectionListValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.list); - } - - public E get(int index) { - return this.list.get(index); - } - - public int size() { - return this.list.size(); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - - // ********** behavior ********** - - @Override - protected void engageModel() { - 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(); - } - - @Override - protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - // clear out the list when we are not listening to the collection holder - this.list.clear(); - } - - protected void buildList() { - // if the new collection is empty, do nothing - int size = this.collectionHolder.size(); - if (size != 0) { - this.buildList(size); - } - } - - protected void buildList(int size) { - this.list.ensureCapacity(size); - for (E each : this.collectionHolder) { - this.list.add(each); - } - } - - protected void itemsAdded(CollectionAddEvent event) { - this.addItemsToList(this.indexToAddItems(), this.getItems(event), this.list, LIST_VALUES); - } - - protected int indexToAddItems() { - return this.list.size(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(CollectionAddEvent event) { - return (Iterable<E>) event.getItems(); - } - - protected void itemsRemoved(CollectionRemoveEvent event) { - this.removeItemsFromList(this.getItems(event), this.list, LIST_VALUES); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(CollectionRemoveEvent event) { - return (Iterable<E>) event.getItems(); - } - - protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) { - this.clearList(this.list, LIST_VALUES); - } - - /** - * synchronize our internal list with the wrapped collection - * and fire the appropriate events - */ - protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) { - int size = this.collectionHolder.size(); - if (size == 0) { - if (this.list.isEmpty()) { - // no change - } else { - this.clearList(this.list, LIST_VALUES); - } - } else { - if (this.list.isEmpty()) { - this.buildList(size); - this.fireItemsAdded(LIST_VALUES, 0, this.list); - } else { - this.synchronizeList(this.buildSyncList(), this.list, LIST_VALUES); - } - } - } - - protected Iterable<? extends E> buildSyncList() { - return this.collectionHolder; - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.list); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionPropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionPropertyValueModelAdapter.java deleted file mode 100644 index 24d18b27ab..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionPropertyValueModelAdapter.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a collection value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * <p> - * Subclasses must override:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current collection value - * </ul> - * Subclasses might want to override the following methods - * to improve performance (by not recalculating the value, if possible):<ul> - * <li>{@link #itemsAdded(CollectionAddEvent event)} - * <li>{@link #itemsRemoved(CollectionRemoveEvent event)} - * <li>{@link #collectionCleared(CollectionClearEvent event)} - * <li>{@link #collectionChanged(CollectionChangeEvent event)} - * </ul> - */ -public abstract class CollectionPropertyValueModelAdapter<V> - extends AbstractPropertyValueModelAdapter<V> -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<?> collectionModel; - - /** A listener that allows us to synch with changes to the wrapped collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * collection value model. - */ - protected CollectionPropertyValueModelAdapter(CollectionValueModel<?> collectionModel) { - super(); - this.collectionModel = collectionModel; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - CollectionPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - CollectionPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - CollectionPropertyValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the collection holder. - */ - @Override - protected void engageModel_() { - this.collectionModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - /** - * Stop listening to the collection holder. - */ - @Override - protected void disengageModel_() { - this.collectionModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(@SuppressWarnings("unused") CollectionAddEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were removed from the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected void itemsRemoved(@SuppressWarnings("unused") CollectionRemoveEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped collection holder was cleared; - * propagate the change notification appropriately. - */ - protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The value of the wrapped collection holder has changed; - * propagate the change notification appropriately. - */ - protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionValueModelWrapper.java deleted file mode 100644 index a791dcb3d3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CollectionValueModelWrapper.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another collection value model, "lazily" listen to it, and propagate - * its change notifications. Subclasses must implement the appropriate - * {@link CollectionValueModel}. - */ -public abstract class CollectionValueModelWrapper<E> - extends AbstractCollectionValueModel -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<? extends E> collectionHolder; - - /** A listener that allows us to synch with changes to the wrapped collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model. - */ - protected CollectionValueModelWrapper(CollectionValueModel<? extends E> collectionHolder) { - super(); - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - CollectionValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - CollectionValueModelWrapper.this.itemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - CollectionValueModelWrapper.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** AbstractCollectionValueModel implementation ********** - - /** - * Start listening to the collection holder. - */ - @Override - protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - /** - * Stop listening to the collection holder. - */ - @Override - protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - - // ********** helper methods ********** - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(CollectionAddEvent event) { - return (Iterable<E>) event.getItems(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(CollectionRemoveEvent event) { - return (Iterable<E>) event.getItems(); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(CollectionAddEvent event); - - /** - * Items were removed from the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(CollectionRemoveEvent event); - - /** - * The wrapped collection holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void collectionCleared(CollectionClearEvent event); - - /** - * The value of the wrapped collection holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void collectionChanged(CollectionChangeEvent event); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeBooleanPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeBooleanPropertyValueModel.java deleted file mode 100644 index acedc5ebb4..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeBooleanPropertyValueModel.java +++ /dev/null @@ -1,338 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Collection; - -import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A <code>CompositeBooleanPropertyValueModel</code> adapts a - * {@link CollectionValueModel} holding boolean {@link PropertyValueModel}s - * to a single boolean {@link PropertyValueModel}. The composite value is - * determined by the {@link CompositeBooleanPropertyValueModel.Adapter} provided - * at construction. Typically the composite will be either an AND or an OR of - * all the boolean values. - * <p> - * If there are <em>no</em> boolean {@link PropertyValueModel}s, the composite - * will return its default value; which, by default, is <code>null</code>. - * <p> - * <strong>NB:</strong> None of the wrapped boolean models can return a - * <code>null</code> value or this class will throw an exception. The assumption - * is that all the wrapped boolean models are configured with "default" values - * that determine the model's value (TRUE or FALSE) when <code>null</code>. - */ -public class CompositeBooleanPropertyValueModel - extends CompositePropertyValueModel<Boolean> -{ - /** - * Calculation of the model's value is delegated to this adapter. - */ - protected final Adapter adapter; - - /** - * The default setting for the composite boolean property value model; - * for when the underlying collection model is empty. - * The default [default value] is <code>null</code>. - */ - private final Boolean defaultValue; - - - // ********** AND factory methods ********** - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static CompositeBooleanPropertyValueModel and(PropertyValueModel<Boolean>... array) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, array); - } - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static CompositeBooleanPropertyValueModel and(Boolean defaultValue, PropertyValueModel<Boolean>... array) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, array); - } - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel and(Collection<E> collection) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, collection); - } - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel and(Boolean defaultValue, Collection<E> collection) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, collection); - } - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static CompositeBooleanPropertyValueModel and(CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, collectionModel); - } - - /** - * Construct a boolean property value model that is a composite AND of the - * specified boolean property value models; i.e. the model's value is true - * if all the contained models are true, otherwise its value is false. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static CompositeBooleanPropertyValueModel and(Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, collectionModel); - } - - - // ********** OR factory methods ********** - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static CompositeBooleanPropertyValueModel or(PropertyValueModel<Boolean>... array) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, array); - } - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static CompositeBooleanPropertyValueModel or(Boolean defaultValue, PropertyValueModel<Boolean>... array) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, array); - } - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel or(Collection<E> collection) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, collection); - } - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel or(Boolean defaultValue, Collection<E> collection) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, collection); - } - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public static CompositeBooleanPropertyValueModel or(CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, collectionModel); - } - - /** - * Construct a boolean property value model that is a composite OR of the - * specified boolean property value models; i.e. the model's value is false - * if all the contained models are false, otherwise its value is true. - * When the model contains no nested models, its value will be the - * specified default. - */ - public static CompositeBooleanPropertyValueModel or(Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, collectionModel); - } - - - // ********** constructors ********** - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public CompositeBooleanPropertyValueModel(Adapter adapter, PropertyValueModel<Boolean>... array) { - this(adapter, null, array); - } - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * When the model contains no nested models, its value will be the - * specified default. - */ - public CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, PropertyValueModel<Boolean>... array) { - super(array); - this.adapter = adapter; - this.defaultValue = defaultValue; - } - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel(Adapter adapter, Collection<E> collection) { - this(adapter, null, collection); - } - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * When the model contains no nested models, its value will be the - * specified default. - */ - public <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, Collection<E> collection) { - super(collection); - this.adapter = adapter; - this.defaultValue = defaultValue; - } - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * The model's default value, when it contains no nested models, is - * <code>null</code>. - */ - public CompositeBooleanPropertyValueModel(Adapter adapter, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - this(adapter, null, collectionModel); - } - - /** - * Construct a boolean property value model that is a composite of the specified - * boolean property value models, as defined by the specified adapter. - * When the model contains no nested models, its value will be the - * specified default. - */ - public CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) { - super(collectionModel); - this.adapter = adapter; - this.defaultValue = defaultValue; - } - - - // ********** implementation ********** - - /** - * Return true if all the contained booleans are true; otherwise return - * false. - */ - @Override - protected Boolean buildValue() { - return (this.collectionModel.size() == 0) ? this.defaultValue : this.buildValue_(); - } - - protected Boolean buildValue_() { - return this.adapter.buildValue(this.getBooleans()); - } - - protected Iterable<Boolean> getBooleans() { - return new TransformationIterable<PropertyValueModel<Boolean>, Boolean>(this.getCollectionModel()) { - @Override - protected Boolean transform(PropertyValueModel<Boolean> booleanModel) { - return booleanModel.getValue(); - } - }; - } - - @Override - @SuppressWarnings("unchecked") - protected CollectionValueModel<? extends PropertyValueModel<Boolean>> getCollectionModel() { - return (CollectionValueModel<? extends PropertyValueModel<Boolean>>) super.getCollectionModel(); - } - - - // ********** adapter ********** - - /** - * This adapter allows the {@link CompositeBooleanPropertyValueModel} to be - * pluggable. - */ - public interface Adapter { - /** - * Return the composite boolean value of the specified collection - * of boolean models. - */ - Boolean buildValue(Iterable<Boolean> booleans); - } - - /** - * Return true if all the booleans are true; otherwise return false. - */ - public static final Adapter AND_ADAPTER = new Adapter() { - public Boolean buildValue(Iterable<Boolean> booleans) { - for (Boolean b : booleans) { - if ( ! b.booleanValue()) { - return Boolean.FALSE; - } - } - return Boolean.TRUE; - } - @Override - public String toString() { - return "AND_ADAPTER"; //$NON-NLS-1$ - } - }; - - /** - * Return false if all the booleans are false; otherwise return true. - */ - public static final Adapter OR_ADAPTER = new Adapter() { - public Boolean buildValue(Iterable<Boolean> booleans) { - for (Boolean b : booleans) { - if (b.booleanValue()) { - return Boolean.TRUE; - } - } - return Boolean.FALSE; - } - @Override - public String toString() { - return "OR_ADAPTER"; //$NON-NLS-1$ - } - }; - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeCollectionValueModel.java deleted file mode 100644 index 72f16a3344..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeCollectionValueModel.java +++ /dev/null @@ -1,448 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.NullList; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.Transformer; -import org.eclipse.jpt.common.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.common.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * A <code>CompositeCollectionValueModel</code> wraps another - * {@link CollectionValueModel} and uses a {@link Transformer} - * to convert each item in the wrapped collection to yet another - * {@link CollectionValueModel}. This composite collection contains - * the combined items from all these component collections. - * <p> - * <strong>NB:</strong> The wrapped collection must be an "identity set" that does not - * contain the same item twice or this class will throw an exception. - * <p> - * Terminology:<ul> - * <li><em>sources</em> - the items in the wrapped collection value model; these - * are converted into component CVMs by the transformer - * <li><em>component CVMs</em> - the component collection value models that are combined - * by this composite collection value model - * <li><em>items</em> - the items held by the component CVMs - * </ul> - */ -public class CompositeCollectionValueModel<E1, E2> - extends CollectionValueModelWrapper<E1> - implements CollectionValueModel<E2> -{ - /** - * This is the (optional) user-supplied object that transforms - * the items in the wrapped collection to collection value models. - */ - private final Transformer<E1, CollectionValueModel<E2>> transformer; - - /** - * Cache of the component collection value models that - * were generated by the transformer; keyed by the item - * in the wrapped collection that was passed to the transformer. - */ - private final IdentityHashMap<E1, CollectionValueModel<E2>> componentCVMs = - new IdentityHashMap<E1, CollectionValueModel<E2>>(); - - /** - * Cache of the collections corresponding to the component - * collection value models above; keyed by the component - * collection value models. - * Use {@link ArrayList}s so we can use {@link ArrayList}-specific methods - * (e.g. {@link ArrayList#clone()} and {@link ArrayList#ensureCapacity(int)}). - */ - private final IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>> collections = - new IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>>(); - - /** Listener that listens to all the component collection value models. */ - private final CollectionChangeListener componentCVMListener; - - /** Cache the size of the composite collection. */ - private int size; - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model. Use this constructor if<ul> - * <li> the wrapped collection value model already contains other - * collection value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionHolder) { - this(collectionHolder, Transformer.Null.<E1, CollectionValueModel<E2>>instance()); - } - - /** - * Construct a collection value model with the specified wrapped - * collection value model and transformer. - */ - public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, CollectionValueModel<E2>> transformer) { - super(collectionHolder); - this.transformer = transformer; - this.componentCVMListener = this.buildComponentListener(); - this.size = 0; - } - - /** - * Construct a collection value model with the specified wrapped - * list value model. Use this constructor if<ul> - * <li> the wrapped collection value model already contains other - * collection value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeCollectionValueModel(ListValueModel<? extends E1> listHolder) { - this(new ListCollectionValueModelAdapter<E1>(listHolder)); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and transformer. - */ - public CompositeCollectionValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, CollectionValueModel<E2>> transformer) { - this(new ListCollectionValueModelAdapter<E1>(listHolder), transformer); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection. Use this constructor if<ul> - * <li> the wrapped collection value model already contains other - * collection value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeCollectionValueModel(Collection<? extends E1> collection) { - this(new StaticCollectionValueModel<E1>(collection)); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection and transformer. - */ - public CompositeCollectionValueModel(Collection<? extends E1> collection, Transformer<E1, CollectionValueModel<E2>> transformer) { - this(new StaticCollectionValueModel<E1>(collection), transformer); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection. Use this constructor if<ul> - * <li> the wrapped collection value model already contains other - * collection value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeCollectionValueModel(E1... collection) { - this(new StaticCollectionValueModel<E1>(collection)); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection and transformer. - */ - public CompositeCollectionValueModel(E1[] collection, Transformer<E1, CollectionValueModel<E2>> transformer) { - this(new StaticCollectionValueModel<E1>(collection), transformer); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildComponentListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - CompositeCollectionValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - CompositeCollectionValueModel.this.componentItemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - CompositeCollectionValueModel.this.componentCollectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentCollectionChanged(event); - } - @Override - public String toString() { - return "component listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E2> iterator() { - return new CompositeIterator<E2>(this.buildCollectionsIterators()); - } - - protected Iterator<Iterator<E2>> buildCollectionsIterators() { - return new TransformationIterator<ArrayList<E2>, Iterator<E2>>(this.collections.values().iterator()) { - @Override - protected Iterator<E2> transform(ArrayList<E2> next) { - return next.iterator(); - } - }; - } - - public int size() { - return this.size; - } - - - // ********** CollectionValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the wrapped collection, - // since its value might change when a listener is added - this.addAllComponentSources(); - } - - /** - * Transform all the sources to collection value models - * and add their items to our cache, with no event notification. - */ - protected void addAllComponentSources() { - for (E1 source : this.collectionHolder) { - this.addComponentSource(source, NullList.<E2>instance()); - } - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // stop listening to the components... - for (CollectionValueModel<E2> componentCVM : this.componentCVMs.values()) { - componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener); - } - // ...and clear the cache - this.componentCVMs.clear(); - this.collections.clear(); - this.size = 0; - } - - /** - * Some component sources were added; - * add their corresponding items to our cache. - */ - @Override - protected void itemsAdded(CollectionAddEvent event) { - ArrayList<E2> addedItems = new ArrayList<E2>(); - for (E1 item : this.getItems(event)) { - this.addComponentSource(item, addedItems); - } - this.fireItemsAdded(VALUES, addedItems); - } - - /** - * Transform the specified source to a collection value model - * and add its items to our cache and the "collecting parameter". - */ - protected void addComponentSource(E1 source, List<E2> addedItems) { - CollectionValueModel<E2> componentCVM = this.transform(source); - if (this.componentCVMs.put(source, componentCVM) != null) { - throw new IllegalStateException("duplicate component: " + source); //$NON-NLS-1$ - } - componentCVM.addCollectionChangeListener(VALUES, this.componentCVMListener); - ArrayList<E2> componentCollection = new ArrayList<E2>(componentCVM.size()); - if (this.collections.put(componentCVM, componentCollection) != null) { - throw new IllegalStateException("duplicate collection: " + source); //$NON-NLS-1$ - } - this.addComponentItems(componentCVM, componentCollection); - addedItems.addAll(componentCollection); - } - - /** - * Add the items in the specified component CVM to the specified component - * collection. - */ - protected void addComponentItems(CollectionValueModel<E2> componentCVM, ArrayList<E2> componentCollection) { - int itemsSize = componentCVM.size(); - this.size += itemsSize; - componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - CollectionTools.addAll(componentCollection, componentCVM); - } - - /** - * Some component sources were removed; - * remove their corresponding items from our cache. - */ - @Override - protected void itemsRemoved(CollectionRemoveEvent event) { - ArrayList<E2> removedItems = new ArrayList<E2>(); - for (E1 item : this.getItems(event)) { - this.removeComponentSource(item, removedItems); - } - this.fireItemsRemoved(VALUES, removedItems); - } - - /** - * Remove the items corresponding to the specified source - * from our cache. - */ - protected void removeComponentSource(E1 source, List<E2> removedItems) { - CollectionValueModel<E2> componentCVM = this.componentCVMs.remove(source); - if (componentCVM == null) { - throw new IllegalStateException("missing component: " + source); //$NON-NLS-1$ - } - componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener); - ArrayList<E2> componentCollection = this.collections.remove(componentCVM); - if (componentCollection == null) { - throw new IllegalStateException("missing collection: " + source); //$NON-NLS-1$ - } - removedItems.addAll(componentCollection); - this.removeComponentItems(componentCollection); - } - - /** - * Update our size and collection cache. - */ - protected void removeComponentItems(ArrayList<E2> componentCollection) { - this.size -= componentCollection.size(); - componentCollection.clear(); - } - - /** - * The component sources cleared; - * clear our cache. - */ - @Override - protected void collectionCleared(CollectionClearEvent event) { - this.removeAllComponentSources(); - this.fireCollectionCleared(VALUES); - } - - protected void removeAllComponentSources() { - // copy the keys so we don't eat our own tail - ArrayList<E1> copy = new ArrayList<E1>(this.componentCVMs.keySet()); - for (E1 source : copy) { - this.removeComponentSource(source, NullList.<E2>instance()); - } - } - - /** - * The component sources changed; - * rebuild our cache. - */ - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.removeAllComponentSources(); - this.addAllComponentSources(); - this.fireCollectionChanged(VALUES, CollectionTools.collection(this.iterator())); - } - - - // ********** internal methods ********** - - /** - * Transform the specified object into a collection value model. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a {@link Transformer}. - */ - protected CollectionValueModel<E2> transform(E1 value) { - return this.transformer.transform(value); - } - - /** - * One of the component collections had items added; - * synchronize our caches. - */ - protected void componentItemsAdded(CollectionAddEvent event) { - int itemsSize = event.getItemsSize(); - this.size += itemsSize; - - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - - this.addItemsToCollection(this.getComponentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections had items removed; - * synchronize our caches. - */ - protected void componentItemsRemoved(CollectionRemoveEvent event) { - this.size -= event.getItemsSize(); - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - this.removeItemsFromCollection(this.getComponentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections was cleared; - * synchronize our caches by clearing out the appropriate - * collection. - */ - protected void componentCollectionCleared(CollectionClearEvent event) { - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - ArrayList<E2> removedItems = new ArrayList<E2>(componentCollection); - this.removeComponentItems(componentCollection); - this.fireItemsRemoved(VALUES, removedItems); - } - - /** - * One of the component collections changed; - * synchronize our caches by clearing out the appropriate - * collection and then rebuilding it. - */ - protected void componentCollectionChanged(CollectionChangeEvent event) { - CollectionValueModel<E2> componentCVM = this.componentCVM(event); - ArrayList<E2> componentCollection = this.collections.get(componentCVM); - this.removeComponentItems(componentCollection); - this.addComponentItems(componentCVM, componentCollection); - this.fireCollectionChanged(VALUES, CollectionTools.collection(this.iterator())); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E2> getComponentItems(CollectionAddEvent event) { - return (Iterable<E2>) event.getItems(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E2> getComponentItems(CollectionRemoveEvent event) { - return (Iterable<E2>) event.getItems(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected CollectionValueModel<E2> componentCVM(CollectionEvent event) { - return (CollectionValueModel<E2>) event.getSource(); - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeListValueModel.java deleted file mode 100644 index 3b017b08c9..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositeListValueModel.java +++ /dev/null @@ -1,683 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.ArrayTools; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.Transformer; -import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.common.utility.internal.iterators.TransformationListIterator; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * A <code>CompositeListValueModel</code> wraps another - * {@link ListValueModel} and uses a {@link Transformer} - * to convert each item in the wrapped list to yet another - * {@link ListValueModel}. This composite list contains - * the combined items from all these component lists. - * <p> - * Terminology:<ul> - * <li><em>sources</em> - the items in the wrapped list value model; these - * are converted into component LVMs by the transformer - * <li><em>component LVMs</em> - the component list value models that are combined - * by this composite list value model - * <li><em>items</em> - the items held by the component LVMs - * </ul> - */ -public class CompositeListValueModel<E1, E2> - extends ListValueModelWrapper<E1> - implements ListValueModel<E2> -{ - /** - * This is the (optional) user-supplied object that transforms - * the items in the wrapped list to list value models. - */ - private final Transformer<E1, ListValueModel<E2>> transformer; - - /** - * Cache of the sources, component LVMs, lists. - */ - private final ArrayList<Info> infoList = new ArrayList<Info>(); - protected class Info { - // the object passed to the transformer - final E1 source; - // the list value model generated by the transformer - final ListValueModel<E2> componentLVM; - // cache of the items held by the component LVM - final ArrayList<E2> items; - // the component LVM's beginning index within the composite LVM - int begin; - protected Info(E1 source, ListValueModel<E2> componentLVM, ArrayList<E2> items, int begin) { - super(); - this.source = source; - this.componentLVM = componentLVM; - this.items = items; - this.begin = begin; - } - } - - /** Listener that listens to all the component list value models. */ - private final ListChangeListener componentLVMListener; - - /** Cache the size of the composite list. */ - private int size; - - - // ********** constructors ********** - - /** - * Construct a list value model with the specified wrapped - * list value model. Use this constructor if<ul> - * <li> the wrapped list value model already contains other - * list value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeListValueModel(ListValueModel<? extends E1> listHolder) { - this(listHolder, Transformer.Null.<E1, ListValueModel<E2>>instance()); - } - - /** - * Construct a list value model with the specified wrapped - * list value model and transformer. - */ - public CompositeListValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, ListValueModel<E2>> transformer) { - super(listHolder); - this.transformer = transformer; - this.componentLVMListener = this.buildComponentLVMListener(); - this.size = 0; - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list. Use this constructor if<ul> - * <li> the wrapped list value model already contains other - * list value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeListValueModel(List<? extends E1> list) { - this(new StaticListValueModel<E1>(list)); - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list and transformer. - */ - public CompositeListValueModel(List<? extends E1> list, Transformer<E1, ListValueModel<E2>> transformer) { - this(new StaticListValueModel<E1>(list), transformer); - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list. Use this constructor if<ul> - * <li> the wrapped list value model already contains other - * list value models, or - * <li> you want to override {@link #transform(E1)} - * instead of building a {@link Transformer} - * </ul> - */ - public CompositeListValueModel(E1... list) { - this(new StaticListValueModel<E1>(list)); - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list and transformer. - */ - public CompositeListValueModel(E1[] list, Transformer<E1, ListValueModel<E2>> transformer) { - this(new StaticListValueModel<E1>(list), transformer); - } - - - // ********** initialization ********** - - protected ListChangeListener buildComponentLVMListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - CompositeListValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - CompositeListValueModel.this.componentItemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - CompositeListValueModel.this.componentItemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - CompositeListValueModel.this.componentItemsMoved(event); - } - public void listCleared(ListClearEvent event) { - CompositeListValueModel.this.componentListCleared(event); - } - public void listChanged(ListChangeEvent event) { - CompositeListValueModel.this.componentListChanged(event); - } - @Override - public String toString() { - return "component LVM listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ListValueModel implementation ********** - - public E2 get(int index) { - if ((index < 0) || (index >= this.size)) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size); //$NON-NLS-1$ //$NON-NLS-2$ - } - // move backwards through the info list - for (int i = this.infoList.size(); i-- > 0; ) { - Info info = this.infoList.get(i); - if (index >= info.begin) { - return info.items.get(index - info.begin); - } - } - throw new IllegalStateException(); // something is wack - } - - public Iterator<E2> iterator() { - return this.listIterator(); - } - - public ListIterator<E2> listIterator() { - return new ReadOnlyCompositeListIterator<E2>(this.buildListsIterators()); - } - - protected ListIterator<ListIterator<E2>> buildListsIterators() { - return new TransformationListIterator<Info, ListIterator<E2>>(this.infoList.listIterator()) { - @Override - protected ListIterator<E2> transform(Info info) { - return info.items.listIterator(); - } - }; - } - - public int size() { - return this.size; - } - - public Object[] toArray() { - return ArrayTools.array(this.listIterator(), this.size); - } - - - // ********** ListValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the wrapped list, - // since its value might change when a listener is added - this.addComponentSources(0, this.listHolder, this.listHolder.size(), false); // false = do not fire event - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // stop listening to the component LVMs... - for (Info info : this.infoList) { - info.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener); - } - // ...and clear the cache - this.infoList.clear(); - this.size = 0; - } - - /** - * Some component sources were added; update our cache. - */ - @Override - protected void itemsAdded(ListAddEvent event) { - this.addComponentSources(event.getIndex(), this.getItems(event), event.getItemsSize(), true); // true = fire event - } - - /** - * Add infos corresponding to the specified sources to our cache. - * Fire the appropriate event if requested. - */ - protected void addComponentSources(int addedSourcesIndex, Iterable<? extends E1> addedSources, int addedSourcesSize, boolean fireEvent) { - ArrayList<Info> newInfoList = new ArrayList<Info>(addedSourcesSize); - // the 'items' are either tacked on to the end or - // at the 'begin' index of the first 'info' that is being pushed back - int newItemsIndex = (addedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(addedSourcesIndex).begin; - - int begin = newItemsIndex; - for (E1 source : addedSources) { - ListValueModel<E2> componentLVM = this.transform(source); - componentLVM.addListChangeListener(LIST_VALUES, this.componentLVMListener); - ArrayList<E2> items = new ArrayList<E2>(componentLVM.size()); - CollectionTools.addAll(items, componentLVM.listIterator()); - newInfoList.add(new Info(source, componentLVM, items, begin)); - begin += items.size(); - } - this.infoList.addAll(addedSourcesIndex, newInfoList); - int newItemsSize = begin - newItemsIndex; - this.size += newItemsSize; - - // bump the 'begin' index for all the infos that were pushed back by the insert - int movedInfosIndex = addedSourcesIndex + addedSourcesSize; - for (int i = movedInfosIndex; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - - if (fireEvent) { - ArrayList<E2> newItems = new ArrayList<E2>(newItemsSize); - for (int i = addedSourcesIndex; i < movedInfosIndex; i++) { - newItems.addAll(this.infoList.get(i).items); - } - this.fireItemsAdded(LIST_VALUES, newItemsIndex, newItems); - } - } - - /** - * Some component sources were removed; update our cache. - */ - @Override - protected void itemsRemoved(ListRemoveEvent event) { - this.removeComponentSources(event.getIndex(), event.getItemsSize(), true); // true = fire event - } - - /** - * Remove the infos corresponding to the specified sources from our cache. - */ - protected void removeComponentSources(int removedSourcesIndex, int removedSourcesSize, boolean fireEvent) { - int removedItemsIndex = this.infoList.get(removedSourcesIndex).begin; - int movedSourcesIndex = removedSourcesIndex + removedSourcesSize; - int movedItemsIndex = (movedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(movedSourcesIndex).begin; - int removedItemsSize = movedItemsIndex - removedItemsIndex; - this.size -= removedItemsSize; - - List<Info> subList = this.infoList.subList(removedSourcesIndex, removedSourcesIndex + removedSourcesSize); - ArrayList<Info> removedInfoList = new ArrayList<Info>(subList); // make a copy - subList.clear(); - - // decrement the 'begin' index for all the infos that were moved forward by the deletes - for (int i = removedSourcesIndex; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - - for (Info removedInfo : removedInfoList) { - removedInfo.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener); - } - - if (fireEvent) { - ArrayList<E2> removedItems = new ArrayList<E2>(removedItemsSize); - for (Info removedInfo : removedInfoList) { - removedItems.addAll(removedInfo.items); - } - this.fireItemsRemoved(LIST_VALUES, removedItemsIndex, removedItems); - } - } - - /** - * Some component sources were replaced; update our cache. - */ - @Override - protected void itemsReplaced(ListReplaceEvent event) { - this.replaceComponentSources(event.getIndex(), this.getNewItems(event), event.getItemsSize(), true); // true = fire event - } - - /** - * Replaced component sources will not (typically) map to a set of replaced - * items, so we remove and add the corresponding lists of items, resulting in - * two events. - */ - protected void replaceComponentSources(int replacedSourcesIndex, Iterable<? extends E1> newSources, int replacedSourcesSize, boolean fireEvent) { - this.removeComponentSources(replacedSourcesIndex, replacedSourcesSize, fireEvent); - this.addComponentSources(replacedSourcesIndex, newSources, replacedSourcesSize, fireEvent); - } - - /** - * Some component sources were moved; update our cache. - */ - @Override - protected void itemsMoved(ListMoveEvent event) { - this.moveComponentSources(event.getTargetIndex(), event.getSourceIndex(), event.getLength(), true); // true = fire event - } - - protected void moveComponentSources(int targetSourcesIndex, int sourceSourcesIndex, int movedSourcesLength, boolean fireEvent) { - int sourceItemsIndex = this.infoList.get(sourceSourcesIndex).begin; - - int nextSourceSourceIndex = sourceSourcesIndex + movedSourcesLength; - int nextSourceItemIndex = (nextSourceSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextSourceSourceIndex).begin; - int moveItemsLength = nextSourceItemIndex - sourceItemsIndex; - - int targetItemsIndex = -1; - if (sourceSourcesIndex > targetSourcesIndex) { - // move from high to low index - targetItemsIndex = this.infoList.get(targetSourcesIndex).begin; - } else { - // move from low to high index (higher items move down during move) - int nextTargetSourceIndex = targetSourcesIndex + movedSourcesLength; - targetItemsIndex = (nextTargetSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextTargetSourceIndex).begin; - targetItemsIndex = targetItemsIndex - moveItemsLength; - } - - CollectionTools.move(this.infoList, targetSourcesIndex, sourceSourcesIndex, movedSourcesLength); - - // update the 'begin' indexes of all the affected 'infos' - int min = Math.min(targetSourcesIndex, sourceSourcesIndex); - int max = Math.max(targetSourcesIndex, sourceSourcesIndex) + movedSourcesLength; - int begin = Math.min(targetItemsIndex, sourceItemsIndex); - for (int i = min; i < max; i++) { - Info info = this.infoList.get(i); - info.begin = begin; - begin += info.componentLVM.size(); - } - - if (fireEvent) { - this.fireItemsMoved(LIST_VALUES, targetItemsIndex, sourceItemsIndex, moveItemsLength); - } - } - - /** - * The component sources were cleared; clear our cache. - */ - @Override - protected void listCleared(ListClearEvent event) { - this.clearComponentSources(); - } - - protected void clearComponentSources() { - this.removeComponentSources(0, this.infoList.size(), false); // false = do not fire event - this.fireListCleared(LIST_VALUES); - } - - /** - * The component sources changed; rebuild our cache. - */ - @Override - protected void listChanged(ListChangeEvent event) { - int newSize = this.listHolder.size(); - if (newSize == 0) { - this.clearComponentSources(); - return; - } - - int oldSize = this.infoList.size(); - if (oldSize == 0) { - this.addComponentSources(0, this.listHolder, newSize, true); // true = fire event - return; - } - - int min = Math.min(newSize, oldSize); - // handle replaced sources individually so we don't fire events for unchanged sources - for (int i = 0; i < min; i++) { - E1 newSource = this.listHolder.get(i); - E1 oldSource = this.infoList.get(i).source; - if (this.valuesAreDifferent(newSource, oldSource)) { - this.replaceComponentSources(i, new SingleElementIterable<E1>(newSource), 1, true); // true = fire event - } - } - - if (newSize == oldSize) { - return; - } - - if (newSize < oldSize) { - this.removeComponentSources(min, oldSize - newSize, true); // true = fire event - return; - } - - // newSize > oldSize - this.addComponentSources(min, this.buildSubListHolder(min), newSize - oldSize, true); // true = fire event - } - - protected Iterable<? extends E1> buildSubListHolder(int fromIndex) { - int listHolderSize = this.listHolder.size(); - return CollectionTools.list(this.listHolder, listHolderSize).subList(fromIndex, listHolderSize); - } - - protected Iterable<? extends E1> buildSubListHolder(int fromIndex, int toIndex) { - int listHolderSize = this.listHolder.size(); - return ((fromIndex == 0) && (toIndex == listHolderSize)) ? - this.listHolder : - CollectionTools.list(this.listHolder, listHolderSize).subList(fromIndex, toIndex); - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - - - // ********** internal methods ********** - - /** - * Transform the specified object into a list value model. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a {@link Transformer}. - */ - protected ListValueModel<E2> transform(E1 value) { - return this.transformer.transform(value); - } - - /** - * Return the index of the specified component LVM. - */ - protected int indexOf(ListValueModel<E2> componentLVM) { - for (int i = 0; i < this.infoList.size(); i++) { - if (this.infoList.get(i).componentLVM == componentLVM) { - return i; - } - } - throw new IllegalArgumentException("invalid component LVM: " + componentLVM); //$NON-NLS-1$ - } - - /** - * Return the index of the specified event's component LVM. - */ - protected int indexFor(ListEvent event) { - return this.indexOf(this.getComponentLVM(event)); - } - - /** - * Items were added to one of the component lists; - * synchronize our cache. - */ - protected void componentItemsAdded(ListAddEvent event) { - int componentLVMIndex = this.indexFor(event); - this.addComponentItems(componentLVMIndex, this.infoList.get(componentLVMIndex), event.getIndex(), this.getComponentItems(event), event.getItemsSize()); - } - - protected void addComponentItems(int componentLVMIndex, Info info, int addedItemsIndex, Iterable<E2> addedItems, int addedItemsSize) { - // update the affected 'begin' indices - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += addedItemsSize; - } - this.size += addedItemsSize; - - // synchronize the cached list - CollectionTools.addAll(info.items, addedItemsIndex, addedItems, addedItemsSize); - - // translate the event - this.fireItemsAdded(LIST_VALUES, info.begin + addedItemsIndex, info.items.subList(addedItemsIndex, addedItemsIndex + addedItemsSize)); - } - - /** - * Items were removed from one of the component lists; - * synchronize our cache. - */ - protected void componentItemsRemoved(ListRemoveEvent event) { - // update the affected 'begin' indices - int componentLVMIndex = this.indexFor(event); - int removedItemsSize = event.getItemsSize(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - this.size -= removedItemsSize; - - // synchronize the cached list - Info info = this.infoList.get(componentLVMIndex); - int itemIndex = event.getIndex(); - info.items.subList(itemIndex, itemIndex + event.getItemsSize()).clear(); - - // translate the event - this.fireItemsRemoved(event.clone(this, LIST_VALUES, info.begin)); - } - - /** - * Items were replaced in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsReplaced(ListReplaceEvent event) { - // no changes to the 'begin' indices or size - - // synchronize the cached list - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - int i = event.getIndex(); - for (E2 item : this.getComponentItems(event)) { - info.items.set(i++, item); - } - - // translate the event - this.fireItemsReplaced(event.clone(this, LIST_VALUES, info.begin)); - } - - /** - * Items were moved in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsMoved(ListMoveEvent event) { - // no changes to the 'begin' indices or size - - // synchronize the cached list - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - CollectionTools.move(info.items, event.getTargetIndex(), event.getSourceIndex(), event.getLength()); - - // translate the event - this.fireItemsMoved(event.clone(this, LIST_VALUES, info.begin)); - } - - /** - * One of the component lists was cleared; - * synchronize our cache. - */ - protected void componentListCleared(ListClearEvent event) { - int componentLVMIndex = this.indexFor(event); - this.clearComponentList(componentLVMIndex, this.infoList.get(componentLVMIndex)); - } - - protected void clearComponentList(int componentLVMIndex, Info info) { - // update the affected 'begin' indices - int removedItemsSize = info.items.size(); - if (removedItemsSize == 0) { - return; - } - - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - this.size -= removedItemsSize; - - // synchronize the cached list - ArrayList<E2> items = new ArrayList<E2>(info.items); // make a copy - info.items.clear(); - - // translate the event - this.fireItemsRemoved(LIST_VALUES, info.begin, items); - } - - /** - * One of the component lists changed; - * synchronize our cache by synchronizing the appropriate - * list and firing the appropriate events. - */ - protected void componentListChanged(ListChangeEvent event) { - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - - int newItemsSize = info.componentLVM.size(); - if (newItemsSize == 0) { - this.clearComponentList(componentLVMIndex, info); - return; - } - - int oldItemsSize = info.items.size(); - if (oldItemsSize == 0) { - this.addComponentItems(componentLVMIndex, info, 0, info.componentLVM, newItemsSize); - return; - } - - int min = Math.min(newItemsSize, oldItemsSize); - // handle replaced items individually so we don't fire events for unchanged items - for (int i = 0; i < min; i++) { - E2 newItem = info.componentLVM.get(i); - E2 oldItem = info.items.set(i, newItem); - this.fireItemReplaced(LIST_VALUES, info.begin + i, newItem, oldItem); - } - - int delta = newItemsSize - oldItemsSize; - if (delta == 0) { // newItemsSize == oldItemsSize - return; - } - - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += delta; - } - this.size += delta; - - if (delta < 0) { // newItemsSize < oldItemsSize - List<E2> subList = info.items.subList(newItemsSize, oldItemsSize); - ArrayList<E2> removedItems = new ArrayList<E2>(subList); // make a copy - subList.clear(); - this.fireItemsRemoved(LIST_VALUES, info.begin + newItemsSize, removedItems); - return; - } - - // newItemsSize > oldItemsSize - ArrayList<E2> addedItems = new ArrayList<E2>(delta); - for (int i = oldItemsSize; i < newItemsSize; i++) { - addedItems.add(info.componentLVM.get(i)); - } - info.items.addAll(addedItems); - this.fireItemsAdded(LIST_VALUES, info.begin + oldItemsSize, addedItems); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E2> getComponentItems(ListAddEvent event) { - return (Iterable<E2>) event.getItems(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E2> getComponentItems(ListReplaceEvent event) { - return (Iterable<E2>) event.getNewItems(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected ListValueModel<E2> getComponentLVM(ListEvent event) { - return (ListValueModel<E2>) event.getSource(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositePropertyValueModel.java deleted file mode 100644 index 0654c0694c..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/CompositePropertyValueModel.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.common.utility.internal.IdentityHashBag; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A <code>CompositePropertyValueModel</code> adapts a - * {@link CollectionValueModel} holding other {@link PropertyValueModel}s - * to a single {@link PropertyValueModel}. - * <p> - * Subclasses must implement:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * component values - * </ul> - * <strong>NB:</strong> The wrapped collection must not contain any duplicates - * or this class will throw an exception. - */ -public abstract class CompositePropertyValueModel<V> - extends CollectionPropertyValueModelAdapter<V> -{ - /** - * Cache the component property value models so we can stop listening to - * them when they are removed from the collection value model. - */ - protected final IdentityHashBag<PropertyValueModel<?>> componentPVMs = - new IdentityHashBag<PropertyValueModel<?>>(); - - /** - * Listen to every property value model in the collection value model. - * If one changes, we need to re-calculate our value. - */ - protected final PropertyChangeListener propertyChangeListener; - - - // ********** constructors ********** - - /** - * Construct a property value model that is a composite of the specified - * property value models. - */ - public CompositePropertyValueModel(PropertyValueModel<?>... collection) { - this(Arrays.asList(collection)); - } - - /** - * Construct a property value model that is a composite of the specified - * property value models. - */ - public <E extends PropertyValueModel<?>> CompositePropertyValueModel(Collection<E> collection) { - this(new StaticCollectionValueModel<E>(collection)); - } - - /** - * Construct a property value model that is a composite of the specified - * property value models. - */ - public CompositePropertyValueModel(CollectionValueModel<? extends PropertyValueModel<?>> collectionModel) { - super(collectionModel); - this.propertyChangeListener = this.buildPropertyChangeListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - CompositePropertyValueModel.this.propertyChanged(event); - } - @Override - public String toString() { - return "property change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Subclasses can override this method if the event can be used to improve - * the performance of building a new value (e.g. some property changes may - * not necessitate the re-calculation of the value). - */ - protected void propertyChanged(@SuppressWarnings("unused") PropertyChangeEvent event) { - this.propertyChanged(); - } - - - // ********** CollectionPropertyValueModelAdapter overrides ********** - - @Override - protected void engageModel_() { - super.engageModel_(); - this.addComponentPVMs(this.getCollectionModel()); - } - - protected <E extends PropertyValueModel<?>> void addComponentPVMs(Iterable<E> pvms) { - for (PropertyValueModel<?> each : pvms) { - this.componentPVMs.add(each); - each.addPropertyChangeListener(VALUE, this.propertyChangeListener); - } - } - - @Override - protected void disengageModel_() { - this.removeComponentPVMs(this.getCollectionModel()); - super.disengageModel_(); - } - - protected <E extends PropertyValueModel<?>> void removeComponentPVMs(Iterable<E> pvms) { - for (PropertyValueModel<?> each : pvms) { - each.removePropertyChangeListener(VALUE, this.propertyChangeListener); - this.componentPVMs.remove(each); - } - } - - @Override - protected void itemsAdded(CollectionAddEvent event) { - this.addComponentPVMs(this.getItems(event)); - super.itemsAdded(event); - } - - @Override - protected void itemsRemoved(CollectionRemoveEvent event) { - this.removeComponentPVMs(this.getItems(event)); - super.itemsRemoved(event); - } - - @Override - protected void collectionCleared(CollectionClearEvent event) { - this.removeAllComponentPVMs(); - super.collectionCleared(event); - } - - protected void removeAllComponentPVMs() { - // copy the list so we don't eat our own tail - ArrayList<PropertyValueModel<?>> copy = new ArrayList<PropertyValueModel<?>>(this.componentPVMs); - this.removeComponentPVMs(copy); - } - - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.removeAllComponentPVMs(); - this.addComponentPVMs(this.getCollectionModel()); - super.collectionChanged(event); - } - - - // ********** convenience methods ********** - - /** - * Our constructor accepts only a {@link CollectionValueModel}{@code<? extends }{@link PropertyValueModel}{@code<?>>}. - */ - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected CollectionValueModel<? extends PropertyValueModel<?>> getCollectionModel() { - return (CollectionValueModel<? extends PropertyValueModel<?>>) this.collectionModel; - } - - /** - * Our constructor accepts only a {@link CollectionValueModel}{@code<? extends }{@link PropertyValueModel}{@code<?>>}. - */ - @SuppressWarnings("unchecked") - protected Iterable<? extends PropertyValueModel<?>> getItems(CollectionAddEvent event) { - return (Iterable<? extends PropertyValueModel<?>>) event.getItems(); - } - - /** - * Our constructor accepts only a {@link CollectionValueModel}{@code<? extends }{@link PropertyValueModel}{@code<?>>}. - */ - @SuppressWarnings("unchecked") - protected Iterable<? extends PropertyValueModel<?>> getItems(CollectionRemoveEvent event) { - return (Iterable<? extends PropertyValueModel<?>>) event.getItems(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ExtendedListValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ExtendedListValueModelWrapper.java deleted file mode 100644 index 6601615cc4..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ExtendedListValueModelWrapper.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This wrapper extends a {@link ListValueModel} (or {@link CollectionValueModel}) - * with fixed collections of items on either end. - * <p> - * <strong>NB:</strong> Be careful using or wrapping this list value model, since the - * "extended" items may be unexpected by the client code or wrapper. - */ -public class ExtendedListValueModelWrapper<E> - extends ListValueModelWrapper<E> - implements ListValueModel<E> -{ - /** the items "prepended" to the wrapped list */ - protected List<E> prefix; - - /** the items "appended" to the wrapped list */ - protected List<E> suffix; - - - // ********** lots o' constructors ********** - - /** - * Extend the specified list with a prefix and suffix. - */ - public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder, List<? extends E> suffix) { - super(listHolder); - this.prefix = new ArrayList<E>(prefix); - this.suffix = new ArrayList<E>(suffix); - } - - /** - * Extend the specified list with a prefix and suffix. - */ - public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder, E suffix) { - super(listHolder); - this.prefix = Collections.singletonList(prefix); - this.suffix = Collections.singletonList(suffix); - } - - /** - * Extend the specified list with a prefix. - */ - public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = new ArrayList<E>(prefix); - this.suffix = Collections.emptyList(); - } - - /** - * Extend the specified list with a prefix. - */ - public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = Collections.singletonList(prefix); - this.suffix = Collections.emptyList(); - } - - /** - * Extend the specified list with a suffix. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, List<? extends E> suffix) { - super(listHolder); - this.prefix = Collections.emptyList(); - this.suffix = new ArrayList<E>(suffix); - } - - /** - * Extend the specified list with a suffix. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, E suffix) { - super(listHolder); - this.prefix = Collections.emptyList(); - this.suffix = Collections.singletonList(suffix); - } - - /** - * Extend the specified list with a prefix containing a single null item. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = Collections.singletonList(null); - this.suffix = Collections.emptyList(); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.listIterator_()); - } - - @SuppressWarnings("unchecked") - protected ListIterator<E> listIterator_() { - return new ReadOnlyCompositeListIterator<E>( - this.prefix.listIterator(), - this.listHolder.listIterator(), - this.suffix.listIterator() - ); - } - - public E get(int index) { - int prefixSize = this.prefix.size(); - if (index < prefixSize) { - return this.prefix.get(index); - } else if (index >= prefixSize + this.listHolder.size()) { - return this.suffix.get(index - (prefixSize + this.listHolder.size())); - } else { - return this.listHolder.get(index - prefixSize); - } - } - - public int size() { - return this.prefix.size() + this.listHolder.size() + this.suffix.size(); - } - - public Object[] toArray() { - ArrayList<E> list = new ArrayList<E>(this.size()); - list.addAll(this.prefix); - CollectionTools.addAll(list, this.listHolder.iterator()); - list.addAll(this.suffix); - return list.toArray(); - } - - - // ********** ListValueModelWrapper implementation/overrides ********** - - @Override - protected void itemsAdded(ListAddEvent event) { - this.fireItemsAdded(event.clone(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsRemoved(ListRemoveEvent event) { - this.fireItemsRemoved(event.clone(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsReplaced(ListReplaceEvent event) { - this.fireItemsReplaced(event.clone(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsMoved(ListMoveEvent event) { - this.fireItemsMoved(event.clone(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void listCleared(ListClearEvent event) { - this.fireListChanged(LIST_VALUES, this.buildList()); // not "cleared" - } - - @Override - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES, this.buildList()); - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - - - // ********** miscellaneous ********** - - public void setPrefix(List<E> prefix) { - this.prefix = prefix; - this.fireListChanged(LIST_VALUES, this.buildList()); - } - - public void setSuffix(List<E> suffix) { - this.suffix = suffix; - this.fireListChanged(LIST_VALUES, this.buildList()); - } - - private List<E> buildList() { - return CollectionTools.list(this.listIterator_()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringCollectionValueModel.java deleted file mode 100644 index 3defd4f00d..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringCollectionValueModel.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.Filter; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * A <code>FilteringCollectionValueModel</code> wraps another - * {@link CollectionValueModel} and uses a {@link Filter} - * to determine which items in the collection are returned by calls - * to {@link #iterator()}. - * <p> - * The filter can be changed at any time; allowing the same - * adapter to be used with different filter criteria (e.g. when the user - * wants to view a list of <code>.java</code> files). - * <p> - * <strong>NB:</strong> If the objects in the "filtered" collection can change in such a way - * that they should be removed from the "filtered" collection, you will - * need to wrap the original collection in an {@link ItemAspectListValueModelAdapter}. - * For example, if the filter only "accepts" items whose names begin - * with "X" and the names of the items can change, you will need to - * wrap the original list of unfiltered items with an - * {@link ItemPropertyListValueModelAdapter} that listens for changes to each - * item's name and fires the appropriate event whenever an item's name - * changes. The event will cause this wrapper to re-filter the changed - * item and add or remove it from the "filtered" collection as appropriate. - */ -public class FilteringCollectionValueModel<E> - extends CollectionValueModelWrapper<E> - implements CollectionValueModel<E> -{ - /** This filters the items in the nested collection. */ - private Filter<E> filter; - - /** Cache the items that were accepted by the filter */ - private final Collection<E> filteredItems = new ArrayList<E>(); - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model and a filter that simply accepts every object. - */ - public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionHolder) { - this(collectionHolder, Filter.Null.<E>instance()); - } - - /** - * Construct a collection value model with the specified wrapped - * collection value model and filter. - */ - public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionHolder, Filter<E> filter) { - super(collectionHolder); - this.filter = filter; - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and a filter that simply accepts every object. - */ - public FilteringCollectionValueModel(ListValueModel<E> listHolder) { - this(new ListCollectionValueModelAdapter<E>(listHolder)); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and filter. - */ - public FilteringCollectionValueModel(ListValueModel<E> listHolder, Filter<E> filter) { - this(new ListCollectionValueModelAdapter<E>(listHolder), filter); - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.filteredItems); - } - - public int size() { - return this.filteredItems.size(); - } - - - // ********** CollectionValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the nested collection, - // since its value might change when a listener is added - CollectionTools.addAll(this.filteredItems, this.filter(this.collectionHolder)); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the cache when we are not listening to the nested collection - this.filteredItems.clear(); - } - - @Override - protected void itemsAdded(CollectionAddEvent event) { - // filter the values before propagating the change event - this.addItemsToCollection(this.filter(this.getItems(event)), this.filteredItems, VALUES); - } - - @Override - protected void itemsRemoved(CollectionRemoveEvent event) { - // 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(event.getItems(), this.filteredItems, VALUES); - } - - @Override - protected void collectionCleared(CollectionClearEvent event) { - this.clearCollection(this.filteredItems, VALUES); - } - - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.rebuildFilteredItems(); - } - - - // ********** miscellaneous ********** - - /** - * Change the filter and rebuild the collection. - */ - public void setFilter(Filter<E> filter) { - this.filter = filter; - this.rebuildFilteredItems(); - } - - /** - * Return an iterable that filters the specified iterable. - */ - protected Iterable<E> filter(Iterable<? extends E> items) { - return new FilteringIterable<E>(items, this.filter); - } - - /** - * Synchronize our cache with the wrapped collection. - */ - protected void rebuildFilteredItems() { - this.filteredItems.clear(); - CollectionTools.addAll(this.filteredItems, this.filter(this.collectionHolder)); - this.fireCollectionChanged(VALUES, this.filteredItems); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.filteredItems); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringPropertyValueModel.java deleted file mode 100644 index 56935822d8..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringPropertyValueModel.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.Filter; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A <code>FilteringPropertyValueModel</code> wraps another - * {@link PropertyValueModel} and uses a {@link Filter} - * to determine when the wrapped value is to be returned by calls - * to {@link #getValue()}. - * <p> - * As an alternative to building a {@link Filter}, a subclass - * can override {@link #accept(T)}. - * <p> - * One, possibly undesirable, side-effect of using this value model is that - * it must return *something* as the value. The default behavior is - * to return <code>null</code> whenever the wrapped value is not "accepted", - * which can be configured and/or overridden ({@link #getDefaultValue()}). - */ -public class FilteringPropertyValueModel<T> - extends PropertyValueModelWrapper<T> - implements PropertyValueModel<T> -{ - protected final Filter<T> filter; - protected final T defaultValue; - - - // ********** constructors ********** - - /** - * Construct a filtering property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override {@link #accept(T)} - * instead of building a {@link Filter}. - * The default value will be <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder) { - this(valueHolder, Filter.Disabled.<T>instance(), null); - } - - /** - * Construct a filtering property value model with the specified nested - * property value model, specified default value, and a disabled filter. - * Use this constructor if you want to override {@link #accept(T)} - * instead of building a {@link Filter} - * <em>and</em> you need to specify - * a default value other than <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, T defaultValue) { - this(valueHolder, Filter.Disabled.<T>instance(), defaultValue); - } - - /** - * Construct a filtering property value model with the specified nested - * property value model and filter. - * The default value will be <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, Filter<T> filter) { - this(valueHolder, filter, null); - } - - /** - * Construct a filtering property value model with the specified nested - * property value model, filter, and default value. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, Filter<T> filter, T defaultValue) { - super(valueHolder); - this.filter = filter; - this.defaultValue = defaultValue; - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.filterValue(this.valueHolder.getValue()); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - // filter the values before propagating the change event - @SuppressWarnings("unchecked") - T eventOldValue = (T) event.getOldValue(); - Object oldValue = this.filterValue(eventOldValue); - @SuppressWarnings("unchecked") - T eventNewValue = (T) event.getNewValue(); - Object newValue = this.filterValue(eventNewValue); - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - - // ********** queries ********** - - /** - * If the specified value is "accepted" simply return it, - * otherwise return the default value. - */ - protected T filterValue(T value) { - return this.accept(value) ? value : this.getDefaultValue(); - } - - /** - * Return whether the filtering property value model should - * return the specified value from a call to - * {@link #getValue()}; the value came - * from the nested property value model - * <p> - * This method can be overridden by a subclass as an - * alternative to building a {@link Filter}. - */ - protected boolean accept(T value) { - return this.filter.accept(value); - } - - /** - * Return the object that should be returned if - * the nested value was rejected by the filter. - * The default is <code>null</code>. - */ - protected T getDefaultValue() { - return this.defaultValue; - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringWritablePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringWritablePropertyValueModel.java deleted file mode 100644 index 61eac0eec9..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/FilteringWritablePropertyValueModel.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.BidiFilter; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>FilteringWritablePropertyValueModel</code> wraps another - * {@link WritablePropertyValueModel} and uses a {@link BidiFilter} - * to determine when the wrapped value is to be returned by calls - * to {@link FilteringPropertyValueModel#getValue() getValue()} and modified by calls to - * {@link #setValue(T)}. - * <p> - * As an alternative to building a {@link BidiFilter}, a subclass - * can override {@link FilteringPropertyValueModel#accept(T) accept(T)} and {@link #reverseAccept(T)}. - * <p> - * One, possibly undesirable, side-effect of using this value model is that - * it must return *something* as the value. The default behavior is - * to return <code>null</code> whenever the wrapped value is not "accepted", - * which can be configured and/or overridden ({@link FilteringPropertyValueModel#getDefaultValue() getDefaultValue()}). - * <p> - * Similarly, if an incoming value is not "reverse accepted", <em>nothing</em> - * will passed through to the wrapped value holder, not even <code>null</code>. - */ -public class FilteringWritablePropertyValueModel<T> - extends FilteringPropertyValueModel<T> - implements WritablePropertyValueModel<T> -{ - - - // ********** constructors ********** - - /** - * Construct a filtering property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override - * {@link #accept(T)} and {@link #reverseAccept(T)} - * instead of building a {@link BidiFilter}. - * The default value will be <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder) { - this(valueHolder, BidiFilter.Disabled.<T>instance(), null); - } - - /** - * Construct a filtering property value model with the specified nested - * property value model, specified default value, and a disabled filter. - * Use this constructor if you want to override - * {@link #accept(T)} and {@link #reverseAccept(T)} - * instead of building a {@link BidiFilter}. - * <em>and</em> you need to specify - * a default value other than <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, T defaultValue) { - this(valueHolder, BidiFilter.Disabled.<T>instance(), defaultValue); - } - - /** - * Construct an property value model with the specified nested - * property value model and filter. - * The default value will be <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, BidiFilter<T> filter) { - this(valueHolder, filter, null); - } - - /** - * Construct an property value model with the specified nested - * property value model, filter, and default value. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, BidiFilter<T> filter, T defaultValue) { - super(valueHolder, filter, defaultValue); - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - if (this.reverseAccept(value)) { - this.getValueHolder().setValue(value); - } - } - - - // ********** queries ********** - - /** - * Return whether the filtering writable property value model - * should pass through the specified value to the nested - * writable property value model in a call to - * {@link #setValue(T)}. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a {@link BidiFilter}. - */ - protected boolean reverseAccept(T value) { - return this.getFilter().reverseAccept(value); - } - - /** - * Our constructor accepts only a {@link WritablePropertyValueModel}{@code<T>}. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> getValueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - /** - * Our constructors accept only a bidirectional filter. - */ - protected BidiFilter<T> getFilter() { - return (BidiFilter<T>) this.filter; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemAspectListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemAspectListValueModelAdapter.java deleted file mode 100644 index eff8183982..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemAspectListValueModelAdapter.java +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.EventObject; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.SimpleIntReference; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Abstract list value model that provides behavior for wrapping a {@link ListValueModel} - * (or {@link CollectionValueModel}) and listening for changes to aspects of the - * <em>items</em> held by the list (or collection). Changes to the actual list - * (or collection) are also monitored. - * - * This is useful if you have a collection of items that can be modified by adding - * or removing items or the items themselves might change in a fashion that - * might change the list or collection's external appearance. - * - * Subclasses need to override two methods:<ul> - * <li>{@link #engageItem_(Model)}<p> - * begin listening to the appropriate aspect of the specified item and call - * {@link #itemAspectChanged(EventObject)} whenever the aspect changes - * <li>{@link #disengageItem_(Model)}<p> - * stop listening to the appropriate aspect of the specified item - * </ul> - */ -public abstract class ItemAspectListValueModelAdapter<E> - extends ListValueModelWrapper<E> - implements ListValueModel<E> -{ - - /** - * Maintain a counter for each of the items in the - * wrapped list holder we are listening to. - */ - protected final IdentityHashMap<E, SimpleIntReference> counters; - - - // ********** constructors ********** - - /** - * Constructor - the list holder is required. - */ - protected ItemAspectListValueModelAdapter(ListValueModel<? extends E> listHolder) { - super(listHolder); - this.counters = new IdentityHashMap<E, SimpleIntReference>(); - } - - /** - * Constructor - the collection holder is required. - */ - protected ItemAspectListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - this(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.listHolder.listIterator()); - } - - public E get(int index) { - return this.listHolder.get(index); - } - - public int size() { - return this.listHolder.size(); - } - - public Object[] toArray() { - return this.listHolder.toArray(); - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder and the items in the list. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.engageAllItems(); - } - - protected void engageAllItems() { - this.engageItems(this.listHolder); - } - - protected void engageItems(Iterable<? extends E> items) { - for (E item : items) { - this.engageItem(item); - } - } - - protected void engageItem(E item) { - // listen to each item only once - SimpleIntReference counter = this.counters.get(item); - if (counter == null) { - counter = new SimpleIntReference(); - this.counters.put(item, counter); - this.engageItem_((Model) item); - } - counter.increment(); - } - - /** - * Start listening to the specified item. - */ - protected abstract void engageItem_(Model item); - - /** - * Stop listening to the list holder and the items in the list. - */ - @Override - protected void disengageModel() { - this.disengageAllItems(); - super.disengageModel(); - } - - protected void disengageAllItems() { - this.disengageItems(this.listHolder); - } - - protected void disengageItems(Iterable<? extends E> items) { - for (E item : items) { - this.disengageItem(item); - } - } - - protected void disengageItem(E item) { - // stop listening to each item only once - SimpleIntReference counter = this.counters.get(item); - if (counter == null) { - // something is wrong if this happens... ~bjv - throw new IllegalStateException("missing counter: " + item); //$NON-NLS-1$ - } - if (counter.decrement() == 0) { - this.counters.remove(item); - this.disengageItem_((Model) item); - } - } - - /** - * Stop listening to the specified item. - */ - protected abstract void disengageItem_(Model item); - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder. - * Forward the event and begin listening to the added items. - */ - @Override - protected void itemsAdded(ListAddEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsAdded(event.clone(this, LIST_VALUES)); - this.engageItems(this.getItems(event)); - } - - /** - * Items were removed from the wrapped list holder. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void itemsRemoved(ListRemoveEvent event) { - this.disengageItems(this.getItems(event)); - // re-fire event with the wrapper as the source - this.fireItemsRemoved(event.clone(this, LIST_VALUES)); - } - - /** - * Items were replaced in the wrapped list holder. - * Stop listening to the removed items, forward the event, - * and begin listening to the added items. - */ - @Override - protected void itemsReplaced(ListReplaceEvent event) { - this.disengageItems(this.getOldItems(event)); - // re-fire event with the wrapper as the source - this.fireItemsReplaced(event.clone(this, LIST_VALUES)); - this.engageItems(this.getNewItems(event)); - } - - /** - * Items were moved in the wrapped list holder. - * No need to change any listeners; just forward the event. - */ - @Override - protected void itemsMoved(ListMoveEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsMoved(event.clone(this, LIST_VALUES)); - } - - /** - * The wrapped list holder was cleared. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void listCleared(ListClearEvent event) { - // we should only need to disengage each item once... - // make a copy to prevent a ConcurrentModificationException - Collection<E> keys = new ArrayList<E>(this.counters.keySet()); - this.disengageItems(keys); - this.counters.clear(); - // re-fire event with the wrapper as the source - this.fireListCleared(LIST_VALUES); - } - - /** - * The wrapped list holder has changed in some dramatic fashion. - * Reconfigure our listeners and forward the event. - */ - @Override - protected void listChanged(ListChangeEvent event) { - // we should only need to disengage each item once... - // make a copy to prevent a ConcurrentModificationException - Collection<E> keys = new ArrayList<E>(this.counters.keySet()); - this.disengageItems(keys); - this.counters.clear(); - // re-fire event with the wrapper as the source - this.fireListChanged(event.clone(this)); - this.engageAllItems(); - } - - - // ********** item change support ********** - - /** - * The specified item has a bound property that has changed. - * Notify listeners of the change. The listeners will have to determine - * whether the item aspect change is significant. - */ - protected void itemAspectChanged(@SuppressWarnings("unused") EventObject event) { - this.fireListChanged(LIST_VALUES, CollectionTools.list(this.listHolder, this.listHolder.size())); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemChangeListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemChangeListValueModelAdapter.java deleted file mode 100644 index b6f817b79c..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemChangeListValueModelAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.SimpleChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to all of the changes - * of each item in the wrapped list model. - */ -public class ItemChangeListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - /** Listener that listens to all the items in the list. */ - protected final ChangeListener itemChangeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified items. - */ - public ItemChangeListValueModelAdapter(ListValueModel<E> listHolder) { - super(listHolder); - this.itemChangeListener = this.buildItemChangeListener(); - } - - - // ********** initialization ********** - - protected ChangeListener buildItemChangeListener() { - return new SimpleChangeListener() { - @Override - protected void modelChanged(ChangeEvent event) { - ItemChangeListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - item.addChangeListener(this.itemChangeListener); - } - - @Override - protected void disengageItem_(Model item) { - item.removeChangeListener(this.itemChangeListener); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemCollectionListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemCollectionListValueModelAdapter.java deleted file mode 100644 index 8079739d76..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemCollectionListValueModelAdapter.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more collection - * aspects of each item in the wrapped list model. - */ -public class ItemCollectionListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' collections that we listen to. */ - protected final String[] collectionNames; - - /** Listener that listens to all the items in the list. */ - protected final CollectionChangeListener itemCollectionListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item Collections. - */ - public ItemCollectionListValueModelAdapter(ListValueModel<E> listHolder, String... collectionNames) { - super(listHolder); - this.collectionNames = collectionNames; - this.itemCollectionListener = this.buildItemCollectionListener(); - } - - /** - * Construct an adapter for the specified item Collections. - */ - public ItemCollectionListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... collectionNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), collectionNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a Collection aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected CollectionChangeListener buildItemCollectionListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void collectionCleared(CollectionClearEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void collectionChanged(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item collection listener: " + Arrays.asList(ItemCollectionListValueModelAdapter.this.collectionNames); //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - for (String collectionName : this.collectionNames) { - item.addCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - - @Override - protected void disengageItem_(Model item) { - for (String collectionName : this.collectionNames) { - item.removeCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemListListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemListListValueModelAdapter.java deleted file mode 100644 index 79cac2cdcc..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemListListValueModelAdapter.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more list - * aspects of each item in the wrapped list model. - */ -public class ItemListListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the subject's lists that we listen to. */ - protected final String[] listNames; - - /** Listener that listens to all the items in the list. */ - protected final ListChangeListener itemListListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item List aspects. - */ - public ItemListListValueModelAdapter(ListValueModel<E> listHolder, String... listNames) { - super(listHolder); - this.listNames = listNames; - this.itemListListener = this.buildItemListListener(); - } - - /** - * Construct an adapter for the specified item List aspects. - */ - public ItemListListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... listNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), listNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that the List aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected ListChangeListener buildItemListListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsMoved(ListMoveEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void listCleared(ListClearEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void listChanged(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item list listener: " + Arrays.asList(ItemListListValueModelAdapter.this.listNames); //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - for (String listName : this.listNames) { - item.addListChangeListener(listName, this.itemListListener); - } - } - - @Override - protected void disengageItem_(Model item) { - for (String listName : this.listNames) { - item.removeListChangeListener(listName, this.itemListListener); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemPropertyListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemPropertyListValueModelAdapter.java deleted file mode 100644 index 870a36590f..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemPropertyListValueModelAdapter.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more - * properties of each item in the wrapped list model. - */ -public class ItemPropertyListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' properties that we listen to. */ - protected final String[] propertyNames; - - /** Listener that listens to all the items in the list. */ - protected final PropertyChangeListener itemPropertyListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item properties. - */ - public ItemPropertyListValueModelAdapter(ListValueModel<E> listHolder, String... propertyNames) { - super(listHolder); - this.propertyNames = propertyNames; - this.itemPropertyListener = this.buildItemPropertyListener(); - } - - /** - * Construct an adapter for the specified item properties. - */ - public ItemPropertyListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... propertyNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), propertyNames); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildItemPropertyListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ItemPropertyListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item property listener: " + Arrays.asList(ItemPropertyListValueModelAdapter.this.propertyNames); //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - for (String propertyName : this.propertyNames) { - item.addPropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - - @Override - protected void disengageItem_(Model item) { - for (String propertyName : this.propertyNames) { - item.removePropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemStateListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemStateListValueModelAdapter.java deleted file mode 100644 index b4dc5ee61d..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemStateListValueModelAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to the - * "state" of each item in the wrapped list model. - */ -public class ItemStateListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - /** Listener that listens to all the items in the list. */ - protected final StateChangeListener itemStateListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the item state. - */ - public ItemStateListValueModelAdapter(ListValueModel<E> listHolder) { - super(listHolder); - this.itemStateListener = this.buildItemStateListener(); - } - - /** - * Construct an adapter for the item state. - */ - public ItemStateListValueModelAdapter(CollectionValueModel<E> collectionHolder) { - this(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** initialization ********** - - protected StateChangeListener buildItemStateListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ItemStateListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item state listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - item.addStateChangeListener(this.itemStateListener); - } - - @Override - protected void disengageItem_(Model item) { - item.removeStateChangeListener(this.itemStateListener); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemTreeListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemTreeListValueModelAdapter.java deleted file mode 100644 index 5ae5a968bd..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ItemTreeListValueModelAdapter.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more tree - * aspects of each item in the wrapped list model. - */ -public class ItemTreeListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' tree that we listen to. */ - protected final String[] treeNames; - - /** Listener that listens to all the items in the list. */ - protected final TreeChangeListener itemTreeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item trees. - */ - public ItemTreeListValueModelAdapter(ListValueModel<E> listHolder, String... treeNames) { - super(listHolder); - this.treeNames = treeNames; - this.itemTreeListener = this.buildItemTreeListener(); - } - - /** - * Construct an adapter for the specified item trees. - */ - public ItemTreeListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... treeNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), treeNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a tree aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected TreeChangeListener buildItemTreeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeAddEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void nodeRemoved(TreeRemoveEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void treeCleared(TreeClearEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void treeChanged(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item tree listener: " + Arrays.asList(ItemTreeListValueModelAdapter.this.treeNames); //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageItem_(Model item) { - for (String treeName : this.treeNames) { - item.addTreeChangeListener(treeName, this.itemTreeListener); - } - } - - @Override - protected void disengageItem_(Model item) { - for (String treeName : this.treeNames) { - item.removeTreeChangeListener(treeName, this.itemTreeListener); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListAspectAdapter.java deleted file mode 100644 index 82b5eb4e9b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListAspectAdapter.java +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This extension of {@link AspectListValueModelAdapter} provides - * basic list change support. - * This converts a set of one or more lists into - * a single {@link #LIST_VALUES} list. - * <p> - * The typical subclass will override the following methods (see the descriptions - * in {@link AspectListValueModelAdapter}):<ul> - * <li>{@link #listIterator_()} - * <li>{@link #get(int)} - * <li>{@link #size_()} - * <li>{@link #toArray_()} - * <li>{@link #listIterator()} - * <li>{@link #size()} - * <li>{@link #toArray()} - * </ul> - */ -public abstract class ListAspectAdapter<S extends Model, E> - extends AspectListValueModelAdapter<S, E> -{ - /** - * The name of the subject's lists that we use for the value. - */ - protected final String[] listNames; - protected static final String[] EMPTY_LIST_NAMES = new String[0]; - - /** A listener that listens to the subject's list aspects. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Construct a list aspect adapter for the specified subject - * and list. - */ - protected ListAspectAdapter(String listName, S subject) { - this(new String[] {listName}, subject); - } - - /** - * Construct a list aspect adapter for the specified subject - * and lists. - */ - protected ListAspectAdapter(String[] listNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), listNames); - } - - /** - * Construct a list aspect adapter for the specified subject holder - * and lists. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... listNames) { - super(subjectHolder); - this.listNames = listNames; - this.listChangeListener = this.buildListChangeListener(); - } - - /** - * Construct a list aspect adapter for the specified subject holder - * and lists. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> listNames) { - this(subjectHolder, listNames.toArray(new String[listNames.size()])); - } - - /** - * Construct a list aspect adapter for an "unchanging" list in - * the specified subject. This is useful for a list aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new list. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_LIST_NAMES); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - // transform the subject's list change events into VALUE list change events - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ListAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ListAspectAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ListAspectAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ListAspectAdapter.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ListAspectAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListAspectAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener: " + Arrays.asList(ListAspectAdapter.this.listNames); //$NON-NLS-1$ - } - }; - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected void engageSubject_() { - for (String listName : this.listNames) { - ((Model) this.subject).addListChangeListener(listName, this.listChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String listName : this.listNames) { - ((Model) this.subject).removeListChangeListener(listName, this.listChangeListener); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(ListAddEvent event) { - this.fireItemsAdded(event.clone(this, LIST_VALUES)); - } - - protected void itemsRemoved(ListRemoveEvent event) { - this.fireItemsRemoved(event.clone(this, LIST_VALUES)); - } - - protected void itemsReplaced(ListReplaceEvent event) { - this.fireItemsReplaced(event.clone(this, LIST_VALUES)); - } - - protected void itemsMoved(ListMoveEvent event) { - this.fireItemsMoved(event.clone(this, LIST_VALUES)); - } - - protected void listCleared(ListClearEvent event) { - this.fireListCleared(event.clone(this, LIST_VALUES)); - } - - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(event.clone(this, LIST_VALUES)); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCollectionValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCollectionValueModelAdapter.java deleted file mode 100644 index e37f223a6f..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCollectionValueModelAdapter.java +++ /dev/null @@ -1,233 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a {@link ListValueModel} behave like - * a read-only {@link CollectionValueModel}, sorta. - * <p> - * We keep an internal collection somewhat in synch with the wrapped list. - * <p> - * <strong>NB:</strong> Since we only listen to the wrapped list when we have - * listeners ourselves and we can only stay in synch with the wrapped - * list while we are listening to it, results to various methods - * (e.g. {@link #size()}, {@link iterator()}) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - */ -public class ListCollectionValueModelAdapter<E> - extends AbstractCollectionValueModel - implements CollectionValueModel<E> -{ - /** The wrapped list value model. */ - protected final ListValueModel<? extends E> listHolder; - - /** A listener that forwards any events fired by the list holder. */ - protected final ListChangeListener listChangeListener; - - /** - * Our internal collection, which holds the same elements as - * the wrapped list. - */ - // we declare this an ArrayList so we can use #clone() and #ensureCapacity(int) - protected final ArrayList<E> collection; - - - // ********** constructors ********** - - /** - * Wrap the specified list value model. - */ - public ListCollectionValueModelAdapter(ListValueModel<? extends E> listHolder) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - this.collection = new ArrayList<E>(); - // postpone building the collection and listening to the underlying list - // until we have listeners ourselves... - } - - - // ********** initialization ********** - - /** - * The wrapped list has changed, forward an equivalent - * collection change event to our listeners. - */ - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ListCollectionValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ListCollectionValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ListCollectionValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ListCollectionValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ListCollectionValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - // try to prevent backdoor modification of the list - return new ReadOnlyIterator<E>(this.collection); - } - - public int size() { - return this.collection.size(); - } - - - // ********** AbstractCollectionValueModel implementation ********** - - @Override - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, 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(); - } - - @Override - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - // clear out the collection when we are not listening to the list holder - this.collection.clear(); - } - - - // ********** behavior ********** - - protected void itemsAdded(ListAddEvent event) { - this.addItemsToCollection(this.getItems(event), this.collection, VALUES); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(ListAddEvent event) { - return (Iterable<E>) event.getItems(); - } - - protected void itemsRemoved(ListRemoveEvent event) { - this.removeItemsFromCollection(this.getItems(event), this.collection, VALUES); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(ListRemoveEvent event) { - return (Iterable<E>) event.getItems(); - } - - protected void itemsReplaced(ListReplaceEvent event) { - this.removeItemsFromCollection(this.getOldItems(event), this.collection, VALUES); - this.addItemsToCollection(this.getNewItems(event), this.collection, VALUES); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getOldItems(ListReplaceEvent event) { - return (Iterable<E>) event.getOldItems(); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getNewItems(ListReplaceEvent event) { - return (Iterable<E>) event.getNewItems(); - } - - protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) { - // do nothing? moving items in a list has no net effect on a collection... - } - - protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - this.collection.clear(); - this.fireCollectionCleared(VALUES); - } - } - - /** - * synchronize our internal collection with the wrapped list - * and fire the appropriate events - */ - protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) { - if (this.listHolder.size() == 0) { - if (this.collection.isEmpty()) { - // no change - } else { - this.clearCollection(this.collection, VALUES); - } - } else { - if (this.collection.isEmpty()) { - this.buildCollection(); - this.fireItemsAdded(VALUES, this.collection); - } else { - this.collection.clear(); - this.buildCollection(); - this.fireCollectionChanged(VALUES, this.collection); - } - } - } - - protected void buildCollection() { - // if the new list is empty, do nothing - int size = this.listHolder.size(); - if (size != 0) { - this.buildCollection(size); - } - } - - protected void buildCollection(int size) { - this.collection.ensureCapacity(size); - for (E each : this.listHolder) { - this.collection.add(each); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collection); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCurator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCurator.java deleted file mode 100644 index 753638b098..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListCurator.java +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.EventListener; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This extension of {@link AspectAdapter} provides list change support - * by adapting a subject's state change events to a minimum set - * of list change events. - */ -public abstract class ListCurator<S extends Model, E> - extends AspectAdapter<S> - implements ListValueModel<E> -{ - /** How the list looked before the last state change */ - private final ArrayList<E> record; - - /** A listener that listens for the subject's state to change */ - private final StateChangeListener stateChangeListener; - - - // ********** constructors ********** - - /** - * Construct a curator for the specified subject. - */ - protected ListCurator(S subject) { - this(new StaticPropertyValueModel<S>(subject)); - } - - /** - * Construct a curator for the specified subject holder. - * The subject holder cannot be null. - */ - protected ListCurator(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - this.record = new ArrayList<E>(); - this.stateChangeListener = this.buildStateChangeListener(); - } - - - // ********** initialization ********** - - /** - * The subject's state has changed, do inventory and report to listeners. - */ - protected StateChangeListener buildStateChangeListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ListCurator.this.submitInventoryReport(); - } - @Override - public String toString() { - return "state change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ListValueModel implementation ********** - - public ListIterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.record); - } - - /** - * Return the item at the specified index of the subject's list aspect. - */ - public E get(int index) { - return this.record.get(index); - } - - /** - * Return the size of the subject's list aspect. - */ - public int size() { - return this.record.size(); - } - - /** - * Return an array manifestation of the subject's list aspect. - */ - public Object[] toArray() { - return this.record.toArray(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected ListIterator<E> getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends EventListener> getListenerClass() { - return ListChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return LIST_VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - /** - * The aspect has changed, notify listeners appropriately. - */ - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - this.fireListChanged(LIST_VALUES, this.record); - } - - /** - * The subject is not null - add our listener. - */ - @Override - protected void engageSubject_() { - ((Model) this.subject).addStateChangeListener(this.stateChangeListener); - // synch our list *after* we start listening to the subject, - // since its value might change when a listener is added - CollectionTools.addAll(this.record, this.iteratorForRecord()); - } - - /** - * The subject is not null - remove our listener. - */ - @Override - protected void disengageSubject_() { - ((Model) this.subject).removeStateChangeListener(this.stateChangeListener); - // clear out the list when we are not listening to the subject - this.record.clear(); - } - - - // ********** ListCurator protocol ********** - - /** - * This is intended to be different from {@link ListValueModel#iterator()}. - * It is intended to be used only when the subject changes or the - * subject's "state" changes (as signified by a state change event). - */ - protected abstract Iterator<E> iteratorForRecord(); - - - // ********** behavior ********** - - void submitInventoryReport() { - List<E> newRecord = CollectionTools.list(this.iteratorForRecord()); - int recordIndex = 0; - - // add items from the new record - for (E newItem : newRecord) { - this.inventoryNewItem(recordIndex, newItem); - recordIndex++; - } - - // clean out items that are no longer in the new record - for (recordIndex = 0; recordIndex < this.record.size(); ) { - E item = this.record.get(recordIndex); - - if (newRecord.contains(item)) { - recordIndex++; - } else { - this.removeItemFromInventory(recordIndex, item); - } - } - } - - private void inventoryNewItem(int recordIndex, E newItem) { - List<E> rec = new ArrayList<E>(this.record); - - if ((recordIndex < rec.size()) && rec.get(recordIndex).equals(newItem)) { - return; - } - if (rec.contains(newItem)) { - this.removeItemFromInventory(recordIndex, rec.get(recordIndex)); - this.inventoryNewItem(recordIndex, newItem); - } else { - this.addItemToInventory(recordIndex, newItem); - } - } - - private void addItemToInventory(int index, E item) { - this.addItemToList(index, item, this.record, LIST_VALUES); - } - - private void removeItemFromInventory(int index, @SuppressWarnings("unused") E item) { - this.removeItemFromList(index, this.record, LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.record); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListPropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListPropertyValueModelAdapter.java deleted file mode 100644 index e3f7105771..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListPropertyValueModelAdapter.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a list value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * <p> - * Subclasses must override:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current list value - * </ul> - * Subclasses might want to override the following methods - * to improve performance (by not recalculating the value, if possible):<ul> - * <li>{@link #itemsAdded(ListAddEvent event)} - * <li>{@link #itemsRemoved(ListRemoveEvent event)} - * <li>{@link #itemsReplaced(ListReplaceEvent event)} - * <li>{@link #itemsMoved(ListMoveEvent event)} - * <li>{@link #listCleared(ListClearEvent event)} - * <li>{@link #listChanged(ListChangeEvent event)} - * </ul> - */ -public abstract class ListPropertyValueModelAdapter<T> - extends AbstractPropertyValueModelAdapter<T> -{ - /** The wrapped list value model. */ - protected final ListValueModel<?> listHolder; - - /** A listener that allows us to synch with changes to the wrapped list holder. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * list value model. - */ - protected ListPropertyValueModelAdapter(ListValueModel<?> listHolder) { - super(); - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - } - - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ListPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ListPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ListPropertyValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ListPropertyValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ListPropertyValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder. - */ - @Override - protected void engageModel_() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - /** - * Stop listening to the list holder. - */ - @Override - protected void disengageModel_() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(@SuppressWarnings("unused") ListAddEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were removed from the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsRemoved(@SuppressWarnings("unused") ListRemoveEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were replaced in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsReplaced(@SuppressWarnings("unused") ListReplaceEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were moved in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped list holder was cleared; - * propagate the change notification appropriately. - */ - protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The value of the wrapped list holder has changed; - * propagate the change notification appropriately. - */ - protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListValueModelWrapper.java deleted file mode 100644 index 7e01a399f3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ListValueModelWrapper.java +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another list value model, "lazily" listen to it, and propagate - * its change notifications. Subclasses must implement the appropriate - * {@link ListValueModel}. - */ -public abstract class ListValueModelWrapper<E> - extends AbstractListValueModel -{ - /** The wrapped list value model. */ - protected final ListValueModel<? extends E> listHolder; - - /** A listener that allows us to synch with changes to the wrapped list holder. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Construct a list value model with the specified wrapped - * list value model. - */ - protected ListValueModelWrapper(ListValueModel<? extends E> listHolder) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ListValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ListValueModelWrapper.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ListValueModelWrapper.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ListValueModelWrapper.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ListValueModelWrapper.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListValueModelWrapper.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder. - */ - @Override - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - /** - * Stop listening to the list holder. - */ - @Override - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(ListAddEvent event) { - return (Iterable<E>) event.getItems(); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getItems(ListRemoveEvent event) { - return (Iterable<E>) event.getItems(); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getNewItems(ListReplaceEvent event) { - return (Iterable<E>) event.getNewItems(); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<E> getOldItems(ListReplaceEvent event) { - return (Iterable<E>) event.getOldItems(); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(ListAddEvent event); - - /** - * Items were removed from the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(ListRemoveEvent event); - - /** - * Items were replaced in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsReplaced(ListReplaceEvent event); - - /** - * Items were moved in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsMoved(ListMoveEvent event); - - /** - * The wrapped list holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void listCleared(ListClearEvent event); - - /** - * The value of the wrapped list holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void listChanged(ListChangeEvent event); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullCollectionValueModel.java deleted file mode 100644 index ba1061b96c..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullCollectionValueModel.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * A read-only collection value model for when you - * don't need to support a collection. In particular, this - * is useful for the leaf nodes of a tree that never have - * children. - * <p> - * We don't use a singleton because we hold on to listeners. - */ -public final class NullCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullCollectionValueModel() { - super(); - } - - - // ********** CollectionValueModel implementation ********** - - public int size() { - return 0; - } - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullListValueModel.java deleted file mode 100644 index 78801cce30..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullListValueModel.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * An empty list value model for when you don't - * need to support a list. - * <p> - * We don't use a singleton because we hold on to listeners. - */ -public final class NullListValueModel<E> - extends AbstractModel - implements ListValueModel<E> -{ - private static final Object[] EMPTY_ARRAY = new Object[0]; - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullListValueModel() { - super(); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - public ListIterator<E> listIterator() { - return EmptyListIterator.instance(); - } - - public int size() { - return 0; - } - - public E get(int index) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public Object[] toArray() { - return EMPTY_ARRAY; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullPropertyValueModel.java deleted file mode 100644 index f445d96b36..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullPropertyValueModel.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A property value model for when you - * don't need to support a value. - * <p> - * We don't use a singleton because we hold on to listeners. - */ -public final class NullPropertyValueModel<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullPropertyValueModel() { - super(); - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return null; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullTreeValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullTreeValueModel.java deleted file mode 100644 index ad4b960b6e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/NullTreeValueModel.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.TreeValueModel; - -/** - * A tree value model for when you - * don't need to support any nodes. - * <p> - * We don't use a singleton because we hold on to listeners. - */ -public final class NullTreeValueModel<E> - extends AbstractModel - implements TreeValueModel<E> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullTreeValueModel() { - super(); - } - - - // ********** TreeValueModel implementation ********** - - public Iterator<E> nodes() { - return EmptyIterator.instance(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java deleted file mode 100644 index 327a7342d3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This {@link AspectPropertyValueModelAdapter} provides basic property change support. - * This converts a set of one or more standard properties into - * a single {@link #VALUE} property. - * <p> - * The typical subclass will override the following methods (see the descriptions - * in {@link AspectPropertyValueModelAdapter}):<ul> - * <li>{@link #buildValue_()} - * <li>{@link #setValue_(Object)} - * <li>{@link #buildValue()} - * <li>{@link #setValue(Object)} - * </ul> - */ -public abstract class PropertyAspectAdapter<S extends Model, V> - extends AspectPropertyValueModelAdapter<S, V> -{ - /** The name of the subject's properties that we use for the value. */ - protected final String[] propertyNames; - protected static final String[] EMPTY_PROPERTY_NAMES = new String[0]; - - /** A listener that listens to the appropriate properties of the subject. */ - protected final PropertyChangeListener propertyChangeListener; - - - // ********** constructors ********** - - /** - * Construct a property aspect adapter for the specified subject - * and property. - */ - protected PropertyAspectAdapter(String propertyName, S subject) { - this(new String[] {propertyName}, subject); - } - - /** - * Construct a property aspect adapter for the specified subject - * and properties. - */ - protected PropertyAspectAdapter(String[] propertyNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), propertyNames); - } - - /** - * Construct a property aspect adapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... propertyNames) { - super(subjectHolder); - this.propertyNames = propertyNames; - this.propertyChangeListener = this.buildPropertyChangeListener(); - } - - /** - * Construct a property aspect adapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> propertyNames) { - this(subjectHolder, propertyNames.toArray(new String[propertyNames.size()])); - } - - /** - * Construct a property aspect adapter for an "unchanging" property in - * the specified subject. This is useful for a property aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new property. (A {@link TransformationPropertyValueModel} could also be - * used in this situation.) - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_PROPERTY_NAMES); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildPropertyChangeListener() { - // transform the subject's property change events into VALUE property change events - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - PropertyAspectAdapter.this.propertyChanged(event); - } - @Override - public String toString() { - return "property change listener: " + Arrays.asList(PropertyAspectAdapter.this.propertyNames); //$NON-NLS-1$ - } - }; - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected void engageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).addPropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).removePropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - protected void propertyChanged(@SuppressWarnings("unused") PropertyChangeEvent event) { - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyCollectionValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyCollectionValueModelAdapter.java deleted file mode 100644 index 1d432aeda5..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyCollectionValueModelAdapter.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Collections; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.internal.iterators.SingleElementIterator; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a {@link PropertyValueModel} behave like - * a read-only, single-element {@link CollectionValueModel}, sorta. - * <p> - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a collection with a <code>null</code> element). - */ -public class PropertyCollectionValueModelAdapter<E> - extends AbstractCollectionValueModel - implements CollectionValueModel<E> -{ - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends E> valueHolder; - - /** A listener that forwards any events fired by the value holder. */ - protected final PropertyChangeListener propertyChangeListener; - - /** Cache the value. */ - protected E value; - - - // ********** constructors/initialization ********** - - /** - * Convert the specified property value model to a collection - * value model. - */ - public PropertyCollectionValueModelAdapter(PropertyValueModel<? extends E> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.propertyChangeListener = this.buildPropertyChangeListener(); - this.value = null; - // postpone building the value and listening to the underlying value - // until we have listeners ourselves... - } - - /** - * The wrapped value has changed, forward an equivalent - * collection change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - @SuppressWarnings("unchecked") - E eventNewValue = (E) event.getNewValue(); - PropertyCollectionValueModelAdapter.this.valueChanged(eventNewValue); - } - @Override - public String toString() { - return "property change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return (this.value == null) ? EmptyIterator.<E>instance() : this.iterator_(); - } - - protected Iterator<E> iterator_() { - return new SingleElementIterator<E>(this.value); - } - - public int size() { - return (this.value == null) ? 0 : 1; - } - - - // ********** AbstractCollectionValueModel implementation ********** - - @Override - protected void engageModel() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.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.getValue(); - } - - @Override - protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // clear out the value when we are not listening to the value holder - this.value = null; - } - - - // ********** behavior ********** - - /** - * synchronize our internal value with the wrapped value - * and fire the appropriate events - */ - protected void valueChanged(E newValue) { - E oldValue = this.value; - this.value = newValue; - if (oldValue == null) { - // we wouldn't get the event if the new value were null too - this.fireItemAdded(VALUES, newValue); - } else { - if (newValue == null) { - this.fireItemRemoved(VALUES, oldValue); - } else { - // we wouldn't get the event if the new value was the same as the old - this.fireCollectionChanged(VALUES, Collections.singleton(newValue)); - } - } - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyListValueModelAdapter.java deleted file mode 100644 index 81fa3cc8a8..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyListValueModelAdapter.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.common.utility.internal.iterators.SingleElementListIterator; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a {@link PropertyValueModel} behave like - * a read-only, single-element {@link ListValueModel}, sorta. - * <p> - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a collection with a <code>null</code> element). - */ -public class PropertyListValueModelAdapter<E> - extends AbstractListValueModel - implements ListValueModel<E> -{ - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends E> valueHolder; - - /** A listener that forwards any events fired by the value holder. */ - protected final PropertyChangeListener propertyChangeListener; - - /** Cache the value. */ - protected E value; - - - // ********** constructors/initialization ********** - - /** - * Convert the specified property value model to a list - * value model. - */ - public PropertyListValueModelAdapter(PropertyValueModel<? extends E> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.propertyChangeListener = this.buildPropertyChangeListener(); - // postpone building the value and listening to the underlying value - // until we have listeners ourselves... - } - - /** - * The wrapped value has changed, forward an equivalent - * list change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - @SuppressWarnings("unchecked") - E eventNewValue = (E) event.getNewValue(); - PropertyListValueModelAdapter.this.valueChanged(eventNewValue); - } - @Override - public String toString() { - return "property change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return (this.value == null) ? - EmptyListIterator.<E>instance() - : - new SingleElementListIterator<E>(this.value); - } - - public int size() { - return (this.value == null) ? 0 : 1; - } - - public E get(int index) { - if (this.value == null) { - throw this.buildIOOBE(index, 0); - } - if (index > 0) { - throw this.buildIOOBE(index, 1); - } - return this.value; - } - - protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - public Object[] toArray() { - return (this.value == null) ? EMPTY_OBJECT_ARRAY : new Object[] {this.value}; - } - - - // ********** behavior ********** - - protected IndexOutOfBoundsException buildIOOBE(int index, int size) { - return new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - protected void engageModel() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.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.getValue(); - } - - @Override - protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // clear out the value when we are not listening to the value holder - this.value = null; - } - - /** - * synchronize our internal value with the wrapped value - * and fire the appropriate events - */ - protected void valueChanged(E newValue) { - E oldValue = this.value; - this.value = newValue; - if (oldValue == null) { - this.fireItemAdded(LIST_VALUES, 0, newValue); - } else { - if (newValue == null) { - this.fireItemRemoved(LIST_VALUES, 0, oldValue); - } else { - this.fireItemReplaced(LIST_VALUES, 0, newValue, oldValue); - } - } - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelWrapper.java deleted file mode 100644 index 241b85d609..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelWrapper.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another property value model, "lazily" listen to it, and propagate - * its change notifications. Subclasses must implement the appropriate - * {@link PropertyValueModel}. - * <p> - * Subclasses must implement the following methods:<ul> - * <li>{@link #valueChanged(PropertyChangeEvent)}<p> - * implement this method to propagate the appropriate change notification - * </ul> - */ -public abstract class PropertyValueModelWrapper<V> - extends AbstractPropertyValueModel -{ - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends V> valueHolder; - - /** A listener that allows us to synch with changes to the wrapped value holder. */ - protected final PropertyChangeListener valueChangeListener; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * property value model. The value holder is required. - */ - protected PropertyValueModelWrapper(PropertyValueModel<? extends V> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.valueChangeListener = this.buildValueChangeListener(); - } - - protected PropertyChangeListener buildValueChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - PropertyValueModelWrapper.this.valueChanged(event); - } - @Override - public String toString() { - return "value change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Begin listening to the value holder. - */ - @Override - protected void engageModel() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - /** - * Stop listening to the value holder. - */ - @Override - protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - - // ********** property change support ********** - - /** - * The value of the wrapped value holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void valueChanged(PropertyChangeEvent event); - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ReadOnlyWritablePropertyValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ReadOnlyWritablePropertyValueModelWrapper.java deleted file mode 100644 index dcf7b97594..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ReadOnlyWritablePropertyValueModelWrapper.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * A simple implementation of {@link WritablePropertyValueModel} that actually - * ... <em>isn't</em> ... writable. It can however be used in places that require a - * {@link WritablePropertyValueModel} and where the developer is sure that no - * attempt will be made to write to it. - */ -public class ReadOnlyWritablePropertyValueModelWrapper<T> - extends PropertyValueModelWrapper<T> - implements WritablePropertyValueModel<T> -{ - public ReadOnlyWritablePropertyValueModelWrapper(PropertyValueModel<? extends T> valueHolder) { - super(valueHolder); - } - - - public T getValue() { - return this.valueHolder.getValue(); - } - - public void setValue(T value) { - throw new UnsupportedOperationException(); - } - - @Override - protected void valueChanged(PropertyChangeEvent event) { - this.firePropertyChanged(event.clone(this)); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SetCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SetCollectionValueModel.java deleted file mode 100644 index d04722f9ff..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SetCollectionValueModel.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.HashBag; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * A <code>SetCollectionValueModel</code> wraps another - * {@link CollectionValueModel} and returns the items in the collection - * only once. - */ -public class SetCollectionValueModel<E> - extends CollectionValueModelWrapper<E> - implements CollectionValueModel<E> -{ - private final HashBag<E> bag = new HashBag<E>(); - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model and a filter that simply accepts every object. - */ - public SetCollectionValueModel(CollectionValueModel<? extends E> collectionHolder) { - super(collectionHolder); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and a filter that simply accepts every object. - */ - public SetCollectionValueModel(ListValueModel<E> listHolder) { - this(new ListCollectionValueModelAdapter<E>(listHolder)); - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.bag.uniqueIterator()); - } - - public int size() { - return this.bag.uniqueCount(); - } - - - // ********** CollectionValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the nested collection, - // since its value might change when a listener is added - CollectionTools.addAll(this.bag, this.collectionHolder); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the cache when we are not listening to the nested collection - this.bag.clear(); - } - - @Override - protected void itemsAdded(CollectionAddEvent event) { - ArrayList<E> addedItems = new ArrayList<E>(event.getItemsSize()); - int uniqueCount = this.bag.uniqueCount(); - for (E item : this.getItems(event)) { - this.bag.add(item); - if (this.bag.uniqueCount() > uniqueCount) { - uniqueCount = this.bag.uniqueCount(); - addedItems.add(item); - } - } - this.fireItemsAdded(VALUES, addedItems); - } - - @Override - protected void itemsRemoved(CollectionRemoveEvent event) { - ArrayList<E> removedItems = new ArrayList<E>(event.getItemsSize()); - int uniqueCount = this.bag.uniqueCount(); - for (E item : this.getItems(event)) { - if (this.bag.remove(item)) { - if (this.bag.uniqueCount() < uniqueCount) { - uniqueCount = this.bag.uniqueCount(); - removedItems.add(item); - } - } else { - throw new IllegalStateException("missing item: " + item); //$NON-NLS-1$ - } - } - this.fireItemsRemoved(VALUES, removedItems); - } - - @Override - protected void collectionCleared(CollectionClearEvent event) { - this.clearCollection(this.bag, VALUES); - } - - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.bag.clear(); - CollectionTools.addAll(this.bag, this.collectionHolder); - this.fireCollectionChanged(VALUES, new HashSet<E>(this.bag)); - } - - @Override - public void toString(StringBuilder sb) { - StringTools.append(sb, this); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleCollectionValueModel.java deleted file mode 100644 index 794eec1e11..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleCollectionValueModel.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.HashBag; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.WritableCollectionValueModel; - -/** - * Implementation of {@link WritableCollectionValueModel} and {@link Collection} - * that simply holds a collection and notifies listeners of any changes. - */ -public class SimpleCollectionValueModel<E> - extends AbstractModel - implements WritableCollectionValueModel<E>, Collection<E> -{ - /** The collection. */ - protected final Collection<E> collection; - - - // ********** constructors ********** - - /** - * Construct a collection value model for the specified collection. - */ - public SimpleCollectionValueModel(Collection<E> collection) { - super(); - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - } - - /** - * Construct a collection value model with an empty initial collection. - */ - public SimpleCollectionValueModel() { - this(new HashBag<E>()); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return new LocalIterator<E>(this.collection.iterator()); - } - - public int size() { - return this.collection.size(); - } - - - // ********** WritableCollectionValueModel implementation ********** - - /** - * Allow the collection's elements to be replaced. - */ - public void setValues(Iterable<E> values) { - if (values == null) { - throw new NullPointerException(); - } - this.collection.clear(); - CollectionTools.addAll(this.collection, values); - this.fireCollectionChanged(VALUES, this.collection); - } - - - // ********** Collection implementation ********** - - public boolean isEmpty() { - return this.collection.isEmpty(); - } - - public boolean contains(Object o) { - return this.collection.contains(o); - } - - public Object[] toArray() { - return this.collection.toArray(); - } - - public <T extends Object> T[] toArray(T[] a) { - return this.collection.toArray(a); - } - - public boolean add(E o) { - return this.addItemToCollection(o, this.collection, VALUES); - } - - public boolean remove(Object o) { - return this.removeItemFromCollection(o, this.collection, VALUES); - } - - public boolean containsAll(Collection<?> c) { - return this.collection.containsAll(c); - } - - public boolean addAll(Collection<? extends E> c) { - return this.addItemsToCollection(c, this.collection, VALUES); - } - - public boolean removeAll(Collection<?> c) { - return this.removeItemsFromCollection(c, this.collection, VALUES); - } - - public boolean retainAll(Collection<?> c) { - return this.retainItemsInCollection(c, this.collection, VALUES); - } - - public void clear() { - this.clearCollection(this.collection, VALUES); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ((o instanceof Collection<?>) && (o instanceof CollectionValueModel<?>)) { - Collection<E> c1 = CollectionTools.collection(this.collection); - @SuppressWarnings("unchecked") - Collection<E> c2 = CollectionTools.collection(((Collection<E>) o).iterator()); - return c1.equals(c2); - } - return false; - } - - @Override - public int hashCode() { - return CollectionTools.collection(this.collection).hashCode(); - } - - - // ********** miscellaneous ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collection); - } - - - // ********** iterator ********** - - private class LocalIterator<T> implements Iterator<T> { - private final Iterator<T> iterator; - private T next; - - LocalIterator(Iterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - return this.next = this.iterator.next(); - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleCollectionValueModel.this.fireItemRemoved(VALUES, this.next); - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleListValueModel.java deleted file mode 100644 index 90943f9af1..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimpleListValueModel.java +++ /dev/null @@ -1,322 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.WritableListValueModel; - -/** - * Implementation of {@link ListValueModel} and {@link List} that simply holds a - * list and notifies listeners of any changes. - */ -public class SimpleListValueModel<E> - extends AbstractModel - implements WritableListValueModel<E>, List<E> -{ - /** The list. */ - protected List<E> list; - - - // ********** constructors ********** - - /** - * Construct a list value model for the specified list. - */ - public SimpleListValueModel(List<E> list) { - super(); - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - } - - /** - * Construct a list value model with an empty initial list. - */ - public SimpleListValueModel() { - this(new ArrayList<E>()); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return new LocalIterator<E>(this.list.iterator()); - } - - public ListIterator<E> listIterator() { - return new LocalListIterator<E>(this.list.listIterator()); - } - - public int size() { - return this.list.size(); - } - - public E get(int index) { - return this.list.get(index); - } - - - // ********** WritableListValueModel implementation ********** - - /** - * Allow the list's elements to be replaced. - */ - public void setListValues(Iterable<E> list) { - if (list == null) { - throw new NullPointerException(); - } - this.list.clear(); - CollectionTools.addAll(this.list, list); - this.fireListChanged(LIST_VALUES, this.list); - } - - - // ********** List implementation ********** - - public boolean isEmpty() { - return this.list.isEmpty(); - } - - public boolean contains(Object o) { - return this.list.contains(o); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - public <T extends Object> T[] toArray(T[] a) { - return this.list.toArray(a); - } - - public boolean add(E o) { - return this.addItemToList(o, this.list, LIST_VALUES); - } - - public boolean remove(Object o) { - return this.removeItemFromList(o, this.list, LIST_VALUES); - } - - public boolean containsAll(Collection<?> c) { - return this.list.containsAll(c); - } - - public boolean addAll(Collection<? extends E> c) { - return this.addItemsToList(c, this.list, LIST_VALUES); - } - - public boolean addAll(int index, Collection<? extends E> c) { - return this.addItemsToList(index, c, this.list, LIST_VALUES); - } - - public boolean removeAll(Collection<?> c) { - return this.removeItemsFromList(c, this.list, LIST_VALUES); - } - - public boolean retainAll(Collection<?> c) { - return this.retainItemsInList(c, this.list, LIST_VALUES); - } - - public void clear() { - this.clearList(this.list, LIST_VALUES); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ((o instanceof List<?>) && (o instanceof ListValueModel<?>)) { - List<E> l1 = CollectionTools.list(this.list); - @SuppressWarnings("unchecked") - List<E> l2 = CollectionTools.list(((List<E>) o).iterator()); - return l1.equals(l2); - } - return false; - } - - @Override - public int hashCode() { - return this.list.hashCode(); - } - - public E set(int index, E element) { - return this.setItemInList(index, element, this.list, LIST_VALUES); - } - - public void add(int index, E element) { - this.addItemToList(index, element, this.list, LIST_VALUES); - } - - public E remove(int index) { - return this.removeItemFromList(index, this.list, LIST_VALUES); - } - - public int indexOf(Object o) { - return this.list.indexOf(o); - } - - public int lastIndexOf(Object o) { - return this.list.lastIndexOf(o); - } - - public ListIterator<E> listIterator(int index) { - return new LocalListIterator<E>(this.list.listIterator(index)); - } - - public List<E> subList(int fromIndex, int toIndex) { - // TODO hmmm ~bjv - throw new UnsupportedOperationException(); - } - - - // ********** additional behavior ********** - - /** - * Move a single element. - */ - public void move(int targetIndex, int sourceIndex) { - this.moveItemInList(targetIndex, sourceIndex, this.list, LIST_VALUES); - } - - /** - * Move a sub-list of elements. - */ - public void move(int targetIndex, int sourceIndex, int length) { - this.moveItemsInList(targetIndex, sourceIndex, length, this.list, LIST_VALUES); - } - - /** - * Remove a range of elements. - */ - public void remove(int index, int length) { - this.removeItemsFromList(index, length, this.list, LIST_VALUES); - } - - /** - * Set a range of elements. - */ - public void set(int index, List<E> elements) { - this.setItemsInList(index, elements, this.list, LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.list); - } - - - // ********** iterators ********** - - private class LocalIterator<T> implements Iterator<T> { - private final Iterator<T> iterator; - private int index = -1; - private T next; - - LocalIterator(Iterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - this.next = this.iterator.next(); - this.index++; - return this.next; - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.index, this.next); - } - - } - - private class LocalListIterator<T> implements ListIterator<T> { - private final ListIterator<T> iterator; - private int last = -1; - private int next = 0; - private T current; - - LocalListIterator(ListIterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - this.current = this.iterator.next(); - this.last = this.next++; - return this.current; - } - - public int nextIndex() { - return this.iterator.nextIndex(); - } - - public boolean hasPrevious() { - return this.iterator.hasPrevious(); - } - - public T previous() { - this.current = this.iterator.previous(); - this.last = --this.next; - return this.current; - } - - public int previousIndex() { - return this.iterator.previousIndex(); - } - - @SuppressWarnings("synthetic-access") - public void set(T o) { - this.iterator.set(o); - SimpleListValueModel.this.fireItemReplaced(LIST_VALUES, this.last, o, this.current); - } - - @SuppressWarnings("synthetic-access") - public void add(T o) { - this.iterator.add(o); - SimpleListValueModel.this.fireItemAdded(LIST_VALUES, this.next, o); - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.last, this.current); - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimplePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimplePropertyValueModel.java deleted file mode 100644 index 844d1c693e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SimplePropertyValueModel.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Implementation of {@link WritablePropertyValueModel} that simply holds on to an - * object and uses it as the value. - */ -public class SimplePropertyValueModel<T> - extends AbstractModel - implements WritablePropertyValueModel<T> -{ - /** The value. */ - protected T value; - - - /** - * Construct a property value model for the specified value. - */ - public SimplePropertyValueModel(T value) { - super(); - this.value = value; - } - - /** - * Construct a property value model with a starting value of null. - */ - public SimplePropertyValueModel() { - this(null); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, VALUE); - } - - - public T getValue() { - return this.value; - } - - public void setValue(T value) { - T old = this.value; - this.value = value; - this.firePropertyChanged(VALUE, old, value); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.value); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelAdapter.java deleted file mode 100644 index 0f1ff4cf55..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelAdapter.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.Range; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * An adapter that allows us to make a {@link CollectionValueModel} - * (or {@link ListValueModel}) behave like a {@link ListValueModel} - * that keeps its contents sorted and notifies listeners appropriately. - * <p> - * The {@link Comparator} can be changed at any time; allowing the same - * adapter to be used with different sort criteria (e.g. when the user - * wants to sort a list of files first by name, then by date, then by size). - * <p> - * <strong>NB:</strong> Since we only listen to the wrapped collection when we have - * listeners ourselves and we can only stay in synch with the wrapped - * collection while we are listening to it, results to various methods - * (e.g. {@link #size()}, {@link #get(int)}) will be - * unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - * - * @see SortedListValueModelWrapper - */ -public class SortedListValueModelAdapter<E> - extends CollectionListValueModelAdapter<E> -{ - /** - * A comparator used for sorting the elements; - * if it is null, we use "natural ordering". - */ - protected Comparator<E> comparator; - - - // ********** constructors ********** - - /** - * Wrap the specified collection value model and sort its contents - * using the specified comparator. - */ - public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder, Comparator<E> comparator) { - super(collectionHolder); - this.comparator = comparator; - } - - /** - * Wrap the specified collection value model and sort its contents - * based on the elements' "natural ordering". - */ - public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - this(collectionHolder, null); - } - - - // ********** accessors ********** - - public void setComparator(Comparator<E> comparator) { - this.comparator = comparator; - this.sortList(); - } - - - // ********** behavior ********** - - /** - * Sort the internal list before the superclass - * sends out change notification. - */ - @Override - protected void buildList(int size) { - super.buildList(size); - Collections.sort(this.list, this.comparator); - } - - /** - * Sort the list after adding the items. - */ - @Override - protected void itemsAdded(CollectionAddEvent event) { - @SuppressWarnings("unchecked") - ArrayList<E> newList = (ArrayList<E>) this.list.clone(); - newList.ensureCapacity(newList.size() + event.getItemsSize()); - CollectionTools.addAll(newList, this.getItems(event)); - Collections.sort(newList, this.comparator); - this.synchronizeList(newList, this.list, LIST_VALUES); - } - - @Override - protected Iterable<? extends E> buildSyncList() { - return CollectionTools.sortedSet(this.collectionHolder, this.comparator, this.collectionHolder.size()); - } - - /** - * sort the list and notify our listeners, if necessary; - */ - protected void sortList() { - // save the unsorted state of the sorted list so we can minimize the number of "replaced" items - @SuppressWarnings("unchecked") - ArrayList<E> unsortedList = (ArrayList<E>) this.list.clone(); - Collections.sort(this.list, this.comparator); - Range diffRange = CollectionTools.identityDiffRange(unsortedList, this.list); - if (diffRange.size > 0) { - List<E> unsortedItems = unsortedList.subList(diffRange.start, diffRange.end + 1); - List<E> sortedItems = this.list.subList(diffRange.start, diffRange.end + 1); - this.fireItemsReplaced(LIST_VALUES, diffRange.start, sortedItems, unsortedItems); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelWrapper.java deleted file mode 100644 index 8514f37266..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/SortedListValueModelWrapper.java +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.Range; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * A wrapper that keeps the contents of a {@link ListValueModel} sorted - * and notifies listeners appropriately. - * <p> - * The {@link Comparator} can be changed at any time; allowing the same - * adapter to be used with different sort criteria (e.g. when the user - * wants to sort a list of files first by name, then by date, then by size). - * <p> - * <strong>NB:</strong> Since we only listen to the wrapped collection when we have - * listeners ourselves and we can only stay in synch with the wrapped - * collection while we are listening to it, results to various methods - * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - * - * @see SortedListValueModelAdapter - */ -public class SortedListValueModelWrapper<E> - extends ListValueModelWrapper<E> - implements ListValueModel<E> -{ - /** - * A comparator used for sorting the elements; - * if it is null, we use "natural ordering". - */ - protected Comparator<E> comparator; - - /** - * Our internal list, which holds the same elements as - * the wrapped list, but keeps them sorted. - */ - // we declare this an ArrayList so we can use #clone() and #ensureCapacity(int) - protected final ArrayList<E> sortedList; - - - // ********** constructors ********** - - /** - * Wrap the specified list value model and sort its contents - * using the specified comparator. - */ - public SortedListValueModelWrapper(ListValueModel<? extends E> listHolder, Comparator<E> comparator) { - super(listHolder); - this.comparator = comparator; - this.sortedList = new ArrayList<E>(listHolder.size()); - // postpone building the sorted list and listening to the wrapped list - // until we have listeners ourselves... - } - - /** - * Wrap the specified list value model and sort its contents - * based on the elements' "natural ordering". - */ - public SortedListValueModelWrapper(ListValueModel<? extends E> listHolder) { - this(listHolder, null); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.sortedList); - } - - public E get(int index) { - return this.sortedList.get(index); - } - - public int size() { - return this.sortedList.size(); - } - - public Object[] toArray() { - return this.sortedList.toArray(); - } - - - // ********** accessors ********** - - public void setComparator(Comparator<E> comparator) { - this.comparator = comparator; - this.sortList(); - } - - - // ********** behavior ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch the sorted list *after* we start listening to the wrapped list holder, - // since its value might change when a listener is added - this.buildSortedList(); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the sorted list when we are not listening to the wrapped list holder - this.sortedList.clear(); - } - - protected void buildSortedList() { - // if the new list is empty, do nothing - int size = this.listHolder.size(); - if (size != 0) { - this.buildSortedList(size); - } - } - - protected void buildSortedList(int size) { - this.sortedList.ensureCapacity(size); - for (E each : this.listHolder) { - this.sortedList.add(each); - } - Collections.sort(this.sortedList, this.comparator); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list. - */ - @Override - protected void itemsAdded(ListAddEvent event) { - // first add the items and notify our listeners... - this.addItemsToList(this.getItems(event), this.sortedList, LIST_VALUES); - // ...then sort the list and notify our listeners - this.sortList(); - } - - /** - * Items were removed from the wrapped list. - */ - @Override - protected void itemsRemoved(ListRemoveEvent event) { - this.removeItemsFromList(this.getItems(event), this.sortedList, LIST_VALUES); - // no sorting needed - } - - /** - * Items were replaced in the wrapped list. - */ - @Override - protected void itemsReplaced(ListReplaceEvent event) { - // first remove the old items and notify our listeners... - this.removeItemsFromList(this.getOldItems(event), this.sortedList, LIST_VALUES); - // then add the new items and notify our listeners... - this.addItemsToList(this.getNewItems(event), this.sortedList, LIST_VALUES); - // ...then sort the list and notify our listeners - this.sortList(); - } - - /** - * Items were moved in the wrapped list. - */ - @Override - protected void itemsMoved(ListMoveEvent event) { - // do nothing - sort order should remain unchanged - } - - /** - * The wrapped list was cleared. - */ - @Override - protected void listCleared(ListClearEvent event) { - this.clearList(this.sortedList, LIST_VALUES); - } - - /** - * The wrapped list has changed in some dramatic fashion. - * Rebuild our sorted list and notify our listeners. - */ - @Override - protected void listChanged(ListChangeEvent event) { - int size = this.listHolder.size(); - if (size == 0) { - if (this.sortedList.isEmpty()) { - // no change - } else { - this.clearList(this.sortedList, LIST_VALUES); - } - } else { - if (this.sortedList.isEmpty()) { - this.buildSortedList(size); - this.fireItemsAdded(LIST_VALUES, 0, this.sortedList); - } else { - this.sortedList.clear(); - this.buildSortedList(size); - this.fireListChanged(LIST_VALUES, this.sortedList); - } - } - } - - /** - * sort the sorted list and notify our listeners, if necessary; - */ - protected void sortList() { - // save the unsorted state of the sorted list so we can minimize the number of "replaced" items - @SuppressWarnings("unchecked") - ArrayList<E> unsortedList = (ArrayList<E>) this.sortedList.clone(); - Collections.sort(this.sortedList, this.comparator); - Range diffRange = CollectionTools.identityDiffRange(unsortedList, this.sortedList); - if (diffRange.size > 0) { - List<E> unsortedItems = unsortedList.subList(diffRange.start, diffRange.end + 1); - List<E> sortedItems = this.sortedList.subList(diffRange.start, diffRange.end + 1); - this.fireItemsReplaced(LIST_VALUES, diffRange.start, sortedItems, unsortedItems); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.sortedList); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StatePropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StatePropertyValueModelAdapter.java deleted file mode 100644 index 6d179ffa63..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StatePropertyValueModelAdapter.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; - -/** - * This abstract class provides the infrastructure needed to wrap - * a model, "lazily" listen to it, and convert - * its state change notifications into property value model change - * notifications. - * <p> - * Subclasses must implement:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current model - * </ul> - * Subclasses might want to override the following methods - * to improve performance (by not recalculating the value, if possible):<ul> - * <li>{@link #stateChanged(StateChangeEvent event)} - * </ul> - */ -public abstract class StatePropertyValueModelAdapter<T> - extends AbstractPropertyValueModelAdapter<T> -{ - /** The wrapped model. */ - protected final Model model; - - /** A listener that allows us to synch with changes to the wrapped model. */ - protected final StateChangeListener stateChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped model. - */ - protected StatePropertyValueModelAdapter(Model model) { - super(); - this.model = model; - this.stateChangeListener = this.buildStateChangeListener(); - } - - protected StateChangeListener buildStateChangeListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - StatePropertyValueModelAdapter.this.stateChanged(event); - } - @Override - public String toString() { - return "state change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the model. - */ - @Override - protected void engageModel_() { - this.model.addStateChangeListener(this.stateChangeListener); - } - - /** - * Stop listening to the model. - */ - @Override - protected void disengageModel_() { - this.model.removeStateChangeListener(this.stateChangeListener); - } - - - // ********** state change support ********** - - /** - * The model's state changed; - * propagate the change notification appropriately. - */ - protected void stateChanged(@SuppressWarnings("unused") StateChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticCollectionValueModel.java deleted file mode 100644 index 854528690a..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticCollectionValueModel.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.internal.ArrayTools; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; - -/** - * Implementation of {@link CollectionValueModel} that can be used for - * returning an iterator on a static collection, but still allows listeners to be added. - * Listeners will <em>never</em> be notified of any changes, because there should be none. - */ -public class StaticCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - /** The elements. */ - protected final Object[] elements; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static collection value model for the specified array. - */ - public StaticCollectionValueModel(E... elements) { - super(); - this.elements = elements.clone(); - } - - /** - * Construct a static collection value model for the specified elements. - */ - public StaticCollectionValueModel(Iterable<? extends E> elements) { - super(); - this.elements = ArrayTools.array(elements); - } - - - // ********** CollectionValueModel implementation ********** - - public int size() { - return this.elements.length; - } - - @SuppressWarnings("unchecked") - public Iterator<E> iterator() { - // we can cast here since our constructors require the elements to be - // of type E and ArrayIterator is read-only - return (Iterator<E>) new ArrayIterator<Object>(this.elements); - } - - - // ********** Object overrides ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(Arrays.toString(this.elements)); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticListValueModel.java deleted file mode 100644 index c08b6f42e8..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticListValueModel.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.ArrayTools; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayListIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * Implementation of {@link ListValueModel} that can be used for - * returning a list iterator on a static list, but still allows listeners to be added. - * Listeners will <em>never</em> be notified of any changes, because there should be none. - */ -public class StaticListValueModel<E> - extends AbstractModel - implements ListValueModel<E> -{ - /** The elements. */ - protected final Object[] elements; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static list value model for the specified elements. - */ - public StaticListValueModel(E... elements) { - super(); - this.elements = elements.clone(); - } - - /** - * Construct a static list value model for the specified elements. - */ - public StaticListValueModel(Iterable<? extends E> elements) { - super(); - this.elements = ArrayTools.array(elements); - } - - - // ********** ListValueModel implementation ********** - - @SuppressWarnings("unchecked") - public Iterator<E> iterator() { - // we can cast here since our constructors require the elements to be - // of type E and ArrayIterator is read-only - return (Iterator<E>) new ArrayIterator<Object>(this.elements); - } - - @SuppressWarnings("unchecked") - public ListIterator<E> listIterator() { - // we can cast here since our constructors require the elements to be - // of type E and ArrayListIterator is read-only - return (ListIterator<E>) new ArrayListIterator<Object>(this.elements); - } - - public int size() { - return this.elements.length; - } - - @SuppressWarnings("unchecked") - public E get(int index) { - // we can cast here since our constructors require the elements to be - // of type E - return (E) this.elements[index]; - } - - public Object[] toArray() { - return this.elements.clone(); - } - - - // ********** Object overrides ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(Arrays.toString(this.elements)); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticPropertyValueModel.java deleted file mode 100644 index 678f5aaefd..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticPropertyValueModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * Implementation of {@link PropertyValueModel} that can be used for - * returning a static value, but still allows listeners to be added. - * Listeners will <em>never</em> be notified of any changes, because there should be none. - */ -public class StaticPropertyValueModel<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - /** The value. */ - protected final T value; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static property value model for the specified value. - */ - public StaticPropertyValueModel(T value) { - super(); - this.value = value; - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.value; - } - - - // ********** Object overrides ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.value); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticTreeValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticTreeValueModel.java deleted file mode 100644 index 576e608985..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/StaticTreeValueModel.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.common.utility.internal.model.AbstractModel; -import org.eclipse.jpt.common.utility.model.value.TreeValueModel; - -/** - * Implementation of {@link TreeValueModel} that can be used for - * returning an iterator on a static tree, but still allows listeners to be added. - * Listeners will <em>never</em> be notified of any changes, because there should be none. - */ -public class StaticTreeValueModel<E> - extends AbstractModel - implements TreeValueModel<E> -{ - /** The tree's nodes. */ - protected final Iterable<? extends E> nodes; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a read-only tree value model for the specified nodes. - */ - public StaticTreeValueModel(Iterable<? extends E> nodes) { - super(); - if (nodes == null) { - throw new NullPointerException(); - } - this.nodes = nodes; - } - - // ********** TreeValueModel implementation ********** - - public Iterator<E> nodes() { - return new ReadOnlyIterator<E>(this.nodes.iterator()); - } - - - // ********** Object overrides ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.nodes); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationListValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationListValueModel.java deleted file mode 100644 index edc4055ff3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationListValueModel.java +++ /dev/null @@ -1,309 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.common.utility.internal.Transformer; -import org.eclipse.jpt.common.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to transform a {@link ListValueModel} - * (or adapted {@link CollectionValueModel}) into a read-only {@link ListValueModel} - * whose items are tranformations of the items in the wrapped - * {@link ListValueModel}. It will keep its contents in synch with - * the contents of the wrapped {@link ListValueModel} and notifies its - * listeners of any changes. - * <p> - * The {@link Transformer} can be changed at any time; allowing the same - * adapter to be used with different transformations. - * <p> - * As an alternative to building a {@link Transformer}, - * a subclass of <code>TransformationListValueModelAdapter</code> can - * either override {@link #transformItem_(Object)} or, - * if something other than <code>null</code> should be returned when the - * wrapped item is <code>null</code>, override {@link #transformItem(Object)}. - * <p> - * <strong>NB:</strong> Since we only listen to the wrapped list when we have - * listeners ourselves and we can only stay in synch with the wrapped - * list while we are listening to it, results to various methods - * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, clients will also be listeners. - * - * @see Transformer - */ -public class TransformationListValueModel<E1, E2> - extends ListValueModelWrapper<E1> - implements ListValueModel<E2> -{ - - /** This transforms the items, unless the subclass overrides {@link #transformItem(Object)}). */ - protected Transformer<E1, E2> transformer; - - /** The list of transformed items. */ - protected final List<E2> transformedList; - - - // ********** constructors ********** - - /** - * Construct a list value model with the specified nested - * list value model and transformer. - */ - public TransformationListValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, E2> transformer) { - super(listHolder); - this.transformer = transformer; - this.transformedList = new ArrayList<E2>(); - } - - /** - * Construct a list value model with the specified nested - * list value model and the default transformer. - * Use this constructor if you want to override - * {@link #transformItem_(Object)} or {@link #transformItem(Object)} - * method instead of building a {@link Transformer}. - */ - public TransformationListValueModel(ListValueModel<? extends E1> listHolder) { - super(listHolder); - this.transformer = this.buildTransformer(); - this.transformedList = new ArrayList<E2>(); - } - - /** - * Construct a list value model with the specified nested - * collection value model and transformer. - */ - public TransformationListValueModel(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, E2> transformer) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder), transformer); - } - - /** - * Construct a list value model with the specified nested - * collection value model and the default transformer. - * Use this constructor if you want to override - * {@link #transformItem_(Object)} or {@link #transformItem(Object)} - * method instead of building a {@link Transformer}. - */ - public TransformationListValueModel(CollectionValueModel<? extends E1> collectionHolder) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder)); - } - - protected Transformer<E1, E2> buildTransformer() { - return new DefaultTransformer(); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E2> iterator() { - return this.listIterator(); - } - - public ListIterator<E2> listIterator() { - return new ReadOnlyListIterator<E2>(this.transformedList); - } - - public E2 get(int index) { - return this.transformedList.get(index); - } - - public int size() { - return this.transformedList.size(); - } - - public Object[] toArray() { - return this.transformedList.toArray(); - } - - // ********** behavior ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch the transformed list *after* we start listening to the list holder, - // since its value might change when a listener is added - this.transformedList.addAll(this.transformItems(this.listHolder)); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the list when we are not listening to the collection holder - this.transformedList.clear(); - } - - /** - * Transform the items in the specified list value model. - */ - protected List<E2> transformItems(ListValueModel<? extends E1> lvm) { - return this.transformItems(lvm, lvm.size()); - } - - /** - * Transform the items associated with the specified event. - */ - protected List<E2> transformItems(ListAddEvent event) { - return this.transformItems(this.getItems(event), event.getItemsSize()); - } - - /** - * Transform the items associated with the specified event. - */ - protected List<E2> transformItems(ListRemoveEvent event) { - return this.transformItems(this.getItems(event), event.getItemsSize()); - } - - /** - * Transform the new items associated with the specified event. - */ - protected List<E2> transformNewItems(ListReplaceEvent event) { - return this.transformItems(this.getNewItems(event), event.getItemsSize()); - } - - /** - * Transform the old items associated with the specified event. - */ - protected List<E2> transformOldItems(ListReplaceEvent event) { - return this.transformItems(this.getOldItems(event), event.getItemsSize()); - } - - /** - * Transform the specified items. - */ - protected List<E2> transformItems(Iterable<? extends E1> items, int size) { - List<E2> result = new ArrayList<E2>(size); - for (E1 item : items) { - result.add(this.transformItem(item)); - } - return result; - } - - /** - * Transform the specified item. - */ - protected E2 transformItem(E1 item) { - return this.transformer.transform(item); - } - - /** - * Transform the specified, non-null, item and return the result. - */ - protected E2 transformItem_(@SuppressWarnings("unused") E1 item) { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - /** - * Change the transformer and rebuild the collection. - */ - public void setTransformer(Transformer<E1, E2> transformer) { - this.transformer = transformer; - this.rebuildTransformedList(); - } - - /** - * Synchronize our cache with the wrapped collection. - */ - protected void rebuildTransformedList() { - this.synchronizeList(this.transformItems(this.listHolder), this.transformedList, LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.transformedList); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder. - * Transform them, add them to our transformation list, - * and notify our listeners. - */ - @Override - protected void itemsAdded(ListAddEvent event) { - this.addItemsToList(event.getIndex(), this.transformItems(event), this.transformedList, LIST_VALUES); - } - - /** - * Items were removed from the wrapped list holder. - * Remove the corresponding items from our transformation list - * and notify our listeners. - */ - @Override - protected void itemsRemoved(ListRemoveEvent event) { - this.removeItemsFromList(event.getIndex(), event.getItemsSize(), this.transformedList, LIST_VALUES); - } - - /** - * Items were replaced in the wrapped list holder. - * Replace the corresponding items in our transformation list - * and notify our listeners. - */ - @Override - protected void itemsReplaced(ListReplaceEvent event) { - this.setItemsInList(event.getIndex(), this.transformNewItems(event), this.transformedList, LIST_VALUES); - } - - /** - * Items were moved in the wrapped list holder. - * Move the corresponding items in our transformation list - * and notify our listeners. - */ - @Override - protected void itemsMoved(ListMoveEvent event) { - this.moveItemsInList(event.getTargetIndex(), event.getSourceIndex(), event.getLength(), this.transformedList, LIST_VALUES); - } - - /** - * The wrapped list holder was cleared. - * Clear our transformation list and notify our listeners. - */ - @Override - protected void listCleared(ListClearEvent event) { - this.clearList(this.transformedList, LIST_VALUES); - } - - /** - * The wrapped list holder has changed in some dramatic fashion. - * Rebuild our transformation list and notify our listeners. - */ - @Override - protected void listChanged(ListChangeEvent event) { - this.rebuildTransformedList(); - } - - - // ********** default transformer ********** - - /** - * The default transformer will return null if the wrapped item is null. - * If the wrapped item is not null, it is transformed by a subclass - * implementation of {@link TransformationListValueModel#transformItem_(Object)}. - */ - protected class DefaultTransformer implements Transformer<E1, E2> { - public E2 transform(E1 item) { - return (item == null) ? null : TransformationListValueModel.this.transformItem_(item); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationPropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationPropertyValueModel.java deleted file mode 100644 index 6c7dadb7c4..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationPropertyValueModel.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.Transformer; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * A <code>TransformationPropertyValueModel</code> wraps another - * {@link PropertyValueModel} and uses a {@link Transformer} - * to transform the wrapped value before it is returned by {@link #getValue()}. - * <p> - * As an alternative to building a {@link Transformer}, - * a subclass of <code>TransformationPropertyValueModel</code> can - * either override {@link #transform_(Object)} or, - * if something other than null should be returned when the wrapped value - * is null, override {@link #transform(Object)}. - * - * @see Transformer - */ -public class TransformationPropertyValueModel<T1, T2> - extends PropertyValueModelWrapper<T1> - implements PropertyValueModel<T2> -{ - protected final Transformer<T1, T2> transformer; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified nested - * property value model and the default transformer. - * Use this constructor if you want to override - * {@link #transform_(Object)} or {@link #transform(Object)} - * method instead of building a {@link Transformer}. - */ - public TransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder) { - super(valueHolder); - this.transformer = this.buildTransformer(); - } - - /** - * Construct a property value model with the specified nested - * property value model and transformer. - */ - public TransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder, Transformer<T1, T2> transformer) { - super(valueHolder); - this.transformer = transformer; - } - - protected Transformer<T1, T2> buildTransformer() { - return new DefaultTransformer(); - } - - - // ********** PropertyValueModel implementation ********** - - public T2 getValue() { - // transform the object returned by the nested value model before returning it - return this.transform(this.valueHolder.getValue()); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - // transform the values before propagating the change event - @SuppressWarnings("unchecked") - T1 eventOldValue = (T1) event.getOldValue(); - Object oldValue = this.transformOld(eventOldValue); - @SuppressWarnings("unchecked") - T1 eventNewValue = (T1) event.getNewValue(); - Object newValue = this.transformNew(eventNewValue); - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - - // ********** behavior ********** - - /** - * Transform the specified value and return the result. - * This is called by - * {@link #getValue()}, - * {@link #transformOld(Object)}, and - * {@link #transformNew(Object)}. - */ - protected T2 transform(T1 value) { - return this.transformer.transform(value); - } - - /** - * Transform the specified, non-null, value and return the result. - */ - protected T2 transform_(@SuppressWarnings("unused") T1 value) { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - /** - * Transform the specified old value and return the result. - * By default, call {@link #transform(Object)}. - * This is called by {@link #valueChanged(PropertyChangeEvent)}. - */ - protected T2 transformOld(T1 value) { - return this.transform(value); - } - - /** - * Transform the specified new value and return the result. - * By default, call {@link #transform(Object)}. - * This is called by {@link #valueChanged(PropertyChangeEvent)}. - */ - protected T2 transformNew(T1 value) { - return this.transform(value); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - - - // ********** default transformer ********** - - /** - * The default transformer will return null if the wrapped value is null. - * If the wrapped value is not null, it is transformed by a subclass - * implementation of {@link TransformationPropertyValueModel#transform_(Object)}. - */ - protected class DefaultTransformer implements Transformer<T1, T2> { - public T2 transform(T1 value) { - return (value == null) ? null : TransformationPropertyValueModel.this.transform_(value); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationWritablePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationWritablePropertyValueModel.java deleted file mode 100644 index 1d42d4c54e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TransformationWritablePropertyValueModel.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.BidiTransformer; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>TransformationWritablePropertyValueModel</code> wraps another - * {@link WritablePropertyValueModel} and uses a {@link BidiTransformer} - * to:<ul> - * <li>transform the wrapped value before it is returned by {@link #getValue()} - * <li>"reverse-transform" the new value that comes in via - * {@link #setValue(Object)} - * </ul> - * As an alternative to building a {@link BidiTransformer}, - * a subclass of <code>TransformationWritablePropertyValueModel</code> can - * override {@link #transform_(Object)} and {@link #reverseTransform_(Object)}; - * or, if something other than null should be returned when the wrapped value - * is null or the new value is null, override {@link #transform(Object)} - * and {@link #reverseTransform(Object)}. - */ -public class TransformationWritablePropertyValueModel<T1, T2> - extends TransformationPropertyValueModel<T1, T2> - implements WritablePropertyValueModel<T2> -{ - - // ********** constructors/initialization ********** - - /** - * Construct a writable property value model with the specified nested - * writable property value model and the default bidi transformer. - * Use this constructor if you want to override the - * {@link #transform_(Object)} and {@link #reverseTransform_(Object)} - * (or {@link #transform(Object)} and {@link #reverseTransform(Object)}) - * methods instead of building a {@link BidiTransformer}. - */ - public TransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct a writable property value model with the specified nested - * writable property value model and bidi transformer. - */ - public TransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder, BidiTransformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - @Override - protected BidiTransformer<T1, T2> buildTransformer() { - return new DefaultBidiTransformer(); - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T2 value) { - // "reverse-transform" the object before passing it to the the nested value model - this.getValueHolder().setValue(this.reverseTransform(value)); - } - - - // ********** behavior ********** - - /** - * "Reverse-transform" the specified value and return the result. - * This is called by {@link #setValue(Object)}. - */ - protected T1 reverseTransform(T2 value) { - return this.getTransformer().reverseTransform(value); - } - - /** - * "Reverse-transform" the specified, non-<code>null</code>, - * value and return the result. - */ - protected T1 reverseTransform_(@SuppressWarnings("unused") T2 value) { - throw new RuntimeException("This method was not overridden."); //$NON-NLS-1$ - } - - - // ********** queries ********** - - /** - * Our constructors accept only a {@link WritablePropertyValueModel<T1>}, - * so this cast should be safe. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T1> getValueHolder() { - return (WritablePropertyValueModel<T1>) this.valueHolder; - } - - /** - * Our constructors accept only a {@link BidiTransformer<T1, T2>}, - * so this cast should be safe. - */ - protected BidiTransformer<T1, T2> getTransformer() { - return (BidiTransformer<T1, T2>) this.transformer; - } - - - // ********** default bidi transformer ********** - - /** - * The default bidi transformer will return <code>null</code> if the - * wrapped value is <code>null</code>. - * If the wrapped value is not <code>null</code>, it is transformed by a subclass - * implementation of {@link #transform_(Object)}. - * The default bidi transformer will also return <code>null</code> - * if the new value is <code>null</code>. - * If the new value is not <code>null</code>, it is reverse-transformed - * by a subclass implementation of {@link #reverseTransform_(Object)}. - */ - protected class DefaultBidiTransformer - extends DefaultTransformer - implements BidiTransformer<T1, T2> - { - public T1 reverseTransform(T2 value) { - return (value == null) ? null : TransformationWritablePropertyValueModel.this.reverseTransform_(value); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreeAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreeAspectAdapter.java deleted file mode 100644 index 178d1ed2bb..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreeAspectAdapter.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This extension of {@link AspectTreeValueModelAdapter} provides - * basic tree change support. - * This converts a set of one or more trees into - * a single {@link #NODES} tree. - * <p> - * The typical subclass will override the following methods (see the descriptions - * in {@link AspectTreeValueModelAdapter}):<ul> - * <li>{@link #nodes_()} - * <li>{@link #nodes()} - * </ul> - */ -public abstract class TreeAspectAdapter<S extends Model, E> - extends AspectTreeValueModelAdapter<S, E> -{ - /** - * The name of the subject's trees that we use for the value. - */ - protected final String[] treeNames; - protected static final String[] EMPTY_TREE_NAMES = new String[0]; - - /** A listener that listens to the subject's tree aspects. */ - protected final TreeChangeListener treeChangeListener; - - - // ********** constructors ********** - - /** - * Construct a tree aspect adapter for the specified subject - * and tree. - */ - protected TreeAspectAdapter(String treeName, S subject) { - this(new String[] {treeName}, subject); - } - - /** - * Construct a tree aspect adapter for the specified subject - * and trees. - */ - protected TreeAspectAdapter(String[] treeNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), treeNames); - } - - /** - * Construct a tree aspect adapter for the specified subject holder - * and trees. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... treeNames) { - super(subjectHolder); - this.treeNames = treeNames; - this.treeChangeListener = this.buildTreeChangeListener(); - } - - /** - * Construct a tree aspect adapter for the specified subject holder - * and trees. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> treeNames) { - this(subjectHolder, treeNames.toArray(new String[treeNames.size()])); - } - - /** - * Construct a tree aspect adapter for an "unchanging" tree in - * the specified subject. This is useful for a tree aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new tree. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_TREE_NAMES); - } - - - // ********** initialization ********** - - protected TreeChangeListener buildTreeChangeListener() { - // transform the subject's tree change events into VALUE tree change events - return new TreeChangeListener() { - public void nodeAdded(TreeAddEvent event) { - TreeAspectAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeRemoveEvent event) { - TreeAspectAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeClearEvent event) { - TreeAspectAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - TreeAspectAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "tree change listener: " + Arrays.asList(TreeAspectAdapter.this.treeNames); //$NON-NLS-1$ - } - }; - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected void engageSubject_() { - for (String treeName : this.treeNames) { - ((Model) this.subject).addTreeChangeListener(treeName, this.treeChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String treeName : this.treeNames) { - ((Model) this.subject).removeTreeChangeListener(treeName, this.treeChangeListener); - } - } - - - // ********** behavior ********** - - protected void nodeAdded(TreeAddEvent event) { - this.fireNodeAdded(event.clone(this, NODES)); - } - - protected void nodeRemoved(TreeRemoveEvent event) { - this.fireNodeRemoved(event.clone(this, NODES)); - } - - protected void treeCleared(TreeClearEvent event) { - this.fireTreeCleared(event.clone(this, NODES)); - } - - protected void treeChanged(TreeChangeEvent event) { - this.fireTreeChanged(event.clone(this, NODES)); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreePropertyValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreePropertyValueModelAdapter.java deleted file mode 100644 index 66258c2108..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/TreePropertyValueModelAdapter.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.common.utility.model.value.TreeValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a tree value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * <p> - * Subclasses must override:<ul> - * <li>{@link #buildValue()}<p> - * to return the current property value, as derived from the - * current collection value - * </ul> - * Subclasses might want to override the following methods - * to improve performance (by not recalculating the value, if possible):<ul> - * <li>{@link #nodeAdded(TreeChangeEvent event)} - * <li>{@link #nodeRemoved(TreeChangeEvent event)} - * <li>{@link #treeCleared(TreeChangeEvent event)} - * <li>{@link #treeChanged(TreeChangeEvent event)} - * </ul> - */ -public abstract class TreePropertyValueModelAdapter<T> - extends AbstractPropertyValueModelAdapter<T> -{ - /** The wrapped tree value model. */ - protected final TreeValueModel<?> treeHolder; - - /** A listener that allows us to synch with changes to the wrapped tree holder. */ - protected final TreeChangeListener treeChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * tree value model. - */ - protected TreePropertyValueModelAdapter(TreeValueModel<?> treeHolder) { - super(); - this.treeHolder = treeHolder; - this.treeChangeListener = this.buildTreeChangeListener(); - } - - protected TreeChangeListener buildTreeChangeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeAddEvent event) { - TreePropertyValueModelAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeRemoveEvent event) { - TreePropertyValueModelAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeClearEvent event) { - TreePropertyValueModelAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "tree change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the tree holder. - */ - @Override - protected void engageModel_() { - this.treeHolder.addTreeChangeListener(TreeValueModel.NODES, this.treeChangeListener); - } - - /** - * Stop listening to the tree holder. - */ - @Override - protected void disengageModel_() { - this.treeHolder.removeTreeChangeListener(TreeValueModel.NODES, this.treeChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.treeHolder); - } - - - // ********** state change support ********** - - /** - * Nodes were added to the wrapped tree holder; - * propagate the change notification appropriately. - */ - protected void nodeAdded(@SuppressWarnings("unused") TreeAddEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Nodes were removed from the wrapped tree holder; - * propagate the change notification appropriately. - */ - protected void nodeRemoved(@SuppressWarnings("unused") TreeRemoveEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped tree holder was cleared; - * propagate the change notification appropriately. - */ - protected void treeCleared(@SuppressWarnings("unused") TreeClearEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped tree holder changed; - * propagate the change notification appropriately. - */ - protected void treeChanged(@SuppressWarnings("unused") TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueAspectAdapter.java deleted file mode 100644 index 5876d5e444..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueAspectAdapter.java +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Abstract class that provides support for wrapping a {@link WritablePropertyValueModel} - * and listening for changes to <em>aspects</em> of the <em>value</em> contained - * by the {@link WritablePropertyValueModel}. Changes to the {@link WritablePropertyValueModel}'s - * value are also monitored. - * <p> - * This is useful if you have a value that may change, but whose aspects can also - * change in a fashion that might be of interest to the client. - * <p> - * <strong>NB:</strong> Clients will need to listen for two different change notifications: - * a property change event will be be fired when the <em>value</em> changes; - * a state change event will be fired when an <em>aspect</em> of the value changes. - * <p> - * Subclasses need to override two methods:<ul> - * <li>{@link #engageValue_()}<p> - * begin listening to the appropriate aspect of the value and call - * {@link #valueAspectChanged()} whenever the aspect changes - * (this will fire a state change event) - * <li>{@link #disengageValue_()}<p> - * stop listening to the appropriate aspect of the value - * </ul> - */ -public abstract class ValueAspectAdapter<V> - extends PropertyValueModelWrapper<V> - implements WritablePropertyValueModel<V> -{ - /** Cache the value so we can disengage. Null until we have a listener*/ - protected V value; - - - // ********** constructors/initialization ********** - - /** - * Constructor - the value holder is required. - */ - protected ValueAspectAdapter(WritablePropertyValueModel<V> valueHolder) { - super(valueHolder); - this.value = null; - } - - /** - * Override to allow both property and state change listeners. - */ - @Override - protected ChangeSupport buildChangeSupport() { - return new ChangeSupport(this); - } - - - // ********** PropertyValueModel implementation ********** - - public V getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(V value) { - this.getValueHolder().setValue(value); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - this.disengageValue(); - this.engageValue(); - this.firePropertyChanged(event.clone(this)); - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public synchronized void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addStateChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public synchronized void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** AbstractPropertyValueModel overrides ********** - - /** - * Extend to check for state change listeners. - */ - @Override - protected boolean hasListeners() { - return this.hasAnyStateChangeListeners() || super.hasListeners(); - } - - - // ********** PropertyValueModelWrapper overrides ********** - - /** - * Extend to engage an aspect of the value model's value. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.engageValue(); - } - - /** - * Extend to disengage an aspect of the value model's value. - */ - @Override - protected void disengageModel() { - this.disengageValue(); - super.disengageModel(); - } - - - // ********** behavior ********** - - /** - * Start listening to an aspect of the current value. - */ - protected void engageValue() { - this.value = this.valueHolder.getValue(); - if (this.value != null) { - this.engageValue_(); - } - } - - /** - * Start listening to some aspect of the current value. - * At this point we can be sure the value is not null. - */ - protected abstract void engageValue_(); - - /** - * Stop listening to an aspect of the current value. - */ - protected void disengageValue() { - if (this.value != null) { - this.disengageValue_(); - this.value = null; - } - } - - /** - * Stop listening to an aspect of the current value. - * At this point we can be sure the value is not null. - */ - protected abstract void disengageValue_(); - - /** - * Subclasses should call this method whenever the value's aspect changes. - */ - protected void valueAspectChanged() { - this.fireStateChanged(); - } - - /** - * Our constructor accepts only a {@link WritablePropertyValueModel}{@code<V>}. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<V> getValueHolder() { - return (WritablePropertyValueModel<V>) this.valueHolder; - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueChangeAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueChangeAdapter.java deleted file mode 100644 index 36dca8e8dd..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueChangeAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ChangeListener; -import org.eclipse.jpt.common.utility.model.listener.SimpleChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to all the aspects - * of the value in the wrapped value model. - */ -public class ValueChangeAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** Listener that listens to the value. */ - protected final ChangeListener valueAspectListener; - - - // ********** constructors ********** - - /** - * Construct a change adapter for the specified value. - */ - public ValueChangeAdapter(WritablePropertyValueModel<V> valueHolder) { - super(valueHolder); - this.valueAspectListener = this.buildValueAspectListener(); - } - - - // ********** initialization ********** - - protected ChangeListener buildValueAspectListener() { - return new SimpleChangeListener() { - @Override - protected void modelChanged(ChangeEvent event) { - ValueChangeAdapter.this.valueAspectChanged(event); - } - @Override - public String toString() { - return "value change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - this.value.addChangeListener(this.valueAspectListener); - } - - @Override - protected void disengageValue_() { - this.value.removeChangeListener(this.valueAspectListener); - } - - - // ********** change events ********** - - protected void valueAspectChanged(@SuppressWarnings("unused") ChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueCollectionAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueCollectionAdapter.java deleted file mode 100644 index a06dfbb2f3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueCollectionAdapter.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent; -import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to one or more collection - * aspects of the value in the wrapped value model. - */ -public class ValueCollectionAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** The names of the value's collections that we listen to. */ - protected final String[] collectionNames; - - /** Listener that listens to the value. */ - protected final CollectionChangeListener valueCollectionListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value collections. - */ - public ValueCollectionAdapter(WritablePropertyValueModel<V> valueHolder, String... collectionNames) { - super(valueHolder); - this.collectionNames = collectionNames; - this.valueCollectionListener = this.buildValueCollectionListener(); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildValueCollectionListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionAddEvent event) { - ValueCollectionAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionRemoveEvent event) { - ValueCollectionAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionClearEvent event) { - ValueCollectionAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - ValueCollectionAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "value collection listener: " + Arrays.asList(ValueCollectionAdapter.this.collectionNames); //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - for (String collectionName : this.collectionNames) { - this.value.addCollectionChangeListener(collectionName, this.valueCollectionListener); - } - } - - @Override - protected void disengageValue_() { - for (String collectionName : this.collectionNames) { - this.value.removeCollectionChangeListener(collectionName, this.valueCollectionListener); - } - } - - - // ********** change events ********** - - protected void itemsAdded(@SuppressWarnings("unused") CollectionAddEvent event) { - this.valueAspectChanged(); - } - - protected void itemsRemoved(@SuppressWarnings("unused") CollectionRemoveEvent event) { - this.valueAspectChanged(); - } - - protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) { - this.valueAspectChanged(); - } - - protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueListAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueListAdapter.java deleted file mode 100644 index ba69a17da3..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueListAdapter.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to one or more list - * aspects of the value in the wrapped value model. - */ -public class ValueListAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** The names of the value's lists that we listen to. */ - protected final String[] listNames; - - /** Listener that listens to the value. */ - protected final ListChangeListener valueListListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value lists. - */ - public ValueListAdapter(WritablePropertyValueModel<V> valueHolder, String... listNames) { - super(valueHolder); - this.listNames = listNames; - this.valueListListener = this.buildValueListListener(); - } - - - // ********** initialization ********** - - protected ListChangeListener buildValueListListener() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ValueListAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ValueListAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ValueListAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ValueListAdapter.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ValueListAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ValueListAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "value list listener: " + Arrays.asList(ValueListAdapter.this.listNames); //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - for (String listName : this.listNames) { - this.value.addListChangeListener(listName, this.valueListListener); - } - } - - @Override - protected void disengageValue_() { - for (String listName : this.listNames) { - this.value.removeListChangeListener(listName, this.valueListListener); - } - } - - - // ********** change events ********** - - protected void itemsAdded(@SuppressWarnings("unused") ListAddEvent event) { - this.valueAspectChanged(); - } - - protected void itemsRemoved(@SuppressWarnings("unused") ListRemoveEvent event) { - this.valueAspectChanged(); - } - - protected void itemsReplaced(@SuppressWarnings("unused") ListReplaceEvent event) { - this.valueAspectChanged(); - } - - protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) { - this.valueAspectChanged(); - } - - protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) { - this.valueAspectChanged(); - } - - protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValuePropertyAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValuePropertyAdapter.java deleted file mode 100644 index cbb6be7df8..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValuePropertyAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to one or more - * properties of the value in the wrapped value model. - */ -public class ValuePropertyAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** The names of the value's properties we listen to. */ - protected final String[] propertyNames; - - /** Listener that listens to the value. */ - protected final PropertyChangeListener valuePropertyListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value properties. - */ - public ValuePropertyAdapter(WritablePropertyValueModel<V> valueHolder, String... propertyNames) { - super(valueHolder); - this.propertyNames = propertyNames; - this.valuePropertyListener = this.buildValuePropertyListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValuePropertyListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ValuePropertyAdapter.this.propertyChanged(event); - } - @Override - public String toString() { - return "value property listener: " + Arrays.asList(ValuePropertyAdapter.this.propertyNames); //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - for (String propertyName : this.propertyNames) { - this.value.addPropertyChangeListener(propertyName, this.valuePropertyListener); - } - } - - @Override - protected void disengageValue_() { - for (String propertyName : this.propertyNames) { - this.value.removePropertyChangeListener(propertyName, this.valuePropertyListener); - } - } - - - // ********** change events ********** - - protected void propertyChanged(@SuppressWarnings("unused") PropertyChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueStateAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueStateAdapter.java deleted file mode 100644 index ed9e6372c2..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueStateAdapter.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to the - * "state" of the value in the wrapped value model. - */ -public class ValueStateAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** Listener that listens to value. */ - protected final StateChangeListener valueStateListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the value state. - */ - public ValueStateAdapter(WritablePropertyValueModel<V> valueHolder) { - super(valueHolder); - this.valueStateListener = this.buildValueStateListener(); - } - - - // ********** initialization ********** - - protected StateChangeListener buildValueStateListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ValueStateAdapter.this.stateChanged(event); - } - @Override - public String toString() { - return "value state listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - this.value.addStateChangeListener(this.valueStateListener); - } - - @Override - protected void disengageValue_() { - this.value.removeStateChangeListener(this.valueStateListener); - } - - - // ********** change events ********** - - protected void stateChanged(@SuppressWarnings("unused") StateChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueTreeAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueTreeAdapter.java deleted file mode 100644 index a8ec0af59a..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ValueTreeAdapter.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.common.utility.model.Model; -import org.eclipse.jpt.common.utility.model.event.TreeAddEvent; -import org.eclipse.jpt.common.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.common.utility.model.event.TreeClearEvent; -import org.eclipse.jpt.common.utility.model.event.TreeRemoveEvent; -import org.eclipse.jpt.common.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * Extend {@link ValueAspectAdapter} to listen to one or more - * tree aspects of the value in the wrapped value model. - */ -public class ValueTreeAdapter<V extends Model> - extends ValueAspectAdapter<V> -{ - /** The names of the value's trees that we listen to. */ - protected final String[] treeNames; - - /** Listener that listens to the value. */ - protected final TreeChangeListener valueTreeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value trees. - */ - public ValueTreeAdapter(WritablePropertyValueModel<V> valueHolder, String... treeNames) { - super(valueHolder); - this.treeNames = treeNames; - this.valueTreeListener = this.buildValueTreeListener(); - } - - - // ********** initialization ********** - - protected TreeChangeListener buildValueTreeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeAddEvent event) { - ValueTreeAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeRemoveEvent event) { - ValueTreeAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeClearEvent event) { - ValueTreeAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - ValueTreeAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "value tree listener: " + Arrays.asList(ValueTreeAdapter.this.treeNames); //$NON-NLS-1$ - } - }; - } - - - // ********** ValueAspectAdapter implementation ********** - - @Override - protected void engageValue_() { - for (String treeName : this.treeNames) { - this.value.addTreeChangeListener(treeName, this.valueTreeListener); - } - } - - @Override - protected void disengageValue_() { - for (String treeName : this.treeNames) { - this.value.removeTreeChangeListener(treeName, this.valueTreeListener); - } - } - - - // ********** change events ********** - - protected void nodeAdded(@SuppressWarnings("unused") TreeAddEvent event) { - this.valueAspectChanged(); - } - - protected void nodeRemoved(@SuppressWarnings("unused") TreeRemoveEvent event) { - this.valueAspectChanged(); - } - - protected void treeCleared(@SuppressWarnings("unused") TreeClearEvent event) { - this.valueAspectChanged(); - } - - protected void treeChanged(@SuppressWarnings("unused") TreeChangeEvent event) { - this.valueAspectChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyCollectionValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyCollectionValueModelAdapter.java deleted file mode 100644 index be61d4904b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyCollectionValueModelAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.model.value.WritableCollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * An adapter that allows us to make a {@link WritablePropertyValueModel} behave like - * a single-element {@link WritableCollectionValueModel}, sorta. - * <p> - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a collection with a <code>null</code> element). - * Also, only a single-element collection can be written to the adapter. - */ -public class WritablePropertyCollectionValueModelAdapter<E> - extends PropertyCollectionValueModelAdapter<E> - implements WritableCollectionValueModel<E> -{ - - // ********** constructor ********** - - /** - * Convert the specified writable property value model to a writable - * collection value model. - */ - public WritablePropertyCollectionValueModelAdapter(WritablePropertyValueModel<E> valueHolder) { - super(valueHolder); - } - - - // ********** WritableCollectionValueModel implementation ********** - - public void setValues(Iterable<E> values) { - Iterator<E> stream = values.iterator(); - if (stream.hasNext()) { - E newValue = stream.next(); - if (stream.hasNext()) { - throw new IllegalArgumentException("non-singleton collection: " + values); //$NON-NLS-1$ - } - this.getValueHolder().setValue(newValue); - } else { - this.getValueHolder().setValue(null); - } - } - - // our constructor takes only writable property value models - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<E> getValueHolder() { - return (WritablePropertyValueModel<E>) this.valueHolder; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyListValueModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyListValueModelAdapter.java deleted file mode 100644 index c9f30847cd..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/WritablePropertyListValueModelAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.common.utility.model.value.WritableListValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * An adapter that allows us to make a {@link WritablePropertyValueModel} behave like - * a single-element {@link WritableListValueModel}, sorta. - * <p> - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a list with a <code>null</code> element). - * Also, only a single-element list can be written to the adapter. - */ -public class WritablePropertyListValueModelAdapter<E> - extends PropertyListValueModelAdapter<E> - implements WritableListValueModel<E> -{ - - // ********** constructor ********** - - /** - * Convert the specified writable property value model to a writable - * collection value model. - */ - public WritablePropertyListValueModelAdapter(WritablePropertyValueModel<E> valueHolder) { - super(valueHolder); - } - - - // ********** WritableListValueModel implementation ********** - - public void setListValues(Iterable<E> listValues) { - Iterator<E> stream = listValues.iterator(); - if (stream.hasNext()) { - E newValue = stream.next(); - if (stream.hasNext()) { - throw new IllegalArgumentException("non-singleton list: " + listValues); //$NON-NLS-1$ - } - this.getValueHolder().setValue(newValue); - } else { - this.getValueHolder().setValue(null); - } - } - - // our constructor takes only writable property value models - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<E> getValueHolder() { - return (WritablePropertyValueModel<E>) this.valueHolder; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencePropertyValueModel.java deleted file mode 100644 index 2b6670abe4..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencePropertyValueModel.java +++ /dev/null @@ -1,346 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.prefs; - -import java.util.EventListener; -import java.util.prefs.PreferenceChangeEvent; -import java.util.prefs.PreferenceChangeListener; -import java.util.prefs.Preferences; - -import org.eclipse.jpt.common.utility.internal.BidiStringConverter; -import org.eclipse.jpt.common.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.common.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This adapter wraps a Preference and converts it into a PropertyValueModel. - * It listens for the appropriate "preference" changes and converts them into - * VALUE property changes. It also allows the specification of a default value - * for the Preference, which, by default, is null (and is probably *not* a very - * good default). - * - * You can configure whether the preference's value is returned, - * unchanged, as a string or as some other object (e.g. an Integer) by - * setting the adapter's converter. Internally, the preference's value - * is stored as the converted object; and the conversions take place - * when reading or writing from the preferences node or retrieving the - * value from an event fired by the preferences node. - * - * This adapter is a bit different from most other adapters because the - * change events fired off by a Preferences node are asynchronous from - * the change itself. (AbstractPreferences uses an event dispatch daemon.) - * As a result, a client can set our value with #setValue(Object) and we - * will return from that method before we ever receive notification from - * the Preferences node that *it* has changed. This means we cannot - * rely on that event to keep our internally cached value in synch. - */ -public class PreferencePropertyValueModel<P> - extends AspectAdapter<Preferences> - implements WritablePropertyValueModel<P> -{ - /** The key to the preference we use for the value. */ - protected final String key; - - /** - * Cache the current (object) value of the preference so we - * can pass an "old value" when we fire a property change event. - */ - protected P value; - - /** - * The default (object) value returned if there is no value - * associated with the preference. - */ - protected final P defaultValue; - - /** - * This converter is used to convert the preference's - * string value to and from an object. - */ - protected final BidiStringConverter<P> converter; - - /** A listener that listens to the appropriate preference. */ - protected final PreferenceChangeListener preferenceChangeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified preference. - * The default value of the preference will be null. - */ - public PreferencePropertyValueModel(Preferences preferences, String key) { - this(preferences, key, null); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(Preferences preferences, String key, P defaultValue) { - this(preferences, key, defaultValue, BidiStringConverter.Default.<P>instance()); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(Preferences preferences, String key, P defaultValue, BidiStringConverter<P> converter) { - this(new StaticPropertyValueModel<Preferences>(preferences), key, defaultValue, converter); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public static PreferencePropertyValueModel<Boolean> forBoolean(Preferences preferences, String key, boolean defaultValue) { - return new PreferencePropertyValueModel<Boolean>( - preferences, - key, - defaultValue ? Boolean.TRUE : Boolean.FALSE, - BidiStringConverter.BooleanConverter.instance() - ); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public static PreferencePropertyValueModel<Integer> forInteger(Preferences preferences, String key, int defaultValue) { - return new PreferencePropertyValueModel<Integer>( - preferences, - key, - Integer.valueOf(defaultValue), - BidiStringConverter.IntegerConverter.instance() - ); - } - - /** - * Construct an adapter for the specified preference. - * The default value of the preference will be null. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key) { - this(preferencesHolder, key, null); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key, P defaultValue) { - this(preferencesHolder, key, defaultValue, BidiStringConverter.Default.<P>instance()); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key, P defaultValue, BidiStringConverter<P> converter) { - super(preferencesHolder); - this.key = key; - this.defaultValue = defaultValue; - this.converter = converter; - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - // our value is null when we are not listening to the preference - this.value = null; - } - - - // ********** initialization ********** - - /** - * A preference has changed, notify the listeners if necessary. - */ - protected PreferenceChangeListener buildPreferenceChangeListener() { - // transform the preference change events into VALUE property change events - return new PreferenceChangeListener() { - public void preferenceChange(PreferenceChangeEvent event) { - PreferencePropertyValueModel.this.preferenceChanged(event.getKey(), event.getNewValue()); - } - @Override - public String toString() { - return "preference change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ValueModel implementation ********** - - /** - * Return the cached (converted) value. - */ - @Override - public synchronized P getValue() { - return this.value; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Set the cached value, then set the appropriate preference value. - */ - public synchronized void setValue(P value) { - if (this.hasNoListeners()) { - return; // no changes allowed when we have no listeners - } - - Object old = this.value; - this.value = value; - this.fireAspectChanged(old, value); - - if ((this.subject != null) && this.preferenceIsToBeSet(old, value)) { - this.setValue_(value); - } - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends EventListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - @Override - protected synchronized void engageSubject_() { - this.subject.addPreferenceChangeListener(this.preferenceChangeListener); - this.value = this.buildValue(); - } - - @Override - protected synchronized void disengageSubject_() { - try { - this.subject.removePreferenceChangeListener(this.preferenceChangeListener); - } catch (IllegalStateException ex) { - // for some odd reason, we are not allowed to remove a listener from a "dead" - // preferences node; so handle the exception that gets thrown here - if ( ! ex.getMessage().equals("Node has been removed.")) { //$NON-NLS-1$ - // if it is not the expected exception, re-throw it - throw ex; - } - } - this.value = null; - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.key); - sb.append(" => "); //$NON-NLS-1$ - sb.append(this.value); - } - - - // ********** public API ********** - - /** - * Return the preference's key. - */ - public String getKey() { - return this.key; - } - - - // ********** internal methods ********** - - /** - * Return the preference's value. - * At this point the subject may be null. - */ - protected P buildValue() { - return (this.subject == null) ? null : this.buildValue_(); - } - - /** - * Return the appropriate preference, converted to the appropriate object. - * At this point we can be sure that the subject is not null. - */ - protected P buildValue_() { - return this.convertToObject(this.subject.get(this.key, this.convertToString(this.defaultValue))); - } - - /** - * Set the appropriate preference after converting the value to a string. - * At this point we can be sure that the subject is not null. - */ - protected void setValue_(P value) { - this.subject.put(this.key, this.convertToString(value)); - } - - /** - * Return whether the specified new value should be passed - * through to the preference. By default, only if the value has changed, - * will it be passed through to the preference. This also has the - * effect of not creating new preferences in the "backing store" - * if the new value is the same as the default value. - * - * Subclasses can override this method to return true if they - * would like to ALWAYS pass through the new value to the preference. - */ - protected boolean preferenceIsToBeSet(Object oldValue, Object newValue) { - return this.attributeValueHasChanged(oldValue, newValue); - } - - /** - * Convert the specified object to a string that can be stored as - * the value of the preference. - */ - protected String convertToString(P o) { - return this.converter.convertToString(o); - } - - /** - * Convert the specified preference value string to an - * appropriately-typed object to be returned to the client. - */ - protected P convertToObject(String s) { - return this.converter.convertToObject(s); - } - - protected void preferenceChanged(String prefKey, @SuppressWarnings("unused") String newValue) { - if (prefKey.equals(this.key)) { - this.preferenceChanged(); - } - } - - /** - * The underlying preference changed; either because we changed it - * in #setValue_(Object) or a third-party changed it. - * If this is called because of our own change, the event will be - * swallowed because the old and new values are the same. - */ - protected synchronized void preferenceChanged() { - Object old = this.value; - this.value = this.buildValue(); - this.fireAspectChanged(old, this.value); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java deleted file mode 100644 index f12a84f138..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java +++ /dev/null @@ -1,203 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.prefs; - -import java.util.EventListener; -import java.util.HashMap; -import java.util.Iterator; -import java.util.prefs.BackingStoreException; -import java.util.prefs.PreferenceChangeEvent; -import java.util.prefs.PreferenceChangeListener; -import java.util.prefs.Preferences; - -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.common.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.common.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.common.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; - -/** - * This adapter wraps a Preferences node and converts its preferences into a - * CollectionValueModel of PreferencePropertyValueModels. It listens for - * "preference" changes and converts them into VALUE collection changes. - */ -public class PreferencesCollectionValueModel<P> - extends AspectAdapter<Preferences> - implements CollectionValueModel<PreferencePropertyValueModel<P>> -{ - - /** Cache the current preferences, stored in models and keyed by name. */ - protected final HashMap<String, PreferencePropertyValueModel<P>> preferences; - - /** A listener that listens to the preferences node for added or removed preferences. */ - protected final PreferenceChangeListener preferenceChangeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified preferences node. - */ - public PreferencesCollectionValueModel(Preferences preferences) { - this(new StaticPropertyValueModel<Preferences>(preferences)); - } - - /** - * Construct an adapter for the specified preferences node. - */ - public PreferencesCollectionValueModel(PropertyValueModel<? extends Preferences> preferencesHolder) { - super(preferencesHolder); - this.preferences = new HashMap<String, PreferencePropertyValueModel<P>>(); - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - } - - - // ********** initialization ********** - - /** - * A preferences have changed, notify the listeners. - */ - protected PreferenceChangeListener buildPreferenceChangeListener() { - // transform the preference change events into VALUE collection change events - return new PreferenceChangeListener() { - public void preferenceChange(PreferenceChangeEvent event) { - PreferencesCollectionValueModel.this.preferenceChanged(event.getKey(), event.getNewValue()); - } - @Override - public String toString() { - return "preference change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - /** - * Return an iterator on the preference models. - */ - public synchronized Iterator<PreferencePropertyValueModel<P>> iterator() { - return this.preferences.values().iterator(); - } - - public synchronized int size() { - return this.preferences.size(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends EventListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChanged(Object oldValue, Object newValue) { - @SuppressWarnings("unchecked") Iterator<PreferencePropertyValueModel<P>> iterator = (Iterator<PreferencePropertyValueModel<P>>) newValue; - this.fireCollectionChanged(VALUES, CollectionTools.collection(iterator)); - } - - @Override - protected void engageSubject_() { - this.subject.addPreferenceChangeListener(this.preferenceChangeListener); - for (Iterator<PreferencePropertyValueModel<P>> stream = this.preferenceModels(); stream.hasNext(); ) { - PreferencePropertyValueModel<P> preferenceModel = stream.next(); - this.preferences.put(preferenceModel.getKey(), preferenceModel); - } - } - - @Override - protected void disengageSubject_() { - try { - this.subject.removePreferenceChangeListener(this.preferenceChangeListener); - } catch (IllegalStateException ex) { - // for some odd reason, we are not allowed to remove a listener from a "dead" - // preferences node; so handle the exception that gets thrown here - if ( ! ex.getMessage().equals("Node has been removed.")) { //$NON-NLS-1$ - // if it is not the expected exception, re-throw it - throw ex; - } - } - this.preferences.clear(); - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.subject); - } - - - // ********** internal methods ********** - - /** - * Return an iterator on the preference models. - * At this point we can be sure that the subject is not null. - */ - protected Iterator<PreferencePropertyValueModel<P>> preferenceModels() { - String[] keys; - try { - keys = this.subject.keys(); - } catch (BackingStoreException ex) { - throw new RuntimeException(ex); - } - return new TransformationIterator<String, PreferencePropertyValueModel<P>>(new ArrayIterator<String>(keys)) { - @Override - protected PreferencePropertyValueModel<P> transform(String key) { - return PreferencesCollectionValueModel.this.buildPreferenceModel(key); - } - }; - } - - /** - * Override this method to tweak the model used to wrap the - * specified preference (e.g. to customize the model's converter). - */ - protected PreferencePropertyValueModel<P> buildPreferenceModel(String key) { - return new PreferencePropertyValueModel<P>(this.subjectHolder, key); - } - - protected synchronized void preferenceChanged(String key, String newValue) { - if (newValue == null) { - // a preference was removed - PreferencePropertyValueModel<P> preferenceModel = this.preferences.remove(key); - this.fireItemRemoved(VALUES, preferenceModel); - } else if ( ! this.preferences.containsKey(key)) { - // a preference was added - PreferencePropertyValueModel<P> preferenceModel = this.buildPreferenceModel(key); - this.preferences.put(key, preferenceModel); - this.fireItemAdded(VALUES, preferenceModel); - } else { - // a preference's value changed - do nothing - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/AbstractTreeModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/AbstractTreeModel.java deleted file mode 100644 index 0a3ab42d06..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/AbstractTreeModel.java +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.io.Serializable; -import javax.swing.event.EventListenerList; -import javax.swing.event.TreeModelEvent; -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreeModel; - -/** - * Abstract class that should have been provided by the JDK - * (à la javax.swing.AbstractListModel). This class provides: - * - support for a collection of listeners - * - a number of convenience methods for firing events for those listeners - */ -public abstract class AbstractTreeModel - implements TreeModel, Serializable -{ - /** Our listeners. */ - protected final EventListenerList listenerList; - - - // ********** constructors/initialization ********** - - protected AbstractTreeModel() { - super(); - this.listenerList = new EventListenerList(); - } - - - // ********** partial TreeModel implementation ********** - - public void addTreeModelListener(TreeModelListener l) { - this.listenerList.add(TreeModelListener.class, l); - } - - public void removeTreeModelListener(TreeModelListener l) { - this.listenerList.remove(TreeModelListener.class, l); - } - - - // ********** queries ********** - - /** - * Return the model's current collection of listeners. - * (There seems to be a pattern of making this type of method public; - * although it should probably be protected....) - */ - public TreeModelListener[] treeModelListeners() { - return this.listenerList.getListeners(TreeModelListener.class); - } - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoTreeModelListeners() { - return this.listenerList.getListenerCount(TreeModelListener.class) == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasTreeModelListeners() { - return ! this.hasNoTreeModelListeners(); - } - - - // ********** behavior ********** - - /** - * Notify listeners of a model change. - * A significant property of the nodes changed, but the nodes themselves - * are still the same objects. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesChanged(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesChanged(event); - } - } - } - - - /** - * Notify listeners of a model change. - * A significant property of the node changed, but the node itself is the same object. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeChanged(Object[] path, int childIndex, Object child) { - this.fireTreeNodesChanged(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * A significant property of the root changed, but the root itself is the same object. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeRootChanged(Object root) { - this.fireTreeNodesChanged(new Object[] {root}, null, null); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesInserted(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesInserted(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeInserted(Object[] path, int childIndex, Object child) { - this.fireTreeNodesInserted(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesRemoved(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesRemoved(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeRemoved(Object[] path, int childIndex, Object child) { - this.fireTreeNodesRemoved(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeStructureChanged(Object[] path) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path); - } - ((TreeModelListener) listeners[i+1]).treeStructureChanged(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeRootReplaced(Object newRoot) { - this.fireTreeStructureChanged(new Object[] {newRoot}); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/CheckBoxModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/CheckBoxModelAdapter.java deleted file mode 100644 index 78069cd6b0..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/CheckBoxModelAdapter.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JCheckBox) in synch with a PropertyValueModel that - * holds a boolean. - * - * Maybe not the richest class in our toolbox, but it was the - * victim of refactoring.... ~bjv - */ -public class CheckBoxModelAdapter - extends ToggleButtonModelAdapter -{ - - // ********** constructors ********** - - /** - * Constructor - the boolean holder is required. - */ - public CheckBoxModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) { - super(booleanHolder, defaultValue); - } - - /** - * Constructor - the boolean holder is required. - * The default value will be false. - */ - public CheckBoxModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder) { - super(booleanHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ColumnAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ColumnAdapter.java deleted file mode 100644 index e101823abc..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ColumnAdapter.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - - -/** - * This adapter is used by the table model adapter to - * convert a model object into the models used for each of - * the cells for the object's corresponding row in the table. - */ -public interface ColumnAdapter { - /** - * Return the number of columns in the table. - * Typically this is static. - */ - int columnCount(); - - /** - * Return the name of the specified column. - */ - String columnName(int index); - - /** - * Return the class of the specified column. - */ - Class<?> columnClass(int index); - - /** - * Return whether the specified column is editable. - * Typically this is the same for every row. - */ - boolean columnIsEditable(int index); - - /** - * Return the cell models for the specified subject - * that corresponds to a single row in the table. - */ - WritablePropertyValueModel<Object>[] cellModels(Object subject); - -}
\ No newline at end of file diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ComboBoxModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ComboBoxModelAdapter.java deleted file mode 100644 index 7cb5f7d88e..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ComboBoxModelAdapter.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import javax.swing.ComboBoxModel; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ComboBoxModel can be used to keep a ListDataListener - * (e.g. a JComboBox) in synch with a ListValueModel (or a CollectionValueModel). - * For combo boxes, the model object that holds the current selection is - * typically a different model object than the one that holds the collection - * of choices. - * - * For example, a MWReference (the selectionOwner) has an attribute - * "sourceTable" (the collectionOwner) - * which holds on to a collection of MWDatabaseFields. When the selection - * is changed this model will keep the listeners aware of the changes. - * The inherited list model will keep its listeners aware of changes to the - * collection model - * - * In addition to the collection holder required by the superclass, - * an instance of this ComboBoxModel must be supplied with a - * selection holder, which is a PropertyValueModel that provides access - * to the selection (typically a PropertyAspectAdapter). - */ -public class ComboBoxModelAdapter - extends ListModelAdapter - implements ComboBoxModel -{ - protected final WritablePropertyValueModel<Object> selectionHolder; - protected final PropertyChangeListener selectionListener; - - - // ********** constructors ********** - - /** - * Constructor - the list holder and selection holder are required; - */ - public ComboBoxModelAdapter(ListValueModel<?> listHolder, WritablePropertyValueModel<Object> selectionHolder) { - super(listHolder); - if (selectionHolder == null) { - throw new NullPointerException(); - } - this.selectionHolder = selectionHolder; - this.selectionListener = this.buildSelectionListener(); - } - - /** - * Constructor - the collection holder and selection holder are required; - */ - public ComboBoxModelAdapter(CollectionValueModel<?> collectionHolder, WritablePropertyValueModel<Object> selectionHolder) { - super(collectionHolder); - if (selectionHolder == null) { - throw new NullPointerException(); - } - this.selectionHolder = selectionHolder; - this.selectionListener = this.buildSelectionListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildSelectionListener() { - return new AWTPropertyChangeListenerWrapper(this.buildSelectionListener_()); - } - - protected PropertyChangeListener buildSelectionListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - // notify listeners that the selection has changed - ComboBoxModelAdapter.this.fireSelectionChanged(); - } - @Override - public String toString() { - return "selection listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ComboBoxModel implementation ********** - - public Object getSelectedItem() { - return this.selectionHolder.getValue(); - } - - public void setSelectedItem(Object selectedItem) { - this.selectionHolder.setValue(selectedItem); - } - - - // ********** behavior ********** - - /** - * Extend to engage the selection holder. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.selectionHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener); - } - - /** - * Extend to disengage the selection holder. - */ - @Override - protected void disengageModel() { - this.selectionHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener); - super.disengageModel(); - } - - /** - * Notify the listeners that the selection has changed. - */ - protected void fireSelectionChanged() { - // I guess this will work... - this.fireContentsChanged(this, -1, -1); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.selectionHolder + ":" + this.listHolder); //$NON-NLS-1$ - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DateSpinnerModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DateSpinnerModelAdapter.java deleted file mode 100644 index 61ef8cee8f..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DateSpinnerModelAdapter.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.Calendar; -import java.util.Date; -import javax.swing.SpinnerDateModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerDateModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a date. - * - * This class must be a sub-class of SpinnerDateModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see ListSpinnerModelAdapter - * @see NumberSpinnerModelAdapter - */ -public class DateSpinnerModelAdapter - extends SpinnerDateModel -{ - - /** - * The default spinner value; used when the underlying model date value is null. - * The default is the current date. - */ - private final Date defaultValue; - - /** A value model on the underlying date. */ - private final WritablePropertyValueModel<Object> dateHolder; - - /** A listener that allows us to synchronize with changes made to the underlying date. */ - private final PropertyChangeListener dateChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the date holder is required. - * The default spinner value is the current date. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder) { - this(dateHolder, new Date()); - } - - /** - * Constructor - the date holder and default value are required. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Date defaultValue) { - this(dateHolder, null, null, Calendar.DAY_OF_MONTH, defaultValue); - } - - /** - * Constructor - the date holder is required. - * The default spinner value is the current date. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField) { - this(dateHolder, start, end, calendarField, new Date()); - } - - /** - * Constructor - the date holder is required. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField, Date defaultValue) { - super(dateHolder.getValue() == null ? defaultValue : (Date) dateHolder.getValue(), start, end, calendarField); - this.dateHolder = dateHolder; - this.dateChangeListener = this.buildDateChangeListener(); - // postpone listening to the underlying date - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildDateChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildDateChangeListener_()); - } - - protected PropertyChangeListener buildDateChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - DateSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "date listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.dateHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying date directly. - * The resulting event will be ignored: @see #synchronize(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.dateHolder.setValue(value); - } - - /** - * Extend to start listening to the underlying date if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.dateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener); - this.synchronize(this.dateHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying date if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.dateHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener); - } - } - - - // ********** queries ********** - - protected Date getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the spinner date has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.dateHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DocumentAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DocumentAdapter.java deleted file mode 100644 index 1f7f4043de..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/DocumentAdapter.java +++ /dev/null @@ -1,375 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.EventObject; - -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.EventListenerList; -import javax.swing.event.UndoableEditEvent; -import javax.swing.event.UndoableEditListener; -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.PlainDocument; -import javax.swing.text.Position; -import javax.swing.text.Segment; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.text.Document can be used to keep a DocumentListener - * (e.g. a JTextField) in synch with a PropertyValueModel that holds a string. - * - * NB: This model should only be used for "small" documents; - * i.e. documents used by text fields, not text panes. - * @see #synchronizeDelegate(String) - */ -public class DocumentAdapter - implements Document, Serializable -{ - - /** The delegate document whose behavior we "enhance". */ - protected final Document delegate; - - /** A listener that allows us to forward any changes made to the delegate document. */ - protected final CombinedListener delegateListener; - - /** A value model on the underlying model string. */ - protected final WritablePropertyValueModel<String> stringHolder; - - /** A listener that allows us to synchronize with changes made to the underlying model string. */ - protected transient PropertyChangeListener stringListener; - - /** The event listener list for the document. */ - protected final EventListenerList listenerList = new EventListenerList(); - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Constructor - the string holder is required. - * Wrap the specified document. - */ - public DocumentAdapter(WritablePropertyValueModel<String> stringHolder, Document delegate) { - super(); - if (stringHolder == null || delegate == null) { - throw new NullPointerException(); - } - this.stringHolder = stringHolder; - // postpone listening to the underlying model string - // until we have listeners ourselves... - this.delegate = delegate; - this.stringListener = this.buildStringListener(); - this.delegateListener = this.buildDelegateListener(); - } - - /** - * Constructor - the string holder is required. - * Wrap a plain document. - */ - public DocumentAdapter(WritablePropertyValueModel<String> stringHolder) { - this(stringHolder, new PlainDocument()); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildStringListener() { - return new AWTPropertyChangeListenerWrapper(this.buildStringListener_()); - } - - protected PropertyChangeListener buildStringListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - DocumentAdapter.this.stringChanged(event); - } - @Override - public String toString() { - return "string listener"; //$NON-NLS-1$ - } - }; - } - - protected CombinedListener buildDelegateListener() { - return new InternalListener(); - } - - - // ********** Document implementation ********** - - public int getLength() { - return this.delegate.getLength(); - } - - /** - * Extend to start listening to the underlying models if necessary. - */ - public void addDocumentListener(DocumentListener listener) { - if (this.listenerList.getListenerCount(DocumentListener.class) == 0) { - this.delegate.addDocumentListener(this.delegateListener); - this.engageStringHolder(); - } - this.listenerList.add(DocumentListener.class, listener); - } - - /** - * Extend to stop listening to the underlying models if appropriate. - */ - public void removeDocumentListener(DocumentListener listener) { - this.listenerList.remove(DocumentListener.class, listener); - if (this.listenerList.getListenerCount(DocumentListener.class) == 0) { - this.disengageStringHolder(); - this.delegate.removeDocumentListener(this.delegateListener); - } - } - - /** - * Extend to start listening to the delegate document if necessary. - */ - public void addUndoableEditListener(UndoableEditListener listener) { - if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) { - this.delegate.addUndoableEditListener(this.delegateListener); - } - this.listenerList.add(UndoableEditListener.class, listener); - } - - /** - * Extend to stop listening to the delegate document if appropriate. - */ - public void removeUndoableEditListener(UndoableEditListener listener) { - this.listenerList.remove(UndoableEditListener.class, listener); - if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) { - this.delegate.removeUndoableEditListener(this.delegateListener); - } - } - - public Object getProperty(Object key) { - return this.delegate.getProperty(key); - } - - public void putProperty(Object key, Object value) { - this.delegate.putProperty(key, value); - } - - /** - * Extend to update the underlying model string directly. - * The resulting event will be ignored: @see #synchronizeDelegate(String). - */ - public void remove(int offset, int len) throws BadLocationException { - this.delegate.remove(offset, len); - this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength())); - } - - /** - * Extend to update the underlying model string directly. - * The resulting event will be ignored: @see #synchronizeDelegate(String). - */ - public void insertString(int offset, String insertedString, AttributeSet a) throws BadLocationException { - this.delegate.insertString(offset, insertedString, a); - this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength())); - } - - public String getText(int offset, int length) throws BadLocationException { - return this.delegate.getText(offset, length); - } - - public void getText(int offset, int length, Segment txt) throws BadLocationException { - this.delegate.getText(offset, length, txt); - } - - public Position getStartPosition() { - return this.delegate.getStartPosition(); - } - - public Position getEndPosition() { - return this.delegate.getEndPosition(); - } - - public Position createPosition(int offs) throws BadLocationException { - return this.delegate.createPosition(offs); - } - - public Element[] getRootElements() { - return this.delegate.getRootElements(); - } - - public Element getDefaultRootElement() { - return this.delegate.getDefaultRootElement(); - } - - public void render(Runnable r) { - this.delegate.render(r); - } - - - // ********** queries ********** - - public DocumentListener[] documentListeners() { - return this.listenerList.getListeners(DocumentListener.class); - } - - public UndoableEditListener[] undoableEditListeners() { - return this.listenerList.getListeners(UndoableEditListener.class); - } - - - // ********** behavior ********** - - /** - * A third party has modified the underlying model string. - * Synchronize the delegate document accordingly. - */ - protected void stringChanged(PropertyChangeEvent event) { - this.synchronizeDelegate((String) event.getNewValue()); - } - - /** - * Replace the document's entire text string with the new string. - */ - protected void synchronizeDelegate(String s) { - try { - int len = this.delegate.getLength(); - // check to see whether the delegate has already been synchronized - // (via #insertString() or #remove()) - if ( ! this.delegate.getText(0, len).equals(s)) { - this.delegate.remove(0, len); - this.delegate.insertString(0, s, null); - } - } catch (BadLocationException ex) { - throw new IllegalStateException(ex.getMessage()); // this should not happen... - } - } - - protected void engageStringHolder() { - this.stringHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringListener); - this.synchronizeDelegate(this.stringHolder.getValue()); - } - - protected void disengageStringHolder() { - this.stringHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.stringListener); - } - - protected void delegateChangedUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].changedUpdate(ee); - } - } - - protected void delegateInsertUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].insertUpdate(ee); - } - } - - protected void delegateRemoveUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].removeUpdate(ee); - } - } - - protected void delegateUndoableEditHappened(UndoableEditEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - UndoableEditEvent ee = new UndoableEditEvent(this, event.getEdit()); - UndoableEditListener[] listeners = this.undoableEditListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].undoableEditHappened(ee); - } - } - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.stringHolder); - } - - private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { - // read in any hidden stuff - s.defaultReadObject(); - this.stringListener = this.buildStringListener(); - } - - -// ********** inner class ********** - - protected interface CombinedListener extends DocumentListener, UndoableEditListener, Serializable { - // just consolidate the two interfaces - } - - protected class InternalListener implements CombinedListener { - private static final long serialVersionUID = 1L; - public void changedUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateChangedUpdate(event); - } - public void insertUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateInsertUpdate(event); - } - public void removeUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateRemoveUpdate(event); - } - public void undoableEditHappened(UndoableEditEvent event) { - DocumentAdapter.this.delegateUndoableEditHappened(event); - } - } - - protected static class InternalDocumentEvent - extends EventObject - implements DocumentEvent - { - protected DocumentEvent delegate; - - protected InternalDocumentEvent(Document document, DocumentEvent delegate) { - super(document); - this.delegate = delegate; - } - public ElementChange getChange(Element elem) { - return this.delegate.getChange(elem); - } - public Document getDocument() { - return (Document) this.source; - } - public int getLength() { - return this.delegate.getLength(); - } - public int getOffset() { - return this.delegate.getOffset(); - } - public EventType getType() { - return this.delegate.getType(); - } - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListModelAdapter.java deleted file mode 100644 index 2d1c1e4b5d..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListModelAdapter.java +++ /dev/null @@ -1,292 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import javax.swing.AbstractListModel; -import javax.swing.event.ListDataListener; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This javax.swing.ListModel can be used to keep a ListDataListener - * (e.g. a JList) in synch with a ListValueModel (or a CollectionValueModel). - * - * An instance of this ListModel *must* be supplied with a value model, - * which is a ListValueModel on the bound list or a CollectionValueModel - * on the bound collection. This is required - the list (or collection) - * itself can be null, but the value model that holds it cannot. - */ -public class ListModelAdapter - extends AbstractListModel -{ - /** A value model on the underlying model list. */ - protected ListValueModel<?> listHolder; - - /** - * Cache the size of the list for "dramatic" changes. - * @see #listChanged(ListChangeEvent) - */ - protected int listSize; - - /** A listener that allows us to forward changes made to the underlying model list. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Default constructor - initialize stuff. - */ - private ListModelAdapter() { - super(); - this.listSize = 0; - this.listChangeListener = this.buildListChangeListener(); - } - - /** - * Constructor - the list holder is required. - */ - public ListModelAdapter(ListValueModel<?> listHolder) { - this(); - this.setModel(listHolder); - } - - /** - * Constructor - the collection holder is required. - */ - public ListModelAdapter(CollectionValueModel<?> collectionHolder) { - this(); - this.setModel(collectionHolder); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - ListModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListRemoveEvent event) { - ListModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListReplaceEvent event) { - ListModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListMoveEvent event) { - ListModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListClearEvent event) { - ListModelAdapter.this.listCleared(); - } - public void listChanged(ListChangeEvent event) { - ListModelAdapter.this.listChanged(); - } - @Override - public String toString() { - return "list listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ListModel implementation ********** - - public int getSize() { - return this.listHolder.size(); - } - - public Object getElementAt(int index) { - return this.listHolder.get(index); - } - - /** - * Extend to start listening to the underlying model list if necessary. - */ - @Override - public void addListDataListener(ListDataListener l) { - if (this.hasNoListDataListeners()) { - this.engageModel(); - this.listSize = this.listHolder.size(); - } - super.addListDataListener(l); - } - - /** - * Extend to stop listening to the underlying model list if appropriate. - */ - @Override - public void removeListDataListener(ListDataListener l) { - super.removeListDataListener(l); - if (this.hasNoListDataListeners()) { - this.disengageModel(); - this.listSize = 0; - } - } - - - // ********** public API ********** - - /** - * Return the underlying list model. - */ - public ListValueModel<?> model() { - return this.listHolder; - } - - /** - * Set the underlying list model. - */ - public void setModel(ListValueModel<?> listHolder) { - if (listHolder == null) { - throw new NullPointerException(); - } - boolean hasListeners = this.hasListDataListeners(); - if (hasListeners) { - this.disengageModel(); - } - this.listHolder = listHolder; - if (hasListeners) { - this.engageModel(); - this.listChanged(); - } - } - - /** - * Set the underlying collection model. - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void setModel(CollectionValueModel<?> collectionHolder) { - this.setModel(new CollectionListValueModelAdapter(collectionHolder)); - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoListDataListeners() { - return this.getListDataListeners().length == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasListDataListeners() { - return ! this.hasNoListDataListeners(); - } - - - // ********** behavior ********** - - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - - - // ********** list change support ********** - - /** - * Items were added to the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsAdded(ListAddEvent event) { - int start = event.getIndex(); - int end = start + event.getItemsSize() - 1; - this.fireIntervalAdded(this, start, end); - this.listSize += event.getItemsSize(); - } - - /** - * Items were removed from the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsRemoved(ListRemoveEvent event) { - int start = event.getIndex(); - int end = start + event.getItemsSize() - 1; - this.fireIntervalRemoved(this, start, end); - this.listSize -= event.getItemsSize(); - } - - /** - * Items were replaced in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsReplaced(ListReplaceEvent event) { - int start = event.getIndex(); - int end = start + event.getItemsSize() - 1; - this.fireContentsChanged(this, start, end); - } - - /** - * Items were moved in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsMoved(ListMoveEvent event) { - int start = Math.min(event.getSourceIndex(), event.getTargetIndex()); - int end = Math.max(event.getSourceIndex(), event.getTargetIndex()) + event.getLength() - 1; - this.fireContentsChanged(this, start, end); - } - - /** - * The underlying model list was cleared. - * Notify listeners of the changes. - */ - protected void listCleared() { - if (this.listSize != 0) { - this.fireIntervalRemoved(this, 0, this.listSize - 1); - this.listSize = 0; - } - } - - /** - * The underlying model list has changed "dramatically". - * Notify listeners of the changes. - */ - protected void listChanged() { - if (this.listSize != 0) { - this.fireIntervalRemoved(this, 0, this.listSize - 1); - } - this.listSize = this.listHolder.size(); - if (this.listSize != 0) { - this.fireIntervalAdded(this, 0, this.listSize - 1); - } - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.listHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListSpinnerModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListSpinnerModelAdapter.java deleted file mode 100644 index af3e0b0187..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ListSpinnerModelAdapter.java +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.Arrays; -import java.util.List; -import javax.swing.SpinnerListModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerListModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value - * in the list. - * - * This class must be a sub-class of SpinnerListModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * NB: This model should only be used for values that have a reasonably - * inexpensive #equals() implementation. - * @see #synchronize(Object) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see DateSpinnerModelAdapter - * @see NumberSpinnerModelAdapter - */ -public class ListSpinnerModelAdapter - extends SpinnerListModel -{ - - /** - * The default spinner value; used when the underlying model value is null. - * The default is the first item on the list. - */ - private final Object defaultValue; - - /** A value model on the underlying value. */ - private final WritablePropertyValueModel<Object> valueHolder; - - /** A listener that allows us to synchronize with changes made to the underlying value. */ - private final PropertyChangeListener valueChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the value holder is required. - * Use the model value itself as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder) { - this(valueHolder, valueHolder.getValue()); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object defaultValue) { - this(valueHolder, new Object[] {defaultValue}, defaultValue); - } - - /** - * Constructor - the value holder is required. - * Use the first item in the list of values as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object[] values) { - this(valueHolder, values, values[0]); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object[] values, Object defaultValue) { - this(valueHolder, Arrays.asList(values), defaultValue); - } - - /** - * Constructor - the value holder is required. - * Use the first item in the list of values as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, List<Object> values) { - this(valueHolder, values, values.get(0)); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, List<Object> values, Object defaultValue) { - super(values); - this.valueHolder = valueHolder; - this.valueChangeListener = this.buildValueChangeListener(); - // postpone listening to the underlying value - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValueChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildValueChangeListener_()); - } - - protected PropertyChangeListener buildValueChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ListSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "value listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.valueHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying value directly. - * The resulting event will be ignored: @see #synchronize(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.valueHolder.setValue(value); - } - - /** - * Extend to start listening to the underlying value if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - this.synchronize(this.valueHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying value if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - } - - - // ********** queries ********** - - protected Object getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the spinner value has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.valueHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java deleted file mode 100644 index 4a624639b5..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerNumberModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a number. - * - * This class must be a sub-class of SpinnerNumberModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see DateSpinnerModelAdapter - * @see ListSpinnerModelAdapter - */ -public class NumberSpinnerModelAdapter - extends SpinnerNumberModel -{ - - /** - * The default spinner value; used when the - * underlying model number value is null. - */ - private final Number defaultValue; - - /** A value model on the underlying number. */ - private final WritablePropertyValueModel<Number> numberHolder; - - /** - * A listener that allows us to synchronize with - * changes made to the underlying number. - */ - private final PropertyChangeListener numberChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the number holder is required. - * The default spinner value is zero. - * The step size is one. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder) { - this(numberHolder, 0); - } - - /** - * Constructor - the number holder is required. - * The step size is one. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int defaultValue) { - this(numberHolder, null, null, Integer.valueOf(1), Integer.valueOf(defaultValue)); - } - - /** - * Constructor - the number holder is required. - * Use the minimum value as the default spinner value. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize) { - this(numberHolder, minimum, maximum, stepSize, minimum); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize, int defaultValue) { - this(numberHolder, Integer.valueOf(minimum), Integer.valueOf(maximum), Integer.valueOf(stepSize), Integer.valueOf(defaultValue)); - } - - /** - * Constructor - the number holder is required. - * Use the minimum value as the default spinner value. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double minimum, double maximum, double stepSize) { - this(numberHolder, minimum, maximum, stepSize, minimum); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double minimum, double maximum, double stepSize, double defaultValue) { - this(numberHolder, Double.valueOf(minimum), Double.valueOf(maximum), Double.valueOf(stepSize), Double.valueOf(defaultValue)); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, Comparable<?> minimum, Comparable<?> maximum, Number stepSize, Number defaultValue) { - super(numberHolder.getValue() == null ? defaultValue : (Number) numberHolder.getValue(), minimum, maximum, stepSize); - this.numberHolder = numberHolder; - this.numberChangeListener = this.buildNumberChangeListener(); - // postpone listening to the underlying number - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildNumberChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildNumberChangeListener_()); - } - - protected PropertyChangeListener buildNumberChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - NumberSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "number listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.numberHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying number directly. - * The resulting event will be ignored: @see #synchronizeDelegate(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.numberHolder.setValue((Number) value); - } - - /** - * Extend to start listening to the underlying number if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.numberHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener); - this.synchronize(this.numberHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying number if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.numberHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener); - } - } - - - // ********** queries ********** - - protected Number getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the date has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.numberHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ObjectListSelectionModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ObjectListSelectionModel.java deleted file mode 100644 index 81647b2842..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ObjectListSelectionModel.java +++ /dev/null @@ -1,427 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import javax.swing.DefaultListSelectionModel; -import javax.swing.ListModel; -import javax.swing.event.ListDataEvent; -import javax.swing.event.ListDataListener; -import javax.swing.event.ListSelectionListener; -import org.eclipse.jpt.common.utility.internal.CollectionTools; - -/** - * This ListSelectionModel is aware of the ListModel and - * provides convenience methods to access and set the - * selected *objects*, as opposed to the selected *indexes*. - */ -public class ObjectListSelectionModel - extends DefaultListSelectionModel -{ - /** The list model referenced by the list selection model. */ - private final ListModel listModel; - - /** A listener that allows us to clear the selection when the list model has changed. */ - private final ListDataListener listDataListener; - - - // ********** constructors ********** - - /** - * Construct a list selection model for the specified list model. - */ - public ObjectListSelectionModel(ListModel listModel) { - super(); - this.listModel = listModel; - this.listDataListener = this.buildListDataListener(); - } - - - // ********** initialization ********** - - private ListDataListener buildListDataListener() { - return new ListDataListener() { - public void intervalAdded(ListDataEvent event) { - // this does not affect the selection - } - public void intervalRemoved(ListDataEvent event) { - // this does not affect the selection - } - public void contentsChanged(ListDataEvent event) { - ObjectListSelectionModel.this.listModelContentsChanged(event); - } - @Override - public String toString() { - return "list data listener"; //$NON-NLS-1$ - } - }; - } - - /** - * Typically, the selection does not need to be cleared when the - * contents of the list have changed. Most of the time this just - * means an item has changed in a way that affects its display string - * or icon. We typically only use the class for edits involving - * single selection. - * A subclass can override this method if the selection - * should be cleared because a change could mean the selection is invalid. - */ - protected void listModelContentsChanged(@SuppressWarnings("unused") ListDataEvent event) { - /**this.clearSelection();*/ - } - - - // ********** ListSelectionModel implementation ********** - - @Override - public void addListSelectionListener(ListSelectionListener l) { - if (this.hasNoListSelectionListeners()) { - this.listModel.addListDataListener(this.listDataListener); - } - super.addListSelectionListener(l); - } - - @Override - public void removeListSelectionListener(ListSelectionListener l) { - super.removeListSelectionListener(l); - if (this.hasNoListSelectionListeners()) { - this.listModel.removeListDataListener(this.listDataListener); - } - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoListSelectionListeners() { // private-protected - return this.getListSelectionListeners().length == 0; - } - - /** - * Return the list model referenced by the list selection model. - */ - public ListModel getListModel() { - return this.listModel; - } - - public int selectedValuesSize() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return 0; - } - - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - n++; - } - } - return n; - } - - /** - * Return the first selected value. - * Return null if the selection is empty. - */ - public Object selectedValue() { - int index = this.getMinSelectionIndex(); - if (index == -1) { - return null; - } - if (this.getListModel().getSize() <= index) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * Return an array of the selected values. - */ - public Object[] selectedValues() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return new Object[0]; - } - - int maxSize = (max - min) + 1; - Object[] temp = new Object[maxSize]; - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - temp[n++] = this.getListModel().getElementAt(i); - } - } - if (n == maxSize) { - // all the elements in the range were selected - return temp; - } - // only some of the elements in the range were selected - Object[] result = new Object[n]; - System.arraycopy(temp, 0, result, 0, n); - return result; - } - - /** - * Return an array of the selected indices in order. - */ - public int[] selectedIndices() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return new int[0]; - } - - int maxSize = (max - min) + 1; - int[] temp = new int[maxSize]; - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - temp[n++] = i; - } - } - if (n == maxSize) { - // all the elements in the range were selected - Arrays.sort(temp); - return temp; - } - // only some of the elements in the range were selected - int[] result = new int[n]; - System.arraycopy(temp, 0, result, 0, n); - Arrays.sort(result); - return result; - } - - /** - * Set the selected value. - */ - public void setSelectedValue(Object object) { - this.setSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - this.clearSelection(); - this.addSelectedValuesInternal(objects); - this.setValueIsAdjusting(false); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Collection<?> objects) { - this.setSelectedValues(objects.iterator()); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Object[] objects) { - this.setSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * Add the specified object to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValue(Object object) { - this.addSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - this.addSelectedValuesInternal(objects); - this.setValueIsAdjusting(false); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Collection<?> objects) { - this.addSelectedValues(objects.iterator()); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Object[] objects) { - this.addSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * Remove the specified object from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValue(Object object) { - this.removeSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - ListModel lm = this.getListModel(); - int lmSize = lm.getSize(); - while (objects.hasNext()) { - int index = this.indexOf(objects.next(), lm, lmSize); - this.removeSelectionInterval(index, index); - } - this.setValueIsAdjusting(false); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Collection<?> objects) { - this.removeSelectedValues(objects.iterator()); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Object[] objects) { - this.removeSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * @see javax.swing.ListSelectionModel#getAnchorSelectionIndex() - * Return null if the anchor selection is empty. - */ - public Object getAnchorSelectedValue() { - int index = this.getAnchorSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#setAnchorSelectionIndex(int) - */ - public void setAnchorSelectedValue(Object object) { - this.setAnchorSelectionIndex(this.indexOf(object)); - } - - /** - * @see javax.swing.ListSelectionModel#getLeadSelectionIndex() - * Return null if the lead selection is empty. - */ - public Object getLeadSelectedValue() { - int index = this.getLeadSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#setLeadSelectionIndex(int) - */ - public void setLeadSelectedValue(Object object) { - this.setLeadSelectionIndex(this.indexOf(object)); - } - - /** - * @see javax.swing.ListSelectionModel#getMaxSelectionIndex() - * Return null if the max selection is empty. - */ - public Object getMaxSelectedValue() { - int index = this.getMaxSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#getMinSelectionIndex() - * Return null if the min selection is empty. - */ - public Object getMinSelectedValue() { - int index = this.getMinSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#isSelectedIndex(int) - */ - public boolean valueIsSelected(Object object) { - return this.isSelectedIndex(this.indexOf(object)); - } - - /** - * Add the specified objects to the current set of selected objects, - * without wrapping the actions in "adjusting" events. - */ - private void addSelectedValuesInternal(Iterator<?> objects) { - ListModel lm = this.getListModel(); - int listModelSize = lm.getSize(); - while (objects.hasNext()) { - int index = this.indexOf(objects.next(), lm, listModelSize); - this.addSelectionInterval(index, index); - } - } - - /** - * Return the index in the list model of the specified object. - * Return -1 if the object is not in the list model. - */ - private int indexOf(Object object) { - ListModel lm = this.getListModel(); - return this.indexOf(object, lm, lm.getSize()); - } - - /** - * Return the index in the list model of the specified object. - * Return -1 if the object is not in the list model. - */ - // we're just jerking around with performance optimizations here - // (in memory of Phil...); - // call this method inside loops that do not modify the listModel - private int indexOf(Object object, ListModel lm, int listModelSize) { - for (int i = listModelSize; i-- > 0; ) { - if (lm.getElementAt(i).equals(object)) { - return i; - } - } - return -1; - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/PrimitiveListTreeModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/PrimitiveListTreeModel.java deleted file mode 100644 index 9fe9fca0e8..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/PrimitiveListTreeModel.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.swing.event.TreeModelListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; - -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; - -/** - * This TreeModel implementation provides a tree with a "null" root that - * has a set of "primitive" children. These "primitive" children do not have - * children themselves, making the tree a maximum of 2 levels deep. - * This model automatically synchronizes the root's children with a - * ListValueModel that holds a collection of primitive (non-model) objects - * (e.g. Strings). - * - * This is useful for providing an "editable" list of primitives. Since the JDK - * does not provide us with an editable listbox, we must use an editable tree. - * We wrap everything in DefaultMutableTreeNodes. - * - * Subclasses must implement #primitiveChanged(int, Object) and update - * the model appropriately. This method is called when the user edits the - * list directly and presses <Enter>. - * - * The JTree using this model must be configured as "editable": - * tree.setEditable(true); - */ -// TODO convert to use an adapter instead of requiring subclass -public abstract class PrimitiveListTreeModel - extends DefaultTreeModel -{ - /** a model on the list of primitives */ - private final ListValueModel<?> listHolder; - - /** a listener that handles the adding, removing, and replacing of the primitives */ - private final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Public constructor - the list holder is required - */ - public PrimitiveListTreeModel(ListValueModel<?> listHolder) { - super(new DefaultMutableTreeNode(null, true)); // true = the root can have children - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - // postpone listening to the model until we have listeners ourselves - } - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new PrimitiveListChangeListener(); - } - - - // ********** behavior ********** - - /** - * Subclasses should override this method to update the - * model appropriately. The primitive at the specified index was - * edited directly by the user and the new value is as specified. - * Convert the value appropriately and place it in the model. - */ - protected abstract void primitiveChanged(int index, Object newValue); - - - // ********** TreeModel implementation ********** - - /** - * Override to change the underlying model instead of changing the node directly. - */ - @Override - public void valueForPathChanged(TreePath path, Object newValue) { - TreeNode node = (TreeNode) path.getLastPathComponent(); - int index = ((TreeNode) this.getRoot()).getIndex(node); - this.primitiveChanged(index, newValue); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTreeModelListener(TreeModelListener l) { - if (this.getTreeModelListeners().length == 0) { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - this.synchronizeList(); - } - super.addTreeModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeTreeModelListener(TreeModelListener l) { - super.removeTreeModelListener(l); - if (this.getTreeModelListeners().length == 0) { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - } - - - // ********** behavior ********** - - /** - * Synchronize our list of nodes with the list of primitives - */ - void synchronizeList() { - this.clearList(); - this.buildList(); - } - - void clearList() { - int childcount = this.root.getChildCount(); - for (int i = childcount - 1; i >= 0; i--) { - this.removeNodeFromParent((MutableTreeNode)this.root.getChildAt(i)); - } - } - - private void buildList() { - for (Iterator<?> stream = this.listHolder.iterator(); stream.hasNext(); ) { - this.addPrimitive(stream.next()); - } - } - - /** - * Add the specified primitive to the end of the list. - */ - private void addPrimitive(Object primitive) { - this.insertPrimitive(this.root.getChildCount(), primitive); - } - - /** - * Create a node for the specified primitive - * and insert it as a child of the root. - */ - void insertPrimitive(int index, Object primitive) { - DefaultMutableTreeNode node = new DefaultMutableTreeNode(primitive, false); // don't allow children on the child node - this.insertNodeInto(node, (MutableTreeNode) this.root, index); - } - - /** - * Remove node at the specified index. - */ - MutableTreeNode removeNode(int index) { - MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index); - this.removeNodeFromParent(node); - return node; - } - - /** - * Replace the user object of the node at childIndex. - */ - void replacePrimitive(int index, Object primitive) { - MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index); - node.setUserObject(primitive); - this.nodeChanged(node); - } - - - // ********** inner class ********** - - private class PrimitiveListChangeListener implements ListChangeListener { - PrimitiveListChangeListener() { - super(); - } - - public void itemsAdded(ListAddEvent event) { - int i = event.getIndex(); - for (Object item : event.getItems()) { - PrimitiveListTreeModel.this.insertPrimitive(i++, item); - } - } - - public void itemsRemoved(ListRemoveEvent event) { - for (int i = 0; i < event.getItemsSize(); i++) { - PrimitiveListTreeModel.this.removeNode(event.getIndex()); - } - } - - public void itemsReplaced(ListReplaceEvent event) { - int i = event.getIndex(); - for (Object item : event.getNewItems()) { - PrimitiveListTreeModel.this.replacePrimitive(i++, item); - } - } - - public void itemsMoved(ListMoveEvent event) { - ArrayList<MutableTreeNode> temp = new ArrayList<MutableTreeNode>(event.getLength()); - for (int i = 0; i < event.getLength(); i++) { - temp.add(PrimitiveListTreeModel.this.removeNode(event.getSourceIndex())); - } - int i = event.getTargetIndex(); - for (MutableTreeNode node : temp) { - PrimitiveListTreeModel.this.insertPrimitive(i++, node); - } - } - - public void listCleared(ListClearEvent event) { - PrimitiveListTreeModel.this.clearList(); - } - - public void listChanged(ListChangeEvent event) { - PrimitiveListTreeModel.this.synchronizeList(); - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/RadioButtonModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/RadioButtonModelAdapter.java deleted file mode 100644 index 83d3113454..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/RadioButtonModelAdapter.java +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import org.eclipse.jpt.common.utility.internal.BidiFilter; -import org.eclipse.jpt.common.utility.internal.BidiTransformer; -import org.eclipse.jpt.common.utility.internal.model.value.FilteringWritablePropertyValueModel; -import org.eclipse.jpt.common.utility.internal.model.value.TransformationWritablePropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JRadioButton) in synch with a (typically shared) - * PropertyValueModel that holds one value out of a set of values. - * - * NOTE: Do *not* use this model with a ButtonGroup, since the - * shared value holder and the wrappers built by this adapter will - * keep the appropriate radio button checked. Also, this allows - * us to uncheck all the radio buttons in a group when the shared - * value is null. - */ -public class RadioButtonModelAdapter - extends ToggleButtonModelAdapter -{ - - // ********** constructors ********** - - /** - * Constructor - the value holder is required. - */ - public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue, boolean defaultValue) { - super(buildBooleanHolder(valueHolder, buttonValue), defaultValue); - } - - /** - * Constructor - the value holder is required. - * The default value will be false. - */ - public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) { - super(buildBooleanHolder(valueHolder, buttonValue)); - } - - - // ********** static methods ********** - - /** - * Build up a set of wrappers that will convert the - * specified value holder and button value to/from a boolean. - * - * If the value holder's value matches the button value, - * the wrapper will return true. Likewise, if the value holder's - * value is set to true, the wrapper will set the value holder's - * value to the button value. - */ - public static WritablePropertyValueModel<Boolean> buildBooleanHolder(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) { - WritablePropertyValueModel<Object> filteringPVM = new FilteringWritablePropertyValueModel<Object>(valueHolder, new RadioButtonFilter(buttonValue)); - return new TransformationWritablePropertyValueModel<Object, Boolean>(filteringPVM, new RadioButtonTransformer(buttonValue)); - } - - - // ********** overrides ********** - - /** - * The user cannot de-select a radio button - the user - * can only *select* a radio button. Only the model can - * cause a radio button to be de-selected. We use the - * ARMED flag to indicate whether we are being de-selected - * by the user. - */ - @Override - public void setSelected(boolean b) { - // do not allow the user to de-select a radio button - // radio buttons can - if ((b == false) && this.isArmed()) { - return; - } - super.setSelected(b); - } - - - // ********** inner classes ********** - - /** - * This filter will only pass through a new value to the wrapped - * value holder when it matches the configured button value. - */ - public static class RadioButtonFilter implements BidiFilter<Object> { - private Object buttonValue; - - public RadioButtonFilter(Object buttonValue) { - super(); - this.buttonValue = buttonValue; - } - - /** - * always return the wrapped value - */ - public boolean accept(Object value) { - return true; - } - - /** - * pass through the value to the wrapped property value model - * *only* when it matches our button value - */ - public boolean reverseAccept(Object value) { - return (value != null) && value.equals(this.buttonValue); - } - - } - - /** - * This transformer will convert the wrapped value to Boolean.TRUE - * when it matches the configured button value. - */ - public static class RadioButtonTransformer implements BidiTransformer<Object, Boolean> { - private Object buttonValue; - - public RadioButtonTransformer(Object buttonValue) { - super(); - this.buttonValue = buttonValue; - } - - /** - * if the wrapped value matches our button value return true, - * if it is some other value return false; - * but if it is null simply pass it through because it will cause the - * button model's default value to be used - */ - public Boolean transform(Object value) { - return (value == null) ? null : Boolean.valueOf(value.equals(this.buttonValue)); - } - - /** - * if the new value is true, pass through the our button value; - * otherwise pass through null - */ - public Object reverseTransform(Boolean value) { - return (value.booleanValue()) ? this.buttonValue : null; - } - - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/SpinnerModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/SpinnerModelAdapter.java deleted file mode 100644 index 2490cae9d4..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/SpinnerModelAdapter.java +++ /dev/null @@ -1,207 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import javax.swing.AbstractSpinnerModel; -import javax.swing.SpinnerModel; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value. - * - * Note: it is likely you want to use one of the following classes instead of - * this one: - * DateSpinnerModelAdapter - * NumberSpinnerModelAdapter - * ListSpinnerModelAdapter - * - * NB: This model should only be used for values that have a fairly - * inexpensive #equals() implementation. - * @see #synchronizeDelegate(Object) - */ -public class SpinnerModelAdapter - extends AbstractSpinnerModel -{ - /** The delegate spinner model whose behavior we "enhance". */ - protected final SpinnerModel delegate; - - /** A listener that allows us to forward any changes made to the delegate spinner model. */ - protected final ChangeListener delegateListener; - - /** A value model on the underlying value. */ - protected final WritablePropertyValueModel<Object> valueHolder; - - /** A listener that allows us to synchronize with changes made to the underlying value. */ - protected final PropertyChangeListener valueListener; - - - // ********** constructors ********** - - /** - * Constructor - the value holder and delegate are required. - */ - public SpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, SpinnerModel delegate) { - super(); - if (valueHolder == null || delegate == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.delegate = delegate; - // postpone listening to the underlying value - // until we have listeners ourselves... - this.valueListener = this.buildValueListener(); - this.delegateListener = this.buildDelegateListener(); - } - - /** - * Constructor - the value holder is required. - * This will wrap a simple number spinner model. - */ - public SpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder) { - this(valueHolder, new SpinnerNumberModel()); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValueListener() { - return new AWTPropertyChangeListenerWrapper(this.buildValueListener_()); - } - - protected PropertyChangeListener buildValueListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - SpinnerModelAdapter.this.valueChanged(event); - } - @Override - public String toString() { - return "value listener"; //$NON-NLS-1$ - } - }; - } - - /** - * expand access a bit for inner class - */ - @Override - protected void fireStateChanged() { - super.fireStateChanged(); - } - - protected ChangeListener buildDelegateListener() { - return new ChangeListener() { - public void stateChanged(ChangeEvent event) { - // forward the event, with this as the source - SpinnerModelAdapter.this.fireStateChanged(); - } - @Override - public String toString() { - return "delegate listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** SpinnerModel implementation ********** - - public Object getValue() { - return this.delegate.getValue(); - } - - /** - * Extend to update the underlying value directly. - * The resulting event will be ignored: @see #synchronizeDelegate(Object). - */ - public void setValue(Object value) { - this.delegate.setValue(value); - this.valueHolder.setValue(value); - } - - public Object getNextValue() { - return this.delegate.getNextValue(); - } - - public Object getPreviousValue() { - return this.delegate.getPreviousValue(); - } - - /** - * Extend to start listening to the underlying value if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.listenerList.getListenerCount(ChangeListener.class) == 0) { - this.delegate.addChangeListener(this.delegateListener); - this.engageValueHolder(); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying value if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.listenerList.getListenerCount(ChangeListener.class) == 0) { - this.disengageValueHolder(); - this.delegate.removeChangeListener(this.delegateListener); - } - } - - - // ********** behavior ********** - - /** - * A third party has modified the underlying value. - * Synchronize the delegate model accordingly. - */ - protected void valueChanged(PropertyChangeEvent event) { - this.synchronizeDelegate(event.getNewValue()); - } - - /** - * Set the delegate's value if it has changed. - */ - protected void synchronizeDelegate(Object value) { - // check to see whether the delegate has already been synchronized - // (via #setValue()) - if ( ! this.delegate.getValue().equals(value)) { - this.delegate.setValue(value); - } - } - - protected void engageValueHolder() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueListener); - this.synchronizeDelegate(this.valueHolder.getValue()); - } - - protected void disengageValueHolder() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueListener); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.valueHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TableModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TableModelAdapter.java deleted file mode 100644 index 8c29c1364b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TableModelAdapter.java +++ /dev/null @@ -1,420 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.swing.event.TableModelListener; -import javax.swing.table.AbstractTableModel; - -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This TableModel can be used to keep a TableModelListener (e.g. a JTable) - * in synch with a ListValueModel that holds a collection of model objects, - * each of which corresponds to a row in the table. - * Typically, each column of the table will be bound to a different aspect - * of the contained model objects. - * - * For example, a MWTable has an attribute 'databaseFields' that holds - * a collection of MWDatabaseFields that would correspond to the rows of - * a JTable; and each MWDatabaseField has a number - * of attributes (e.g. name, type, size) that can be bound to the columns of - * a row in the JTable. As these database fields are added, removed, and - * changed, this model will keep the listeners aware of the changes. - * - * An instance of this TableModel must be supplied with a - * list holder (e.g. the 'databaseFields'), which is a value - * model on the bound collection This is required - the - * collection itself can be null, but the list value model that - * holds it is required. Typically this list will be sorted (@see - * SortedListValueModelAdapter). - * - * This TableModel must also be supplied with a ColumnAdapter that - * will be used to configure the headers, renderers, editors, and contents - * of the various columns. - * - * Design decision: - * Cell listener options (from low space/high time to high space/low time): - * - 1 cell listener listening to every cell (this is the current implementation) - * - 1 cell listener per row - * - 1 cell listener per cell - */ -public class TableModelAdapter<E> - extends AbstractTableModel -{ - /** - * a list of user objects that are converted to - * rows via the column adapter - */ - private ListValueModel<? extends E> listHolder; - private final ListChangeListener listChangeListener; - - /** - * each row is an array of cell models - */ - // declare as ArrayList so we can use #ensureCapacity(int) - private final ArrayList<WritablePropertyValueModel<Object>[]> rows; - - /** - * client-supplied adapter that provides with the various column - * settings and converts the objects in the LVM - * into an array of cell models - */ - private final ColumnAdapter columnAdapter; - - /** - * the single listener that listens to every cell's model - */ - private final PropertyChangeListener cellListener; - - - // ********** constructors ********** - - /** - * Construct a table model adapter for the specified objects - * and adapter. - */ - public TableModelAdapter(ListValueModel<? extends E> listHolder, ColumnAdapter columnAdapter) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.columnAdapter = columnAdapter; - this.listChangeListener = this.buildListChangeListener(); - this.rows = new ArrayList<WritablePropertyValueModel<Object>[]>(); - this.cellListener = this.buildCellListener(); - } - - /** - * Construct a table model adapter for the specified objects - * and adapter. - */ - public TableModelAdapter(CollectionValueModel<? extends E> collectionHolder, ColumnAdapter columnAdapter) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), columnAdapter); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - TableModelAdapter.this.addRows(event.getIndex(), event.getItemsSize(), this.getItems(event)); - } - public void itemsRemoved(ListRemoveEvent event) { - TableModelAdapter.this.removeRows(event.getIndex(), event.getItemsSize()); - } - public void itemsReplaced(ListReplaceEvent event) { - TableModelAdapter.this.replaceRows(event.getIndex(), this.getNewItems(event)); - } - public void itemsMoved(ListMoveEvent event) { - TableModelAdapter.this.moveRows(event.getTargetIndex(), event.getSourceIndex(), event.getLength()); - } - public void listCleared(ListClearEvent event) { - TableModelAdapter.this.clearTable(); - } - public void listChanged(ListChangeEvent event) { - TableModelAdapter.this.rebuildTable(); - } - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<Object> getItems(ListAddEvent event) { - return (Iterable<Object>) event.getItems(); - } - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<Object> getNewItems(ListReplaceEvent event) { - return (Iterable<Object>) event.getNewItems(); - } - @Override - public String toString() { - return "list listener"; //$NON-NLS-1$ - } - }; - } - - - protected PropertyChangeListener buildCellListener() { - return new AWTPropertyChangeListenerWrapper(this.buildCellListener_()); - } - - protected PropertyChangeListener buildCellListener_() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - TableModelAdapter.this.cellChanged((WritablePropertyValueModel<Object>) event.getSource()); - } - @Override - public String toString() { - return "cell listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** TableModel implementation ********** - - public int getColumnCount() { - return this.columnAdapter.columnCount(); - } - - public int getRowCount() { - return this.rows.size(); - } - - @Override - public String getColumnName(int column) { - return this.columnAdapter.columnName(column); - } - - @Override - public Class<?> getColumnClass(int columnIndex) { - return this.columnAdapter.columnClass(columnIndex); - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return this.columnAdapter.columnIsEditable(columnIndex); - } - - public Object getValueAt(int rowIndex, int columnIndex) { - WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex); - return row[columnIndex].getValue(); - } - - @Override - public void setValueAt(Object value, int rowIndex, int columnIndex) { - WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex); - row[columnIndex].setValue(value); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTableModelListener(TableModelListener l) { - if (this.hasNoTableModelListeners()) { - this.engageModel(); - } - super.addTableModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public void removeTableModelListener(TableModelListener l) { - super.removeTableModelListener(l); - if (this.hasNoTableModelListeners()) { - this.disengageModel(); - } - } - - - // ********** public API ********** - - /** - * Return the underlying list model. - */ - public ListValueModel<? extends E> getModel() { - return this.listHolder; - } - - /** - * Set the underlying list model. - */ - public void setModel(ListValueModel<E> listHolder) { - if (listHolder == null) { - throw new NullPointerException(); - } - boolean hasListeners = this.hasTableModelListeners(); - if (hasListeners) { - this.disengageModel(); - } - this.listHolder = listHolder; - if (hasListeners) { - this.engageModel(); - this.fireTableDataChanged(); - } - } - - /** - * Set the underlying collection model. - */ - public void setModel(CollectionValueModel<E> collectionHolder) { - this.setModel(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoTableModelListeners() { - return this.listenerList.getListenerCount(TableModelListener.class) == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasTableModelListeners() { - return ! this.hasNoTableModelListeners(); - } - - - // ********** behavior ********** - - /** - * Start listening to the list of objects and the various aspects - * of the objects that make up the rows. - */ - private void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - this.engageAllCells(); - } - - /** - * Convert the objects into rows and listen to the cells. - */ - private void engageAllCells() { - this.rows.ensureCapacity(this.listHolder.size()); - for (Iterator<? extends E> stream = this.listHolder.iterator(); stream.hasNext(); ) { - WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(stream.next()); - this.engageRow(row); - this.rows.add(row); - } - } - - /** - * Listen to the cells in the specified row. - */ - private void engageRow(WritablePropertyValueModel<Object>[] row) { - for (int i = row.length; i-- > 0; ) { - row[i].addPropertyChangeListener(PropertyValueModel.VALUE, this.cellListener); - } - } - - /** - * Stop listening. - */ - private void disengageModel() { - this.disengageAllCells(); - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - private void disengageAllCells() { - for (WritablePropertyValueModel<Object>[] row : this.rows) { - this.disengageRow(row); - } - this.rows.clear(); - } - - private void disengageRow(WritablePropertyValueModel<Object>[] row) { - for (int i = row.length; i-- > 0; ) { - row[i].removePropertyChangeListener(PropertyValueModel.VALUE, this.cellListener); - } - } - - /** - * brute-force search for the cell(s) that changed... - */ - void cellChanged(WritablePropertyValueModel<Object> cellHolder) { - for (int i = this.rows.size(); i-- > 0; ) { - WritablePropertyValueModel<Object>[] row = this.rows.get(i); - for (int j = row.length; j-- > 0; ) { - if (row[j] == cellHolder) { - this.fireTableCellUpdated(i, j); - } - } - } - } - - /** - * convert the items to rows - */ - void addRows(int index, int size, Iterable<Object> items) { - List<WritablePropertyValueModel<Object>[]> newRows = new ArrayList<WritablePropertyValueModel<Object>[]>(size); - for (Object item : items) { - WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(item); - this.engageRow(row); - newRows.add(row); - } - this.rows.addAll(index, newRows); - this.fireTableRowsInserted(index, index + size - 1); - } - - void removeRows(int index, int size) { - for (int i = 0; i < size; i++) { - this.disengageRow(this.rows.remove(index)); - } - this.fireTableRowsDeleted(index, index + size - 1); - } - - void replaceRows(int index, Iterable<Object> items) { - int i = index; - for (Object item : items) { - WritablePropertyValueModel<Object>[] row = this.rows.get(i); - this.disengageRow(row); - row = this.columnAdapter.cellModels(item); - this.engageRow(row); - this.rows.set(i, row); - i++; - } - this.fireTableRowsUpdated(index, i - 1); - } - - void moveRows(int targetIndex, int sourceIndex, int length) { - ArrayList<WritablePropertyValueModel<Object>[]> temp = new ArrayList<WritablePropertyValueModel<Object>[]>(length); - for (int i = 0; i < length; i++) { - temp.add(this.rows.remove(sourceIndex)); - } - this.rows.addAll(targetIndex, temp); - - int start = Math.min(targetIndex, sourceIndex); - int end = Math.max(targetIndex, sourceIndex) + length - 1; - this.fireTableRowsUpdated(start, end); - } - - void clearTable() { - this.disengageAllCells(); - this.fireTableDataChanged(); - } - - void rebuildTable() { - this.disengageAllCells(); - this.engageAllCells(); - this.fireTableDataChanged(); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ToggleButtonModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ToggleButtonModelAdapter.java deleted file mode 100644 index 044b2658a5..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/ToggleButtonModelAdapter.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.awt.event.ActionListener; -import java.awt.event.ItemListener; -import javax.swing.JToggleButton.ToggleButtonModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JCheckBox or a JRadioButton) in synch with a PropertyValueModel - * on a boolean. - */ -public class ToggleButtonModelAdapter - extends ToggleButtonModel -{ - /** - * The default setting for the toggle button; for when the underlying model is null. - * The default [default value] is false (i.e. the toggle button is unchecked/empty). - */ - protected final boolean defaultValue; - - /** A value model on the underlying model boolean. */ - protected final WritablePropertyValueModel<Boolean> booleanHolder; - - /** - * A listener that allows us to synchronize with - * changes made to the underlying model boolean. - */ - protected final PropertyChangeListener booleanChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the boolean holder is required. - */ - public ToggleButtonModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) { - super(); - if (booleanHolder == null) { - throw new NullPointerException(); - } - this.booleanHolder = booleanHolder; - this.booleanChangeListener = this.buildBooleanChangeListener(); - // postpone listening to the underlying model - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - /** - * Constructor - the boolean holder is required. - * The default value will be false. - */ - public ToggleButtonModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder) { - this(booleanHolder, false); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildBooleanChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_()); - } - - protected PropertyChangeListener buildBooleanChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ToggleButtonModelAdapter.this.booleanChanged(event); - } - @Override - public String toString() { - return "boolean listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** ButtonModel implementation ********** - - /** - * Extend to update the underlying model if necessary. - */ - @Override - public void setSelected(boolean b) { - if (this.isSelected() != b) { // stop the recursion! - super.setSelected(b);//put the super call first, otherwise the following gets called twice - this.booleanHolder.setValue(Boolean.valueOf(b)); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addActionListener(ActionListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addActionListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeActionListener(ActionListener l) { - super.removeActionListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addItemListener(ItemListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addItemListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeItemListener(ItemListener l) { - super.removeItemListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addChangeListener(ChangeListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addChangeListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener l) { - super.removeChangeListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether we have no listeners at all. - */ - protected boolean hasNoListeners() { - return this.listenerList.getListenerCount() == 0; - } - - protected boolean getDefaultValue() { - return this.defaultValue; - } - - - // ********** behavior ********** - - /** - * Synchronize with the specified value. - * If it is null, use the default value (which is typically false). - */ - protected void setSelected(Boolean value) { - if (value == null) { - this.setSelected(this.getDefaultValue()); - } else { - this.setSelected(value.booleanValue()); - } - } - - /** - * The underlying model has changed - synchronize accordingly. - */ - protected void booleanChanged(PropertyChangeEvent event) { - this.setSelected((Boolean) event.getNewValue()); - } - - protected void engageModel() { - this.booleanHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener); - this.setSelected(this.booleanHolder.getValue()); - } - - protected void disengageModel() { - this.booleanHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.booleanHolder); - } - -} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TreeModelAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TreeModelAdapter.java deleted file mode 100644 index 12f0faf3a7..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/swing/TreeModelAdapter.java +++ /dev/null @@ -1,914 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.List; - -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreePath; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTStateChangeListenerWrapper; -import org.eclipse.jpt.common.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.common.utility.model.event.ListAddEvent; -import org.eclipse.jpt.common.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.common.utility.model.event.ListClearEvent; -import org.eclipse.jpt.common.utility.model.event.ListEvent; -import org.eclipse.jpt.common.utility.model.event.ListMoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent; -import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.common.utility.model.value.ListValueModel; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.model.value.TreeNodeValueModel; - -/** - * This javax.swing.tree.TreeModel can be used to keep a TreeModelListener - * (e.g. a JTree) in synch with a tree of TreeNodeValueModel objects. Unlike - * javax.swing.tree.DefaultTreeModel, you do not add and remove nodes with - * methods implemented here. You can add and remove nodes by adding and - * removing them directly to/from the nodes (or, more typically, the domain - * objects the nodes are wrapping and listening to). - * - * Due to limitations in JTree, the root of the tree can never be null, - * which, typically, should not be a problem. (If you want to display an empty - * tree you can set the JTree's treeModel to null.) - */ -public class TreeModelAdapter<T> - extends AbstractTreeModel -{ - /** - * A value model on the underlying tree's root node and its - * corresponding listener. This allows clients to swap out - * the entire tree. Due to limitations in JTree, the root should - * never be set to null while we have listeners. - */ - private final PropertyValueModel<TreeNodeValueModel<T>> rootHolder; - private final PropertyChangeListener rootListener; - - /** - * A listener that notifies us when a node's internal - * "state" changes (as opposed to the node's value or list of - * children), allowing us to forward notification to our listeners. - */ - private final StateChangeListener nodeStateListener; - - /** - * A listener that notifies us when a node's "value" - * changes (as opposed to the node's state or list of - * children), allowing us to forward notification to our listeners. - * Typically, this will only happen with nodes that hold - * primitive data. - */ - private final PropertyChangeListener nodeValueListener; - - /** - * A listener that notifies us when an underlying node's - * "list" of children changes, allowing us to keep our - * internal tree in synch with the underlying tree model. - */ - private final ListChangeListener childrenListener; - - /* these attributes make up our internal tree */ - /** - * The root cannot be null while we have listeners, which is - * most of the time. The root is cached so we can disengage - * from it when it has been swapped out. - */ - private TreeNodeValueModel<T> root; - - /** - * Map the nodes to their lists of children. - * We cache these so we can swap out the entire list of children - * when we receive a #listChanged() event (which does not include - * the items that were affected). - * @see EventChangePolicy#rebuildChildren() - */ - final IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>> childrenLists; - - /** - * Map the children models to their parents. - * We cache these so we can figure out the "real" source of the - * list change events (the parent). - * @see EventChangePolicy#parent() - */ - final IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>> parents; - - - // ********** constructors ********** - - /** - * Construct a tree model for the specified root. - */ - public TreeModelAdapter(PropertyValueModel<TreeNodeValueModel<T>> rootHolder) { - super(); - if (rootHolder == null) { - throw new NullPointerException(); - } - this.rootHolder = rootHolder; - this.rootListener = this.buildRootListener(); - this.nodeStateListener = this.buildNodeStateListener(); - this.nodeValueListener = this.buildNodeValueListener(); - this.childrenListener = this.buildChildrenListener(); - this.childrenLists = new IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>>(); - this.parents = new IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>>(); - } - - /** - * Construct a tree model for the specified root. - */ - public TreeModelAdapter(TreeNodeValueModel<T> root) { - this(new StaticPropertyValueModel<TreeNodeValueModel<T>>(root)); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildRootListener() { - return new AWTPropertyChangeListenerWrapper(this.buildRootListener_()); - } - - protected PropertyChangeListener buildRootListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - TreeModelAdapter.this.rootChanged(); - } - @Override - public String toString() { - return "root listener"; //$NON-NLS-1$ - } - }; - } - - protected PropertyChangeListener buildNodeValueListener() { - return new AWTPropertyChangeListenerWrapper(this.buildNodeValueListener_()); - } - - protected PropertyChangeListener buildNodeValueListener_() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource()); - } - @Override - public String toString() { - return "node value listener"; //$NON-NLS-1$ - } - }; - } - - protected StateChangeListener buildNodeStateListener() { - return new AWTStateChangeListenerWrapper(this.buildNodeStateListener_()); - } - - protected StateChangeListener buildNodeStateListener_() { - return new StateChangeListener() { - @SuppressWarnings("unchecked") - public void stateChanged(StateChangeEvent event) { - TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource()); - } - @Override - public String toString() { - return "node state listener"; //$NON-NLS-1$ - } - }; - } - - protected ListChangeListener buildChildrenListener() { - return new AWTListChangeListenerWrapper(this.buildChildrenListener_()); - } - - protected ListChangeListener buildChildrenListener_() { - return new ListChangeListener() { - public void itemsAdded(ListAddEvent event) { - new AddEventChangePolicy(event).addChildren(); - } - public void itemsRemoved(ListRemoveEvent event) { - new RemoveEventChangePolicy(event).removeChildren(); - } - public void itemsReplaced(ListReplaceEvent event) { - new ReplaceEventChangePolicy(event).replaceChildren(); - } - public void itemsMoved(ListMoveEvent event) { - new MoveEventChangePolicy(event).moveChildren(); - } - public void listCleared(ListClearEvent event) { - new ClearEventChangePolicy(event).clearChildren(); - } - public void listChanged(ListChangeEvent event) { - new ChangeEventChangePolicy(event).rebuildChildren(); - } - @Override - public String toString() { - return "children listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** TreeModel implementation ********** - - public Object getRoot() { - return this.root; - } - - @SuppressWarnings("unchecked") - public Object getChild(Object parent, int index) { - return ((TreeNodeValueModel<T>) parent).child(index); - } - - @SuppressWarnings("unchecked") - public int getChildCount(Object parent) { - return ((TreeNodeValueModel<T>) parent).childrenSize(); - } - - @SuppressWarnings("unchecked") - public boolean isLeaf(Object node) { - return ((TreeNodeValueModel<T>) node).isLeaf(); - } - - @SuppressWarnings("unchecked") - public void valueForPathChanged(TreePath path, Object newValue) { - ((TreeNodeValueModel<T>) path.getLastPathComponent()).setValue((T) newValue); - } - - @SuppressWarnings("unchecked") - public int getIndexOfChild(Object parent, Object child) { - return ((TreeNodeValueModel<T>) parent).indexOfChild((TreeNodeValueModel<T>) child); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTreeModelListener(TreeModelListener l) { - if (this.hasNoTreeModelListeners()) { - this.engageModel(); - } - super.addTreeModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeTreeModelListener(TreeModelListener l) { - super.removeTreeModelListener(l); - if (this.hasNoTreeModelListeners()) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Listen to the root and all the other nodes - * in the underlying tree model. - */ - private void engageModel() { - this.rootHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.rootListener); - this.root = this.rootHolder.getValue(); - if (this.root == null) { - throw new NullPointerException(); // the root cannot be null while we have listeners - } - this.engageNode(this.root); - this.addRoot(); - } - - /** - * Add the root and all of the nodes to the underlying tree. - */ - private void addRoot() { - this.addNode(0, this.root); - } - - /** - * Stop listening to the root and all the other - * nodes in the underlying tree model. - */ - private void disengageModel() { - this.removeRoot(); - this.disengageNode(this.root); - this.root = null; - this.rootHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.rootListener); - } - - /** - * Remove the root and all of the nodes from the underlying tree. - */ - private void removeRoot() { - this.removeNode(0, this.root); - } - - /** - * The root has been swapped. - * This method is a bit gnarly because the API for notifying listeners - * that the root has changed is a bit inconsistent with that used for - * non-root nodes. - */ - void rootChanged() { - TreeNodeValueModel<T> newRoot = this.rootHolder.getValue(); - if (newRoot == null) { - throw new NullPointerException(); // the root cannot be null while we have listeners - } - // remove all the current root's children from the tree - // and remove the it from the internal tree - this.removeRoot(); - - // save the old root and swap in the new root - TreeNodeValueModel<T> oldRoot = this.root; - this.root = newRoot; - - // we must be listening to both the old and new roots when we fire the event - // because their values can be affected by whether they have listeners - this.engageNode(this.root); - this.fireTreeRootReplaced(this.root); - // now we can stop listening to the old root - this.disengageNode(oldRoot); - - // add the new root to the internal tree and - // add all its children to the tree also - this.addRoot(); - } - - /** - * Either the "value" or the "state" of the specified node has changed, - * forward notification to our listeners. - */ - void nodeChanged(TreeNodeValueModel<T> node) { - TreeNodeValueModel<T> parent = node.parent(); - if (parent == null) { - this.fireTreeRootChanged(node); - } else { - this.fireTreeNodeChanged(parent.path(), parent.indexOfChild(node), node); - } - } - - /** - * Listen to the nodes, notify our listeners that the nodes were added, - * and then add the nodes to our internal tree. - * We must listen to the nodes before notifying anybody, because - * adding a listener can change the value of a node. - */ - void addChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) { - int len = childIndices.length; - for (int i = 0; i < len; i++) { - this.engageNode(children[i]); - } - this.fireTreeNodesInserted(path, childIndices, children); - for (int i = 0; i < len; i++) { - this.addNode(childIndices[i], children[i]); - } - } - - /** - * Listen to the node and its children model. - */ - private void engageNode(TreeNodeValueModel<T> node) { - node.addStateChangeListener(this.nodeStateListener); - node.addPropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener); - node.childrenModel().addListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener); - } - - /** - * Add the node to our internal tree; - * then recurse down through the node's children, - * adding them to the internal tree also. - */ - private void addNode(int index, TreeNodeValueModel<T> node) { - this.addNodeToInternalTree(node.parent(), index, node, node.childrenModel()); - new NodeChangePolicy(node).addChildren(); - } - - /** - * Add the specified node to our internal tree. - */ - private void addNodeToInternalTree(TreeNodeValueModel<T> parent, int index, TreeNodeValueModel<T> node, ListValueModel<TreeNodeValueModel<T>> childrenModel) { - List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent); - if (siblings == null) { - siblings = new ArrayList<TreeNodeValueModel<T>>(); - this.childrenLists.put(parent, siblings); - } - siblings.add(index, node); - - this.parents.put(childrenModel, node); - } - - /** - * Remove nodes from our internal tree, notify our listeners that the - * nodes were removed, then stop listening to the nodes. - * We must listen to the nodes until after notifying anybody, because - * removing a listener can change the value of a node. - */ - void removeChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) { - int len = childIndices.length; - for (int i = 0; i < len; i++) { - // the indices slide down a notch each time we remove a child - this.removeNode(childIndices[i] - i, children[i]); - } - this.fireTreeNodesRemoved(path, childIndices, children); - for (int i = 0; i < len; i++) { - this.disengageNode(children[i]); - } - } - - /** - * First, recurse down through the node's children, - * removing them from our internal tree; - * then remove the node itself from our internal tree. - */ - private void removeNode(int index, TreeNodeValueModel<T> node) { - new NodeChangePolicy(node).removeChildren(); - this.removeNodeFromInternalTree(node.parent(), index, node.childrenModel()); - } - - /** - * Remove the specified node from our internal tree. - */ - private void removeNodeFromInternalTree(TreeNodeValueModel<T> parent, int index, ListValueModel<TreeNodeValueModel<T>> childrenModel) { - this.parents.remove(childrenModel); - - List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent); - siblings.remove(index); - if (siblings.isEmpty()) { - this.childrenLists.remove(parent); - } - } - - /** - * Stop listening to the node and its children model. - */ - private void disengageNode(TreeNodeValueModel<T> node) { - node.childrenModel().removeListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener); - node.removePropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener); - node.removeStateChangeListener(this.nodeStateListener); - } - - void moveChildren(TreeNodeValueModel<T> parent, int targetIndex, int sourceIndex, int length) { - List<TreeNodeValueModel<T>> childrenList = this.childrenLists.get(parent); - ArrayList<TreeNodeValueModel<T>> temp = new ArrayList<TreeNodeValueModel<T>>(length); - for (int i = 0; i < length; i++) { - temp.add(childrenList.remove(sourceIndex)); - } - childrenList.addAll(targetIndex, temp); - - this.fireTreeStructureChanged(parent.path()); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.root); - } - - - // ********** inner classes ********** - - /** - * Coalesce some of the common change policy behavior. - */ - abstract class ChangePolicy { - - ChangePolicy() { - super(); - } - - /** - * Add the current set of children. - */ - void addChildren() { - TreeModelAdapter.this.addChildren(this.parent().path(), this.childIndices(), this.childArray()); - } - - /** - * Remove the current set of children. - */ - void removeChildren() { - TreeModelAdapter.this.removeChildren(this.parent().path(), this.childIndices(), this.childArray()); - } - - /** - * Return an array of the indices of the current set of children, - * which should be contiguous. - */ - int[] childIndices() { - return this.buildIndices(this.childrenStartIndex(), this.childrenSize()); - } - - /** - * Return an array of the current set of children. - */ - TreeNodeValueModel<T>[] childArray() { - return this.buildArray(this.getChildren(), this.childrenSize()); - } - - /** - * Build an array to hold the elements in the specified iterator. - * If they are different sizes, something is screwed up... - */ - TreeNodeValueModel<T>[] buildArray(Iterable<TreeNodeValueModel<T>> elements, int size) { - @SuppressWarnings("unchecked") - TreeNodeValueModel<T>[] array = new TreeNodeValueModel[size]; - int i = 0; - for (TreeNodeValueModel<T> element : elements) { - array[i++] = element; - } - return array; - } - - /** - * Return a set of indices, starting at zero and - * continuing for the specified size. - */ - int[] buildIndices(int size) { - return buildIndices(0, size); - } - - /** - * Return a set of indices, starting at the specified index and - * continuing for the specified size. - */ - int[] buildIndices(int start, int size) { - int[] indices = new int[size]; - int index = start; - for (int i = 0; i < size; i++) { - indices[i] = index++; - } - return indices; - } - - /** - * Return the parent of the current set of children. - */ - abstract TreeNodeValueModel<T> parent(); - - /** - * Return the starting index for the current set of children. - */ - abstract int childrenStartIndex(); - - /** - * Return the size of the current set of children. - */ - abstract int childrenSize(); - - /** - * Return the current set of children. - */ - abstract Iterable<TreeNodeValueModel<T>> getChildren(); - - } - - - /** - * Wraps a ListEvent for adding, removing, replacing, - * and changing children. - */ - abstract class EventChangePolicy extends ChangePolicy { - final ListEvent event; - - EventChangePolicy(ListEvent event) { - super(); - this.event = event; - } - - /** - * Map the ListChangeEvent's source to the corresponding parent. - */ - @Override - TreeNodeValueModel<T> parent() { - return TreeModelAdapter.this.parents.get(this.event.getSource()); - } - - } - - - /** - * Wraps a ListAddEvent for adding children. - */ - class AddEventChangePolicy extends EventChangePolicy { - - AddEventChangePolicy(ListAddEvent event) { - super(event); - } - - private ListAddEvent getEvent() { - return (ListAddEvent) this.event; - } - - /** - * The ListAddEvent's item index is the children start index. - */ - @Override - int childrenStartIndex() { - return this.getEvent().getIndex(); - } - - /** - * The ListAddEvent's size is the children size. - */ - @Override - int childrenSize() { - return this.getEvent().getItemsSize(); - } - - /** - * The ListAddEvent's items are the children. - */ - @Override - @SuppressWarnings("unchecked") - Iterable<TreeNodeValueModel<T>> getChildren() { - return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getItems(); - } - - } - - - /** - * Wraps a ListRemoveEvent for adding children. - */ - class RemoveEventChangePolicy extends EventChangePolicy { - - RemoveEventChangePolicy(ListRemoveEvent event) { - super(event); - } - - private ListRemoveEvent getEvent() { - return (ListRemoveEvent) this.event; - } - - /** - * The ListRemoveEvent's item index is the children start index. - */ - @Override - int childrenStartIndex() { - return this.getEvent().getIndex(); - } - - /** - * The ListRemoveEvent's size is the children size. - */ - @Override - int childrenSize() { - return this.getEvent().getItemsSize(); - } - - /** - * The ListRemoveEvent's items are the children. - */ - @Override - @SuppressWarnings("unchecked") - Iterable<TreeNodeValueModel<T>> getChildren() { - return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getItems(); - } - - } - - - /** - * Wraps a ListReplaceEvent for replacing children. - */ - class ReplaceEventChangePolicy extends EventChangePolicy { - - ReplaceEventChangePolicy(ListReplaceEvent event) { - super(event); - } - - private ListReplaceEvent getEvent() { - return (ListReplaceEvent) this.event; - } - - /** - * The ListReplaceEvent's item index is the children start index. - */ - @Override - int childrenStartIndex() { - return this.getEvent().getIndex(); - } - - /** - * The ListReplaceEvent's size is the children size. - */ - @Override - int childrenSize() { - return this.getEvent().getItemsSize(); - } - - /** - * The ListReplaceEvent's items are the children. - */ - @Override - @SuppressWarnings("unchecked") - Iterable<TreeNodeValueModel<T>> getChildren() { - return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getNewItems(); - } - - /** - * Remove the old nodes and add the new ones. - */ - void replaceChildren() { - TreeNodeValueModel<T>[] parentPath = this.parent().path(); - int[] childIndices = this.childIndices(); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, this.getOldChildren()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, this.childArray()); - } - - TreeNodeValueModel<T>[] getOldChildren() { - return this.buildArray(this.getOldItems(), this.getEvent().getItemsSize()); - } - - // minimized scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterable<TreeNodeValueModel<T>> getOldItems() { - return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getOldItems(); - } - - } - - - /** - * Wraps a ListMoveEvent for moving children. - */ - class MoveEventChangePolicy extends EventChangePolicy { - - MoveEventChangePolicy(ListMoveEvent event) { - super(event); - } - - private ListMoveEvent getEvent() { - return (ListMoveEvent) this.event; - } - - void moveChildren() { - TreeModelAdapter.this.moveChildren(this.parent(), this.getEvent().getTargetIndex(), this.getEvent().getSourceIndex(), this.getEvent().getLength()); - } - - @Override - int childrenStartIndex() { - throw new UnsupportedOperationException(); - } - - @Override - int childrenSize() { - throw new UnsupportedOperationException(); - } - - @Override - Iterable<TreeNodeValueModel<T>> getChildren() { - throw new UnsupportedOperationException(); - } - - } - - - /** - * Wraps a ListClearEvent for clearing children. - */ - class ClearEventChangePolicy extends EventChangePolicy { - - ClearEventChangePolicy(ListClearEvent event) { - super(event); - } - - /** - * Clear all the nodes. - */ - void clearChildren() { - TreeNodeValueModel<T> parent = this.parent(); - TreeNodeValueModel<T>[] parentPath = parent.path(); - List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent); - int[] childIndices = this.buildIndices(childrenList.size()); - TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList, childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - } - - @Override - int childrenStartIndex() { - throw new UnsupportedOperationException(); - } - - @Override - int childrenSize() { - throw new UnsupportedOperationException(); - } - - @Override - Iterable<TreeNodeValueModel<T>> getChildren() { - throw new UnsupportedOperationException(); - } - - } - - - /** - * Wraps a ListChangeEvent for clearing children. - */ - class ChangeEventChangePolicy extends EventChangePolicy { - - ChangeEventChangePolicy(ListChangeEvent event) { - super(event); - } - - /** - * Remove all the old nodes and add all the new nodes. - */ - void rebuildChildren() { - TreeNodeValueModel<T> parent = this.parent(); - TreeNodeValueModel<T>[] parentPath = parent.path(); - List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent); - int[] childIndices = this.buildIndices(childrenList.size()); - TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList, childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - - childIndices = this.buildIndices(parent.childrenModel().size()); - childArray = this.buildArray(parent.childrenModel(), parent.childrenSize()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, childArray); - } - - @Override - int childrenStartIndex() { - throw new UnsupportedOperationException(); - } - - @Override - int childrenSize() { - throw new UnsupportedOperationException(); - } - - @Override - Iterable<TreeNodeValueModel<T>> getChildren() { - throw new UnsupportedOperationException(); - } - - } - - - /** - * Wraps a TreeNodeValueModel for adding and removing its children. - */ - class NodeChangePolicy extends ChangePolicy { - private final TreeNodeValueModel<T> node; - - NodeChangePolicy(TreeNodeValueModel<T> node) { - super(); - this.node = node; - } - - /** - * The node itself is the parent. - */ - @Override - TreeNodeValueModel<T> parent() { - return this.node; - } - - /** - * Since we will always be dealing with all of the node's - * children, the children start index is always zero. - */ - @Override - int childrenStartIndex() { - return 0; - } - - /** - * Since we will always be dealing with all of the node's - * children, the children size is always equal to the size - * of the children model. - */ - @Override - int childrenSize() { - return this.node.childrenModel().size(); - } - - /** - * Since we will always be dealing with all of the node's - * children, the children are all the objects held by - * the children model. - */ - @Override - Iterable<TreeNodeValueModel<T>> getChildren() { - return this.node.childrenModel(); - } - - } - -} |