Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 160266 Details for
Bug 300043
[DataBinding] Need better support for binding collections of complex types
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Add IListReducer, IListProperty.reduce implementations to Ovidio's patch
clipboard.txt (text/plain), 39.03 KB, created by
Matthew Hall
on 2010-02-26 01:03:33 EST
(
hide
)
Description:
Add IListReducer, IListProperty.reduce implementations to Ovidio's patch
Filename:
MIME Type:
Creator:
Matthew Hall
Created:
2010-02-26 01:03:33 EST
Size:
39.03 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.core.databinding.observable >Index: src/org/eclipse/core/databinding/observable/masterdetail/MasterDetailObservables.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/masterdetail/MasterDetailObservables.java,v >retrieving revision 1.10 >diff -u -r1.10 MasterDetailObservables.java >--- src/org/eclipse/core/databinding/observable/masterdetail/MasterDetailObservables.java 17 Oct 2008 16:44:25 -0000 1.10 >+++ src/org/eclipse/core/databinding/observable/masterdetail/MasterDetailObservables.java 26 Feb 2010 06:01:38 -0000 >@@ -9,6 +9,7 @@ > * IBM Corporation - initial API and implementation > * Brad Reynolds - bug 147515 > * Matthew Hall - bug 221704, 226289 >+ * Ovidio Mallo - bug 300043 > *******************************************************************************/ > > package org.eclipse.core.databinding.observable.masterdetail; >@@ -21,6 +22,8 @@ > import org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableMap; > import org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableSet; > import org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue; >+import org.eclipse.core.internal.databinding.observable.masterdetail.ListDetailValueObservableList; >+import org.eclipse.core.internal.databinding.observable.masterdetail.SetDetailValueObservableMap; > > /** > * Allows for the observation of an attribute, the detail, of an observable >@@ -29,7 +32,7 @@ > * @since 1.0 > */ > public class MasterDetailObservables { >- >+ > /** > * Creates a detail observable value from a master observable value and a > * factory. This can be used to create observable values that represent a >@@ -145,4 +148,58 @@ > return new DetailObservableMap(detailFactory, master, detailKeyType, > detailValueType); > } >+ >+ /** >+ * Creates an unmodifiable observable list of detail values from an >+ * observable list of observable values. For every master value in the given >+ * list, the provided factory is used to create the corresponding detail >+ * observable value. This can e.g. be used to create a list of values that >+ * represent the same property of a set of selected objects in a table. >+ * >+ * @param masterList >+ * the list of master values to track >+ * @param detailFactory >+ * a factory for creating {@link IObservableValue} instances >+ * given a current value of one of the masters >+ * @param detailType >+ * the value type of the detail values, typically of type >+ * java.lang.Class and can be <code>null</code> >+ * @return a list of detail values of the given value type that, for any >+ * current value of any of the master values, behaves like the >+ * observable value created by the factory for that current value. >+ * >+ * @since 1.3 >+ */ >+ public static IObservableList detailListValues(IObservableList masterList, >+ IObservableFactory detailFactory, Object detailType) { >+ return new ListDetailValueObservableList(masterList, detailFactory, >+ detailType); >+ } >+ >+ /** >+ * Creates an unmodifiable observable set of detail values from an >+ * observable set of observable values. For every master value in the given >+ * set, the provided factory is used to create the corresponding detail >+ * observable value. This can e.g. be used to create a list of values that >+ * represent the same property of a set of selected objects in a table. >+ * >+ * @param masterSet >+ * the set of master values to track >+ * @param detailFactory >+ * a factory for creating {@link IObservableValue} instances >+ * given a current value of one of the masters >+ * @param detailType >+ * the value type of the detail values, typically of type >+ * java.lang.Class and can be <code>null</code> >+ * @return a list of detail values of the given value type that, for any >+ * current value of any of the master values, behaves like the >+ * observable value created by the factory for that current value. >+ * >+ * @since 1.3 >+ */ >+ public static IObservableMap detailSetValues(IObservableSet masterSet, >+ IObservableFactory detailFactory, Object detailType) { >+ return new SetDetailValueObservableMap(masterSet, detailFactory, >+ detailType); >+ } > } >Index: src/org/eclipse/core/internal/databinding/observable/masterdetail/ListDetailValueObservableList.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/observable/masterdetail/ListDetailValueObservableList.java >diff -N src/org/eclipse/core/internal/databinding/observable/masterdetail/ListDetailValueObservableList.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/observable/masterdetail/ListDetailValueObservableList.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,241 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Ovidio Mallo and others. >+ * 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: >+ * Ovidio Mallo - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.observable.masterdetail; >+ >+import java.util.ArrayList; >+import java.util.BitSet; >+import java.util.Collections; >+import java.util.Iterator; >+import java.util.RandomAccess; >+ >+import org.eclipse.core.databinding.observable.Diffs; >+import org.eclipse.core.databinding.observable.DisposeEvent; >+import org.eclipse.core.databinding.observable.IDisposeListener; >+import org.eclipse.core.databinding.observable.IObserving; >+import org.eclipse.core.databinding.observable.IStaleListener; >+import org.eclipse.core.databinding.observable.ObservableTracker; >+import org.eclipse.core.databinding.observable.StaleEvent; >+import org.eclipse.core.databinding.observable.list.AbstractObservableList; >+import org.eclipse.core.databinding.observable.list.IListChangeListener; >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.list.ListChangeEvent; >+import org.eclipse.core.databinding.observable.list.ListDiff; >+import org.eclipse.core.databinding.observable.list.ListDiffEntry; >+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.databinding.observable.value.IValueChangeListener; >+import org.eclipse.core.databinding.observable.value.ValueChangeEvent; >+import org.eclipse.core.internal.databinding.identity.IdentitySet; >+ >+/** >+ * >+ */ >+public class ListDetailValueObservableList extends AbstractObservableList >+ implements IObserving, RandomAccess { >+ >+ private IObservableList masterList; >+ >+ private IObservableFactory detailFactory; >+ >+ private Object detailType; >+ >+ private ArrayList detailList; >+ >+ private IdentitySet staleDetailObservables = new IdentitySet(); >+ >+ private IListChangeListener masterListListener = new IListChangeListener() { >+ public void handleListChange(ListChangeEvent event) { >+ adaptMasterListDiff(event.diff); >+ } >+ }; >+ >+ private IValueChangeListener detailValueListener = new IValueChangeListener() { >+ public void handleValueChange(ValueChangeEvent event) { >+ if (!event.getObservable().isStale()) { >+ staleDetailObservables.remove(event.getObservable()); >+ } >+ handleDetailValueChange(event); >+ } >+ }; >+ >+ private IStaleListener detailStaleListener = new IStaleListener() { >+ public void handleStale(StaleEvent staleEvent) { >+ boolean wasStale = isStale(); >+ staleDetailObservables.add((staleEvent.getObservable())); >+ if (!wasStale) { >+ fireStale(); >+ } >+ } >+ }; >+ >+ /** >+ * >+ * @param masterObservableList >+ * @param detailFactory >+ * @param detailType >+ */ >+ public ListDetailValueObservableList(IObservableList masterObservableList, >+ IObservableFactory detailFactory, Object detailType) { >+ super(masterObservableList.getRealm()); >+ this.masterList = masterObservableList; >+ this.detailFactory = detailFactory; >+ this.detailType = detailType; >+ this.detailList = new ArrayList(); >+ >+ masterObservableList.addListChangeListener(masterListListener); >+ masterObservableList.addDisposeListener(new IDisposeListener() { >+ public void handleDispose(DisposeEvent event) { >+ dispose(); >+ } >+ }); >+ >+ ListDiff initMasterDiff = Diffs.computeListDiff(Collections.EMPTY_LIST, >+ masterObservableList); >+ adaptMasterListDiff(initMasterDiff); >+ } >+ >+ private void adaptMasterListDiff(ListDiff masterListDiff) { >+ boolean wasStale = isStale(); >+ >+ ListDiffEntry[] masterEntries = masterListDiff.getDifferences(); >+ ListDiffEntry[] detailEntries = new ListDiffEntry[masterEntries.length]; >+ for (int i = 0; i < masterEntries.length; i++) { >+ ListDiffEntry masterEntry = masterEntries[i]; >+ int index = masterEntry.getPosition(); >+ >+ Object detailValue; >+ if (masterEntry.isAddition()) { >+ Object masterElement = masterEntry.getElement(); >+ detailValue = addDetailObservable(masterElement, index); >+ } else { >+ detailValue = removeDetailObservable(index); >+ } >+ >+ // Create the corresponding diff for the detail list. >+ detailEntries[i] = Diffs.createListDiffEntry(index, masterEntry >+ .isAddition(), detailValue); >+ } >+ >+ if (!wasStale && isStale()) { >+ fireStale(); >+ } >+ >+ // Fire a list change event with the adapted diffs on the detail list. >+ fireListChange(Diffs.createListDiff(detailEntries)); >+ } >+ >+ private Object addDetailObservable(Object masterElement, int index) { >+ IObservableValue detail; >+ ObservableTracker.setIgnore(true); >+ try { >+ detail = (IObservableValue) detailFactory >+ .createObservable(masterElement); >+ } finally { >+ ObservableTracker.setIgnore(false); >+ } >+ >+ detailList.add(index, detail); >+ >+ detail.addValueChangeListener(detailValueListener); >+ >+ detail.addStaleListener(detailStaleListener); >+ if (detail.isStale()) { >+ staleDetailObservables.add(detail); >+ } >+ >+ return detail.getValue(); >+ } >+ >+ private Object removeDetailObservable(int index) { >+ IObservableValue detail = (IObservableValue) detailList.remove(index); >+ staleDetailObservables.remove(detail); >+ Object detailValue = detail.getValue(); >+ detail.dispose(); >+ return detailValue; >+ } >+ >+ private void handleDetailValueChange(ValueChangeEvent event) { >+ IObservableValue detail = event.getObservableValue(); >+ >+ BitSet detailIndexes = new BitSet(); >+ for (int i = 0; i < detailList.size(); i++) { >+ if (detailList.get(i) == detail) { >+ detailIndexes.set(i); >+ } >+ } >+ >+ Object oldValue = event.diff.getOldValue(); >+ Object newValue = event.diff.getNewValue(); >+ ListDiffEntry[] diffEntries = new ListDiffEntry[2 * detailIndexes >+ .cardinality()]; >+ int diffIndex = 0; >+ for (int b = 0; b != -1; b = detailIndexes.nextSetBit(b + 1)) { >+ diffEntries[diffIndex++] = Diffs.createListDiffEntry(b, false, >+ oldValue); >+ diffEntries[diffIndex++] = Diffs.createListDiffEntry(b, true, >+ newValue); >+ } >+ fireListChange(Diffs.createListDiff(diffEntries)); >+ } >+ >+ protected int doGetSize() { >+ return detailList.size(); >+ } >+ >+ public Object get(int index) { >+ ObservableTracker.getterCalled(this); >+ return ((IObservableValue) detailList.get(index)).getValue(); >+ } >+ >+ public Object set(int index, Object element) { >+ IObservableValue detail = (IObservableValue) detailList.get(index); >+ Object oldElement = detail.getValue(); >+ detail.setValue(element); >+ return oldElement; >+ } >+ >+ public Object getElementType() { >+ return detailType; >+ } >+ >+ public boolean isStale() { >+ return super.isStale() >+ || (masterList != null && masterList.isStale()) >+ || (staleDetailObservables != null && !staleDetailObservables >+ .isEmpty()); >+ } >+ >+ public Object getObserved() { >+ return masterList; >+ } >+ >+ public synchronized void dispose() { >+ if (masterList != null) { >+ masterList.removeListChangeListener(masterListListener); >+ } >+ >+ if (detailList != null) { >+ for (Iterator iter = detailList.iterator(); iter.hasNext();) { >+ ((IObservableValue) iter.next()).dispose(); >+ } >+ } >+ >+ masterList = null; >+ detailFactory = null; >+ detailType = null; >+ masterListListener = null; >+ detailValueListener = null; >+ staleDetailObservables = null; >+ >+ super.dispose(); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/observable/masterdetail/SetDetailValueObservableMap.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/observable/masterdetail/SetDetailValueObservableMap.java >diff -N src/org/eclipse/core/internal/databinding/observable/masterdetail/SetDetailValueObservableMap.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/observable/masterdetail/SetDetailValueObservableMap.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,147 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Ovidio Mallo and others. >+ * 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: >+ * Ovidio Mallo - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.observable.masterdetail; >+ >+import java.util.HashMap; >+import java.util.Map; >+ >+import org.eclipse.core.databinding.observable.IObserving; >+import org.eclipse.core.databinding.observable.IStaleListener; >+import org.eclipse.core.databinding.observable.ObservableTracker; >+import org.eclipse.core.databinding.observable.StaleEvent; >+import org.eclipse.core.databinding.observable.map.ComputedObservableMap; >+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory; >+import org.eclipse.core.databinding.observable.set.IObservableSet; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.databinding.observable.value.IValueChangeListener; >+import org.eclipse.core.databinding.observable.value.ValueChangeEvent; >+import org.eclipse.core.internal.databinding.identity.IdentitySet; >+ >+/** >+ * >+ */ >+public class SetDetailValueObservableMap extends ComputedObservableMap >+ implements IObserving { >+ >+ private IObservableFactory observableValueFactory; >+ >+ private Map detailObservableValueMap = new HashMap(); >+ >+ private IdentitySet staleDetailObservables = new IdentitySet(); >+ >+ private IStaleListener detailStaleListener = new IStaleListener() { >+ public void handleStale(StaleEvent staleEvent) { >+ addStaleDetailObservable((IObservableValue) staleEvent >+ .getObservable()); >+ } >+ }; >+ >+ /** >+ * @param masterKeySet >+ * @param observableValueFactory >+ * @param detailValueType >+ */ >+ public SetDetailValueObservableMap(IObservableSet masterKeySet, >+ IObservableFactory observableValueFactory, Object detailValueType) { >+ super(masterKeySet, detailValueType); >+ this.observableValueFactory = observableValueFactory; >+ } >+ >+ protected void hookListener(final Object addedKey) { >+ IObservableValue detailValue = getDetailObservableValue(addedKey); >+ >+ detailValue.addValueChangeListener(new IValueChangeListener() { >+ public void handleValueChange(ValueChangeEvent event) { >+ if (!event.getObservableValue().isStale()) { >+ staleDetailObservables.remove(event.getObservableValue()); >+ } >+ >+ fireSingleChange(addedKey, event.diff.getOldValue(), event.diff >+ .getNewValue()); >+ } >+ }); >+ >+ detailValue.addStaleListener(detailStaleListener); >+ } >+ >+ protected void unhookListener(Object removedKey) { >+ if (isDisposed()) { >+ return; >+ } >+ >+ IObservableValue detailValue = (IObservableValue) detailObservableValueMap >+ .remove(removedKey); >+ staleDetailObservables.remove(detailValue); >+ detailValue.dispose(); >+ } >+ >+ private IObservableValue getDetailObservableValue(Object masterKey) { >+ IObservableValue detailValue = (IObservableValue) detailObservableValueMap >+ .get(masterKey); >+ >+ if (detailValue == null) { >+ ObservableTracker.setIgnore(true); >+ try { >+ detailValue = (IObservableValue) observableValueFactory >+ .createObservable(masterKey); >+ } finally { >+ ObservableTracker.setIgnore(false); >+ } >+ >+ detailObservableValueMap.put(masterKey, detailValue); >+ >+ if (detailValue.isStale()) { >+ addStaleDetailObservable(detailValue); >+ } >+ } >+ >+ return detailValue; >+ } >+ >+ private void addStaleDetailObservable(IObservableValue detailObservable) { >+ boolean wasStale = isStale(); >+ staleDetailObservables.add(detailObservable); >+ if (!wasStale) { >+ fireStale(); >+ } >+ } >+ >+ protected Object doGet(Object key) { >+ IObservableValue detailValue = getDetailObservableValue(key); >+ return detailValue.getValue(); >+ } >+ >+ protected Object doPut(Object key, Object value) { >+ IObservableValue detailValue = getDetailObservableValue(key); >+ Object oldValue = detailValue.getValue(); >+ detailValue.setValue(value); >+ return oldValue; >+ } >+ >+ public boolean isStale() { >+ return super.isStale() || staleDetailObservables != null >+ && !staleDetailObservables.isEmpty(); >+ } >+ >+ public Object getObserved() { >+ return keySet(); >+ } >+ >+ public synchronized void dispose() { >+ super.dispose(); >+ >+ observableValueFactory = null; >+ detailObservableValueMap = null; >+ detailStaleListener = null; >+ staleDetailObservables = null; >+ } >+} >#P org.eclipse.core.databinding.property >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding.property/META-INF/MANIFEST.MF,v >retrieving revision 1.3 >diff -u -r1.3 MANIFEST.MF >--- META-INF/MANIFEST.MF 25 Aug 2009 04:57:24 -0000 1.3 >+++ META-INF/MANIFEST.MF 26 Feb 2010 06:01:39 -0000 >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.core.databinding.property >-Bundle-Version: 1.2.100.qualifier >+Bundle-Version: 1.3.0.qualifier > Bundle-ClassPath: . > Bundle-Vendor: %providerName > Bundle-Localization: plugin >Index: src/org/eclipse/core/databinding/property/list/IListProperty.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/IListProperty.java,v >retrieving revision 1.3 >diff -u -r1.3 IListProperty.java >--- src/org/eclipse/core/databinding/property/list/IListProperty.java 25 May 2009 20:52:27 -0000 1.3 >+++ src/org/eclipse/core/databinding/property/list/IListProperty.java 26 Feb 2010 06:01:39 -0000 >@@ -7,7 +7,7 @@ > * > * Contributors: > * Matthew Hall - initial API and implementation (bug 194734) >- * Matthew Hall - bug 195222 >+ * Matthew Hall - bug 195222, 300043 > ******************************************************************************/ > > package org.eclipse.core.databinding.property.list; >@@ -111,4 +111,12 @@ > * properties > */ > public IListProperty values(IValueProperty detailValue); >+ >+ /** >+ * @param reducer >+ * the strategy that reduces the list down to a value. >+ * @return a read-only reduced value from this list property >+ * @since 1.3 >+ */ >+ public IValueProperty reduce(IListReducer reducer); > } >Index: src/org/eclipse/core/databinding/property/list/IListReducer.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/property/list/IListReducer.java >diff -N src/org/eclipse/core/databinding/property/list/IListReducer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/property/list/IListReducer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,49 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Matthew Hall and others. >+ * 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: >+ * Matthew Hall - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.property.list; >+ >+import java.util.List; >+ >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+ >+/** >+ * A list-to-value reducer. List reducers may be used to condense a list >+ * property down to a value property. >+ * >+ * @since 1.3 >+ * @noimplement This interface is not intended to be implemented by clients. >+ * @see ListReducer >+ */ >+public interface IListReducer { >+ >+ /** >+ * @param list >+ * the list to reduce >+ * @return the list reduction >+ */ >+ public Object reduce(List list); >+ >+ /** >+ * @return the value type of the reduction >+ */ >+ public Object getValueType(); >+ >+ /** >+ * @param master >+ * the master list to reduce >+ * @return an IObservableValue observing the reduction of the specified >+ * IObservableList >+ */ >+ public IObservableValue observeDetail(IObservableList master); >+ >+} >Index: src/org/eclipse/core/databinding/property/list/ListProperty.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/ListProperty.java,v >retrieving revision 1.3 >diff -u -r1.3 ListProperty.java >--- src/org/eclipse/core/databinding/property/list/ListProperty.java 25 May 2009 20:52:27 -0000 1.3 >+++ src/org/eclipse/core/databinding/property/list/ListProperty.java 26 Feb 2010 06:01:40 -0000 >@@ -7,7 +7,7 @@ > * > * Contributors: > * Matthew Hall - initial API and implementation (bug 194734) >- * Matthew Hall - bug 195222 >+ * Matthew Hall - bug 195222, 300043 > ******************************************************************************/ > > package org.eclipse.core.databinding.property.list; >@@ -20,6 +20,7 @@ > import org.eclipse.core.databinding.observable.value.IObservableValue; > import org.eclipse.core.databinding.property.value.IValueProperty; > import org.eclipse.core.internal.databinding.property.ListPropertyDetailValuesList; >+import org.eclipse.core.internal.databinding.property.list.ReducedListValueProperty; > > /** > * Abstract implementation of IListProperty. >@@ -55,4 +56,11 @@ > public final IListProperty values(IValueProperty detailValue) { > return new ListPropertyDetailValuesList(this, detailValue); > } >+ >+ /** >+ * @since 1.3 >+ */ >+ public final IValueProperty reduce(IListReducer reducer) { >+ return new ReducedListValueProperty(this, reducer); >+ } > } >Index: src/org/eclipse/core/databinding/property/list/ListReducer.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/property/list/ListReducer.java >diff -N src/org/eclipse/core/databinding/property/list/ListReducer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/property/list/ListReducer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Matthew Hall and others. >+ * 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: >+ * Matthew Hall - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.property.list; >+ >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.internal.databinding.property.value.ReducedListObservableValue; >+ >+/** >+ * Abstract base implementation if {@link IListReducer}. >+ * >+ * @since 1.3 >+ */ >+public abstract class ListReducer implements IListReducer { >+ >+ private final Object valueType; >+ >+ /** >+ * Constructs a list reducer with the given value type >+ * >+ * @param valueType >+ * the reduction value type >+ */ >+ protected ListReducer(Object valueType) { >+ this.valueType = valueType; >+ } >+ >+ public Object getValueType() { >+ return valueType; >+ } >+ >+ public IObservableValue observeDetail(IObservableList master) { >+ return new ReducedListObservableValue(master, this); >+ } >+ >+} >Index: src/org/eclipse/core/databinding/property/list/ListReducers.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/property/list/ListReducers.java >diff -N src/org/eclipse/core/databinding/property/list/ListReducers.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/property/list/ListReducers.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,44 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Matthew Hall and others. >+ * 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: >+ * Matthew Hall - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.property.list; >+ >+import java.util.Iterator; >+import java.util.List; >+ >+/** >+ * Factory class for common list reducers >+ * >+ * @since 1.3 >+ */ >+public class ListReducers { >+ /** >+ * @param delimiter >+ * the delimiter between each list element >+ * @return a String-valued list reducer which concatenates all elements in >+ * the list, with the specified delimiter between each element. >+ */ >+ public static IListReducer join(final String delimiter) { >+ return new ListReducer(String.class) { >+ public Object reduce(List list) { >+ StringBuffer buf = new StringBuffer(); >+ >+ for (Iterator it = list.iterator(); it.hasNext();) { >+ buf.append(it.next()); >+ if (it.hasNext()) >+ buf.append(delimiter); >+ } >+ >+ return buf.toString(); >+ } >+ }; >+ } >+} >Index: src/org/eclipse/core/databinding/property/value/ValueProperty.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/ValueProperty.java,v >retrieving revision 1.3 >diff -u -r1.3 ValueProperty.java >--- src/org/eclipse/core/databinding/property/value/ValueProperty.java 25 May 2009 20:52:27 -0000 1.3 >+++ src/org/eclipse/core/databinding/property/value/ValueProperty.java 26 Feb 2010 06:01:41 -0000 >@@ -7,15 +7,18 @@ > * > * Contributors: > * Matthew Hall - initial API and implementation (bug 194734) >- * Matthew Hall - bug 195222 >+ * Matthew Hall - bugs 195222, 300043 > ******************************************************************************/ > > package org.eclipse.core.databinding.property.value; > > import org.eclipse.core.databinding.observable.IObservable; > import org.eclipse.core.databinding.observable.Realm; >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.map.IObservableMap; > import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory; > import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables; >+import org.eclipse.core.databinding.observable.set.IObservableSet; > import org.eclipse.core.databinding.observable.value.IObservableValue; > import org.eclipse.core.databinding.property.list.IListProperty; > import org.eclipse.core.databinding.property.map.IMapProperty; >@@ -56,6 +59,22 @@ > .getRealm()), getValueType()); > } > >+ /** >+ * @since 1.3 >+ */ >+ public IObservableList observeDetail(IObservableList master) { >+ return MasterDetailObservables.detailListValues(master, >+ valueFactory(master.getRealm()), getValueType()); >+ } >+ >+ /** >+ * @since 1.3 >+ */ >+ public IObservableMap observeDetail(IObservableSet master) { >+ return MasterDetailObservables.detailSetValues(master, >+ valueFactory(master.getRealm()), getValueType()); >+ } >+ > public final IValueProperty value(IValueProperty detailValue) { > return new ValuePropertyDetailValue(this, detailValue); > } >Index: src/org/eclipse/core/internal/databinding/property/list/ReducedListValueProperty.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/property/list/ReducedListValueProperty.java >diff -N src/org/eclipse/core/internal/databinding/property/list/ReducedListValueProperty.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/property/list/ReducedListValueProperty.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,77 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Matthew Hall and others. >+ * 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: >+ * Matthew Hall - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.property.list; >+ >+import org.eclipse.core.databinding.observable.ObservableTracker; >+import org.eclipse.core.databinding.observable.Realm; >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.map.IObservableMap; >+import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables; >+import org.eclipse.core.databinding.observable.set.IObservableSet; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.databinding.property.list.IListReducer; >+import org.eclipse.core.databinding.property.list.ListProperty; >+import org.eclipse.core.databinding.property.value.ValueProperty; >+import org.eclipse.core.internal.databinding.property.PropertyObservableUtil; >+ >+/** >+ * >+ */ >+public class ReducedListValueProperty extends ValueProperty { >+ >+ private final ListProperty masterProperty; >+ private final IListReducer reducer; >+ >+ /** >+ * @param masterProperty >+ * @param reducer >+ */ >+ public ReducedListValueProperty(ListProperty masterProperty, >+ IListReducer reducer) { >+ this.masterProperty = masterProperty; >+ this.reducer = reducer; >+ } >+ >+ public Object getValueType() { >+ return reducer.getValueType(); >+ } >+ >+ public IObservableValue observe(Realm realm, Object source) { >+ IObservableList masterList; >+ >+ ObservableTracker.setIgnore(true); >+ try { >+ masterList = masterProperty.observe(realm, source); >+ } finally { >+ ObservableTracker.setIgnore(false); >+ } >+ >+ IObservableValue detailValue = reducer.observeDetail(masterList); >+ PropertyObservableUtil.cascadeDispose(detailValue, masterList); >+ return detailValue; >+ } >+ >+ public IObservableList observeDetail(IObservableList master) { >+ return MasterDetailObservables.detailListValues(master, >+ valueFactory(master.getRealm()), getValueType()); >+ } >+ >+ public IObservableMap observeDetail(IObservableSet master) { >+ return MasterDetailObservables.detailSetValues(master, >+ valueFactory(master.getRealm()), getValueType()); >+ } >+ >+ public IObservableMap observeDetail(IObservableMap master) { >+ throw new UnsupportedOperationException(); >+ } >+ >+} >Index: src/org/eclipse/core/internal/databinding/property/value/ReducedListObservableValue.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/property/value/ReducedListObservableValue.java >diff -N src/org/eclipse/core/internal/databinding/property/value/ReducedListObservableValue.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/property/value/ReducedListObservableValue.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 Matthew Hall and others. >+ * 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: >+ * Matthew Hall - initial API and implementation (bug 300043) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.property.value; >+ >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.value.ComputedValue; >+import org.eclipse.core.databinding.property.list.IListReducer; >+ >+/** >+ * >+ */ >+public class ReducedListObservableValue extends ComputedValue { >+ >+ private IObservableList masterList; >+ private IListReducer reducer; >+ >+ /** >+ * @param masterList >+ * @param reducer >+ */ >+ public ReducedListObservableValue(IObservableList masterList, >+ IListReducer reducer) { >+ super(masterList.getRealm(), reducer.getValueType()); >+ this.masterList = masterList; >+ this.reducer = reducer; >+ } >+ >+ protected Object calculate() { >+ return reducer.reduce(masterList); >+ } >+ >+} >#P org.eclipse.jface.examples.databinding >Index: src/org/eclipse/jface/examples/databinding/snippets/Snippet025TableViewerWithPropertyDerivedColumns.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet025TableViewerWithPropertyDerivedColumns.java,v >retrieving revision 1.5 >diff -u -r1.5 Snippet025TableViewerWithPropertyDerivedColumns.java >--- src/org/eclipse/jface/examples/databinding/snippets/Snippet025TableViewerWithPropertyDerivedColumns.java 25 May 2009 20:52:49 -0000 1.5 >+++ src/org/eclipse/jface/examples/databinding/snippets/Snippet025TableViewerWithPropertyDerivedColumns.java 26 Feb 2010 06:01:42 -0000 >@@ -14,6 +14,9 @@ > > import java.beans.PropertyChangeListener; > import java.beans.PropertyChangeSupport; >+import java.util.ArrayList; >+import java.util.Arrays; >+import java.util.List; > > import org.eclipse.core.databinding.DataBindingContext; > import org.eclipse.core.databinding.beans.BeanProperties; >@@ -21,10 +24,12 @@ > import org.eclipse.core.databinding.observable.list.IObservableList; > import org.eclipse.core.databinding.observable.list.WritableList; > import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.databinding.property.list.ListReducers; >+import org.eclipse.core.databinding.property.value.IValueProperty; > import org.eclipse.jface.databinding.swt.SWTObservables; > import org.eclipse.jface.databinding.swt.WidgetProperties; >-import org.eclipse.jface.databinding.viewers.ViewerSupport; > import org.eclipse.jface.databinding.viewers.ViewerProperties; >+import org.eclipse.jface.databinding.viewers.ViewerSupport; > import org.eclipse.jface.layout.GridDataFactory; > import org.eclipse.jface.layout.GridLayoutFactory; > import org.eclipse.jface.viewers.ComboViewer; >@@ -106,11 +111,28 @@ > String name = "Donald Duck"; > Person mother; > Person father; >+ List children = new ArrayList(); > > public Person(String name, Person mother, Person father) { > this.name = name; > this.mother = mother; > this.father = father; >+ if (mother != null) { >+ mother.addChild(this); >+ } >+ if (father != null) { >+ father.addChild(this); >+ } >+ } >+ >+ private void addChild(Person person) { >+ children.add(person); >+ firePropertyChange("children", null, children); >+ } >+ >+ private void removeChild(Person person) { >+ children.remove(person); >+ firePropertyChange("children", null, children); > } > > public String getName() { >@@ -125,8 +147,18 @@ > return mother; > } > >+ public Person[] getChildren() { >+ return (Person[]) children.toArray(new Person[children.size()]); >+ } >+ > public void setMother(Person mother) { >+ if (this.mother != null) { >+ this.mother.removeChild(this); >+ } > firePropertyChange("mother", this.mother, this.mother = mother); >+ if (this.mother != null) { >+ this.mother.addChild(this); >+ } > } > > public Person getFather() { >@@ -134,7 +166,13 @@ > } > > public void setFather(Person father) { >+ if (this.father != null) { >+ this.father.removeChild(this); >+ } > firePropertyChange("father", this.father, this.father = father); >+ if (this.father != null) { >+ this.father.addChild(this); >+ } > } > } > >@@ -145,6 +183,7 @@ > // data access tier. Since this snippet doesn't have any persistent objects > // ro retrieve, this ViewModel just instantiates a model object to edit. > static class ViewModel { >+ > // The model to bind > private IObservableList people = new WritableList(); > { >@@ -197,6 +236,7 @@ > createColumn("Maternal Grandfather"); > createColumn("Paternal Grandmother"); > createColumn("Paternal Grandfather"); >+ createColumn("Children").setWidth(200); > > duckFamily.setLinesVisible(true); > >@@ -216,17 +256,18 @@ > > GridLayoutFactory.swtDefaults().numColumns(2).applyTo(shell); > // Open and return the Shell >- shell.setSize(800, 300); >+ shell.setSize(1000, 300); > shell.open(); > return shell; > } > >- private void createColumn(String string) { >+ private TableColumn createColumn(String string) { > final TableColumn column = new TableColumn(duckFamily, SWT.NONE); > column.setText(string); > column.pack(); > if (column.getWidth() < 100) > column.setWidth(100); >+ return column; > } > > protected void bindGUI(DataBindingContext dbc) { >@@ -240,10 +281,7 @@ > }); > > ViewerSupport.bind(peopleViewer, viewModel.getPeople(), >- BeanProperties.values(Person.class, new String[] { "name", >- "mother.name", "father.name", "mother.mother.name", >- "mother.father.name", "father.mother.name", >- "father.father.name" })); >+ getProperties()); > > IObservableValue masterSelection = ViewerProperties > .singleSelection().observe(peopleViewer); >@@ -269,4 +307,20 @@ > "father").observeDetail(masterSelection)); > } > } >+ >+ private static IValueProperty[] getProperties() { >+ List<IValueProperty> properties = new ArrayList<IValueProperty>(); >+ >+ // Add the "simple" properties. >+ properties.addAll(Arrays.asList(BeanProperties.values(Person.class, >+ new String[] { "name", "mother.name", "father.name", >+ "mother.mother.name", "mother.father.name", >+ "father.mother.name", "father.father.name" }))); >+ >+ // Add the "complex" property. >+ properties.add(BeanProperties.list("children").values("name").reduce( >+ ListReducers.join(", "))); >+ >+ return properties.toArray(new IValueProperty[properties.size()]); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 300043
:
156495
|
157682
|
158232
|
160266
|
161317
|
161641
|
189359