diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java')
-rw-r--r-- | jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java | 407 |
1 files changed, 0 insertions, 407 deletions
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(); - } - -} |