diff options
author | bvosburgh | 2007-12-04 04:53:15 +0000 |
---|---|---|
committer | bvosburgh | 2007-12-04 04:53:15 +0000 |
commit | 4a641379db22fa4d6a59403bc298ec4921cd333c (patch) | |
tree | 79d9f69afc68c48a8c99d64db3434573efa23f8a | |
parent | 185c777d6f346b9e791666d9605d20acdf569c7c (diff) | |
download | webtools.dali-4a641379db22fa4d6a59403bc298ec4921cd333c.tar.gz webtools.dali-4a641379db22fa4d6a59403bc298ec4921cd333c.tar.xz webtools.dali-4a641379db22fa4d6a59403bc298ec4921cd333c.zip |
[201159] model rework: changed value models to allow filter, prefix/suffix, transformer to be changed
4 files changed, 104 insertions, 82 deletions
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 index 95c9188a8f..da5a33401f 100644 --- 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 @@ -15,6 +15,7 @@ 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.CompositeListIterator; import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent; @@ -22,7 +23,7 @@ import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent; /** * 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. */ @@ -30,10 +31,10 @@ public class ExtendedListValueModelWrapper extends ListValueModelWrapper { /** the items "prepended" to the wrapped list */ - protected final List prefix; + protected List prefix; /** the items "appended" to the wrapped list */ - protected final List suffix; + protected List suffix; // ********** lots o' constructors ********** @@ -51,42 +52,54 @@ public class ExtendedListValueModelWrapper * Extend the specified list with a prefix and suffix. */ public ExtendedListValueModelWrapper(Object prefix, ListValueModel listHolder, Object suffix) { - this(Collections.singletonList(prefix), listHolder, Collections.singletonList(suffix)); + super(listHolder); + this.prefix = Collections.singletonList(prefix); + this.suffix = Collections.singletonList(suffix); } /** * Extend the specified list with a prefix. */ public ExtendedListValueModelWrapper(List prefix, ListValueModel listHolder) { - this(prefix, listHolder, Collections.EMPTY_LIST); + super(listHolder); + this.prefix = new ArrayList(prefix); + this.suffix = Collections.EMPTY_LIST; } /** * Extend the specified list with a prefix. */ public ExtendedListValueModelWrapper(Object prefix, ListValueModel listHolder) { - this(Collections.singletonList(prefix), listHolder, Collections.EMPTY_LIST); + super(listHolder); + this.prefix = Collections.singletonList(prefix); + this.suffix = Collections.EMPTY_LIST; } /** * Extend the specified list with a suffix. */ public ExtendedListValueModelWrapper(ListValueModel listHolder, List suffix) { - this(Collections.EMPTY_LIST, listHolder, suffix); + super(listHolder); + this.prefix = Collections.EMPTY_LIST; + this.suffix = new ArrayList(suffix); } /** * Extend the specified list with a suffix. */ public ExtendedListValueModelWrapper(ListValueModel listHolder, Object suffix) { - this(Collections.EMPTY_LIST, listHolder, Collections.singletonList(suffix)); + super(listHolder); + this.prefix = Collections.EMPTY_LIST; + this.suffix = Collections.singletonList(suffix); } /** * Extend the specified list with a prefix containing a single null item. */ public ExtendedListValueModelWrapper(ListValueModel listHolder) { - this(Collections.singletonList(null), listHolder, Collections.EMPTY_LIST); + super(listHolder); + this.prefix = Collections.singletonList(null); + this.suffix = Collections.EMPTY_LIST; } @@ -107,6 +120,7 @@ public class ExtendedListValueModelWrapper ); } + @Override public Object get(int index) { int prefixSize = this.prefix.size(); if (index < prefixSize) { @@ -118,12 +132,22 @@ public class ExtendedListValueModelWrapper } } + @Override public int size() { return this.prefix.size() + this.listHolder.size() + this.suffix.size(); } + @Override + public Object[] toArray() { + ArrayList list = new ArrayList(this.size()); + list.addAll(this.prefix); + CollectionTools.addAll(list, this.listHolder.iterator()); + list.addAll(this.suffix); + return list.toArray(); + } + - // ********** ListValueModelWrapper implementation ********** + // ********** ListValueModelWrapper implementation/overrides ********** @Override protected void itemsAdded(ListChangeEvent e) { @@ -155,9 +179,6 @@ public class ExtendedListValueModelWrapper this.fireListChanged(LIST_VALUES); } - - // ********** AbstractModel implementation ********** - @Override public void toString(StringBuilder sb) { sb.append(this.prefix); @@ -167,4 +188,17 @@ public class ExtendedListValueModelWrapper sb.append(this.suffix); } + + // ********** miscellaneous ********** + + public void setPrefix(List prefix) { + this.prefix = prefix; + this.fireListChanged(LIST_VALUES); + } + + public void setSuffix(List 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 index 1792ffdf7f..fadfcaf6ae 100644 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java +++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java @@ -16,17 +16,18 @@ import java.util.Iterator; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.Filter; import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent; /** * 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>value()</code>. + * to <code>#iterator()</code>. * <p> - * As an alternative to building a <code>Filter</code>, a subclass - * of <code>FilteringCollectionValueModel</code> can override the - * <code>accept(Object)</code> method. + * 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 @@ -43,10 +44,7 @@ public class FilteringCollectionValueModel extends CollectionValueModelWrapper { /** This filters the items in the nested collection. */ - private final Filter filter; - - /** This filters the items in the nested collection. */ - private final Filter localFilter; + private Filter filter; /** Cache the items that were accepted by the filter */ private final Collection filteredItems; @@ -56,13 +54,10 @@ public class FilteringCollectionValueModel /** * Construct a collection value model with the specified wrapped - * collection 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>. + * collection value model and a filter that simply accepts every object. */ public FilteringCollectionValueModel(CollectionValueModel collectionHolder) { - this(collectionHolder, Filter.Disabled.instance()); + this(collectionHolder, Filter.Null.instance()); } /** @@ -72,16 +67,12 @@ public class FilteringCollectionValueModel public FilteringCollectionValueModel(CollectionValueModel collectionHolder, Filter filter) { super(collectionHolder); this.filter = filter; - this.localFilter = this.buildLocalFilter(); this.filteredItems = new ArrayList(); } /** * Construct a collection value model with the specified wrapped * list value model and a filter that simply accepts every object. - * Use this constructor if you want to override the - * <code>accept(Object)</code> method - * instead of building a <code>Filter</code>. */ public FilteringCollectionValueModel(ListValueModel listHolder) { this(new ListCollectionValueModelAdapter(listHolder)); @@ -96,26 +87,10 @@ public class FilteringCollectionValueModel } - // ********** initialization ********** - - /** - * Implement the filter by calling back to the collection - * value model. This allows us to keep the method - * #accept(Object) protected. - */ - protected Filter buildLocalFilter() { - return new Filter() { - public boolean accept(Object o) { - return FilteringCollectionValueModel.this.accept(o); - } - }; - } - - // ********** CollectionValueModel implementation ********** public Iterator iterator() { - return this.filteredItems.iterator(); + return new ReadOnlyIterator(this.filteredItems); } public int size() { @@ -130,7 +105,7 @@ public class FilteringCollectionValueModel super.engageModel(); // synch our cache *after* we start listening to the nested collection, // since its value might change when a listener is added - this.synchFilteredItems(); + CollectionTools.addAll(this.filteredItems, this.filter(this.collectionHolder.iterator())); } @Override @@ -161,42 +136,34 @@ public class FilteringCollectionValueModel @Override protected void collectionChanged(CollectionChangeEvent e) { - this.synchFilteredItems(); - this.fireCollectionChanged(VALUES); + this.rebuildFilteredItems(); } - // ********** queries ********** + // ********** miscellaneous ********** /** - * Return whether the <code>FilteringCollectionValueModel</code> should - * include the specified value in the iterator returned from a call to the - * <code>value()</code> method; the value came - * from the nested collection value model. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Filter</code>. + * Change the filter and rebuild the collection. */ - protected boolean accept(Object value) { - return this.filter.accept(value); + public void setFilter(Filter filter) { + this.filter = filter; + this.rebuildFilteredItems(); } /** * Return an iterator that filters the specified iterator. */ protected Iterator filter(Iterator items) { - return new FilteringIterator(items, this.localFilter); + return new FilteringIterator(items, this.filter); } - - // ********** behavior ********** - /** * Synchronize our cache with the wrapped collection. */ - protected void synchFilteredItems() { + 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/SortedListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java index f9591da839..449cc1e62f 100644 --- 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 @@ -19,18 +19,19 @@ import org.eclipse.jpt.utility.internal.Range; import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent; /** - * An adapter that allows us to make a CollectionValueModel - * (or ListValueModel) behave like a read-only 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. #size(), getItem(int)) will be unpredictable whenever + * (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. */ 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 index d44d381a6e..60f464fd4f 100644 --- 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 @@ -24,15 +24,14 @@ import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent; * ListValueModel. It will keep its contents in synch with * the contents of the wrapped ListValueModel and notifies its * listeners of any changes. - * - * To use, supply a <code>Transformer</code> or subclass - * <code>TransformationListValueModelAdapter</code> - * and override the <code>transformItem(Object)</code> method. - * + * <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 + * (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. */ @@ -41,7 +40,7 @@ public class TransformationListValueModelAdapter { /** This transforms the items, unless the subclass overrides #transformItem(Object). */ - protected final Transformer transformer; + protected Transformer transformer; /** The list of transformed items. */ protected final List transformedList; @@ -62,7 +61,7 @@ public class TransformationListValueModelAdapter * Constructor - the list holder is required. */ public TransformationListValueModelAdapter(ListValueModel listHolder) { - this(listHolder, Transformer.Disabled.instance()); + this(listHolder, Transformer.Null.instance()); } /** @@ -76,7 +75,7 @@ public class TransformationListValueModelAdapter * Constructor - the collection holder is required. */ public TransformationListValueModelAdapter(CollectionValueModel collectionHolder) { - this(collectionHolder, Transformer.Disabled.instance()); + this(new CollectionListValueModelAdapter(collectionHolder)); } @@ -87,14 +86,20 @@ public class TransformationListValueModelAdapter return new ReadOnlyListIterator(this.transformedList); } + @Override public Object get(int index) { return this.transformedList.get(index); } + @Override public int size() { return this.transformedList.size(); } + @Override + public Object[] toArray() { + return this.transformedList.toArray(); + } // ********** behavior ********** @@ -152,6 +157,23 @@ public class TransformationListValueModelAdapter return this.transformer.transform(item); } + /** + * Change the transformer and rebuild the collection. + */ + public void setTransformer(Transformer 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 ********** @@ -210,9 +232,7 @@ public class TransformationListValueModelAdapter */ @Override protected void listChanged(ListChangeEvent e) { - this.transformedList.clear(); - this.transformedList.addAll(this.transformItems(this.listHolder)); - this.fireListChanged(LIST_VALUES); + this.rebuildTransformedList(); } } |