diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model')
80 files changed, 0 insertions, 17980 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java deleted file mode 100644 index 5aa4d9a886..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java +++ /dev/null @@ -1,1002 +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.utility.internal.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.HashBag; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Convenience implementation of Model protocol. - */ -public abstract class AbstractModel implements Model, Serializable { - /** - * Delegate state/property/collection/list/tree change support to this - * helper object. The change support object is "lazy-initialized". - */ - private ChangeSupport changeSupport; - - - // ********** constructors/initialization ********** - - /** - * Default constructor. - * This will call #initialize() on the newly-created instance. - */ - protected AbstractModel() { - super(); - this.initialize(); - } - - protected void initialize() { - // do nothing by default - } - - /** - * This accessor will build the change support when required. - */ - 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); - } - - - // ********** state change support ********** - - public synchronized void addStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().addStateChangeListener(listener); - } - - public synchronized void removeStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().removeStateChangeListener(listener); - } - - protected final void fireStateChanged() { - this.getChangeSupport().fireStateChanged(); - } - - protected final void fireStateChanged(StateChangeEvent event) { - this.getChangeSupport().fireStateChanged(event); - } - - - // ********** property change support ********** - - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - this.getChangeSupport().addPropertyChangeListener(listener); - } - - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().addPropertyChangeListener(propertyName, listener); - } - - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - this.getChangeSupport().removePropertyChangeListener(listener); - } - - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().removePropertyChangeListener(propertyName, listener); - } - - protected final void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, int oldValue, int newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, Object newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, null, newValue); - } - - protected final void firePropertyChanged(PropertyChangeEvent event) { - this.getChangeSupport().firePropertyChanged(event); - } - - - // ********** collection change support ********** - - public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - this.getChangeSupport().addCollectionChangeListener(listener); - } - - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().addCollectionChangeListener(collectionName, listener); - } - - public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { - this.getChangeSupport().removeCollectionChangeListener(listener); - } - - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().removeCollectionChangeListener(collectionName, listener); - } - - protected final void fireItemAdded(String collectionName, Object addedItem) { - this.getChangeSupport().fireItemAdded(collectionName, addedItem); - } - - protected final void fireItemsAdded(String collectionName, Collection<?> addedItems) { - this.getChangeSupport().fireItemsAdded(collectionName, addedItems); - } - - protected final void fireItemsAdded(CollectionChangeEvent event) { - this.getChangeSupport().fireItemsAdded(event); - } - - protected final void fireItemRemoved(String collectionName, Object removedItem) { - this.getChangeSupport().fireItemRemoved(collectionName, removedItem); - } - - protected final void fireItemsRemoved(String collectionName, Collection<?> removedItems) { - this.getChangeSupport().fireItemsRemoved(collectionName, removedItems); - } - - protected final void fireItemsRemoved(CollectionChangeEvent event) { - this.getChangeSupport().fireItemsRemoved(event); - } - - protected final void fireCollectionCleared(String collectionName) { - this.getChangeSupport().fireCollectionCleared(collectionName); - } - - protected final void fireCollectionCleared(CollectionChangeEvent event) { - this.getChangeSupport().fireCollectionCleared(event); - } - - protected final void fireCollectionChanged(String collectionName) { - this.getChangeSupport().fireCollectionChanged(collectionName); - } - - protected final void fireCollectionChanged(CollectionChangeEvent event) { - this.getChangeSupport().fireCollectionChanged(event); - } - - /** - * Convenience method. - * Add the specified item to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#add(Object) - */ - protected <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) { - if (collection.add(item)) { - this.fireItemAdded(collectionName, item); - return true; - } - return false; - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) { - return this.addItemsToCollection(new ArrayIterator<E>(items), collection, collectionName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) { - return this.addItemsToCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - 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; - } - - /** - * Convenience method. - * Remove the specified item from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#remove(Object) - */ - protected boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) { - if (collection.remove(item)) { - this.fireItemRemoved(collectionName, item); - return true; - } - return false; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.removeItemsFromCollection(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.removeItemsFromCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - Collection<?> items2 = CollectionTools.collection(items); - items2.retainAll(collection); - boolean changed = collection.removeAll(items2); - - if ( ! items2.isEmpty()) { - this.fireItemsRemoved(collectionName, items2); - } - return changed; - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.retainItemsInCollection(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.retainItemsInCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - Collection<?> items2 = CollectionTools.collection(items); - Collection<?> removedItems = CollectionTools.collection(collection); - removedItems.removeAll(items2); - boolean changed = collection.retainAll(items2); - - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved(collectionName, removedItems); - } - return changed; - } - - /** - * Convenience method. - * Clear the entire collection - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see java.util.Collection#clear() - */ - protected boolean clearCollection(Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - collection.clear(); - this.fireCollectionCleared(collectionName); - return true; - } - - /** - * Convenience method. - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - protected <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, collection, 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; - } - - /** - * Convenience method. - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - protected <E> boolean synchronizeCollection(Iterator<E> newItems, Collection<E> collection, String collectionName) { - return this.synchronizeCollection(CollectionTools.collection(newItems), collection, collectionName); - } - - - // ********** list change support ********** - - public synchronized void addListChangeListener(ListChangeListener listener) { - this.getChangeSupport().addListChangeListener(listener); - } - - public synchronized void addListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().addListChangeListener(listName, listener); - } - - public synchronized void removeListChangeListener(ListChangeListener listener) { - this.getChangeSupport().removeListChangeListener(listener); - } - - public synchronized void removeListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().removeListChangeListener(listName, listener); - } - - protected final void fireItemAdded(String listName, int index, Object addedItem) { - this.getChangeSupport().fireItemAdded(listName, index, addedItem); - } - - protected final void fireItemsAdded(String listName, int index, List<?> addedItems) { - this.getChangeSupport().fireItemsAdded(listName, index, addedItems); - } - - protected final void fireItemsAdded(ListChangeEvent event) { - this.getChangeSupport().fireItemsAdded(event); - } - - protected final void fireItemRemoved(String listName, int index, Object removedItem) { - this.getChangeSupport().fireItemRemoved(listName, index, removedItem); - } - - protected final void fireItemsRemoved(String listName, int index, List<?> removedItems) { - this.getChangeSupport().fireItemsRemoved(listName, index, removedItems); - } - - protected final void fireItemsRemoved(ListChangeEvent event) { - this.getChangeSupport().fireItemsRemoved(event); - } - - protected final void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - this.getChangeSupport().fireItemReplaced(listName, index, newItem, replacedItem); - } - - protected final <E> void fireItemsReplaced(String listName, int index, List<? extends E> newItems, List<E> replacedItems) { - this.getChangeSupport().fireItemsReplaced(listName, index, newItems, replacedItems); - } - - protected final void fireItemsReplaced(ListChangeEvent event) { - this.getChangeSupport().fireItemsReplaced(event); - } - - protected final void fireItemMoved(String listName, int targetIndex, int sourceIndex) { - this.getChangeSupport().fireItemMoved(listName, targetIndex, sourceIndex); - } - - protected final <E> void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - this.getChangeSupport().fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - protected final void fireItemsMoved(ListChangeEvent event) { - this.getChangeSupport().fireItemsMoved(event); - } - - protected final void fireListCleared(String listName) { - this.getChangeSupport().fireListCleared(listName); - } - - protected final void fireListCleared(ListChangeEvent event) { - this.getChangeSupport().fireListCleared(event); - } - - protected final void fireListChanged(String listName) { - this.getChangeSupport().fireListChanged(listName); - } - - protected final void fireListChanged(ListChangeEvent event) { - this.getChangeSupport().fireListChanged(event); - } - - /** - * Convenience method. - * Add the specified item to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#add(int, Object) - */ - protected <E> void addItemToList(int index, E item, List<E> list, String listName) { - list.add(index, item); - this.fireItemAdded(listName, index, item); - } - - /** - * Convenience method. - * Add the specified item to the end of the specified bound list - * and fire the appropriate event if necessary. - * Return whether list changed. - * @see java.util.List#add(Object) - */ - protected <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; - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) { - return this.addItemsToList(index, new ArrayIterator<E>(items), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(index, items.iterator(), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) { - List<E> items2 = CollectionTools.list(items); - if (list.addAll(index, items2)) { - this.fireItemsAdded(listName, index, items2); - return true; - } - return false; - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(E[] items, List<E> list, String listName) { - return this.addItemsToList(new ArrayIterator<E>(items), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) { - List<E> items2 = CollectionTools.list(items); - int index = list.size(); - if (list.addAll(items2)) { - this.fireItemsAdded(listName, index, items2); - return true; - } - return false; // empty list of items added - } - - /** - * Convenience method. - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed item. - * @see java.util.List#remove(int) - */ - protected <E> E removeItemFromList(int index, List<E> list, String listName) { - E item = list.remove(index); - this.fireItemRemoved(listName, index, item); - return item; - } - - /** - * Convenience method. - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed item. - * @see java.util.List#remove(Object) - */ - protected 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; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#remove(int) - */ - protected <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) { - List<E> subList = list.subList(index, index + length); - List<E> removedItems = new ArrayList<E>(subList); - subList.clear(); - this.fireItemsRemoved(listName, index, removedItems); - return removedItems; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Object[] items, List<?> list, String listName) { - return this.removeItemsFromList(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) { - return this.removeItemsFromList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) { - boolean changed = false; - while (items.hasNext()) { - changed |= this.removeItemFromList(items.next(), list, listName); - } - return changed; - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Object[] items, List<?> list, String listName) { - return this.retainItemsInList(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) { - return this.retainItemsInList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) { - Collection<?> items2 = CollectionTools.collection(items); - Collection<?> removedItems = CollectionTools.collection(list); - removedItems.removeAll(items2); - return this.removeItemsFromList(removedItems, list, listName); - } - - /** - * Convenience method. - * Set the specified item in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced item. - * @see java.util.List#set(int, Object) - */ - protected <E> E setItemInList(int index, E item, List<E> list, String listName) { - E replacedItem = list.set(index, item); - this.fireItemReplaced(listName, index, item, replacedItem); - return replacedItem; - } - - /** - * Convenience method. - * Replace the specified item in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced item. - * @see java.util.List#set(int, Object) - */ - protected <E> E replaceItemInList(E oldItem, E newItem, List<E> list, String listName) { - return this.setItemInList(list.indexOf(oldItem), newItem, list, listName); - } - - /** - * Convenience method. - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see java.util.List#set(int, Object) - */ - protected <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) { - return this.setItemsInList(index, Arrays.asList(items), list, listName); - } - - /** - * Convenience method. - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see java.util.List#set(int, Object) - */ - 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> replacedItems = new ArrayList<E>(subList); - for (int i = 0; i < items.size(); i++) { - subList.set(i, items.get(i)); - } - this.fireItemsReplaced(listName, index, items, replacedItems); - return replacedItems; - } - - /** - * Convenience method. - * Move items in the specified list from the specified source index to the - * specified target index for the specified length. - */ - protected <E> void moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) { - CollectionTools.move(list, targetIndex, sourceIndex, length); - this.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - /** - * Convenience method. - * Move an item in the specified list from the specified source index to the - * specified target index. - */ - protected <E> void moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) { - CollectionTools.move(list, targetIndex, sourceIndex); - this.fireItemMoved(listName, targetIndex, sourceIndex); - } - - /** - * Convenience method. - * Clear the entire list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see java.util.List#clear() - */ - protected boolean clearList(List<?> list, String listName) { - if (list.isEmpty()) { - return false; - } - list.clear(); - this.fireListCleared(listName); - return true; - } - - - // ********** tree change support ********** - - public synchronized void addTreeChangeListener(TreeChangeListener listener) { - this.getChangeSupport().addTreeChangeListener(listener); - } - - public synchronized void addTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().addTreeChangeListener(treeName, listener); - } - - public synchronized void removeTreeChangeListener(TreeChangeListener listener) { - this.getChangeSupport().removeTreeChangeListener(listener); - } - - public synchronized void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().removeTreeChangeListener(treeName, listener); - } - - protected final void fireNodeAdded(String treeName, Object[] path) { - this.getChangeSupport().fireNodeAdded(treeName, path); - } - - protected final void fireNodeAdded(TreeChangeEvent event) { - this.getChangeSupport().fireNodeAdded(event); - } - - protected final void fireNodeRemoved(String treeName, Object[] path) { - this.getChangeSupport().fireNodeRemoved(treeName, path); - } - - protected final void fireNodeRemoved(TreeChangeEvent event) { - this.getChangeSupport().fireNodeRemoved(event); - } - - protected final void fireTreeCleared(String treeName) { - this.getChangeSupport().fireTreeCleared(treeName); - } - - protected final void fireTreeCleared(TreeChangeEvent event) { - this.getChangeSupport().fireTreeCleared(event); - } - - protected final void fireTreeChanged(String treeName) { - this.getChangeSupport().fireTreeChanged(treeName); - } - - protected final void fireTreeChanged(String treeName, Object[] path) { - this.getChangeSupport().fireTreeChanged(treeName, path); - } - - protected final void fireTreeChanged(TreeChangeEvent event) { - this.getChangeSupport().fireTreeChanged(event); - } - - - // ********** queries ********** - - /** - * Return whether there are any state change listeners. - */ - public boolean hasAnyStateChangeListeners() { - return this.getChangeSupport().hasAnyStateChangeListeners(); - } - - /** - * Return whether there are no state change listeners. - */ - public boolean hasNoStateChangeListeners() { - return ! this.hasAnyStateChangeListeners(); - } - - /** - * Return whether there are any property change listeners for a specific property. - */ - public boolean hasAnyPropertyChangeListeners(String propertyName) { - return this.getChangeSupport().hasAnyPropertyChangeListeners(propertyName); - } - - /** - * Return whether there are any property change listeners for a specific property. - */ - public boolean hasNoPropertyChangeListeners(String propertyName) { - return ! this.hasAnyPropertyChangeListeners(propertyName); - } - - /** - * Return whether there are any collection change listeners for a specific collection. - */ - public boolean hasAnyCollectionChangeListeners(String collectionName) { - return this.getChangeSupport().hasAnyCollectionChangeListeners(collectionName); - } - - /** - * Return whether there are any collection change listeners for a specific collection. - */ - public boolean hasNoCollectionChangeListeners(String collectionName) { - return ! this.hasAnyCollectionChangeListeners(collectionName); - } - - /** - * Return whether there are any list change listeners for a specific list. - */ - public boolean hasAnyListChangeListeners(String listName) { - return this.getChangeSupport().hasAnyListChangeListeners(listName); - } - - /** - * Return whether there are any list change listeners for a specific list. - */ - public boolean hasNoListChangeListeners(String listName) { - return ! this.hasAnyListChangeListeners(listName); - } - - /** - * Return whether there are any tree change listeners for a specific tree. - */ - public boolean hasAnyTreeChangeListeners(String treeName) { - return this.getChangeSupport().hasAnyTreeChangeListeners(treeName); - } - - /** - * Return whether there are any tree change listeners for a specific tree. - */ - public boolean hasNoTreeChangeListeners(String treeName) { - return ! this.hasAnyTreeChangeListeners(treeName); - } - - - // ********** convenience methods ********** - - /** - * Return whether the values are equal, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - * - * DO NOT use this to determine whether to fire a change notification, - * ChangeSupport already does that. - */ - protected final boolean valuesAreEqual(Object value1, Object value2) { - return this.getChangeSupport().valuesAreEqual(value1, value2); - } - protected final boolean attributeValueHasNotChanged(Object oldValue, Object newValue) { - return this.valuesAreEqual(oldValue, newValue); - } - - - /** - * Return whether the values are different, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - * - * DO NOT use this to determine whether to fire a change notification, - * ChangeSupport already does that. - * - * 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. - */ - protected final boolean valuesAreDifferent(Object value1, Object value2) { - return this.getChangeSupport().valuesAreDifferent(value1, value2); - } - 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(); - clone.postClone(); - return clone; - } - - /** - * Perform any post-clone processing necessary to - * successfully disconnect the clone from the original. - * When this method is called on the clone, the clone - * is a "shallow" copy of the original (i.e. the clone - * shares all its instance variables with the original). - */ - protected void postClone() { - // clear out change support - models do not share listeners - this.changeSupport = null; - // when you override this method, don't forget to include: - // super.postClone(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - StringTools.buildSimpleToStringOn(this, sb); - sb.append(" ("); - this.toString(sb); - sb.append(')'); - return sb.toString(); - } - - /** - * make this public so one model can call a nested model's - * #toString(StringBuilder) - */ - public void toString(StringBuilder sb) { - // subclasses should override this to do something a bit more helpful - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java deleted file mode 100644 index 076f17fe1a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model; - -import org.eclipse.jpt.utility.model.Model; - -/** - * This change support class will notify the source when one of the source's - * aspects has changed. - */ -public class CallbackChangeSupport extends ChangeSupport { - private static final long serialVersionUID = 1L; - - public CallbackChangeSupport(Source source) { - super(source); - } - - protected Source source() { - return (Source) this.source; - } - - @Override - protected ChangeSupport buildChildChangeSupport() { - return new Child(this.source()); - } - - @Override - protected void sourceChanged(String aspectName) { - super.sourceChanged(aspectName); - this.source().aspectChanged(aspectName); - } - - - // ********** child chang support ********** - - /** - * The aspect-specific change support class does not need to - * notify the source node of changes (the parent will take care of that); - * nor does it need to build "grandchildren" change support objects. - */ - protected static class Child extends ChangeSupport { - private static final long serialVersionUID = 1L; - - public Child(Source source) { - super(source); - } - - protected Source source() { - return (Source) this.source; - } - - @Override - protected ChangeSupport buildChildChangeSupport() { - // there are no grandchildren - throw new UnsupportedOperationException(); - } - - } - - - // ********** source interface ********** - - /** - * The callback change support source must implement this interface so it - * can be notified of any aspect changes. - */ - public interface Source extends Model { - - /** - * The specified aspect changed. - */ - void aspectChanged(String aspectName); - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java deleted file mode 100644 index 88748ae149..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java +++ /dev/null @@ -1,2363 +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.utility.internal.model; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Support object that can be used by implementors of the Model interface. - * It provides for state, property, collection, list, and tree change notifications to - * listeners. - * - * NB: 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 - * - * NB2: 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 *before* it is notified. If the listener has been removed - * "concurrently" it will *not* be notified. (See the code that uses the - * 'stillListening' local boolean flag.) - * - * NB3: Any listener that is added during the firing of events will *not* be - * also notified. - * - * NB4: This class is serializable, but it will only write out listeners that - * are also serializable while silently leaving behind listeners that are not. - * - * TODO fire a state change event with *every* change? - * TODO use objects (IDs?) instead of strings to identify aspects? - */ -public class ChangeSupport - implements Serializable -{ - - /** The object to be provided as the "source" for any generated events. */ - protected final Model source; - - /** Associate a listener class to a collection of "generic" listeners for that class. */ - transient private GenericListenerList[] genericListeners = EMPTY_GENERIC_LISTENERS; - private static final GenericListenerList[] EMPTY_GENERIC_LISTENERS = new GenericListenerList[0]; - - /** Associate aspect names to child change support objects. */ - private AspectChild[] aspectChildren = EMPTY_ASPECT_CHILDREN; - private static final AspectChild[] EMPTY_ASPECT_CHILDREN = new AspectChild[0]; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - /** - * Construct support for the specified source of change events. - * The source cannot be null. - */ - public ChangeSupport(Model source) { - super(); - if (source == null) { - throw new NullPointerException(); - } - this.source = source; - } - - - // ********** internal behavior ********** - - /** - * Add a "generic" listener that listens to all events appropriate to that - * listener, regardless of the aspect name associated with that event. - * The listener cannot be null. - */ - protected <T extends ChangeListener> void addListener(Class<T> listenerClass, T listener) { - if (listener == null) { - throw new NullPointerException(); // better sooner than later - } - synchronized (this) { - GenericListenerList gll = this.genericListenerList(listenerClass); - if (gll == null) { - this.addGenericListenerList(listenerClass, listener); - } else { - gll.addListener(listener); - } - } - } - - /** - * Return the "generic" listener list for the specified listener class. - * Return null if the list is not present. - */ - protected GenericListenerList genericListenerList(Class<? extends ChangeListener> listenerClass) { - for (GenericListenerList gll : this.genericListeners) { - if (gll.listenerClass == listenerClass) { - return gll; - } - } - return null; - } - - /** - * Add the "generic" listener list for the specified listener class. - * Return the newly-built generic listener list. - */ - protected <T extends ChangeListener> GenericListenerList addGenericListenerList(Class<T> listenerClass, T listener) { - GenericListenerList gll = new GenericListenerList(listenerClass, listener); - this.genericListeners = CollectionTools.add(this.genericListeners, gll); - return gll; - } - - /** - * Adds a listener that listens to all events appropriate to that listener, - * and only to those events carrying the aspect name specified. - * The aspect name cannot be null and the listener cannot be null. - */ - protected <T extends ChangeListener> void addListener(String aspectName, Class<T> listenerClass, T listener) { - if ((aspectName == null) || (listener == null)) { - throw new NullPointerException(); // better sooner than later - } - synchronized (this) { - ChangeSupport child = this.child(aspectName); - if (child == null) { - child = this.addChild(aspectName); - } - child.addListener(listenerClass, listener); - } - } - - /** - * Return the child change support for the specified aspect name. - * Return null if the aspect name is null or the child is not present. - */ - protected ChangeSupport child(String aspectName) { - // put in a null check to simplify calling code - if (aspectName == null) { - return null; - } - for (AspectChild aspectChild : this.aspectChildren) { - if (aspectChild.aspectName == aspectName) { - return aspectChild.child; - } - } - return null; - } - - /** - * Add the child change support for the specified aspect name. - * Return the newly-built child change support. - */ - protected ChangeSupport addChild(String aspectName) { - ChangeSupport child = this.buildChildChangeSupport(); - this.aspectChildren = CollectionTools.add(this.aspectChildren, new AspectChild(aspectName, child)); - return child; - } - - /** - * Build and return a child change support to hold aspect-specific listeners. - */ - protected ChangeSupport buildChildChangeSupport() { - return new ChangeSupport(this.source); - } - - /** - * Removes a "generic" listener that has been registered for all events - * appropriate to that listener. - */ - protected <T extends ChangeListener> void removeListener(Class<T> listenerClass, T listener) { - synchronized (this) { - GenericListenerList gll = this.genericListenerList(listenerClass); - if (gll == null) { - throw new IllegalArgumentException("listener not registered"); - } - if ( ! gll.removeListener(listener)) { // leave the GLL, even if it is empty? - throw new IllegalArgumentException("listener not registered"); - } - } - } - - /** - * Removes a listener that has been registered for appropriate - * events carrying the specified aspect name. - */ - protected <T extends ChangeListener> void removeListener(String aspectName, Class<T> listenerClass, T listener) { - synchronized (this) { - ChangeSupport child = this.child(aspectName); - if (child == null) { - throw new IllegalArgumentException("listener not registered"); - } - child.removeListener(listenerClass, listener); // leave the child, even if it is empty? - } - } - - - // ********** internal queries ********** - - /** - * Return the "generic" listeners for the specified listener class. - * Return null if there are no listeners. - */ - protected ChangeListener[] listeners(Class<? extends ChangeListener> listenerClass) { - GenericListenerList gll = this.genericListenerList(listenerClass); - return (gll == null) ? null : gll.listeners; - } - - /** - * Return whether there are any "generic" listeners for the specified - * listener class. - */ - protected synchronized <T extends ChangeListener> boolean hasAnyListeners(Class<T> listenerClass) { - GenericListenerList gll = this.genericListenerList(listenerClass); - return (gll != null) && gll.hasListeners(); - } - - /** - * Return whether there are no "generic" listeners for the specified - * listener class. - */ - protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass) { - return ! this.hasAnyListeners(listenerClass); - } - - /** - * Return whether there are any listeners for the specified - * listener class and aspect name. - */ - protected synchronized boolean hasAnyListeners(Class<? extends ChangeListener> listenerClass, String aspectName) { - if (this.hasAnyListeners(listenerClass)) { - return true; // there's a "generic" listener - } - ChangeSupport child = this.child(aspectName); - return (child != null) && - child.hasAnyListeners(listenerClass); - } - - /** - * Return whether there are no "generic" listeners for the specified - * listener class and aspect name. - */ - protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass, String aspectName) { - return ! this.hasAnyListeners(listenerClass, aspectName); - } - - - // ********** behavior ********** - - /** - * The specified aspect of the source has changed; - * override this method to perform things like setting a - * dirty flag or validating the source's state. - * The aspect ID will be null if a "state change" occurred. - */ - protected void sourceChanged(String aspectName) { - // the default is to do nothing - } - - - // ********** 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 StateChangeListener[] stateChangeListeners() { - return (StateChangeListener[]) this.listeners(STATE_CHANGE_LISTENER_CLASS); - } - - /** - * Fire the specified state change event to any registered listeners. - */ - public void fireStateChanged(StateChangeEvent event) { - - StateChangeListener[] targets = null; - - synchronized (this) { - StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); - if (stateChangeListeners != null) { - targets = stateChangeListeners.clone(); - } - } - - if (targets != null) { - for (StateChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.stateChangeListeners(), target); - } - if (stillListening) { - target.stateChanged(event); - } - } - } - - this.sourceChanged(null); - } - - /** - * Report a generic state change event to any registered state change - * listeners. - */ - public void fireStateChanged() { -// this.fireStateChange(new StateChangeEvent(this.source)); - - StateChangeListener[] targets = null; - - synchronized (this) { - StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); - if (stateChangeListeners != null) { - targets = stateChangeListeners.clone(); - } - } - - if (targets != null) { - StateChangeEvent event = null; - for (StateChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.stateChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new StateChangeEvent(this.source); - } - target.stateChanged(event); - } - } - } - - this.sourceChanged(null); - } - - - // ********** property change support ********** - - protected static final Class<PropertyChangeListener> PROPERTY_CHANGE_LISTENER_CLASS = PropertyChangeListener.class; - - /** - * Return whether the values are equal, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - */ - public boolean valuesAreEqual(Object value1, Object value2) { - if ((value1 == null) && (value2 == null)) { - return true; // both are null - } - if ((value1 == null) || (value2 == null)) { - return false; // one is null but the other is not - } - return value1.equals(value2); - } - - /** - * Return whether the values are different, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - */ - public boolean valuesAreDifferent(Object value1, Object value2) { - return ! this.valuesAreEqual(value1, value2); - } - - /** - * Add a property change listener that is registered for all properties. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - this.addListener(PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * 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(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a property change listener that was registered for all properties. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - this.removeListener(PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a property change listener that was registered for a specific property. - */ - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.removeListener(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, 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); - } - - /** - * Return whether there are any property change listeners that will - * be notified when any property has changed. - */ - public boolean hasAnyPropertyChangeListeners() { - return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS); - } - - private PropertyChangeListener[] propertyChangeListeners() { - return (PropertyChangeListener[]) this.listeners(PROPERTY_CHANGE_LISTENER_CLASS); - } - - /** - * Fire the specified property change event to any registered listeners. - * No event is fired if the given event's old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - */ - public void firePropertyChanged(PropertyChangeEvent event) { - if (this.valuesAreEqual(event.getOldValue(), event.getNewValue())) { - return; - } - - String propertyName = event.getPropertyName(); - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - target.propertyChanged(event); - } - } - } - if (child != null) { - child.firePropertyChanged(event); - } - - this.sourceChanged(propertyName); - } - - /** - * Report a bound property update to any registered property change listeners. - * No event is fired if the given old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - */ - public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { -// this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); - if (this.valuesAreEqual(oldValue, newValue)) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - /** - * Report an int bound property update to any registered listeners. - * No event is fired if old and new are equal. - * <p> - * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. - */ - public void firePropertyChanged(String propertyName, int oldValue, int newValue) { -// this.firePropertyChanged(propertyName, new Integer(oldValue), new Integer(newValue)); - if (oldValue == newValue) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, new Integer(oldValue), new Integer(newValue)); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - /** - * Report a boolean bound property update to any registered listeners. - * No event is fired if old and new are equal. - * <p> - * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. - */ - public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { -// this.firePropertyChanged(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - if (oldValue == newValue) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - - // ********** collection change support ********** - - protected static final Class<CollectionChangeListener> COLLECTION_CHANGE_LISTENER_CLASS = CollectionChangeListener.class; - - /** - * Add a collection change listener that is registered for all collections. - */ - public void addCollectionChangeListener(CollectionChangeListener listener) { - this.addListener(COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * 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(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a collection change listener that was registered for all collections. - */ - public void removeCollectionChangeListener(CollectionChangeListener listener) { - this.removeListener(COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a collection change listener that was registered for a specific collection. - */ - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.removeListener(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, 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); - } - - /** - * Return whether there are any collection change listeners that will - * be notified when any collection has changed. - */ - public boolean hasAnyCollectionChangeListeners() { - return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS); - } - - private CollectionChangeListener[] collectionChangeListeners() { - return (CollectionChangeListener[]) this.listeners(COLLECTION_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsAdded(CollectionChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.itemsAdded(event); - } - } - } - if (child != null) { - child.fireItemsAdded(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsAdded(String collectionName, Collection<?> addedItems) { -// this.fireItemsAdded(new CollectionChangeEvent(this.source, collectionName, addedItems)); - if (addedItems.size() == 0) { - return; - } - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, addedItems); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsAdded(collectionName, addedItems); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemAdded(String collectionName, Object addedItem) { -// this.fireItemsAdded(collectionName, Collections.singleton(addedItem)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(addedItem)); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemAdded(collectionName, addedItem); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsRemoved(CollectionChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.itemsRemoved(event); - } - } - } - if (child != null) { - child.fireItemsRemoved(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsRemoved(String collectionName, Collection<?> removedItems) { -// this.fireItemsRemoved(new CollectionChangeEvent(this.source, collectionName, removedItems)); - if (removedItems.size() == 0) { - return; - } - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, removedItems); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsRemoved(collectionName, removedItems); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemRemoved(String collectionName, Object removedItem) { -// this.fireItemsRemoved(collectionName, Collections.singleton(removedItem)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(removedItem)); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemRemoved(collectionName, removedItem); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(CollectionChangeEvent event) { - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.collectionCleared(event); - } - } - } - if (child != null) { - child.fireCollectionCleared(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(String collectionName) { -// this.fireCollectionCleared(new CollectionChangeEvent(this.source, collectionName)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName); - } - target.collectionCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireCollectionCleared(collectionName); - } else { - child.fireCollectionCleared(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(CollectionChangeEvent event) { - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.collectionChanged(event); - } - } - } - if (child != null) { - child.fireCollectionChanged(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(String collectionName) { -// this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName); - } - target.collectionChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireCollectionChanged(collectionName); - } else { - child.fireCollectionChanged(event); - } - } - - this.sourceChanged(collectionName); - } - - - // ********** list change support ********** - - protected static final Class<ListChangeListener> LIST_CHANGE_LISTENER_CLASS = ListChangeListener.class; - - /** - * Add a list change listener that is registered for all lists. - */ - public void addListChangeListener(ListChangeListener listener) { - this.addListener(LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * 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(listName, LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a list change listener that was registered for all lists. - */ - public void removeListChangeListener(ListChangeListener listener) { - this.removeListener(LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a list change listener that was registered for a specific list. - */ - public void removeListChangeListener(String listName, ListChangeListener listener) { - this.removeListener(listName, LIST_CHANGE_LISTENER_CLASS, 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); - } - - /** - * Return whether there are any list change listeners that will - * be notified when any list has changed. - */ - public boolean hasAnyListChangeListeners() { - return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS); - } - - private ListChangeListener[] listChangeListeners() { - return (ListChangeListener[]) this.listeners(LIST_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsAdded(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsAdded(event); - } - } - } - if (child != null) { - child.fireItemsAdded(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsAdded(String listName, int index, List<?> addedItems) { -// this.fireItemsAdded(new ListChangeEvent(this.source, listName, index, addedItems)); - if (addedItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, addedItems); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsAdded(listName, index, addedItems); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(listName); - } - - /** - * 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)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(addedItem)); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemAdded(listName, index, addedItem); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsRemoved(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsRemoved(event); - } - } - } - if (child != null) { - child.fireItemsRemoved(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsRemoved(String listName, int index, List<?> removedItems) { -// this.fireItemsRemoved(new ListChangeEvent(this.source, listName, index, removedItems)); - if (removedItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, removedItems); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsRemoved(listName, index, removedItems); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * 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)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(removedItem)); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemRemoved(listName, index, removedItem); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsReplaced(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsReplaced(event); - } - } - } - if (child != null) { - child.fireItemsReplaced(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) { -// this.fireItemsReplaced(new ListChangeEvent(this.source, listName, index, newItems, replacedItems)); - if (newItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, newItems, replacedItems); - } - target.itemsReplaced(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsReplaced(listName, index, newItems, replacedItems); - } else { - child.fireItemsReplaced(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { -// this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem)); - } - target.itemsReplaced(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemReplaced(listName, index, newItem, replacedItem); - } else { - child.fireItemsReplaced(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsMoved(ListChangeEvent event) { - if (event.getTargetIndex() == event.getSourceIndex()) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsMoved(event); - } - } - } - if (child != null) { - child.fireItemsMoved(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { -// this.fireItemsMoved(new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length)); - if (targetIndex == sourceIndex) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length); - } - target.itemsMoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } else { - child.fireItemsMoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemMoved(String listName, int targetIndex, int sourceIndex) { - this.fireItemsMoved(listName, targetIndex, sourceIndex, 1); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(ListChangeEvent event) { - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.listCleared(event); - } - } - } - if (child != null) { - child.fireListCleared(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(String listName) { -// this.fireListCleared(new ListChangeEvent(this.source, listName)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName); - } - target.listCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireListCleared(listName); - } else { - child.fireListCleared(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(ListChangeEvent event) { - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.listChanged(event); - } - } - } - if (child != null) { - child.fireListChanged(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(String listName) { -// this.fireListChanged(new ListChangeEvent(this.source, listName)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName); - } - target.listChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireListChanged(listName); - } else { - child.fireListChanged(event); - } - } - - this.sourceChanged(listName); - } - - - // ********** tree change support ********** - - protected static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class; - private static final Object[] EMPTY_TREE_PATH = new Object[0]; - - /** - * Add a tree change listener that is registered for all trees. - */ - public void addTreeChangeListener(TreeChangeListener listener) { - this.addListener(TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * 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(treeName, TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a tree change listener that was registered for all tree. - */ - public void removeTreeChangeListener(TreeChangeListener listener) { - this.removeListener(TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a tree change listener that was registered for a specific tree. - */ - public void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.removeListener(treeName, TREE_CHANGE_LISTENER_CLASS, 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); - } - - /** - * Return whether there are any tree change listeners that will - * be notified when any tree has changed. - */ - public boolean hasAnyTreeChangeListeners() { - return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS); - } - - private TreeChangeListener[] treeChangeListeners() { - return (TreeChangeListener[]) this.listeners(TREE_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.nodeAdded(event); - } - } - } - if (child != null) { - child.fireNodeAdded(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(String treeName, Object[] path) { -// this.fireNodeAdded(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.nodeAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireNodeAdded(treeName, path); - } else { - child.fireNodeAdded(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.nodeRemoved(event); - } - } - } - if (child != null) { - child.fireNodeRemoved(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(String treeName, Object[] path) { -// this.fireNodeRemoved(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.nodeRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireNodeRemoved(treeName, path); - } else { - child.fireNodeRemoved(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.treeCleared(event); - } - } - } - if (child != null) { - child.fireTreeCleared(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(String treeName, Object[] path) { -// this.fireTreeCleared(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.treeCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireTreeCleared(treeName, path); - } else { - child.fireTreeCleared(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(String treeName) { - this.fireTreeCleared(treeName, EMPTY_TREE_PATH); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.treeChanged(event); - } - } - } - if (child != null) { - child.fireTreeChanged(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(String treeName, Object[] path) { -// this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.treeChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireTreeChanged(treeName, path); - } else { - child.fireTreeChanged(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(String treeName) { - this.fireTreeChanged(treeName, EMPTY_TREE_PATH); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.source); - } - - - // ********** serialization ********** - - private synchronized void writeObject(ObjectOutputStream s) throws IOException { - // write out the source, children, and any hidden stuff - s.defaultWriteObject(); - - // only write out Serializable listeners - int len1 = this.genericListeners.length; - for (int i = 0; i < len1; i++) { - this.writeObject(s, this.genericListeners[i]); - } - s.writeObject(null); - } - - private void writeObject(ObjectOutputStream s, GenericListenerList gll) throws IOException { - boolean first = true; - int len = gll.listeners.length; - for (int i = 0; i < len; i++) { - ChangeListener listener = gll.listeners[i]; - if (listener instanceof Serializable) { - if (first) { - first = false; - s.writeObject(gll.listenerClass); - } - s.writeObject(listener); - } - } - if ( ! first) { - s.writeObject(null); - } - } - - private synchronized void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { - // read in the source, children, and any hidden stuff - s.defaultReadObject(); - - // read in generic listener lists - this.genericListeners = EMPTY_GENERIC_LISTENERS; - Object o; - while (null != (o = s.readObject())) { - @SuppressWarnings("unchecked") - Class<? extends ChangeListener> listenerClass = (Class<? extends ChangeListener>) o; - GenericListenerList gll = null; - while (null != (o = s.readObject())) { - if (gll == null) { - gll = this.addGenericListenerListInternal(listenerClass, (ChangeListener) o); - } else { - gll.addListener((ChangeListener) o); - } - } - } - } - - @SuppressWarnings("unchecked") - private <T extends ChangeListener> GenericListenerList addGenericListenerListInternal(Class<T> listenerClass, ChangeListener listener) { - return this.addGenericListenerList(listenerClass, (T) listener); - } - - - // ********** member classes ********** - - /** - * Pair a listener class with its "generic" listeners. - */ - private static class GenericListenerList { - final Class<? extends ChangeListener> listenerClass; - ChangeListener[] listeners; - - <T extends ChangeListener> GenericListenerList(Class<T> listenerClass, T listener) { - super(); - this.listenerClass = listenerClass; - this.listeners = (ChangeListener[]) Array.newInstance(listenerClass, 1); - this.listeners[0] = listener; - } - - void addListener(ChangeListener listener) { - this.listeners = CollectionTools.add(this.listeners, listener); - } - - boolean removeListener(ChangeListener listener) { - int len = this.listeners.length; - if (len == 0) { - return false; - } - try { - this.listeners = CollectionTools.remove(this.listeners, listener); - } catch (ArrayIndexOutOfBoundsException ex) { - return false; // listener not in the list - } - return (this.listeners.length + 1) == len; - } - - boolean hasListeners() { - return this.listeners.length > 0; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, ClassTools.shortNameFor(this.listenerClass)); - } - - } - - /** - * Pair an aspect name with the change support holding its associated - * listeners. - */ - private static class AspectChild implements Serializable { - final String aspectName; - final ChangeSupport child; - private static final long serialVersionUID = 1L; - - AspectChild(String aspectName, ChangeSupport child) { - super(); - this.aspectName = aspectName; - this.child = child; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.aspectName); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java deleted file mode 100644 index f63e523c6c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java +++ /dev/null @@ -1,332 +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.utility.internal.model; - -import java.util.Collection; -import java.util.List; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; - -/** - * This change support class changes the behavior of the standard - * ChangeSupport in several ways: - * - All events fired by the source must specify the single aspect. - * - Listeners are required to be either "generic" listeners or - * listeners of the single aspect. - */ -public class SingleAspectChangeSupport - extends ChangeSupport -{ - protected final Class<? extends ChangeListener> listenerClass; - protected final String aspectName; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - public SingleAspectChangeSupport(Model source, Class<? extends ChangeListener> listenerClass, String aspectName) { - super(source); - this.listenerClass = listenerClass; - this.aspectName = aspectName; - } - - - // ********** internal behavior ********** - - private UnsupportedOperationException unsupportedOperationException() { - return new UnsupportedOperationException("This Model supports only changes for the listener type \"" + this.listenerClass.getName() - + "\" and the aspect \"" + this.aspectName + "\""); - } - - private void check(Class<? extends ChangeListener> lClass, String aName) { - if (lClass != this.listenerClass) { - throw new IllegalArgumentException("This Model supports only changes for the listener type \"" + this.listenerClass.getName() + "\" : \"" + lClass.getName() + "\""); - } - if (aName != this.aspectName) { - throw new IllegalArgumentException("This Model supports only changes for the aspect \"" + this.aspectName + "\" : \"" + aName + "\""); - } - } - - @Override - protected <T extends ChangeListener> void addListener(String aName, Class<T> lClass, T listener) { - this.check(lClass, aName); - super.addListener(aName, lClass, listener); - } - - @Override - protected <T extends ChangeListener> void removeListener(String aName, Class<T> lClass, T listener) { - this.check(lClass, aName); - super.removeListener(aName, lClass, listener); - } - - - // ********** internal queries ********** - - @Override - protected boolean hasAnyListeners(Class<? extends ChangeListener> lClass, String aName) { - this.check(lClass, aName); - return super.hasAnyListeners(lClass, aName); - } - - - // ********** state change support ********** - - @Override - public void fireStateChanged(StateChangeEvent event) { - throw this.unsupportedOperationException(); - } - - @Override - public void fireStateChanged() { - throw this.unsupportedOperationException(); - } - - - // ********** property change support ********** - - @Override - public void firePropertyChanged(PropertyChangeEvent event) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, event.getPropertyName()); - super.firePropertyChanged(event); - } - - @Override - public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public void firePropertyChanged(String propertyName, int oldValue, int newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - - // ********** collection change support ********** - - @Override - public void fireItemsAdded(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireItemsAdded(event); - } - - @Override - public void fireItemsAdded(String collectionName, Collection<?> addedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - 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 void fireItemsRemoved(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireItemsRemoved(event); - } - - @Override - public void fireItemsRemoved(String collectionName, Collection<?> removedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - 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(CollectionChangeEvent 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) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireCollectionChanged(collectionName); - } - - - // ********** list change support ********** - - @Override - public void fireItemsAdded(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsAdded(event); - } - - @Override - public void fireItemsAdded(String listName, int index, List<?> addedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - 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 void fireItemsRemoved(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsRemoved(event); - } - - @Override - public void fireItemsRemoved(String listName, int index, List<?> removedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - 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 void fireItemsReplaced(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsReplaced(event); - } - - @Override - public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsReplaced(listName, index, newItems, replacedItems); - } - - @Override - public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemReplaced(listName, index, newItem, replacedItem); - } - - @Override - public void fireItemsMoved(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsMoved(event); - } - - @Override - public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - @Override - public void fireListCleared(ListChangeEvent 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) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireListChanged(listName); - } - - - // ********** tree change support ********** - - @Override - public void fireNodeAdded(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeAdded(event); - } - - @Override - public void fireNodeAdded(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeAdded(treeName, path); - } - - @Override - public void fireNodeRemoved(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeRemoved(event); - } - - @Override - public void fireNodeRemoved(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeRemoved(treeName, path); - } - - @Override - public void fireTreeCleared(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeCleared(event); - } - - @Override - public void fireTreeCleared(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeCleared(treeName, path); - } - - @Override - public void fireTreeChanged(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeChanged(event); - } - - @Override - public void fireTreeChanged(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeChanged(treeName, path); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java deleted file mode 100644 index d8cc166df1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java +++ /dev/null @@ -1,137 +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.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; - -/** - * Wrap another collection change listener and forward events to it on the AWT - * event queue. - * Forward *every* event asynchronously via the UI thread so the listener - * receives in the same order they were generated. - */ -public 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(CollectionChangeEvent event) { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - - public void itemsRemoved(CollectionChangeEvent event) { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - - public void collectionCleared(CollectionChangeEvent event) { - this.executeOnEventQueue(this.buildCollectionClearedRunnable(event)); - } - - public void collectionChanged(CollectionChangeEvent event) { - this.executeOnEventQueue(this.buildCollectionChangedRunnable(event)); - } - - private Runnable buildItemsAddedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added"; - } - }; - } - - private Runnable buildItemsRemovedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed"; - } - }; - } - - private Runnable buildCollectionClearedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionCleared_(event); - } - @Override - public String toString() { - return "collection cleared"; - } - }; - } - - private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionChanged_(event); - } - @Override - public String toString() { - return "collection changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #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_(CollectionChangeEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(CollectionChangeEvent event) { - this.listener.itemsRemoved(event); - } - - void collectionCleared_(CollectionChangeEvent event) { - this.listener.collectionCleared(event); - } - - void collectionChanged_(CollectionChangeEvent event) { - this.listener.collectionChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java deleted file mode 100644 index ac28b92ebf..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java +++ /dev/null @@ -1,177 +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.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; - -/** - * Wrap another list change listener and forward events to it on the AWT - * event queue. - * Forward *every* event asynchronously via the UI thread so the listener - * receives in the same order they were generated. - */ -public 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(ListChangeEvent event) { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - - public void itemsRemoved(ListChangeEvent event) { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - - public void itemsMoved(ListChangeEvent event) { - this.executeOnEventQueue(this.buildItemsMovedRunnable(event)); - } - - public void itemsReplaced(ListChangeEvent event) { - this.executeOnEventQueue(this.buildItemsReplacedRunnable(event)); - } - - public void listCleared(ListChangeEvent event) { - this.executeOnEventQueue(this.buildListClearedRunnable(event)); - } - - public void listChanged(ListChangeEvent event) { - this.executeOnEventQueue(this.buildListChangedRunnable(event)); - } - - private Runnable buildItemsAddedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added"; - } - }; - } - - private Runnable buildItemsRemovedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed"; - } - }; - } - - private Runnable buildItemsMovedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsMoved_(event); - } - @Override - public String toString() { - return "items moved"; - } - }; - } - - private Runnable buildItemsReplacedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsReplaced_(event); - } - @Override - public String toString() { - return "items replaced"; - } - }; - } - - private Runnable buildListClearedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listCleared_(event); - } - @Override - public String toString() { - return "list cleared"; - } - }; - } - - private Runnable buildListChangedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listChanged_(event); - } - @Override - public String toString() { - return "list changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #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_(ListChangeEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(ListChangeEvent event) { - this.listener.itemsRemoved(event); - } - - void itemsMoved_(ListChangeEvent event) { - this.listener.itemsMoved(event); - } - - void itemsReplaced_(ListChangeEvent event) { - this.listener.itemsReplaced(event); - } - - void listCleared_(ListChangeEvent event) { - this.listener.listCleared(event); - } - - void listChanged_(ListChangeEvent event) { - this.listener.listChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java deleted file mode 100644 index 7682773c93..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java +++ /dev/null @@ -1,74 +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.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; - -/** - * Wrap another property change listener and forward events to it on the AWT - * event queue. - * Forward *every* event asynchronously via the UI thread so the listener - * receives in the same order they were generated. - */ -public 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) { - this.executeOnEventQueue(this.buildRunnable(event)); - } - - private Runnable buildRunnable(final PropertyChangeEvent event) { - return new Runnable() { - public void run() { - AWTPropertyChangeListenerWrapper.this.propertyChanged_(event); - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #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() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java deleted file mode 100644 index b59556d185..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java +++ /dev/null @@ -1,73 +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.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; - -/** - * Wrap another state change listener and forward events to it on the AWT - * event queue. - * Forward *every* event asynchronously via the UI thread so the listener - * receives in the same order they were generated. - */ -public 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) { - this.executeOnEventQueue(this.buildRunnable(event)); - } - - private Runnable buildRunnable(final StateChangeEvent event) { - return new Runnable() { - public void run() { - AWTStateChangeListenerWrapper.this.stateChanged_(event); - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #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() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java deleted file mode 100644 index db0a0e342f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java +++ /dev/null @@ -1,137 +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.utility.internal.model.listener.awt; - -import java.awt.EventQueue; - -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Wrap another tree change listener and forward events to it on the AWT - * event queue. - * Forward *every* event asynchronously via the UI thread so the listener - * receives in the same order they were generated. - */ -public 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(TreeChangeEvent event) { - this.executeOnEventQueue(this.buildNodeAddedRunnable(event)); - } - - public void nodeRemoved(TreeChangeEvent event) { - this.executeOnEventQueue(this.buildNodeRemovedRunnable(event)); - } - - public void treeCleared(TreeChangeEvent event) { - this.executeOnEventQueue(this.buildTreeClearedRunnable(event)); - } - - public void treeChanged(TreeChangeEvent event) { - this.executeOnEventQueue(this.buildTreeChangedRunnable(event)); - } - - private Runnable buildNodeAddedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeAdded_(event); - } - @Override - public String toString() { - return "node added"; - } - }; - } - - private Runnable buildNodeRemovedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeRemoved_(event); - } - @Override - public String toString() { - return "node removed"; - } - }; - } - - private Runnable buildTreeClearedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeCleared_(event); - } - @Override - public String toString() { - return "tree cleared"; - } - }; - } - - private Runnable buildTreeChangedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeChanged_(event); - } - @Override - public String toString() { - return "tree changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #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_(TreeChangeEvent event) { - this.listener.nodeAdded(event); - } - - void nodeRemoved_(TreeChangeEvent event) { - this.listener.nodeRemoved(event); - } - - void treeCleared_(TreeChangeEvent event) { - this.listener.treeCleared(event); - } - - void treeChanged_(TreeChangeEvent event) { - this.listener.treeChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java deleted file mode 100644 index b06c83a3ac..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java +++ /dev/null @@ -1,195 +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.utility.internal.model.value; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ChainIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java deleted file mode 100644 index f7d33d56e3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java +++ /dev/null @@ -1,279 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This abstract extension of AbstractModel provides a base for adding - * change listeners (PropertyChange, CollectionChange, ListChange, TreeChange) - * to a subject and converting the subject's change notifications into a single - * set of change notifications for a common aspect (e.g. VALUE). - * - * The adapter will only listen to the subject (and subject holder) when the - * adapter itself actually has listeners. This will allow the adapter to be - * 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 AspectAdapters - * that have the same subject and that subject can change. - * All the AspectAdapters 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 subjectHolder. */ - protected final PropertyChangeListener subjectChangeListener; - - - // ********** constructors ********** - - /** - * Construct an AspectAdapter for the specified subject. - */ - protected AspectAdapter(S subject) { - this(new StaticPropertyValueModel<S>(subject)); - } - - /** - * Construct an AspectAdapter 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"; - } - }; - } - - - // ********** 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.fireAspectChange(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 ChangeListener> 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 fireAspectChange(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. - */ - protected class LocalChangeSupport extends SingleAspectChangeSupport { - private static final long serialVersionUID = 1L; - - public LocalChangeSupport(AspectAdapter<S> source, Class<? extends ChangeListener> listenerClass, String aspectName) { - super(source, listenerClass, aspectName); - } - - protected boolean listenerIsRelevant(Class<? extends ChangeListener> lClass) { - return lClass == this.listenerClass; - } - - protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> lClass) { - return this.listenerIsRelevant(lClass) - && this.hasNoListeners(lClass); - } - - protected boolean listenerIsRelevant(Class<? extends ChangeListener> lClass, String listenerAspectName) { - return this.listenerIsRelevant(lClass) - && (listenerAspectName == AspectAdapter.this.getListenerAspectName()); - } - - protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> lClass, String listenerAspectName) { - return this.listenerIsRelevant(lClass, listenerAspectName) - && this.hasNoListeners(lClass, listenerAspectName); - } - - - // ********** overrides ********** - - @Override - protected <T extends ChangeListener> void addListener(Class<T> lClass, T listener) { - if (this.hasNoRelevantListeners(lClass)) { - AspectAdapter.this.engageModels(); - } - super.addListener(lClass, listener); - } - - @Override - protected <T extends ChangeListener> void addListener(String listenerAspectName, Class<T> lClass, T listener) { - if (this.hasNoRelevantListeners(lClass, listenerAspectName)) { - AspectAdapter.this.engageModels(); - } - super.addListener(listenerAspectName, lClass, listener); - } - - @Override - protected <T extends ChangeListener> void removeListener(Class<T> lClass, T listener) { - super.removeListener(lClass, listener); - if (this.hasNoRelevantListeners(lClass)) { - AspectAdapter.this.disengageModels(); - } - } - - @Override - protected <T extends ChangeListener> void removeListener(String listenerAspectName, Class<T> lClass, T listener) { - super.removeListener(listenerAspectName, lClass, listener); - if (this.hasNoRelevantListeners(lClass, listenerAspectName)) { - AspectAdapter.this.disengageModels(); - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java deleted file mode 100644 index 75853757ad..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current model value - * - */ -public abstract class AspectPropertyValueModelAdapter<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - /** - * 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 the collection - * change event fired by the collection value model. - */ - protected T value; - - - // ********** constructor/initialization ********** - - protected AspectPropertyValueModelAdapter() { - super(); - // our value is null when we are not listening to the collection holder - this.value = null; - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, VALUE); - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the cached value. - */ - public T getValue() { - return this.value; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the wrapped collection if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addPropertyChangeListener(listener); - } - - /** - * Extend to start listening to the wrapped collection if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName == VALUE && this.hasNoListeners()) { - this.engageModel(); - } - super.addPropertyChangeListener(propertyName, listener); - } - - /** - * Extend to stop listening to the wrapped collection if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - super.removePropertyChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the wrapped collection if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName == VALUE && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether there are any listeners for the aspect. - */ - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - /** - * Return whether there are any listeners for the aspect. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - /** - * Start listening to the model and build the value. - */ - protected void engageModel() { - this.engageModel_(); - // synch our value *after* we start listening to the collection, - // since the collection's value might change when a listener is added - this.value = this.buildValue(); - } - - /** - * Start listening to the model. - */ - protected abstract void engageModel_(); - - /** - * Build and return the current value, as derived from the - * current state of the wrapped model. - */ - protected abstract T buildValue(); - - /** - * Stop listening to the model and clear the value. - */ - protected void disengageModel() { - this.disengageModel_(); - // clear out our value when we are not listening to the collection - this.value = null; - } - - /** - * Stop listening to the model. - */ - protected abstract void disengageModel_(); - - /** - * The wrapped model changed in some fashion. - * Recalculate the value and notify any listeners. - */ - protected void propertyChanged() { - Object old = this.value; - this.value = this.buildValue(); - this.firePropertyChanged(VALUE, old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java deleted file mode 100644 index 8781be4afd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java +++ /dev/null @@ -1,345 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A BufferedPropertyValueModel 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. - * - * The trigger is another value model that holds a Boolean and the application - * changes the trigger's value to true on "accept", false on "reset". Typically, - * in a dialog: - * - pressing the OK button will trigger an "accept" and close the dialog - * - pressing the Cancel button will simply close the dialog, - * dropping the "buffered" values into the bit bucket - * - pressing the Apply button will trigger an "accept" and leave the dialog open - * - pressing the Restore button will trigger a "reset" and leave the dialog open - * - * 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"; - } - }; - } - - - // ********** 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 forwarded to the wrapped value holder - * when the trigger is "accepted". - */ - public void setValue(T value) { - Object old = this.getValue(); - this.bufferedValue = value; - this.buffering = true; - this.firePropertyChanged(VALUE, old, this.bufferedValue); - } - - - // ********** PropertyValueModelWrapper extensions ********** - - /** - * extend to engage the trigger holder also - */ - @Override - protected void engageValueHolder() { - super.engageValueHolder(); - this.triggerHolder.addPropertyChangeListener(VALUE, this.triggerChangeListener); - } - - /** - * extend to disengage the trigger holder also - */ - @Override - protected void disengageValueHolder() { - this.triggerHolder.removePropertyChangeListener(VALUE, this.triggerChangeListener); - super.disengageValueHolder(); - } - - - // ********** behavior ********** - - /** - * If we do not yet have a "buffered" value, simply propagate the - * change notification with the buffered model as the source. - * If we do have a "buffered" value, do nothing. - */ - @Override - protected void valueChanged(PropertyChangeEvent event) { - if (this.accepting) { - // if we are currently "accepting" the value, ignore change notifications, - // since we caused them and our own listeners are already aware of the change - return; - } - if (this.buffering) { - this.handleChangeConflict(event); - } else { - this.firePropertyChanged(event.cloneWithSource(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(PropertyChangeEvent event) { - // the default is to do nothing - } - - /** - * The trigger changed: - * If it is now true, "accept" the buffered value and forward - * it to the wrapped value holder. - * If it is now false, "reset" the buffered value to its original value. - */ - protected void triggerChanged(PropertyChangeEvent event) { - if ( ! this.buffering) { - // if nothing has been "buffered", we don't need to do anything: - // nothing needs to be passed through; nothing needs to be reset; - return; - } - if (((Boolean) event.getNewValue()).booleanValue()) { - // set the accepting flag so we ignore any events - // fired by the wrapped value holder - this.accepting = true; - this.valueHolder().setValue(this.bufferedValue); - this.bufferedValue = null; - this.buffering = false; - // clear the flag once the "accept" is complete - this.accepting = false; - } else { - // 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 WritablePropertyValueModel<T>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - - // ********** inner class ********** - - /** - * Trigger is a special property value model that only maintains its - * value (of true or false) during the change notification caused by - * the #setValue(Object) method. In other words, a Trigger object - * only has a valid value - */ - 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 #setValue(Object). - */ - @Override - public Boolean getValue() { - if (this.value == null) { - throw new IllegalStateException("The method Trigger.value() may only be called during change notification."); - } - return this.value; - } - - /** - * Extend to reset the value to null 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: - * - true indicates "accept" - * - false indicates "reset" - */ - public void setValue(boolean value) { - this.setValue(Boolean.valueOf(value)); - } - - /** - * Return the trigger's value: - * - true indicates "accept" - * - false indicates "reset" - */ - public boolean booleanValue() { - return this.getValue().booleanValue(); - } - - /** - * Accept the trigger (i.e. set its value to true). - */ - public void accept() { - this.setValue(true); - } - - /** - * Return whether the trigger has been accepted - * (i.e. its value was changed to true). - */ - public boolean isAccepted() { - return this.booleanValue(); - } - - /** - * Reset the trigger (i.e. set its value to false). - */ - public void reset() { - this.setValue(false); - } - - /** - * Return whether the trigger has been reset - * (i.e. its value was changed to false). - */ - public boolean isReset() { - return ! this.booleanValue(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java deleted file mode 100644 index 725c275d31..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java +++ /dev/null @@ -1,239 +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.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides CollectionChange support. - * This allows us to convert a set of one or more collections into - * a single collection, VALUES. - * - * The typical subclass will override the following methods: - * #iterator_() - * at the very minimum, override this method to return an iterator on the - * subject's collection aspect; it does not need to be overridden if - * #iterator() is overridden and its behavior changed - * #size_() - * override this method to improve performance; it does not need to be overridden if - * #size() is overridden and its behavior changed - * #iterator() - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - * #size() - * override this method only if returning a zero when the - * subject is null is unacceptable - */ -public abstract class CollectionAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements CollectionValueModel<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 aspect. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructors ********** - - /** - * Construct a CollectionAspectAdapter for the specified subject - * and collection. - */ - protected CollectionAspectAdapter(String collectionName, S subject) { - this(new String[] {collectionName}, subject); - } - - /** - * Construct a CollectionAspectAdapter for the specified subject - * and collections. - */ - protected CollectionAspectAdapter(String[] collectionNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), collectionNames); - } - - /** - * Construct a CollectionAspectAdapter 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 CollectionAspectAdapter 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 CollectionAspectAdapter 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 ********** - - /** - * The subject's collection aspect has changed, notify the listeners. - */ - protected CollectionChangeListener buildCollectionChangeListener() { - // transform the subject's collection change events into VALUE collection change events - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionAspectAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent 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); - } - }; - } - - - // ********** 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 that the subject is not null. - * @see #iterator() - */ - protected Iterator<E> iterator_() { - throw new UnsupportedOperationException(); - } - - /** - * 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 that the subject is not null. - * @see #size() - */ - protected int size_() { - return CollectionTools.size(this.iterator()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUES); - } - - @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); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.collectionNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.collectionNames[i]); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(CollectionChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, VALUES)); - } - - protected void itemsRemoved(CollectionChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, VALUES)); - } - - protected void collectionCleared(CollectionChangeEvent event) { - this.fireCollectionCleared(VALUES); // nothing from original event to forward - } - - protected void collectionChanged(CollectionChangeEvent event) { - this.fireCollectionChanged(VALUES); // nothing from original event to forward - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java deleted file mode 100644 index 32ac311a6e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java +++ /dev/null @@ -1,297 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a CollectionValueModel behave like - * a read-only ListValueModel, sorta. - * - * To maintain a reasonably consistent appearance to client code, we - * keep an internal list somewhat in synch with the wrapped collection. - * - * NB: 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. #size(), getItem(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. - */ -public class CollectionListValueModelAdapter<E> - extends AbstractModel - 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 CollectionValueModel. - */ - 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>(); - // postpone building the list and listening to the underlying collection - // until we have listeners ourselves... - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - /** - * The wrapped collection has changed, forward an equivalent - * list change event to our listeners. - */ - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** 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(); - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the collection holder if necessary. - */ - @Override - public void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Override to start listening to the collection holder if necessary. - */ - @Override - public void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Override to stop listening to the collection holder if appropriate. - */ - @Override - public void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the collection holder if appropriate. - */ - @Override - public void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return the index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.list.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.list.get(i) == o) { - return i; - } - } - return -1; - } - - - // ********** behavior ********** - - protected void buildList() { - Iterator<? extends E> stream = this.collectionHolder.iterator(); - // if the new collection is empty, do nothing - if (stream.hasNext()) { - this.list.ensureCapacity(this.collectionHolder.size()); - while (stream.hasNext()) { - this.list.add(stream.next()); - } - this.postBuildList(); - } - } - - /** - * Allow subclasses to manipulate the internal list before - * sending out change notification. - */ - protected void postBuildList() { - // the default is to do nothing... - } - - 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(); - } - - 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 itemsAdded(CollectionChangeEvent e) { - this.addItemsToList(this.indexToAddItems(), CollectionTools.list(this.items(e)), this.list, LIST_VALUES); - } - - protected int indexToAddItems() { - return this.list.size(); - } - - @SuppressWarnings("unchecked") - protected Iterator<E> items(CollectionChangeEvent e) { - return (Iterator<E>) e.items(); - } - - protected void itemsRemoved(CollectionChangeEvent e) { - // we have to remove the items individually, - // since they are probably not in sequence - for (Iterator<E> stream = this.items(e); stream.hasNext(); ) { - this.removeItemFromList(this.lastIdentityIndexOf(stream.next()), this.list, LIST_VALUES); - } - } - - protected void collectionCleared(CollectionChangeEvent e) { - this.clearList(this.list, LIST_VALUES); - } - - /** - * synchronize our internal list with the wrapped collection - * and fire the appropriate events - */ - protected void collectionChanged(CollectionChangeEvent e) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.list.isEmpty()) { - @SuppressWarnings("unchecked") - ArrayList<E> removedItems = (ArrayList<E>) this.list.clone(); - this.list.clear(); - this.fireItemsRemoved(LIST_VALUES, 0, removedItems); - } - - this.buildList(); - // put in empty check so we don't fire events unnecessarily - if ( ! this.list.isEmpty()) { - this.fireItemsAdded(LIST_VALUES, 0, this.list); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java deleted file mode 100644 index a28ff711db..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java +++ /dev/null @@ -1,140 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.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. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current collection value - * - * Subclasses might want to override: - * - #itemsAdded(CollectionChangeEvent event) - * - #itemsRemoved(CollectionChangeEvent event) - * - #collectionCleared(CollectionChangeEvent event) - * - #collectionChanged(CollectionChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class CollectionPropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<T> -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<?> collectionHolder; - - /** 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<?> collectionHolder) { - super(); - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * 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); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(CollectionChangeEvent 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(CollectionChangeEvent 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(CollectionChangeEvent 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(CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java deleted file mode 100644 index f4bd305c89..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java +++ /dev/null @@ -1,180 +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.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.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. - */ -public abstract class CollectionValueModelWrapper<E> - extends AbstractModel -{ - - /** 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 ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, CollectionValueModel.VALUES); - } - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == CollectionValueModel.VALUES && this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == CollectionValueModel.VALUES && this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the collection holder. - */ - protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - /** - * Stop listening to the collection holder. - */ - protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterator<E> items(CollectionChangeEvent event) { - return (Iterator<E>) event.items(); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(CollectionChangeEvent event); - - /** - * Items were removed from the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(CollectionChangeEvent event); - - /** - * The wrapped collection holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void collectionCleared(CollectionChangeEvent event); - - /** - * The value of the wrapped collection holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void collectionChanged(CollectionChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java deleted file mode 100644 index 2fd65eebb1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java +++ /dev/null @@ -1,407 +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.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.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.NullList; -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>CompositeCollectionValueModel</code> wraps another - * <code>CollectionValueModel</code> and uses a <code>Transformer</code> - * to convert each item in the wrapped collection to yet another - * <code>CollectionValueModel</code>. This composite collection contains - * the combined items from all these component collections. - * - * NB: The wrapped collection must be an "identity set" that does not - * contain the same item twice or this class will throw an exception. - * - * Terminology: - * - sources - the items in the wrapped collection value model; these - * are converted into component CVMs by the transformer - * - component CVMs - the component collection value models that are combined - * by this composite collection value model - * - items - the items held by the component CVMs - */ -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; - - /** - * Cache of the collections corresponding to the component - * collection value models above; keyed by the component - * collection value models. - * Use ArrayLists so we can use ArrayList-specific methods - * (e.g. #clone() and #ensureCapacity()). - */ - private final IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>> collections; - - /** 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 - * - the wrapped collection value model already contains other - * collection value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - 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.componentCVMs = new IdentityHashMap<E1, CollectionValueModel<E2>>(); - this.collections = new IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>>(); - this.componentCVMListener = this.buildComponentListener(); - this.size = 0; - } - - /** - * Construct a collection value model with the specified wrapped - * list value model. Use this constructor if - * - the wrapped list value model already contains collection - * value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - 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 - * - the wrapped collection already contains collection - * value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - 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); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildComponentListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentItemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentCollectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentCollectionChanged(event); - } - @Override - public String toString() { - return "component listener"; - } - }; - } - - - // ********** 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(CollectionChangeEvent event) { - ArrayList<E2> addedItems = new ArrayList<E2>(); - for (Iterator<E1> stream = this.items(event); stream.hasNext(); ) { - this.addComponentSource(stream.next(), 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); - } - 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); - } - 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(CollectionChangeEvent event) { - ArrayList<E2> removedItems = new ArrayList<E2>(); - for (Iterator<E1> stream = this.items(event); stream.hasNext(); ) { - this.removeComponentSource(stream.next(), 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); - } - componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener); - ArrayList<E2> componentCollection = this.collections.remove(componentCVM); - if (componentCollection == null) { - throw new IllegalStateException("missing collection: " + source); - } - 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(CollectionChangeEvent 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); - } - - - // ********** 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 <code>Transformer</code>. - */ - 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(CollectionChangeEvent event) { - int itemsSize = event.itemsSize(); - this.size += itemsSize; - - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - - this.addItemsToCollection(this.componentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections had items removed; - * synchronize our caches. - */ - protected void componentItemsRemoved(CollectionChangeEvent event) { - this.size -= event.itemsSize(); - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - this.removeItemsFromCollection(this.componentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections was cleared; - * synchronize our caches by clearing out the appropriate - * collection. - */ - protected void componentCollectionCleared(CollectionChangeEvent 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); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterator<E2> componentItems(CollectionChangeEvent event) { - return (Iterator<E2>) event.items(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected CollectionValueModel<E2> componentCVM(CollectionChangeEvent event) { - return (CollectionValueModel<E2>) event.getSource(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java deleted file mode 100644 index dcc84c447d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java +++ /dev/null @@ -1,575 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>CompositeListValueModel</code> wraps another - * <code>ListValueModel</code> and uses a <code>Transformer</code> - * to convert each item in the wrapped list to yet another - * <code>ListValueModel</code>. This composite list contains - * the combined items from all these component lists. - * - * Terminology: - * - sources - the items in the wrapped list value model; these - * are converted into component LVMs by the transformer - * - componentLVMs - the component list value models that are combined - * by this composite list value model - * - items - the items held by the component LVMs - */ -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; - 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; - 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 - * - the wrapped list value model already contains other - * list value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - 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.infoList = new ArrayList<Info>(); - this.componentLVMListener = this.buildComponentLVMListener(); - this.size = 0; - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list. Use this constructor if - * - the wrapped list already contains list value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - 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); - } - - - // ********** initialization ********** - - protected ListChangeListener buildComponentLVMListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - CompositeListValueModel.this.componentListCleared(event); - } - public void listChanged(ListChangeEvent event) { - CompositeListValueModel.this.componentListChanged(event); - } - @Override - public String toString() { - return "component LVM listener"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public E2 get(int index) { - if ((index < 0) || (index >= this.size)) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size); - } - // 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 CollectionTools.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.listIterator(), this.listHolder.size()); - } - - @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(ListChangeEvent event) { - this.addComponentSources(event.getIndex(), this.items(event), event.itemsSize(), true); // true = fire event - } - - /** - * Do not fire an event. - */ - protected void addComponentSources(int addedSourcesIndex, ListIterator<? extends E1> addedSources, int addedSourcesSize) { - this.addComponentSources(addedSourcesIndex, addedSources, addedSourcesSize, false); // false = do not fire event - } - - /** - * Add infos corresponding to the specified sources to our cache. - * Fire the appropriate event if requested. - */ - protected void addComponentSources(int addedSourcesIndex, ListIterator<? 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; - while (addedSources.hasNext()) { - E1 source = addedSources.next(); - 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(ListChangeEvent event) { - this.removeComponentSources(event.getIndex(), event.itemsSize(), true); // true = fire event - } - - /** - * Do not fire an event. - */ - protected void removeComponentSources(int removedSourcesIndex, int removedSourcesSize) { - this.removeComponentSources(removedSourcesIndex, removedSourcesSize, false); // false = do not 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(ListChangeEvent event) { - this.replaceComponentSources(event.getIndex(), this.items(event), event.itemsSize(), 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, ListIterator<? 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(ListChangeEvent event) { - this.moveComponentSources(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength(), 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(ListChangeEvent event) { - this.removeComponentSources(0, this.infoList.size()); - this.fireListCleared(LIST_VALUES); - } - - /** - * The component sources changed; rebuild our cache. - */ - @Override - protected void listChanged(ListChangeEvent event) { - this.removeComponentSources(0, this.infoList.size()); - this.addComponentSources(0, this.listHolder.listIterator(), this.listHolder.size()); - this.fireListChanged(LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(CollectionTools.list(this.listIterator(), this.size)); - } - - - // ********** 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 <code>Transformer</code>. - */ - 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); - } - - /** - * Return the index of the specified event's component LVM. - */ - protected int indexFor(ListChangeEvent event) { - return this.indexOf(this.componentLVM(event)); - } - - /** - * Items were added to one of the component lists; - * synchronize our cache. - */ - protected void componentItemsAdded(ListChangeEvent event) { - // update the affected 'begin' indices - int componentLVMIndex = this.indexFor(event); - int newItemsSize = event.itemsSize(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - this.size += newItemsSize; - - // synchronize the cached list - Info info = this.infoList.get(componentLVMIndex); - CollectionTools.addAll(info.items, event.getIndex(), this.componentItems(event), event.itemsSize()); - - // translate the event - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were removed from one of the component lists; - * synchronize our cache. - */ - protected void componentItemsRemoved(ListChangeEvent event) { - // update the affected 'begin' indices - int componentLVMIndex = this.indexFor(event); - int removedItemsSize = event.itemsSize(); - 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.itemsSize()).clear(); - - // translate the event - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were replaced in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsReplaced(ListChangeEvent 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 (Iterator<E2> stream = this.componentItems(event); stream.hasNext(); ) { - info.items.set(i++, stream.next()); - } - - // translate the event - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were moved in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsMoved(ListChangeEvent 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.getMoveLength()); - - // translate the event - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * One of the component lists was cleared; - * synchronize our cache. - */ - protected void componentListCleared(ListChangeEvent 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(); - 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); - info.items.clear(); - - // translate the event - this.fireItemsRemoved(LIST_VALUES, info.begin, items); - } - - /** - * One of the component lists changed; - * synchronize our cache by clearing out the appropriate - * list and rebuilding it. - */ - protected void componentListChanged(ListChangeEvent event) { - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - this.clearComponentList(componentLVMIndex, info); - - // update the affected 'begin' indices - int newItemsSize = info.componentLVM.size(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - this.size += newItemsSize; - - // synchronize the cached list - CollectionTools.addAll(info.items, info.componentLVM.listIterator(), newItemsSize); - - // translate the event - this.fireItemsAdded(LIST_VALUES, info.begin, info.items); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E2> componentItems(ListChangeEvent event) { - return (ListIterator<E2>) event.items(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected ListValueModel<E2> componentLVM(ListChangeEvent event) { - return (ListValueModel<E2>) event.getSource(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java deleted file mode 100644 index 84bd413e02..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java +++ /dev/null @@ -1,205 +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.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.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This wrapper extends a ListValueModel (or CollectionValueModel) - * with fixed collections of items on either end. - * <p> - * NB: 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(ListChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsReplaced(ListChangeEvent event) { - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsMoved(ListChangeEvent event) { - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void listCleared(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); // not "cleared" - } - - @Override - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.prefix); - sb.append(" "); - super.toString(sb); - sb.append(" "); - sb.append(this.suffix); - } - - - // ********** miscellaneous ********** - - public void setPrefix(List<E> prefix) { - this.prefix = prefix; - this.fireListChanged(LIST_VALUES); - } - - public void setSuffix(List<E> suffix) { - this.suffix = suffix; - this.fireListChanged(LIST_VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java deleted file mode 100644 index 4cf2e2bc6b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java +++ /dev/null @@ -1,172 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>FilteringCollectionValueModel</code> wraps another - * <code>CollectionValueModel</code> and uses a <code>Filter</code> - * to determine which items in the collection are returned by calls - * to <code>#iterator()</code>. - * <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 .java files). - * <p> - * NB: 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 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 - * 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; - - - // ********** 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; - this.filteredItems = new ArrayList<E>(); - } - - /** - * 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.iterator())); - } - - @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(CollectionChangeEvent event) { - // filter the values before propagating the change event - this.addItemsToCollection(this.filter(this.items(event)), this.filteredItems, VALUES); - } - - @Override - protected void itemsRemoved(CollectionChangeEvent 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.items(), this.filteredItems, VALUES); - } - - @Override - protected void collectionCleared(CollectionChangeEvent 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 iterator that filters the specified iterator. - */ - protected Iterator<E> filter(Iterator<? extends E> items) { - return new FilteringIterator<E, 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.iterator())); - this.fireCollectionChanged(VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java deleted file mode 100644 index a56cc34c80..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java +++ /dev/null @@ -1,138 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A <code>FilteringPropertyValueModel</code> wraps another - * <code>PropertyValueModel</code> and uses a <code>Filter</code> - * to determine when the wrapped value is to be returned by calls - * to <code>value()</code>. - * <p> - * As an alternative to building a <code>Filter</code>, a subclass - * of <code>FilteringPropertyValueModel</code> can override the - * <code>accept(Object)</code> method. - * <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. - */ -public class FilteringPropertyValueModel<T> - extends PropertyValueModelWrapper<T> - implements PropertyValueModel<T> -{ - protected final Filter<T> filter; - protected final T defaultValue; - - - // ********** constructors ********** - - /** - * Construct a property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> - * method instead of building a <code>Filter</code>. - * The default value will be <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder) { - this(valueHolder, Filter.Disabled.<T>instance(), null); - } - - /** - * Construct a 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 the - * <code>accept(Object)</code> - * method instead of building a <code>Filter</code> - * <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 an 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 an 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") - Object oldValue = this.filterValue((T) event.getOldValue()); - @SuppressWarnings("unchecked") - Object newValue = this.filterValue((T) event.getNewValue()); - 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.defaultValue(); - } - - /** - * Return whether the <code>FilteringPropertyValueModel</code> should - * return the specified value from a call to the - * <code>value()</code> method; the value came - * from the nested property value model - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Filter</code>. - */ - 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 defaultValue() { - return this.defaultValue; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java deleted file mode 100644 index d7e20f4cb3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.BidiFilter; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>FilteringWritablePropertyValueModel</code> wraps another - * <code>WritabelPropertyValueModel</code> and uses a <code>BidiFilter</code> - * to determine when the wrapped value is to be returned by calls - * to <code>value()</code> and modified by calls to - * <code>setValue(Object)</code>. - * <p> - * As an alternative to building a <code>BidiFilter</code>, a subclass - * of <code>FilteringWritablePropertyValueModel</code> can override the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods. - * <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. - * <p> - * Similarly, if an incoming value is not "reverseAccepted", *nothing* 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 property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods instead of building a <code>BidiFilter</code>. - * The default value will be <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder) { - this(valueHolder, BidiFilter.Disabled.<T>instance(), null); - } - - /** - * Construct a 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 the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods instead of building a <code>BidiFilter</code> - * <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.valueHolder().setValue(value); - } - } - - - // ********** queries ********** - - /** - * Return whether the <code>FilteringWritablePropertyValueModel</code> - * should pass through the specified value to the nested - * writable property value model in a call to the - * <code>setValue(Object)</code> method - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>BidiFilter</code>. - */ - protected boolean reverseAccept(T value) { - return this.getFilter().reverseAccept(value); - } - - /** - * Our constructors accept only a WritablePropertyValueModel<T>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - /** - * Our constructors accept only a bidirectional filter. - */ - protected BidiFilter<T> getFilter() { - return (BidiFilter<T>) this.filter; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java deleted file mode 100644 index 3c86dbbc91..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java +++ /dev/null @@ -1,296 +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.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.utility.internal.Counter; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Abstract list value model that provides behavior for wrapping a list value - * model (or collection value model) and listening for changes to aspects of the - * *items* 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 collection's external appearance. - * - * Subclasses need to override two methods: - * - * #listenToItem(Model) - * begin listening to the appropriate aspect of the specified item and call - * #itemAspectChanged(Object) whenever the aspect changes - * - * #stopListeningToItem(Model) - * stop listening to the appropriate aspect of the specified item - */ -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, Counter> counters; - - - // ********** constructors ********** - - /** - * Constructor - the list holder is required. - */ - protected ItemAspectListValueModelAdapter(ListValueModel<? extends E> listHolder) { - super(listHolder); - this.counters = new IdentityHashMap<E, Counter>(); - } - - /** - * 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.iterator()); - } - - protected void engageItems(Iterator<? extends E> stream) { - while (stream.hasNext()) { - this.engageItem(stream.next()); - } - } - - protected void engageItem(E item) { - // listen to an item only once - Counter counter = this.counters.get(item); - if (counter == null) { - counter = new Counter(); - this.counters.put(item, counter); - this.startListeningToItem((Model) item); - } - counter.increment(); - } - - /** - * Start listening to the specified item. - */ - protected abstract void startListeningToItem(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.iterator()); - } - - protected void disengageItems(Iterator<? extends E> stream) { - while (stream.hasNext()) { - this.disengageItem(stream.next()); - } - } - - protected void disengageItem(E item) { - // stop listening to an item only once - Counter counter = this.counters.get(item); - if (counter == null) { - // something is wrong if this happens... ~bjv - throw new IllegalStateException("missing counter: " + item); - } - if (counter.decrement() == 0) { - this.counters.remove(item); - this.stopListeningToItem((Model) item); - } - } - - /** - * Stop listening to the specified item. - */ - protected abstract void stopListeningToItem(Model item); - - - // ********** 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(ListChangeEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES)); - this.engageItems(this.items(event)); - } - - /** - * Items were removed from the wrapped list holder. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.disengageItems(this.items(event)); - // re-fire event with the wrapper as the source - this.fireItemsRemoved(event.cloneWithSource(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(ListChangeEvent event) { - this.disengageItems(this.replacedItems(event)); - // re-fire event with the wrapper as the source - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES)); - this.engageItems(this.items(event)); - } - - /** - * Items were moved in the wrapped list holder. - * No need to change any listeners; just forward the event. - */ - @Override - protected void itemsMoved(ListChangeEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES)); - } - - /** - * The wrapped list holder was cleared. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void listCleared(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.iterator()); - 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.iterator()); - this.counters.clear(); - // re-fire event with the wrapper as the source - this.fireListChanged(LIST_VALUES); - this.engageAllItems(); - } - - - // ********** item change support ********** - - /** - * The specified item has a bound property that has changed. - * Notify listeners of the change. - */ - protected void itemAspectChanged(EventObject event) { - Object item = event.getSource(); - int index = this.lastIdentityIndexOf(item); - while (index != -1) { - this.itemAspectChanged(index, item); - index = this.lastIdentityIndexOf(item, index); - } - } - - /** - * The specified item has a bound property that has changed. - * Notify listeners of the change. - */ - protected void itemAspectChanged(int index, Object item) { - this.fireItemReplaced(LIST_VALUES, index, item, item); // hmmm... - } - - /** - * Return the last index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.listHolder.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.listHolder.get(i) == o) { - return i; - } - } - return -1; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java deleted file mode 100644 index 6f46a74c32..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java +++ /dev/null @@ -1,98 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend 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(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void collectionCleared(CollectionChangeEvent 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); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String collectionName : this.collectionNames) { - item.addCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String collectionName : this.collectionNames) { - item.removeCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java deleted file mode 100644 index 9c3ac67ac5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java +++ /dev/null @@ -1,104 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend 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(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsReplaced(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsMoved(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void listCleared(ListChangeEvent 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); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String listName : this.listNames) { - item.addListChangeListener(listName, this.itemListListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String listName : this.listNames) { - item.removeListChangeListener(listName, this.itemListListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java deleted file mode 100644 index 3a00073252..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java +++ /dev/null @@ -1,85 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend 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); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String propertyName : this.propertyNames) { - item.addPropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String propertyName : this.propertyNames) { - item.removePropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java deleted file mode 100644 index 46d7d863fb..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java +++ /dev/null @@ -1,74 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend 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"; - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - item.addStateChangeListener(this.itemStateListener); - } - - @Override - protected void stopListeningToItem(Model item) { - item.removeStateChangeListener(this.itemStateListener); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java deleted file mode 100644 index 5fcc770398..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend 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(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void nodeRemoved(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void treeCleared(TreeChangeEvent 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); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String treeName : this.treeNames) { - item.addTreeChangeListener(treeName, this.itemTreeListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String treeName : this.treeNames) { - item.removeTreeChangeListener(treeName, this.itemTreeListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java deleted file mode 100644 index be004fe730..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java +++ /dev/null @@ -1,288 +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.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides ListChange support. - * This allows us to convert a set of one or more collections into - * a single collection, LIST_VALUES. - * - * The typical subclass will override the following methods: - * #listIterator_() - * at the very minimum, override this method to return a list iterator - * on the subject's list aspect; it does not need to be overridden if - * #listIterator() is overridden and its behavior changed - * #get(int) - * override this method to improve performance - * #size_() - * override this method to improve performance; it does not need to be overridden if - * #size() is overridden and its behavior changed - * #listIterator() - * override this method only if returning an empty list iterator when the - * subject is null is unacceptable - * #size() - * override this method only if returning a zero when the - * subject is null is unacceptable - */ -public abstract class ListAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements ListValueModel<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 aspect. */ - protected final ListChangeListener listChangeListener; - - private static final Object[] EMPTY_ARRAY = new Object[0]; - - - // ********** constructors ********** - - /** - * Construct a ListAspectAdapter for the specified subject - * and list. - */ - protected ListAspectAdapter(String listName, S subject) { - this(new String[] {listName}, subject); - } - - /** - * Construct a ListAspectAdapter for the specified subject - * and lists. - */ - protected ListAspectAdapter(String[] listNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), listNames); - } - - /** - * Construct a ListAspectAdapter 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 ListAspectAdapter 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 ListAspectAdapter 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 ********** - - /** - * The subject's list aspect has changed, notify the listeners. - */ - protected ListChangeListener buildListChangeListener() { - // transform the subject's list change events into VALUE list change events - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListAspectAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListAspectAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListAspectAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent 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); - } - }; - } - - - // ********** ListValueModel implementation ********** - - /** - * Return the elements of the subject's list aspect. - */ - public Iterator<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 that the subject is not null. - * @see #listIterator() - */ - protected ListIterator<E> listIterator_() { - throw new UnsupportedOperationException(); - } - - /** - * 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 that 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 that the subject is not null. - * @see #toArray() - */ - protected Object[] toArray_() { - return CollectionTools.array(this.listIterator(), this.size()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return ListChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return LIST_VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireListChanged(LIST_VALUES); - } - - @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); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.listNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.listNames[i]); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(ListChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsRemoved(ListChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsReplaced(ListChangeEvent event) { - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsMoved(ListChangeEvent event) { - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void listCleared(ListChangeEvent event) { - this.fireListCleared(LIST_VALUES); // nothing from original event to forward - } - - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); // nothing from original event to forward - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java deleted file mode 100644 index 30e73a7bfc..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java +++ /dev/null @@ -1,301 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a ListValueModel behave like - * a read-only CollectionValueModel, sorta. - * - * We keep an internal collection somewhat in synch with the wrapped list. - * - * NB: 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. #size(), value()) 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 AbstractModel - 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/initialization ********** - - /** - * Wrap the specified ListValueModel. - */ - 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... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - /** - * The wrapped list has changed, forward an equivalent - * collection change event to our listeners. - */ - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** 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(); - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the list holder if necessary. - */ - @Override - public void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Override to start listening to the list holder if necessary. - */ - @Override - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Override to stop listening to the list holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the list holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return the index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.collection.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.collection.get(i) == o) { - return i; - } - } - return -1; - } - - - // ********** behavior ********** - - protected void buildCollection() { - Iterator<? extends E> stream = this.listHolder.iterator(); - // if the new list is empty, do nothing - if (stream.hasNext()) { - this.collection.ensureCapacity(this.listHolder.size()); - while (stream.hasNext()) { - this.collection.add(stream.next()); - } - } - } - - 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(); - } - - 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(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> items(ListChangeEvent event) { - return (ListIterator<E>) event.items(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> replacedItems(ListChangeEvent event) { - return (ListIterator<E>) event.replacedItems(); - } - - protected void itemsAdded(ListChangeEvent event) { - this.addItemsToCollection(this.items(event), this.collection, VALUES); - } - - protected void removeInternalItems(Iterator<E> items) { - // we have to remove the items individually, - // since they are probably not in sequence - while (items.hasNext()) { - Object removedItem = items.next(); - int index = this.lastIdentityIndexOf(removedItem); - this.collection.remove(index); - this.fireItemRemoved(VALUES, removedItem); - } - } - - protected void itemsRemoved(ListChangeEvent event) { - this.removeInternalItems(this.items(event)); - } - - protected void itemsReplaced(ListChangeEvent event) { - this.removeInternalItems(this.replacedItems(event)); - this.addItemsToCollection(this.items(event), this.collection, VALUES); - } - - protected void itemsMoved(ListChangeEvent event) { - // do nothing? moving items in a list has no net effect on a collection... - } - - protected void listCleared(ListChangeEvent 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(ListChangeEvent event) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - @SuppressWarnings("unchecked") - ArrayList<E> removedItems = (ArrayList<E>) this.collection.clone(); - this.collection.clear(); - this.fireItemsRemoved(VALUES, removedItems); - } - - this.buildCollection(); - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - this.fireItemsAdded(VALUES, this.collection); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java deleted file mode 100644 index 5420b78d84..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java +++ /dev/null @@ -1,221 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides ListChange 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"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<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 Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> 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 fireAspectChange(Object oldValue, Object newValue) { - this.fireListChanged(LIST_VALUES); - } - - /** - * 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 #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, E item) { - this.removeItemFromList(index, this.record, LIST_VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java deleted file mode 100644 index 6c78b4fd62..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.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. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current list value - * - * Subclasses might want to override: - * - #itemsAdded(ListChangeEvent event) - * - #itemsRemoved(ListChangeEvent event) - * - #itemsReplaced(ListChangeEvent event) - * - #itemsMoved(ListChangeEvent event) - * - #listCleared(ListChangeEvent event) - * - #listChanged(ListChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class ListPropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<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(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** 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); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(ListChangeEvent 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(ListChangeEvent 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(ListChangeEvent 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(ListChangeEvent 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(ListChangeEvent 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(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java deleted file mode 100644 index 3eb604dfd5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java +++ /dev/null @@ -1,207 +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.utility.internal.model.value; - -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.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. - */ -public abstract class ListValueModelWrapper<E> - extends AbstractModel -{ - - /** 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 ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES); - } - - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListValueModelWrapper.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListValueModelWrapper.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListValueModelWrapper.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListValueModelWrapper.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListValueModelWrapper.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == ListValueModel.LIST_VALUES && this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == ListValueModel.LIST_VALUES && this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder. - */ - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - /** - * Stop listening to the list holder. - */ - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> items(ListChangeEvent event) { - return (ListIterator<E>) event.items(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> replacedItems(ListChangeEvent event) { - return (ListIterator<E>) event.replacedItems(); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(ListChangeEvent event); - - /** - * Items were removed from the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(ListChangeEvent event); - - /** - * Items were replaced in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsReplaced(ListChangeEvent event); - - /** - * Items were moved in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsMoved(ListChangeEvent event); - - /** - * The wrapped list holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void listCleared(ListChangeEvent event); - - /** - * The value of the wrapped list holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void listChanged(ListChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java deleted file mode 100644 index 910d90b53a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java +++ /dev/null @@ -1,59 +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.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.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. - * - * 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 ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java deleted file mode 100644 index 3092ed6895..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java +++ /dev/null @@ -1,72 +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.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An empty list value model for when you don't - * need to support a list. - * - * 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"); - } - - public Object[] toArray() { - return EMPTY_ARRAY; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java deleted file mode 100644 index 12c9b670e8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java +++ /dev/null @@ -1,50 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A property value model for when you - * don't need to support a value. - * - * We don't use a singleton because we hold on to listeners. - */ -public 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 ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java deleted file mode 100644 index 4103536ebd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * A tree value model for when you - * don't need to support any nodes. - * - * We don't use a singleton because we hold on to listeners. - */ -public 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 ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java deleted file mode 100644 index 81e93d8765..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java +++ /dev/null @@ -1,256 +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.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This AspectAdapter provides basic PropertyChange support. - * This allows us to convert a set of one or more properties into - * a single property, VALUE. - * - * The typical subclass will override the following methods: - * #buildValue_() - * at the very minimum, override this method to return the value of the - * subject's property (or "virtual" property); it does not need to be - * overridden if #buildValue() is overridden and its behavior changed - * #setValue_(Object) - * override this method if the client code needs to *set* the value of - * the subject's property; oftentimes, though, the client code (e.g. UI) - * will need only to *get* the value; it does not need to be - * overridden if #setValue(Object) is overridden and its behavior changed - * #buildValue() - * override this method only if returning a null value when the subject is null - * is unacceptable - * #setValue(Object) - * override this method only if something must be done when the subject - * is null (e.g. throw an exception) - */ -public abstract class PropertyAspectAdapter<S extends Model, T> - extends AspectAdapter<S> - implements WritablePropertyValueModel<T> -{ - /** - * 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 T value; - - /** 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 PropertyAspectAdapter for the specified subject - * and property. - */ - protected PropertyAspectAdapter(String propertyName, S subject) { - this(new String[] {propertyName}, subject); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject - * and properties. - */ - protected PropertyAspectAdapter(String[] propertyNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), propertyNames); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... propertyNames) { - super(subjectHolder); - this.propertyNames = propertyNames; - this.propertyChangeListener = this.buildPropertyChangeListener(); - // our value is null when we are not listening to the subject - this.value = null; - } - - /** - * Construct a PropertyAspectAdapter 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 PropertyAspectAdapter 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 TransformationPropertyValueModel could also be - * used in this situation.) - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_PROPERTY_NAMES); - } - - - // ********** initialization ********** - - /** - * The subject's property has changed, notify the listeners. - */ - 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(); - } - @Override - public String toString() { - return "property change listener: " + Arrays.asList(PropertyAspectAdapter.this.propertyNames); - } - }; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the value of the subject's property. - */ - @Override - public final T getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - /** - * Set the value of the subject's property. - */ - public void setValue(T value) { - if (this.subject != null) { - this.setValue_(value); - } - } - - /** - * Set the value of the subject's property. - * At this point we can be sure that the subject is not null. - * @see #setValue(Object) - */ - protected void setValue_(T value) { - throw new UnsupportedOperationException(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChange(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 engageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).addPropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - @Override - protected void disengageSubject() { - super.disengageSubject(); - // clear out our value when we are not listening to the subject - this.value = null; - } - - @Override - protected void disengageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).removePropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.propertyNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.propertyNames[i]); - } - } - - - // ********** behavior ********** - - /** - * Return the aspect's value. - * At this point the subject may be null. - */ - protected T buildValue() { - return (this.subject == null) ? null : this.buildValue_(); - } - - /** - * Return the value of the subject's property. - * At this point we can be sure that the subject is not null. - * @see #buildValue() - */ - protected T buildValue_() { - throw new UnsupportedOperationException(); - } - - protected void propertyChanged() { - T old = this.value; - this.value = this.buildValue(); - this.fireAspectChange(old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java deleted file mode 100644 index 9dcc0d4e24..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java +++ /dev/null @@ -1,195 +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.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a PropertyValueModel behave like - * a read-only, single-element CollectionValueModel, sorta. - * - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a collection with a null element). - */ -public class PropertyCollectionValueModelAdapter<E> - extends AbstractModel - 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 ********** - - /** - * Wrap the specified ListValueModel. - */ - public PropertyCollectionValueModelAdapter(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... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - /** - * The wrapped value has changed, forward an equivalent - * collection change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - PropertyCollectionValueModelAdapter.this.valueChanged((E) event.getNewValue()); - } - @Override - public String toString() { - return "property change listener"; - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return (this.value == null) ? - EmptyIterator.<E>instance() - : - new SingleElementIterator<E>(this.value); - } - - public int size() { - return (this.value == null) ? 0 : 1; - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - 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(); - } - - 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) { - // put in "empty" check so we don't fire events unnecessarily - if (this.value != null) { - E oldValue = this.value; - this.value = null; - this.fireItemRemoved(VALUES, oldValue); - } - this.value = newValue; - // put in "empty" check so we don't fire events unnecessarily - if (this.value != null) { - this.fireItemAdded(VALUES, this.value); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java deleted file mode 100644 index 6826af4511..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java +++ /dev/null @@ -1,220 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a PropertyValueModel behave like - * a read-only, single-element ListValueModel, sorta. - * - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a list with a null element). - */ -public class PropertyListValueModelAdapter<E> - extends AbstractModel - 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 ********** - - /** - * Wrap the specified property 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... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - /** - * The wrapped value has changed, forward an equivalent - * list change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - PropertyListValueModelAdapter.this.valueChanged((E) event.getNewValue()); - } - @Override - public String toString() { - return "property change listener"; - } - }; - } - - - // ********** 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.ioobe(index, 0); - } - if (index > 0) { - throw this.ioobe(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}; - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - protected IndexOutOfBoundsException ioobe(int index, int size) { - return new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - } - - 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(); - } - - 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) { - sb.append(this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java deleted file mode 100644 index 0a4e550978..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java +++ /dev/null @@ -1,145 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.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. - */ -public abstract class PropertyValueModelWrapper<T> - extends AbstractModel -{ - - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends T> 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 T> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.valueChangeListener = this.buildValueChangeListener(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE); - } - - protected PropertyChangeListener buildValueChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - PropertyValueModelWrapper.this.valueChanged(event); - } - @Override - public String toString() { - return "value change listener"; - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.engageValueHolder(); - } - super.addPropertyChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName == PropertyValueModel.VALUE && this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.engageValueHolder(); - } - super.addPropertyChangeListener(propertyName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - super.removePropertyChangeListener(listener); - if (this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.disengageValueHolder(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName == PropertyValueModel.VALUE && this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.disengageValueHolder(); - } - } - - - // ********** behavior ********** - - /** - * Begin listening to the value holder. - */ - protected void engageValueHolder() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - /** - * Stop listening to the value holder. - */ - protected void disengageValueHolder() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.valueHolder); - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java deleted file mode 100644 index aa242621c0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java +++ /dev/null @@ -1,184 +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.utility.internal.model.value; - -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.HashBag; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * Implementation of CollectionValueModel and Collection that simply holds a - * collection and notifies listeners of any changes. - */ -public class SimpleCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E>, Collection<E> -{ - /** The collection. */ - protected Collection<E> collection; - - - // ********** constructors ********** - - /** - * Construct a CollectionValueModel for the specified collection. - */ - public SimpleCollectionValueModel(Collection<E> collection) { - super(); - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - } - - /** - * Construct a CollectionValueModel 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(); - } - - - // ********** 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(); - } - - - // ********** additional behavior ********** - - /** - * Allow the collection to be replaced. - */ - public void setCollection(Collection<E> collection) { - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - this.fireCollectionChanged(VALUES); - } - - @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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java deleted file mode 100644 index 7fafe63f2c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java +++ /dev/null @@ -1,317 +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.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.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Implementation of ListValueModel and List that simply holds a - * collection and notifies listeners of any changes. - */ -public class SimpleListValueModel<E> - extends AbstractModel - implements ListValueModel<E>, List<E> -{ - /** The list. */ - protected List<E> list; - - - // ********** constructors ********** - - /** - * Construct a ListValueModel for the specified list. - */ - public SimpleListValueModel(List<E> list) { - super(); - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - } - - /** - * Construct a ListValueModel 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); - } - - - // ********** 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 ********** - - /** - * Allow the list to be replaced. - */ - public void setList(List<E> list) { - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - this.fireListChanged(LIST_VALUES); - } - - /** - * 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java deleted file mode 100644 index e7248e65c5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java +++ /dev/null @@ -1,66 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Implementation of 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 PropertyValueModel for the specified value. - */ - public SimplePropertyValueModel(T value) { - super(); - this.value = value; - } - - /** - * Construct a PropertyValueModel 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java deleted file mode 100644 index b912b9a207..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java +++ /dev/null @@ -1,133 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.Range; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a <code>CollectionValueModel</code> - * (or <code>ListValueModel</code>) behave like a <code>ListValueModel</code> - * that keeps its contents sorted and notifies listeners appropriately. - * <p> - * The 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> - * NB: 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. <code>#size()</code>, <code>#getItem(int)</code>) 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 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); - } - - /** - * Wrap the specified list value model and sort its contents - * using the specified comparator. - */ - public SortedListValueModelAdapter(ListValueModel<? extends E> listHolder, Comparator<E> comparator) { - this(new ListCollectionValueModelAdapter<E>(listHolder), comparator); - } - - /** - * Wrap the specified list value model and sort its contents - * based on the elements' "natural ordering". - */ - public SortedListValueModelAdapter(ListValueModel<? extends E> listHolder) { - this(listHolder, null); - } - - - // ********** accessors ********** - - public void setComparator(Comparator<E> comparator) { - this.comparator = comparator; - this.sortList(); - } - - - // ********** behavior ********** - - /** - * Sort the internal list before - * sending out change notification. - */ - @Override - protected void postBuildList() { - super.postBuildList(); - Collections.sort(this.list, this.comparator); - } - - /** - * the list will need to be sorted after the item is added - */ - @Override - protected void itemsAdded(CollectionChangeEvent event) { - // first add the items and notify our listeners... - super.itemsAdded(event); - // ...then sort the list - this.sortList(); - } - - /** - * 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java deleted file mode 100644 index db6c0c916f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.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. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current model - * - * Subclasses might want to override: - * - #stateChanged(StateChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class StatePropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<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"; - } - }; - } - - - // ********** 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); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.model); - } - - - // ********** state change support ********** - - /** - * The model's state changed; - * propagate the change notification appropriately. - */ - protected void stateChanged(StateChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java deleted file mode 100644 index 1dba4c3b74..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java +++ /dev/null @@ -1,64 +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.utility.internal.model.value; - -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * Implementation of CollectionValueModel that can be used for - * returning an iterator on a static collection, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - /** The collection. */ - protected final Collection<? extends E> collection; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static CollectionValueModel for the specified collection. - */ - public StaticCollectionValueModel(Collection<? extends E> collection) { - super(); - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - } - - // ********** CollectionValueModel implementation ********** - - public int size() { - return this.collection.size(); - } - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.collection.iterator()); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.collection); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java deleted file mode 100644 index 584d4acd32..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java +++ /dev/null @@ -1,79 +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.utility.internal.model.value; - -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Implementation of ListValueModel that can be used for - * returning a list iterator on a static list, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticListValueModel<E> - extends AbstractModel - implements ListValueModel<E> -{ - /** The value. */ - protected final List<? extends E> list; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static ListValueModel for the specified list. - */ - public StaticListValueModel(List<? extends E> list) { - super(); - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.list.iterator()); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.list.listIterator()); - } - - public int size() { - return this.list.size(); - } - - public E get(int index) { - return this.list.get(index); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.list); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java deleted file mode 100644 index e5eccf3ae2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java +++ /dev/null @@ -1,54 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * Implementation of PropertyValueModel that can be used for - * returning a static value, but still allows listeners to be added. - * Listeners will NEVER 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 PropertyValueModel for the specified value. - */ - public StaticPropertyValueModel(T value) { - super(); - this.value = value; - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.value; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java deleted file mode 100644 index 9929535e20..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * Implementation of TreeValueModel that can be used for - * returning an iterator on a static tree, but still allows listeners to be added. - * Listeners will NEVER 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 TreeValueModel 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 String toString() { - return StringTools.buildToStringFor(this, CollectionTools.collection(this.nodes())); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java deleted file mode 100644 index ad4a2a3418..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java +++ /dev/null @@ -1,242 +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.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to transform a ListValueModel - * (or CollectionValueModel) into a read-only ListValueModel - * whose items are tranformations of the items in the wrapped - * ListValueModel. It will keep its contents in synch with - * the contents of the wrapped ListValueModel and notifies its - * listeners of any changes. - * <p> - * The transformer can be changed at any time; allowing the same - * adapter to be used with different transformations. - * <p> - * NB: 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. #size(), #getItem(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. - */ -public class TransformationListValueModelAdapter<E1, E2> - extends ListValueModelWrapper<E1> - implements ListValueModel<E2> -{ - - /** This transforms the items, unless the subclass overrides #transformItem(Object). */ - protected Transformer<E1, E2> transformer; - - /** The list of transformed items. */ - protected final List<E2> transformedList; - - - // ********** constructors ********** - - /** - * Constructor - the list holder is required. - */ - public TransformationListValueModelAdapter(ListValueModel<? extends E1> listHolder, Transformer<E1, E2> transformer) { - super(listHolder); - this.transformer = transformer; - this.transformedList = new ArrayList<E2>(); - } - - /** - * Constructor - the list holder is required. - */ - public TransformationListValueModelAdapter(ListValueModel<? extends E1> listHolder) { - this(listHolder, Transformer.Null.<E1, E2>instance()); - } - - /** - * Constructor - the collection holder is required. - */ - public TransformationListValueModelAdapter(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, E2> transformer) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder), transformer); - } - - /** - * Constructor - the collection holder is required. - */ - public TransformationListValueModelAdapter(CollectionValueModel<? extends E1> collectionHolder) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder)); - } - - - // ********** 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 associated with the specified event. - */ - protected List<E2> transformItems(ListChangeEvent event) { - return this.transformItems(this.items(event), event.itemsSize()); - } - - /** - * Transform the items in the specified list value model. - */ - protected List<E2> transformItems(ListValueModel<? extends E1> lvm) { - return this.transformItems(lvm.listIterator(), lvm.size()); - } - - /** - * Transform the replaced items associated with the specified event. - */ - protected List<E2> transformReplacedItems(ListChangeEvent event) { - return this.transformItems(this.replacedItems(event), event.itemsSize()); - } - - /** - * Transform the specified items. - */ - protected List<E2> transformItems(ListIterator<? extends E1> items, int size) { - List<E2> result = new ArrayList<E2>(size); - while (items.hasNext()) { - result.add(this.transformItem(items.next())); - } - return result; - } - - /** - * Transform the specified item. - */ - protected E2 transformItem(E1 item) { - return this.transformer.transform(item); - } - - /** - * 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.transformedList.clear(); - this.transformedList.addAll(this.transformItems(this.listHolder)); - this.fireListChanged(LIST_VALUES); - } - - - // ********** 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(ListChangeEvent 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(ListChangeEvent event) { - this.removeItemsFromList(event.getIndex(), event.itemsSize(), 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(ListChangeEvent event) { - this.setItemsInList(event.getIndex(), this.transformItems(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(ListChangeEvent event) { - this.moveItemsInList(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength(), this.transformedList, LIST_VALUES); - } - - /** - * The wrapped list holder was cleared. - * Clear our transformation list and notify our listeners. - */ - @Override - protected void listCleared(ListChangeEvent 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(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java deleted file mode 100644 index 5d3b93e821..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java +++ /dev/null @@ -1,114 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A <code>TransformationPropertyValueModel</code> wraps another - * <code>PropertyValueModel</code> and uses a <code>Transformer</code> - * to transform the wrapped value before it is returned by <code>value()</code>. - * <p> - * As an alternative to building a <code>Transformer</code>, - * a subclass of <code>TransformationPropertyValueModel</code> can - * either override the <code>transform_(Object)</code> method or, - * if something other than null should be returned when the wrapped value - * is null, override the <code>transform(Object)</code> method. - */ -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 the - * <code>transform_(Object)</code> or <code>transform(Object)</code> - * method instead of building a <code>Transformer</code>. - */ - public TransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder) { - super(valueHolder); - this.transformer = this.buildTransformer(); - } - - /** - * Construct an 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") - Object oldValue = this.transform((T1) event.getOldValue()); - @SuppressWarnings("unchecked") - Object newValue = this.transform((T1) event.getNewValue()); - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - - // ********** behavior ********** - - /** - * Transform the specified value and return the result. - * This is called by #value() and #valueChanged(PropertyChangeEvent). - */ - protected T2 transform(T1 value) { - return this.transformer.transform(value); - } - - /** - * Transform the specified, non-null, value and return the result. - */ - protected T2 transform_(T1 value) { - throw new UnsupportedOperationException(); - } - - - // ********** 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 #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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java deleted file mode 100644 index aa5cc63c5b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.BidiTransformer; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>TransformationWritablePropertyValueModel</code> wraps another - * <code>WritablePropertyValueModel</code> and uses a <code>BidiTransformer</code> - * to:<ul> - * <li>transform the wrapped value before it is returned by <code>value()</code> - * <li>"reverse-transform" the new value that comes in via - * <code>setValue(Object)</code> - * </ul> - * As an alternative to building a <code>BidiTransformer</code>, - * a subclass of <code>TransformationWritablePropertyValueModel</code> can - * override the <code>transform_(Object)</code> and - * <code>reverseTransform_(Object)</code> methods; or, - * if something other than null should be returned when the wrapped value - * is null or the new value is null, override the <code>transform(Object)</code> - * and <code>reverseTransform(Object)</code> methods. - */ -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 - * <code>transform_(Object)</code> and <code>reverseTransform_(Object)</code> - * (or <code>transform(Object)</code> and <code>reverseTransform(Object)</code>) - * methods instead of building a <code>BidiTransformer</code>. - */ - 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.valueHolder().setValue(this.reverseTransform(value)); - } - - - // ********** behavior ********** - - /** - * "Reverse-transform" the specified value and return the result. - * This is called by #setValue(Object). - */ - protected T1 reverseTransform(T2 value) { - return this.transformer().reverseTransform(value); - } - - /** - * "Reverse-transform" the specified, non-null, value and return the result. - */ - protected T1 reverseTransform_(T2 value) { - throw new UnsupportedOperationException(); - } - - - // ********** queries ********** - - /** - * Our constructors accept only a WritablePropertyValueModel<T1>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T1> valueHolder() { - return (WritablePropertyValueModel<T1>) this.valueHolder; - } - - /** - * Our constructors accept only a bidirectional transformer. - */ - protected BidiTransformer<T1, T2> transformer() { - return (BidiTransformer<T1, T2>) this.transformer; - } - - - // ********** default bidi transformer ********** - - /** - * The default bidi 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 #transform_(Object). - * The default bidi transformer will also return null if the new value is null. - * If the new value is not null, it is reverse-transformed by a subclass - * implementation of #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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java deleted file mode 100644 index ad131da203..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.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.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; - -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * This extension of PropertyAdapter provides TreeChange support. - * This allows us to convert a set of one or more trees into - * a single tree, NODES. - * - * The typical subclass will override the following methods: - * #nodes_() - * 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 - * #nodes() is overridden and its behavior changed - * #nodes() - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - */ -public abstract class TreeAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements TreeValueModel<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 aspect. */ - protected final TreeChangeListener treeChangeListener; - - - // ********** constructors ********** - - /** - * Construct a TreeAspectAdapter for the specified subject - * and tree. - */ - protected TreeAspectAdapter(String treeName, S subject) { - this(new String[] {treeName}, subject); - } - - /** - * Construct a TreeAspectAdapter for the specified subject - * and trees. - */ - protected TreeAspectAdapter(String[] treeNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), treeNames); - } - - /** - * Construct a TreeAspectAdapter 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 TreeAspectAdapter 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 TreeAspectAdapter 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 ********** - - /** - * The subject's tree aspect has changed, notify the listeners. - */ - protected TreeChangeListener buildTreeChangeListener() { - // transform the subject's tree change events into VALUE tree change events - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - TreeAspectAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeChangeEvent event) { - TreeAspectAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeChangeEvent 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); - } - }; - } - - - // ********** 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 that the subject is not null. - * @see #nodes() - */ - protected Iterator<E> nodes_() { - throw new UnsupportedOperationException(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.nodes(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return TreeChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return NODES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyTreeChangeListeners(NODES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireTreeChanged(NODES); - } - - @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); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.treeNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.treeNames[i]); - } - } - - - // ********** behavior ********** - - protected void nodeAdded(TreeChangeEvent event) { - this.fireNodeAdded(NODES, event.getPath()); - } - - protected void nodeRemoved(TreeChangeEvent event) { - this.fireNodeRemoved(NODES, event.getPath()); - } - - protected void treeCleared(TreeChangeEvent event) { - this.fireTreeCleared(NODES); - } - - protected void treeChanged(TreeChangeEvent event) { - this.fireTreeChanged(NODES, event.getPath()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java deleted file mode 100644 index 11b6f1a2b9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.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. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current collection value - * - * Subclasses might want to override: - * - #stateChanged(StateChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class TreePropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<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(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "tree change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the tree holder. - */ - @Override - protected void engageModel_() { - this.treeHolder.addTreeChangeListener(this.treeChangeListener); - } - - /** - * Stop listening to the tree holder. - */ - @Override - protected void disengageModel_() { - this.treeHolder.removeTreeChangeListener(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(TreeChangeEvent 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(TreeChangeEvent 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(TreeChangeEvent 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(TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java deleted file mode 100644 index d47c50f4a2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java +++ /dev/null @@ -1,163 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Abstract model that provides behavior for wrapping a property - * value model and listening for changes to aspects of the *value* contained - * by the property value model. Changes to the actual value are also monitored. - * - * 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. - * - * NB: Clients will need to listen for two different change notifications: a property - * change event will be be fired when the value changes; a state change event - * will be fired when an aspect of the value changes. - * - * Subclasses need to override two methods: - * - * #engageValue_() - * begin listening to the appropriate aspect of the value and call - * #valueAspectChanged(Object) whenever the aspect changes - * - * #disengageValue_() - * stop listening to the appropriate aspect of the value - */ -public abstract class ValueAspectAdapter<T> - extends PropertyValueModelWrapper<T> - implements WritablePropertyValueModel<T> -{ - /** Cache the value so we can disengage. */ - protected T value; - - - // ********** constructors/initialization ********** - - /** - * Constructor - the value holder is required. - */ - protected ValueAspectAdapter(WritablePropertyValueModel<T> valueHolder) { - super(valueHolder); - } - - @Override - protected void initialize() { - super.initialize(); - this.value = null; - } - - /** - * Override to allow both property value model change and state change - * listeners. - */ - @Override - protected ChangeSupport buildChangeSupport() { - return new ChangeSupport(this); - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - this.valueHolder().setValue(value); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - this.disengageValue(); - this.engageValue(); - this.firePropertyChanged(event.cloneWithSource(this)); - } - - - // ********** extend change support ********** - - @Override - public synchronized void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoStateChangeListeners()) { - this.engageValue(); - } - super.addStateChangeListener(listener); - } - - @Override - public synchronized void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoStateChangeListeners()) { - this.disengageValue(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the current value. - */ - protected void engageValue() { - this.value = this.valueHolder.getValue(); - if (this.value != null) { - this.engageValue_(); - } - } - - /** - * Start listening to the current value. - * At this point we can be sure that the value is not null. - */ - protected abstract void engageValue_(); - - /** - * Stop listening to the current value. - */ - protected void disengageValue() { - if (this.value != null) { - this.disengageValue_(); - this.value = null; - } - } - - /** - * Stop listening to the current value. - * At this point we can be sure that 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 constructors accept only a WritablePropertyValueModel<T1>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java deleted file mode 100644 index 2cdb74ea34..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java +++ /dev/null @@ -1,87 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more collection - * aspects of the value in the wrapped value model. - */ -public class ValueCollectionAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - - /** 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<T> valueHolder, String... collectionNames) { - super(valueHolder); - this.collectionNames = collectionNames; - this.valueCollectionListener = this.buildValueCollectionListener(); - } - - - // ********** 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 buildValueCollectionListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void itemsRemoved(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void collectionCleared(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void collectionChanged(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value collection listener: " + Arrays.asList(ValueCollectionAdapter.this.collectionNames); - } - }; - } - - @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); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java deleted file mode 100644 index 224d100319..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java +++ /dev/null @@ -1,93 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more list - * aspects of the value in the wrapped value model. - */ -public class ValueListAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - - /** 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<T> valueHolder, String... listNames) { - super(valueHolder); - this.listNames = listNames; - this.valueListListener = this.buildValueListListener(); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a List aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected ListChangeListener buildValueListListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsRemoved(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsReplaced(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsMoved(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void listCleared(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void listChanged(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value list listener: " + Arrays.asList(ValueListAdapter.this.listNames); - } - }; - } - - @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); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java deleted file mode 100644 index 0c40e891cc..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java +++ /dev/null @@ -1,76 +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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more - * properties of the value in the wrapped value model. - */ -public class ValuePropertyAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** The names of the value's properties that 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<T> 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.valueAspectChanged(); - } - @Override - public String toString() { - return "value property listener: " + Arrays.asList(ValuePropertyAdapter.this.propertyNames); - } - }; - } - - - // ********** behavior ********** - - @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); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java deleted file mode 100644 index d516fdbf1b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java +++ /dev/null @@ -1,66 +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.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to the - * "state" of the value in the wrapped value model. - */ -public class ValueStateAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** Listener that listens to value. */ - protected final StateChangeListener valueStateListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the value state. - */ - public ValueStateAdapter(WritablePropertyValueModel<T> valueHolder) { - super(valueHolder); - this.valueStateListener = this.buildValueStateListener(); - } - - - // ********** initialization ********** - - protected StateChangeListener buildValueStateListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ValueStateAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value state listener"; - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageValue_() { - this.value.addStateChangeListener(this.valueStateListener); - } - - @Override - protected void disengageValue_() { - this.value.removeStateChangeListener(this.valueStateListener); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java deleted file mode 100644 index b1c9c53f54..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.utility.internal.model.value; - -import java.util.Arrays; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more - * tree aspects of the value in the wrapped value model. - */ -public class ValueTreeAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** 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<T> valueHolder, String... treeNames) { - super(valueHolder); - this.treeNames = treeNames; - this.valueTreeListener = this.buildValueTreeListener(); - } - - - // ********** initialization ********** - - protected TreeChangeListener buildValueTreeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void nodeRemoved(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void treeCleared(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void treeChanged(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value tree listener: " + Arrays.asList(ValueTreeAdapter.this.treeNames); - } - }; - } - - - // ********** behavior ********** - - @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); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java deleted file mode 100644 index c6cca7232a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java +++ /dev/null @@ -1,346 +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.utility.internal.model.value.prefs; - -import java.util.prefs.PreferenceChangeEvent; -import java.util.prefs.PreferenceChangeListener; -import java.util.prefs.Preferences; - -import org.eclipse.jpt.utility.internal.BidiStringConverter; -import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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, - new Integer(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"; - } - }; - } - - - // ********** 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.fireAspectChange(old, value); - - if ((this.subject != null) && this.shouldSetPreference(old, value)) { - this.setValue_(value); - } - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - @Override - protected void engageSubject_() { - this.subject.addPreferenceChangeListener(this.preferenceChangeListener); - this.value = this.buildValue(); - } - - @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.")) { - // 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(" => "); - 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 shouldSetPreference(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, 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.fireAspectChange(old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java deleted file mode 100644 index c4cef6640f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java +++ /dev/null @@ -1,201 +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.utility.internal.model.value.prefs; - -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.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - - // ********** 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 ChangeListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUES); - } - - @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.")) { - // 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java deleted file mode 100644 index 0e464155f5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java +++ /dev/null @@ -1,217 +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.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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/CheckBoxModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/CheckBoxModelAdapter.java deleted file mode 100644 index 126cbfa561..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/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.utility.internal.model.value.swing; - -import org.eclipse.jpt.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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ColumnAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ColumnAdapter.java deleted file mode 100644 index 482b5d2468..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/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.utility.internal.model.value.swing; - -import org.eclipse.jpt.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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java deleted file mode 100644 index b6f30cda1d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java +++ /dev/null @@ -1,141 +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.utility.internal.model.value.swing; - -import javax.swing.ComboBoxModel; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - - // ********** 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); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java deleted file mode 100644 index 8d0256b4da..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java +++ /dev/null @@ -1,200 +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.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.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java deleted file mode 100644 index 50f04d9c97..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java +++ /dev/null @@ -1,364 +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.utility.internal.model.value.swing; - -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.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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 final PropertyChangeListener stringListener; - - /** The event listener list for the document. */ - protected final EventListenerList listenerList = new EventListenerList(); - - - // ********** 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"; - } - }; - } - - 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); - } - - -// ********** inner class ********** - - protected interface CombinedListener extends DocumentListener, UndoableEditListener { - // just consolidate the two interfaces - } - - protected class InternalListener implements CombinedListener { - 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java deleted file mode 100644 index e4ad741c12..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java +++ /dev/null @@ -1,287 +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.utility.internal.model.value.swing; - -import javax.swing.AbstractListModel; -import javax.swing.event.ListDataListener; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.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(ListChangeEvent event) { - ListModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListModelAdapter.this.listCleared(); - } - public void listChanged(ListChangeEvent event) { - ListModelAdapter.this.listChanged(); - } - @Override - public String toString() { - return "list listener"; - } - }; - } - - - // ********** 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") - 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(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireIntervalAdded(this, start, end); - this.listSize += event.itemsSize(); - } - - /** - * Items were removed from the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsRemoved(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireIntervalRemoved(this, start, end); - this.listSize -= event.itemsSize(); - } - - /** - * Items were replaced in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsReplaced(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireContentsChanged(this, start, end); - } - - /** - * Items were moved in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsMoved(ListChangeEvent event) { - int start = Math.min(event.getSourceIndex(), event.getTargetIndex()); - int end = Math.max(event.getSourceIndex(), event.getTargetIndex()) + event.getMoveLength() - 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java deleted file mode 100644 index d8ee7b4220..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java +++ /dev/null @@ -1,220 +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.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.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java deleted file mode 100644 index 3188aa4bfc..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java +++ /dev/null @@ -1,224 +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.utility.internal.model.value.swing; - -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeListener; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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, new Integer(1), new Integer(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, new Integer(minimum), new Integer(maximum), new Integer(stepSize), new Integer(defaultValue)); - } - - /** - * Constructor - the number holder is required. - * Use the minimum value as the default spinner value. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double value, double minimum, double maximum, double stepSize) { - this(numberHolder, value, minimum, maximum, stepSize, minimum); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double value, double minimum, double maximum, double stepSize, double defaultValue) { - this(numberHolder, new Double(minimum), new Double(maximum), new Double(stepSize), new Double(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"; - } - }; - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java deleted file mode 100644 index 61d2e3701f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java +++ /dev/null @@ -1,427 +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.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.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"; - } - }; - } - - /** - * 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(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) == object) { - return i; - } - } - return -1; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java deleted file mode 100644 index 2eb4b4dd0f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java +++ /dev/null @@ -1,235 +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.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -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.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.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(ListChangeEvent event) { - int i = event.getIndex(); - for (ListIterator<?> stream = event.items(); stream.hasNext(); ) { - PrimitiveListTreeModel.this.insertPrimitive(i++, stream.next()); - } - } - - public void itemsRemoved(ListChangeEvent event) { - for (int i = 0; i < event.itemsSize(); i++) { - PrimitiveListTreeModel.this.removeNode(event.getIndex()); - } - } - - public void itemsReplaced(ListChangeEvent event) { - int i = event.getIndex(); - for (ListIterator<?> stream = event.items(); stream.hasNext(); ) { - PrimitiveListTreeModel.this.replacePrimitive(i++, stream.next()); - } - } - - public void itemsMoved(ListChangeEvent event) { - ArrayList<MutableTreeNode> temp = new ArrayList<MutableTreeNode>(event.getMoveLength()); - for (int i = 0; i < event.getMoveLength(); i++) { - temp.add(PrimitiveListTreeModel.this.removeNode(event.getSourceIndex())); - } - int i = event.getTargetIndex(); - for (MutableTreeNode node : temp) { - PrimitiveListTreeModel.this.insertPrimitive(i++, node); - } - } - - public void listCleared(ListChangeEvent event) { - PrimitiveListTreeModel.this.clearList(); - } - - public void listChanged(ListChangeEvent event) { - PrimitiveListTreeModel.this.synchronizeList(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java deleted file mode 100644 index 1caee488c8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java +++ /dev/null @@ -1,151 +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.utility.internal.model.value.swing; - -import org.eclipse.jpt.utility.internal.BidiFilter; -import org.eclipse.jpt.utility.internal.BidiTransformer; -import org.eclipse.jpt.utility.internal.model.value.FilteringWritablePropertyValueModel; -import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel; -import org.eclipse.jpt.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 == 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 == 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java deleted file mode 100644 index 6cd893d878..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java +++ /dev/null @@ -1,208 +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.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.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - /** - * 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"; - } - }; - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java deleted file mode 100644 index 8196118331..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java +++ /dev/null @@ -1,412 +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.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.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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(ListChangeEvent event) { - TableModelAdapter.this.addRows(event.getIndex(), event.itemsSize(), this.items(event)); - } - public void itemsRemoved(ListChangeEvent event) { - TableModelAdapter.this.removeRows(event.getIndex(), event.itemsSize()); - } - public void itemsReplaced(ListChangeEvent event) { - TableModelAdapter.this.replaceRows(event.getIndex(), this.items(event)); - } - public void itemsMoved(ListChangeEvent event) { - TableModelAdapter.this.moveRows(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength()); - } - public void listCleared(ListChangeEvent event) { - TableModelAdapter.this.clearTable(); - } - public void listChanged(ListChangeEvent event) { - TableModelAdapter.this.rebuildTable(); - } - /** - * minimize scope of suppressed warnings - */ - @SuppressWarnings("unchecked") - protected Iterator<Object> items(ListChangeEvent event) { - return (Iterator<Object>) event.items(); - } - @Override - public String toString() { - return "list listener"; - } - }; - } - - - 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"; - } - }; - } - - - // ********** 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, Iterator<Object> items) { - List<WritablePropertyValueModel<Object>[]> newRows = new ArrayList<WritablePropertyValueModel<Object>[]>(size); - while (items.hasNext()) { - WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(items.next()); - 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, Iterator<Object> items) { - int i = index; - while (items.hasNext()) { - WritablePropertyValueModel<Object>[] row = this.rows.get(i); - this.disengageRow(row); - row = this.columnAdapter.cellModels(items.next()); - 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java deleted file mode 100644 index 4673babc36..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java +++ /dev/null @@ -1,226 +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.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.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - - // ********** 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/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java deleted file mode 100644 index 0d3ea8a683..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java +++ /dev/null @@ -1,724 +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.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; - -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreePath; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTStateChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.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"; - } - }; - } - - 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"; - } - }; - } - - 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"; - } - }; - } - - protected ListChangeListener buildChildrenListener() { - return new AWTListChangeListenerWrapper(this.buildChildrenListener_()); - } - - protected ListChangeListener buildChildrenListener_() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - new EventChangePolicy(event).addChildren(); - } - public void itemsRemoved(ListChangeEvent event) { - new EventChangePolicy(event).removeChildren(); - } - public void itemsReplaced(ListChangeEvent event) { - new EventChangePolicy(event).replaceChildren(); - } - public void itemsMoved(ListChangeEvent event) { - new EventChangePolicy(event).moveChildren(); - } - public void listCleared(ListChangeEvent event) { - new EventChangePolicy(event).clearChildren(); - } - public void listChanged(ListChangeEvent event) { - new EventChangePolicy(event).rebuildChildren(); - } - @Override - public String toString() { - return "children listener"; - } - }; - } - - - // ********** 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, node.childrenModel()); - } - - /** - * Remove the specified node from our internal tree. - */ - private void removeNodeFromInternalTree(TreeNodeValueModel<T> parent, int index, TreeNodeValueModel<T> node, 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. - */ - private 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.children(), 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(Iterator<TreeNodeValueModel<T>> stream, int size) { - @SuppressWarnings("unchecked") - TreeNodeValueModel<T>[] array = new TreeNodeValueModel[size]; - for (int i = 0; stream.hasNext(); i++) { - array[i] = stream.next(); - } - 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 an interator on the current set of children. - */ - abstract Iterator<TreeNodeValueModel<T>> children(); - - } - - - /** - * Wraps a ListChangeEvent for adding, removing, replacing, - * and changing children. - */ - private class EventChangePolicy extends ChangePolicy { - private ListChangeEvent event; - - EventChangePolicy(ListChangeEvent event) { - this.event = event; - } - - /** - * Map the ListChangeEvent's source to the corresponding parent. - */ - @Override - TreeNodeValueModel<T> parent() { - return TreeModelAdapter.this.parents.get(this.event.getSource()); - } - - /** - * The ListChangeEvent's item index is the children start index. - */ - @Override - int childrenStartIndex() { - return this.event.getIndex(); - } - - /** - * The ListChangeEvent's size is the children size. - */ - @Override - int childrenSize() { - return this.event.itemsSize(); - } - - /** - * The ListChangeEvent's items are the children. - */ - @Override - @SuppressWarnings("unchecked") - Iterator<TreeNodeValueModel<T>> children() { - return (Iterator<TreeNodeValueModel<T>>) this.event.items(); - } - - /** - * 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.replacedChildren()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, this.childArray()); - } - - /** - * Remove the old nodes and add the new ones. - */ - void moveChildren() { - TreeModelAdapter.this.moveChildren(this.parent(), this.event.getTargetIndex(), this.event.getSourceIndex(), this.event.getMoveLength()); - } - - /** - * 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.iterator(), childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - } - - /** - * 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.iterator(), childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - - childIndices = this.buildIndices(parent.childrenModel().size()); - childArray = this.buildArray(parent.childrenModel().iterator(), parent.childrenSize()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, childArray); - } - - /** - * The ListChangeEvent's replaced items are the replaced children. - */ - @SuppressWarnings("unchecked") - TreeNodeValueModel<T>[] replacedChildren() { - return this.buildArray((Iterator<TreeNodeValueModel<T>>) this.event.replacedItems(), this.event.itemsSize()); - } - - } - - - /** - * Wraps a TreeNodeValueModel for adding and removing its children. - */ - private class NodeChangePolicy extends ChangePolicy { - private TreeNodeValueModel<T> node; - - NodeChangePolicy(TreeNodeValueModel<T> node) { - 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 - Iterator<TreeNodeValueModel<T>> children() { - return this.node.childrenModel().iterator(); - } - - } - -} |