Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 262160 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/emf/databinding/EMFUpdateListStrategy.java (-57 / +101 lines)
Lines 9-86 Link Here
9
 * 
9
 * 
10
 * Contributors: 
10
 * Contributors: 
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EMFUpdateListStrategy.java,v 1.1 2007/11/16 21:25:21 emerks Exp $
15
 * $Id: EMFUpdateListStrategy.java,v 1.1 2007/11/16 21:25:21 emerks Exp $
16
 */
16
 */
17
package org.eclipse.emf.databinding;
17
package org.eclipse.emf.databinding;
18
18
19
import org.eclipse.core.databinding.Binding;
20
import org.eclipse.core.databinding.DataBindingContext;
19
import org.eclipse.core.databinding.UpdateListStrategy;
21
import org.eclipse.core.databinding.UpdateListStrategy;
20
import org.eclipse.core.databinding.conversion.Converter;
22
import org.eclipse.core.databinding.conversion.Converter;
21
import org.eclipse.core.databinding.conversion.IConverter;
23
import org.eclipse.core.databinding.conversion.IConverter;
24
import org.eclipse.core.databinding.observable.list.IObservableList;
22
import org.eclipse.emf.ecore.EAttribute;
25
import org.eclipse.emf.ecore.EAttribute;
23
import org.eclipse.emf.ecore.EDataType;
26
import org.eclipse.emf.ecore.EDataType;
24
import org.eclipse.emf.ecore.EFactory;
27
import org.eclipse.emf.ecore.EFactory;
25
28
26
/**
29
/**
27
 * PROVISIONAL
30
 * <p>
28
 * This API is subject to arbitrary change, including renaming or removal.
31
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
32
 * removal.</b>
33
 * </p>
34
 * Customizes a {@link Binding} between two {@link IObservableList observable
35
 * lists}. The following behaviors can be customized via the strategy:
36
 * <ul>
37
 * <li>Conversion</li>
38
 * <li>Automatic processing</li>
39
 * </ul>
40
 * <p>
41
 * Conversion:<br/>
42
 * When elements are added they can be {@link #convert(Object) converted} to the
43
 * destination element type.
44
 * </p>
45
 * <p>
46
 * Automatic processing:<br/>
47
 * The processing to perform when the source observable changes. This behavior
48
 * is configured via policies provided on construction of the strategy (e.g.
49
 * {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST}, {@link #POLICY_UPDATE}).
50
 * </p>
51
 * 
52
 * 
53
 * @see DataBindingContext#bindList(IObservableList, IObservableList,
54
 *      UpdateListStrategy, UpdateListStrategy)
55
 * @see IConverter
56
 * @since 1.0
29
 */
57
 */
30
public class EMFUpdateListStrategy extends UpdateListStrategy
58
public class EMFUpdateListStrategy extends UpdateListStrategy {
31
{
59
	/**
32
  public EMFUpdateListStrategy()
60
	 * Creates a new update list strategy for automatically updating the
33
  {
61
	 * destination observable list whenever the source observable list changes.
34
    this(true, POLICY_UPDATE);
62
	 * A default converter will be provided. The defaults can be changed by
35
  }
63
	 * calling one of the setter methods.
64
	 */
65
	public EMFUpdateListStrategy() {
66
		this(true, POLICY_UPDATE);
67
	}
68
	
69
	/**
70
	 * Creates a new update list strategy with a configurable update policy. A
71
	 * default converter will be provided. The defaults can be changed by
72
	 * calling one of the setter methods.
73
	 *
74
	 * @param updatePolicy
75
	 *            one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST}, or
76
	 *            {@link #POLICY_UPDATE}
77
	 */
78
	public EMFUpdateListStrategy(int updatePolicy) {
79
		this(true, updatePolicy);
80
	}
36
81
37
  public EMFUpdateListStrategy(int updatePolicy)
82
	/**
38
  {
83
	 * Creates a new update list strategy with a configurable update policy. A
39
    this(true, updatePolicy);
84
	 * default converter will be provided if <code>provideDefaults</code> is
40
  }
85
	 * <code>true</code>. The defaults can be changed by calling one of the
86
	 * setter methods.
87
	 *
88
	 * @param provideDefaults
89
	 *            if <code>true</code>, default validators and a default
90
	 *            converter will be provided based on the observable list's
91
	 *            type.
92
	 * @param updatePolicy
93
	 *            one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST}, or
94
	 *            {@link #POLICY_UPDATE}
95
	 */
96
	public EMFUpdateListStrategy(boolean provideDefaults, int updatePolicy) {
97
		super(provideDefaults, updatePolicy);
98
	}
41
99
42
  public EMFUpdateListStrategy(boolean provideDefaults, int updatePolicy)
100
	@Override
43
  {
101
	protected IConverter createConverter(Object fromType, Object toType) {
44
    super(provideDefaults, updatePolicy);
102
		if (fromType == String.class) {
45
  }
103
			if (toType instanceof EAttribute) {
46
  
104
				final EAttribute eAttribute = (EAttribute) toType;
47
  @Override
105
				final EDataType eDataType = eAttribute.getEAttributeType();
48
  protected IConverter createConverter(Object fromType, Object toType)
106
				final EFactory eFactory = eDataType.getEPackage()
49
  {
107
						.getEFactoryInstance();
50
    if (fromType == String.class)
108
				return new Converter(fromType, toType) {
51
    {
109
					public Object convert(Object fromObject) {
52
      if (toType instanceof EAttribute)
110
						return eFactory.createFromString(eDataType,
53
      {
111
								(String) fromObject);
54
        final EAttribute eAttribute = (EAttribute)toType;
112
					}
55
        final EDataType eDataType = eAttribute.getEAttributeType();
113
				};
56
        final EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
114
			}
57
        return
115
		} else if (toType == String.class) {
58
          new Converter(fromType, toType)
116
			if (fromType instanceof EAttribute) {
59
          {
117
				final EAttribute eAttribute = (EAttribute) fromType;
60
            public Object convert(Object fromObject)
118
				final EDataType eDataType = eAttribute.getEAttributeType();
61
            {
119
				final EFactory eFactory = eDataType.getEPackage()
62
              return eFactory.createFromString(eDataType, (String)fromObject);
120
						.getEFactoryInstance();
63
            }
121
				return new Converter(fromType, toType) {
64
          };
122
					public Object convert(Object fromObject) {
65
      }
123
						return eFactory.convertToString(eDataType, fromObject);
66
    }
124
					}
67
    else if (toType == String.class)
125
				};
68
    {
126
			}
69
      if (fromType instanceof EAttribute)
127
		}
70
      {
128
		return super.createConverter(fromType, toType);
71
        final EAttribute eAttribute = (EAttribute)fromType;
129
	}
72
        final EDataType eDataType = eAttribute.getEAttributeType();
73
        final EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
74
        return
75
          new Converter(fromType, toType)
76
          {
77
            public Object convert(Object fromObject)
78
            {
79
              return eFactory.convertToString(eDataType, fromObject);
80
            }
81
          };
82
      }
83
    }
84
    return super.createConverter(fromType, toType);
85
  }
86
}
130
}
(-)src/org/eclipse/emf/databinding/EMFDataBindingContext.java (-24 / +65 lines)
Lines 9-51 Link Here
9
 * 
9
 * 
10
 * Contributors: 
10
 * Contributors: 
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EMFDataBindingContext.java,v 1.1 2007/11/16 21:25:21 emerks Exp $
15
 * $Id: EMFDataBindingContext.java,v 1.1 2007/11/16 21:25:21 emerks Exp $
16
 */
16
 */
17
package org.eclipse.emf.databinding;
17
package org.eclipse.emf.databinding;
18
18
19
import org.eclipse.core.databinding.Binding;
19
import org.eclipse.core.databinding.DataBindingContext;
20
import org.eclipse.core.databinding.DataBindingContext;
20
import org.eclipse.core.databinding.UpdateValueStrategy;
21
import org.eclipse.core.databinding.UpdateValueStrategy;
21
import org.eclipse.core.databinding.observable.Realm;
22
import org.eclipse.core.databinding.observable.Realm;
23
import org.eclipse.core.databinding.observable.list.IObservableList;
22
import org.eclipse.core.databinding.observable.value.IObservableValue;
24
import org.eclipse.core.databinding.observable.value.IObservableValue;
23
25
24
/**
26
/**
25
 * PROVISIONAL
27
 * <p>
26
 * This API is subject to arbitrary change, including renaming or removal.
28
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
29
 * removal.</b>
30
 * </p>
31
 * 
32
 * A DataBindingContext is the point of contact for the creation and management
33
 * of {@link Binding bindings}, and aggregates validation statuses of its
34
 * bindings, or more generally, its validation status providers.
35
 * <p>
36
 * A DataBindingContext provides the following abilities:
37
 * <ul>
38
 * <li>Ability to create bindings between {@link IObservableValue observable
39
 * values}.</li>
40
 * <li>Ability to create bindings between {@link IObservableList observable
41
 * lists}.</li>
42
 * <li>Access to the bindings created by the instance.</li>
43
 * <li>Access to the list of validation status providers (this includes all
44
 * bindings).</li>
45
 * </ul>
46
 * </p>
47
 * <p>
48
 * Multiple contexts can be used at any point in time. One strategy for the
49
 * management of contexts is the aggregation of validation statuses. For example
50
 * an <code>IWizardPage</code> could use a single context and the statuses could
51
 * be aggregated to set the page status and fulfillment. Each page in the
52
 * <code>IWizard</code> would have its own context instance.
53
 * </p>
54
 * 
55
 * @since 1.0
27
 */
56
 */
28
public class EMFDataBindingContext extends DataBindingContext
57
public class EMFDataBindingContext extends DataBindingContext {
29
{
58
	/**
30
  public EMFDataBindingContext()
59
	 * Creates a data binding context, using the current default realm for the
31
  {
60
	 * validation observables.
32
    this(Realm.getDefault());
61
	 * 
33
  }
62
	 * @see Realm
63
	 */
64
	public EMFDataBindingContext() {
65
		this(Realm.getDefault());
66
	}
67
68
	/**
69
	 * Creates a data binding context using the given realm for the validation
70
	 * observables.
71
	 * 
72
	 * @param validationRealm
73
	 *            the realm to be used for the validation observables
74
	 * 
75
	 * @see Realm
76
	 */
77
	public EMFDataBindingContext(Realm validationRealm) {
78
		super(validationRealm);
79
	}
34
80
35
  public EMFDataBindingContext(Realm validationRealm)
81
	@Override
36
  {
82
	protected UpdateValueStrategy createModelToTargetUpdateValueStrategy(
37
    super(validationRealm);
83
			IObservableValue fromValue, IObservableValue toValue) {
38
  }
84
		return new EMFUpdateValueStrategy();
85
	}
39
86
40
  @Override
87
	@Override
41
  protected UpdateValueStrategy createModelToTargetUpdateValueStrategy(IObservableValue fromValue, IObservableValue toValue)
88
	protected UpdateValueStrategy createTargetToModelUpdateValueStrategy(
42
  {
89
			IObservableValue fromValue, IObservableValue toValue) {
43
    return new EMFUpdateValueStrategy();
90
		return new EMFUpdateValueStrategy();
44
  }
91
	}
45
  
46
  @Override
47
  protected UpdateValueStrategy createTargetToModelUpdateValueStrategy(IObservableValue fromValue, IObservableValue toValue)
48
  {
49
    return new EMFUpdateValueStrategy();
50
  }
51
}
92
}
(-)src/org/eclipse/emf/databinding/EObjectObservableValue.java (-117 / +102 lines)
Lines 9-15 Link Here
9
 *
9
 *
10
 * Contributors:
10
 * Contributors:
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EObjectObservableValue.java,v 1.2 2008/01/26 21:01:07 emerks Exp $
15
 * $Id: EObjectObservableValue.java,v 1.2 2008/01/26 21:01:07 emerks Exp $
Lines 28-149 Link Here
28
import org.eclipse.emf.ecore.EStructuralFeature;
28
import org.eclipse.emf.ecore.EStructuralFeature;
29
29
30
/**
30
/**
31
 * PROVISIONAL
31
 * <p>
32
 * This API is subject to arbitrary change, including renaming or removal.
32
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
33
 * removal.</b>
34
 * </p>
33
 */
35
 */
34
public class EObjectObservableValue extends AbstractObservableValue implements IObserving
36
public class EObjectObservableValue extends AbstractObservableValue implements
35
{
37
		IObserving {
36
  protected EObject eObject;
38
	protected EObject eObject;
37
  protected EStructuralFeature eStructuralFeature;
39
	protected EStructuralFeature eStructuralFeature;
38
  protected Adapter listener;
40
	protected Adapter listener;
39
41
40
  public EObjectObservableValue(EObject eObject, EStructuralFeature eStructuralFeature)
42
	public EObjectObservableValue(EObject eObject,
41
  {
43
			EStructuralFeature eStructuralFeature) {
42
    this(Realm.getDefault(), eObject, eStructuralFeature);
44
		this(Realm.getDefault(), eObject, eStructuralFeature);
43
  }
45
	}
44
46
45
  public EObjectObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
47
	public EObjectObservableValue(Realm realm, EObject eObject,
46
  {
48
			EStructuralFeature eStructuralFeature) {
47
    super(realm);
49
		super(realm);
48
    this.eObject = eObject;
50
		this.eObject = eObject;
49
    this.eStructuralFeature = eStructuralFeature;
51
		this.eStructuralFeature = eStructuralFeature;
50
  }
52
	}
51
53
52
  @Override
54
	@Override
53
  public synchronized void dispose()
55
	public synchronized void dispose() {
54
  {
56
		if (listener != null) {
55
    if (listener != null)
57
			eObject.eAdapters().remove(listener);
56
    {
58
			listener = null;
57
      eObject.eAdapters().remove(listener);
59
		}
58
      listener = null;
60
		eObject = null;
59
    }
61
		eStructuralFeature = null;
60
    eObject = null;
62
		super.dispose();
61
    eStructuralFeature = null;
63
	}
62
    super.dispose();
64
63
  }
65
	public Object getObserved() {
64
66
		return eObject;
65
  public Object getObserved()
67
	}
66
  {
68
67
    return eObject;
69
	@Override
68
  }
70
	protected void firstListenerAdded() {
69
71
		listener = new AdapterImpl() {
70
  @Override
72
			@Override
71
  protected void firstListenerAdded()
73
			public void notifyChanged(Notification notification) {
72
  {
74
				if (eStructuralFeature == notification.getFeature()
73
    listener =
75
						&& !notification.isTouch()) {
74
      new AdapterImpl()
76
					final ValueDiff diff = Diffs.createValueDiff(notification
75
      {
77
							.getOldValue(), notification.getNewValue());
76
        @Override
78
					getRealm().exec(new Runnable() {
77
        public void notifyChanged(Notification notification)
79
						public void run() {
78
        {
80
							fireValueChange(diff);
79
          if (eStructuralFeature == notification.getFeature() && !notification.isTouch())
81
						}
80
          {
82
					});
81
            final ValueDiff diff = Diffs.createValueDiff(notification.getOldValue(), notification.getNewValue());
83
				}
82
            getRealm().exec
84
			}
83
              (new Runnable()
85
		};
84
               {
86
		eObject.eAdapters().add(listener);
85
                 public void run()
87
	}
86
                 {
88
87
                   fireValueChange(diff);
89
	@Override
88
                 }
90
	protected void lastListenerRemoved() {
89
               });
91
		eObject.eAdapters().remove(listener);
90
          }
92
		listener = null;
91
        }
93
	}
92
      };
94
93
    eObject.eAdapters().add(listener);
95
	@Override
94
  }
96
	protected Object doGetValue() {
95
97
		return eObject.eGet(eStructuralFeature);
96
  @Override
98
	}
97
  protected void lastListenerRemoved()
99
98
  {
100
	@Override
99
    eObject.eAdapters().remove(listener);
101
	protected void doSetValue(Object value) {
100
    listener = null;
102
		eObject.eSet(eStructuralFeature, value);
101
  }
103
	}
102
104
103
  @Override
105
	public Object getValueType() {
104
  protected Object doGetValue()
106
		return eStructuralFeature;
105
  {
107
	}
106
    return eObject.eGet(eStructuralFeature);
108
107
  }
109
	@Override
108
110
	public String toString() {
109
  @Override
111
		StringBuilder result = new StringBuilder(getClass().getName());
110
  protected void doSetValue(Object value)
112
		result.append('@');
111
  {
113
		result.append(Integer.toHexString(hashCode()));
112
    eObject.eSet(eStructuralFeature, value);
114
113
  }
115
		result.append(" (eObject:");
114
116
		result.append(eObject);
115
  public Object getValueType()
117
		result.append(")");
116
  {
118
117
    return eStructuralFeature;
119
		result.append(" (eStructuralFeature: ");
118
  }
120
		result.append(eStructuralFeature);
119
121
		result.append(")");
120
  @Override
122
121
  public String toString()
123
		try {
122
  {
124
			Object value = eObject.eGet(eStructuralFeature, false);
123
    StringBuilder result = new StringBuilder(getClass().getName());
125
			result.append(" (value: ");
124
    result.append('@');
126
			result.append(value);
125
    result.append(Integer.toHexString(hashCode()));
127
			result.append(")");
126
128
		} catch (Exception exception) {
127
    result.append(" (eObject:");
129
			// Ignore.
128
    result.append(eObject);
130
		}
129
    result.append(")");
130
131
    result.append(" (eStructuralFeature: ");
132
    result.append(eStructuralFeature);
133
    result.append(")");
134
135
    try
136
    {
137
      Object value = eObject.eGet(eStructuralFeature, false);
138
      result.append(" (value: ");
139
      result.append(value);
140
      result.append(")");
141
    }
142
    catch (Exception exception)
143
    {
144
      // Ignore.
145
    }
146
131
147
    return result.toString();
132
		return result.toString();
148
  }
133
	}
149
}
134
}
(-)src/org/eclipse/emf/databinding/EMFObservables.java (-162 / +219 lines)
Lines 10-23 Link Here
10
 * Contributors: 
10
 * Contributors: 
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *   Trevor S. Kaufman - Bug 215131 - added mapFactory
12
 *   Trevor S. Kaufman - Bug 215131 - added mapFactory
13
 *
13
 *   Tom Schindl<tom.schindl@bestsolution.at>
14
 * </copyright>
14
 * </copyright>
15
 *
15
 *
16
 * $Id: EMFObservables.java,v 1.3 2008/04/22 13:36:00 emerks Exp $
16
 * $Id: EMFObservables.java,v 1.3 2008/04/22 13:36:00 emerks Exp $
17
 */
17
 */
18
package org.eclipse.emf.databinding;
18
package org.eclipse.emf.databinding;
19
19
20
21
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.IObservable;
22
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.Realm;
23
import org.eclipse.core.databinding.observable.list.IObservableList;
22
import org.eclipse.core.databinding.observable.list.IObservableList;
Lines 26-194 Link Here
26
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
25
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
27
import org.eclipse.core.databinding.observable.set.IObservableSet;
26
import org.eclipse.core.databinding.observable.set.IObservableSet;
28
import org.eclipse.core.databinding.observable.value.IObservableValue;
27
import org.eclipse.core.databinding.observable.value.IObservableValue;
28
import org.eclipse.emf.common.notify.NotifyingList;
29
import org.eclipse.emf.databinding.internal.EWritableList;
29
import org.eclipse.emf.ecore.EObject;
30
import org.eclipse.emf.ecore.EObject;
30
import org.eclipse.emf.ecore.EStructuralFeature;
31
import org.eclipse.emf.ecore.EStructuralFeature;
32
import org.eclipse.emf.ecore.resource.Resource;
31
33
32
/**
34
/**
33
 * PROVISIONAL
35
 * <p>
34
 * This API is subject to arbitrary change, including renaming or removal.
36
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
37
 * removal.</b>
38
 * </p>
39
 * A factory for creating observable objects of Java objects that conform to the
40
 * <a href="http://java.sun.com/products/javabeans/docs/spec.html">JavaBean
41
 * specification</a> for bound properties.
42
 * 
43
 * @since 1.0
35
 */
44
 */
36
public class EMFObservables
45
public class EMFObservables {
37
{
46
	/**
38
  /**
47
	 * 
39
   * Returns an observable value for the given feature of the object.
48
	 */
40
   * @param eObject the object to observe.
49
	public static final boolean DEBUG = false;
41
   * @param eStructuralFeature the feature of the object to observe.
50
42
   * @return an observable value for the given feature of the object.
51
	/**
43
   */
52
	 * Returns an observable value for the given feature of the object.
44
  public static IObservableValue observeValue(EObject eObject, EStructuralFeature eStructuralFeature)
53
	 * 
45
  {
54
	 * @param eObject
46
    return new EObjectObservableValue(eObject, eStructuralFeature);
55
	 *            the object to observe.
47
  }
56
	 * @param eStructuralFeature
48
57
	 *            the feature of the object to observe.
49
  /**
58
	 * @return an observable value for the given feature of the object.
50
   * Returns an observable value for the given feature of the object.
59
	 */
51
   * @param realm the realm in which to observe.
60
	public static IObservableValue observeValue(EObject eObject,
52
   * @param eObject the object to observe.
61
			EStructuralFeature eStructuralFeature) {
53
   * @param eStructuralFeature the feature of the object to observe.
62
		return new EObjectObservableValue(eObject, eStructuralFeature);
54
   * @return an observable value for the given feature of the object.
63
	}
55
   */
64
56
  public static IObservableValue observeValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
65
	/**
57
  {
66
	 * Returns an observable value for the given feature of the object.
58
    return new EObjectObservableValue(realm, eObject, eStructuralFeature);
67
	 * 
59
  }
68
	 * @param realm
60
69
	 *            the realm in which to observe.
61
  /**
70
	 * @param eObject
62
   * Returns an observable list for the given multi-valued feature of the object.
71
	 *            the object to observe.
63
   * @param eObject the object to observe.
72
	 * @param eStructuralFeature
64
   * @param eStructuralFeature the feature of the object to observe.
73
	 *            the feature of the object to observe.
65
   * @return an observable list for the given multi-valued feature of the object.
74
	 * @return an observable value for the given feature of the object.
66
   */
75
	 */
67
  public static IObservableList observeList(EObject eObject, EStructuralFeature eStructuralFeature)
76
	public static IObservableValue observeValue(Realm realm, EObject eObject,
68
  {
77
			EStructuralFeature eStructuralFeature) {
69
    return new EObjectObservableList(eObject, eStructuralFeature);
78
		return new EObjectObservableValue(realm, eObject, eStructuralFeature);
70
  }
79
	}
71
80
72
  /**
81
	/**
73
   * Returns an observable list for the given multi-valued feature of the object.
82
	 * Returns an observable list for the given multi-valued feature of the
74
   * @param realm the realm in which to observe.
83
	 * object.
75
   * @param eObject the object to observe.
84
	 * 
76
   * @param eStructuralFeature the feature of the object to observe.
85
	 * @param eObject
77
   * @return an observable list for the given multi-valued feature of the object.
86
	 *            the object to observe.
78
   */
87
	 * @param eStructuralFeature
79
  public static IObservableList observeList(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
88
	 *            the feature of the object to observe.
80
  {
89
	 * @return an observable list for the given multi-valued feature of the
81
    return new EObjectObservableList(realm, eObject, eStructuralFeature);
90
	 *         object.
82
  }
91
	 */
83
92
	public static IObservableList observeList(EObject eObject,
84
  /**
93
			EStructuralFeature eStructuralFeature) {
85
   * Returns an observable map in the default realm 
94
		return new EObjectObservableList(eObject, eStructuralFeature);
86
   * tracking the current value of the given feature for each object in the given set.
95
	}
87
   * @param objects the objects to track.
96
88
   * @param eStructuralFeature the feature for which to track the value.
97
	/**
89
   * @return an observable map tracking the current value of the given feature for each object in the given set.
98
	 * Returns an observable list for the given multi-valued feature of the
90
   */
99
	 * object.
91
  public static IObservableMap observeMap(IObservableSet objects, EStructuralFeature eStructuralFeature)
100
	 * 
92
  {
101
	 * @param realm
93
    return new EObjectObservableMap(objects, eStructuralFeature);
102
	 *            the realm in which to observe.
94
  }
103
	 * @param eObject
95
104
	 *            the object to observe.
96
  /**
105
	 * @param eStructuralFeature
97
   * Returns an array of observable maps in the default realm 
106
	 *            the feature of the object to observe.
98
   * tracking the current value of the given features for each object in the given set.
107
	 * @return an observable list for the given multi-valued feature of the
99
   * @param objects the objects to track.
108
	 *         object.
100
   * @param eStructuralFeatures the features for which to track the value.
109
	 */
101
   * @return an array of observable maps tracking the current value of the given features for each object in the given set.
110
	public static IObservableList observeList(Realm realm, EObject eObject,
102
   */
111
			EStructuralFeature eStructuralFeature) {
103
  public static IObservableMap[] observeMaps(IObservableSet objects, EStructuralFeature[] eStructuralFeatures)
112
		return new EObjectObservableList(realm, eObject, eStructuralFeature);
104
  {
113
	}
105
    IObservableMap[] result = new IObservableMap [eStructuralFeatures.length];
114
106
    for (int i = 0; i < eStructuralFeatures.length; i++)
115
	/**
107
    {
116
	 * Returns an observable map in the default realm tracking the current value
108
      result[i] = observeMap(objects, eStructuralFeatures[i]);
117
	 * of the given feature for each object in the given set.
109
    }
118
	 * 
110
    return result;
119
	 * @param objects
111
  }
120
	 *            the objects to track.
112
121
	 * @param eStructuralFeature
113
  /**
122
	 *            the feature for which to track the value.
114
   * Returns an observable value that tracks the current value of the feature of the current value of the master observable value.
123
	 * @return an observable map tracking the current value of the given feature
115
   * @param realm the realm in which to observe.
124
	 *         for each object in the given set.
116
   * @param value the master observable value.
125
	 */
117
   * @param eStructuralFeature the feature for which to track the value.
126
	public static IObservableMap observeMap(IObservableSet objects,
118
   * @return an observable value that tracks the current value of the named property for the current value of the master observable value
127
			EStructuralFeature eStructuralFeature) {
119
   * @see MasterDetailObservables#detailValue(IObservableValue, IObservableFactory, Object)
128
		return new EObjectObservableMap(objects, eStructuralFeature);
120
   */
129
	}
121
  public static IObservableValue observeDetailValue(Realm realm, IObservableValue value, EStructuralFeature eStructuralFeature)
130
122
  {
131
	/**
123
    return MasterDetailObservables.detailValue(value, valueFactory(realm, eStructuralFeature), eStructuralFeature);
132
	 * Returns an array of observable maps in the default realm tracking the
124
  }
133
	 * current value of the given features for each object in the given set.
125
134
	 * 
126
  /**
135
	 * @param objects
127
   * Returns a factory for creating observable values
136
	 *            the objects to track.
128
   * tracking the value of the given feature of a particular {@link EObject object}.
137
	 * @param eStructuralFeatures
129
   * @param realm the realm in which to observe.
138
	 *            the features for which to track the value.
130
   * @param eStructuralFeature the feature for which to track the value.
139
	 * @return an array of observable maps tracking the current value of the
131
   * @return an observable factory.
140
	 *         given features for each object in the given set.
132
   */
141
	 */
133
  public static IObservableFactory valueFactory(final Realm realm, final EStructuralFeature eStructuralFeature)
142
	public static IObservableMap[] observeMaps(IObservableSet objects,
134
  {
143
			EStructuralFeature[] eStructuralFeatures) {
135
    return 
144
		IObservableMap[] result = new IObservableMap[eStructuralFeatures.length];
136
      new IObservableFactory()
145
		for (int i = 0; i < eStructuralFeatures.length; i++) {
137
      {
146
			result[i] = observeMap(objects, eStructuralFeatures[i]);
138
        public IObservable createObservable(Object target)
147
		}
139
        {
148
		return result;
140
          return observeValue(realm, (EObject)target, eStructuralFeature);
149
	}
141
        }
150
142
      };
151
	/**
143
  }
152
	 * Returns an observable value that tracks the current value of the feature
144
153
	 * of the current value of the master observable value.
145
  /**
154
	 * 
146
   * Returns an observable list that tracks the current value of the feature of the current value of the master observable value.
155
	 * @param realm
147
   * @param realm the realm in which to observe.
156
	 *            the realm in which to observe.
148
   * @param value the master observable value.
157
	 * @param value
149
   * @param eStructuralFeature the feature for which to track the value.
158
	 *            the master observable value.
150
   * @return an observable value that tracks the current value of the named property for the current value of the master observable value
159
	 * @param eStructuralFeature
151
   * @see MasterDetailObservables#detailList(IObservableValue, IObservableFactory, Object)
160
	 *            the feature for which to track the value.
152
   */
161
	 * @return an observable value that tracks the current value of the named
153
  public static IObservableList observeDetailList(Realm realm, IObservableValue value, EStructuralFeature eStructuralFeature)
162
	 *         property for the current value of the master observable value
154
  {
163
	 * @see MasterDetailObservables#detailValue(IObservableValue,
155
    return MasterDetailObservables.detailList(value, listFactory(realm, eStructuralFeature), eStructuralFeature);
164
	 *      IObservableFactory, Object)
156
  }
165
	 */
157
166
	public static IObservableValue observeDetailValue(Realm realm,
158
  /**
167
			IObservableValue value, EStructuralFeature eStructuralFeature) {
159
   * Returns a factory for creating observable lists
168
		return MasterDetailObservables.detailValue(value, valueFactory(realm,
160
   * tracking the value of the given feature of a particular {@link EObject object}.
169
				eStructuralFeature), eStructuralFeature);
161
   * @param realm the realm in which to observe.
170
	}
162
   * @param eStructuralFeature the feature for which to track the value.
171
163
   * @return an observable factory.
172
	/**
164
   */
173
	 * Returns a factory for creating observable values tracking the value of
165
  public static IObservableFactory listFactory(final Realm realm, final EStructuralFeature eStructuralFeature)
174
	 * the given feature of a particular {@link EObject object}.
166
  {
175
	 * 
167
    return 
176
	 * @param realm
168
      new IObservableFactory()
177
	 *            the realm in which to observe.
169
      {
178
	 * @param eStructuralFeature
170
        public IObservable createObservable(Object target)
179
	 *            the feature for which to track the value.
171
        {
180
	 * @return an observable factory.
172
          return observeList(realm, (EObject)target, eStructuralFeature);
181
	 */
173
        }
182
	public static IObservableFactory valueFactory(final Realm realm,
174
      };
183
			final EStructuralFeature eStructuralFeature) {
175
  }
184
		return new IObservableFactory() {
176
  
185
			public IObservable createObservable(Object target) {
177
  /**
186
				return observeValue(realm, (EObject) target, eStructuralFeature);
178
   * Returns a factory for creating observable maps
187
			}
179
   * tracking the value of the given feature of a particular {@link EObject object}.
188
		};
180
   * @param eStructuralFeature the feature for which to track the value.
189
	}
181
   * @return an observable factory.
190
182
   */
191
	/**
183
  public static IObservableFactory mapFactory(final EStructuralFeature eStructuralFeature)
192
	 * Returns an observable list that tracks the current value of the feature
184
  {
193
	 * of the current value of the master observable value.
185
    return
194
	 * 
186
      new IObservableFactory()
195
	 * @param realm
187
      {
196
	 *            the realm in which to observe.
188
        public IObservable createObservable(Object target)
197
	 * @param value
189
        {
198
	 *            the master observable value.
190
          return observeMap((IObservableSet)target, eStructuralFeature);
199
	 * @param eStructuralFeature
191
        }
200
	 *            the feature for which to track the value.
192
      };
201
	 * @return an observable value that tracks the current value of the named
193
   }
202
	 *         property for the current value of the master observable value
203
	 * @see MasterDetailObservables#detailList(IObservableValue,
204
	 *      IObservableFactory, Object)
205
	 */
206
	public static IObservableList observeDetailList(Realm realm,
207
			IObservableValue value, EStructuralFeature eStructuralFeature) {
208
		return MasterDetailObservables.detailList(value, listFactory(realm,
209
				eStructuralFeature), eStructuralFeature);
210
	}
211
212
	/**
213
	 * Returns a factory for creating observable lists tracking the value of the
214
	 * given feature of a particular {@link EObject object}.
215
	 * 
216
	 * @param realm
217
	 *            the realm in which to observe.
218
	 * @param eStructuralFeature
219
	 *            the feature for which to track the value.
220
	 * @return an observable factory.
221
	 */
222
	public static IObservableFactory listFactory(final Realm realm,
223
			final EStructuralFeature eStructuralFeature) {
224
		return new IObservableFactory() {
225
			public IObservable createObservable(Object target) {
226
				return observeList(realm, (EObject) target, eStructuralFeature);
227
			}
228
		};
229
	}
230
231
	/**
232
	 * Returns a factory for creating observable maps tracking the value of the
233
	 * given feature of a particular {@link EObject object}.
234
	 * 
235
	 * @param eStructuralFeature
236
	 *            the feature for which to track the value.
237
	 * @return an observable factory.
238
	 */
239
	public static IObservableFactory mapFactory(
240
			final EStructuralFeature eStructuralFeature) {
241
		return new IObservableFactory() {
242
			public IObservable createObservable(Object target) {
243
				return observeMap((IObservableSet) target, eStructuralFeature);
244
			}
245
		};
246
	}
247
	
248
	public static IObservableList observeResourceContents(Resource resource) {
249
		return new EWritableList<EObject>((NotifyingList<EObject>) resource.getContents());
250
	}
194
}
251
}
(-)src/org/eclipse/emf/databinding/EObjectObservableList.java (-254 / +241 lines)
Lines 9-15 Link Here
9
 *
9
 *
10
 * Contributors:
10
 * Contributors:
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EObjectObservableList.java,v 1.4 2008/02/21 15:26:16 emerks Exp $
15
 * $Id: EObjectObservableList.java,v 1.4 2008/02/21 15:26:16 emerks Exp $
Lines 33-294 Link Here
33
import org.eclipse.emf.ecore.EStructuralFeature;
33
import org.eclipse.emf.ecore.EStructuralFeature;
34
34
35
/**
35
/**
36
 * PROVISIONAL
36
 * <p>
37
 * This API is subject to arbitrary change, including renaming or removal.
37
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
38
 * removal.</b>
39
 * </p>
38
 */
40
 */
39
public class EObjectObservableList extends ObservableList implements IObserving, InternalRawEList
41
public class EObjectObservableList extends ObservableList implements
40
{
42
		IObserving, InternalRawEList {
41
  protected EObject eObject;
43
	protected EObject eObject;
42
  protected EStructuralFeature eStructuralFeature;
44
	protected EStructuralFeature eStructuralFeature;
43
  protected Adapter listener;
45
	protected Adapter listener;
44
46
45
  public EObjectObservableList(EObject eObject, EStructuralFeature eStructuralFeature)
47
	public EObjectObservableList(EObject eObject,
46
  {
48
			EStructuralFeature eStructuralFeature) {
47
    this(Realm.getDefault(), eObject, eStructuralFeature);
49
		this(Realm.getDefault(), eObject, eStructuralFeature);
48
  }
50
	}
49
51
50
  public EObjectObservableList(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
52
	public EObjectObservableList(Realm realm, EObject eObject,
51
  {
53
			EStructuralFeature eStructuralFeature) {
52
    super(realm, (EList<?>)eObject.eGet(eStructuralFeature), eStructuralFeature);
54
		super(realm, (EList<?>) eObject.eGet(eStructuralFeature),
53
    this.eObject = eObject;
55
				eStructuralFeature);
54
    this.eStructuralFeature = eStructuralFeature;
56
		this.eObject = eObject;
55
  }
57
		this.eStructuralFeature = eStructuralFeature;
56
58
	}
57
  @Override
59
58
  protected void firstListenerAdded()
60
	@Override
59
  {
61
	protected void firstListenerAdded() {
60
    listener =
62
		listener = new AdapterImpl() {
61
      new AdapterImpl()
63
			@Override
62
      {
64
			public void notifyChanged(Notification notification) {
63
        @Override
65
				if (eStructuralFeature == notification.getFeature()
64
        public void notifyChanged(Notification notification)
66
						&& !notification.isTouch()) {
65
        {
67
					final ListDiff diff;
66
          if (eStructuralFeature == notification.getFeature() && !notification.isTouch())
68
					switch (notification.getEventType()) {
67
          {
69
					case Notification.ADD: {
68
            final ListDiff diff;
70
						diff = Diffs.createListDiff(Diffs.createListDiffEntry(
69
            switch (notification.getEventType())
71
								notification.getPosition(), true, notification
70
            {
72
										.getNewValue()));
71
              case Notification.ADD:
73
						break;
72
              {
74
					}
73
                diff = Diffs.createListDiff(Diffs.createListDiffEntry(notification.getPosition(), true, notification.getNewValue()));
75
					case Notification.ADD_MANY: {
74
                break;
76
						Collection<?> newValues = (Collection<?>) notification
75
              }
77
								.getNewValue();
76
              case Notification.ADD_MANY:
78
						ListDiffEntry[] listDiffEntries = new ListDiffEntry[newValues
77
              {
79
								.size()];
78
                Collection<?> newValues = (Collection<?>)notification.getNewValue();
80
						int position = notification.getPosition();
79
                ListDiffEntry [] listDiffEntries = new ListDiffEntry [newValues.size()];
81
						int index = 0;
80
                int position = notification.getPosition();
82
						for (Object newValue : newValues) {
81
                int index = 0;
83
							listDiffEntries[index++] = Diffs
82
                for (Object newValue : newValues)
84
									.createListDiffEntry(position++, true,
83
                {
85
											newValue);
84
                  listDiffEntries[index++] = Diffs.createListDiffEntry(position++, true, newValue);
86
						}
85
                }
87
						diff = Diffs.createListDiff(listDiffEntries);
86
                diff = Diffs.createListDiff(listDiffEntries);
88
						break;
87
                break;
89
					}
88
              }
90
					case Notification.REMOVE: {
89
              case Notification.REMOVE:
91
						diff = Diffs.createListDiff(Diffs.createListDiffEntry(
90
              {
92
								notification.getPosition(), false, notification
91
                diff = Diffs.createListDiff(Diffs.createListDiffEntry(notification.getPosition(), false, notification.getOldValue()));
93
										.getOldValue()));
92
                break;
94
						break;
93
              }
95
					}
94
              case Notification.REMOVE_MANY:
96
					case Notification.REMOVE_MANY: {
95
              {
97
						Collection<?> oldValues = (Collection<?>) notification
96
                Collection<?> oldValues = (Collection<?>)notification.getOldValue();
98
								.getOldValue();
97
                ListDiffEntry [] listDiffEntries = new ListDiffEntry [oldValues.size()];
99
						ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues
98
                int position = notification.getPosition();
100
								.size()];
99
                int index = 0;
101
						int position = notification.getPosition();
100
                for (Object oldValue : oldValues)
102
						int index = 0;
101
                {
103
						for (Object oldValue : oldValues) {
102
                  listDiffEntries[index++] = Diffs.createListDiffEntry(position++, false, oldValue);
104
							listDiffEntries[index++] = Diffs
103
                }
105
									.createListDiffEntry(position++, false,
104
                diff = Diffs.createListDiff(listDiffEntries);
106
											oldValue);
105
                break;
107
						}
106
              }
108
						diff = Diffs.createListDiff(listDiffEntries);
107
              case Notification.SET:
109
						break;
108
              case Notification.RESOLVE:
110
					}
109
              {
111
					case Notification.SET:
110
                ListDiffEntry [] listDiffEntries = new ListDiffEntry [2];
112
					case Notification.RESOLVE: {
111
                listDiffEntries[0] = Diffs.createListDiffEntry(notification.getPosition(), false, notification.getOldValue());
113
						ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
112
                listDiffEntries[1] = Diffs.createListDiffEntry(notification.getPosition(), true, notification.getNewValue());
114
						listDiffEntries[0] = Diffs.createListDiffEntry(
113
                diff = Diffs.createListDiff(listDiffEntries);
115
								notification.getPosition(), false, notification
114
                break;
116
										.getOldValue());
115
              }
117
						listDiffEntries[1] = Diffs.createListDiffEntry(
116
              case Notification.MOVE:
118
								notification.getPosition(), true, notification
117
              {
119
										.getNewValue());
118
                Object movedValue = notification.getNewValue();
120
						diff = Diffs.createListDiff(listDiffEntries);
119
                ListDiffEntry [] listDiffEntries = new ListDiffEntry [2];
121
						break;
120
                listDiffEntries[0] = Diffs.createListDiffEntry((Integer)notification.getOldValue(), false, movedValue);
122
					}
121
                listDiffEntries[1] = Diffs.createListDiffEntry(notification.getPosition(), true, movedValue);
123
					case Notification.MOVE: {
122
                diff = Diffs.createListDiff(listDiffEntries);
124
						Object movedValue = notification.getNewValue();
123
                break;
125
						ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
124
              }
126
						listDiffEntries[0] = Diffs.createListDiffEntry(
125
              case Notification.UNSET:
127
								(Integer) notification.getOldValue(), false,
126
              {
128
								movedValue);
127
                // This just represents going back to the unset state, but that doesn't affect the contents of the list.
129
						listDiffEntries[1] = Diffs.createListDiffEntry(
128
                //
130
								notification.getPosition(), true, movedValue);
129
                return;
131
						diff = Diffs.createListDiff(listDiffEntries);
130
              }
132
						break;
131
              default:
133
					}
132
              {
134
					case Notification.UNSET: {
133
                throw new RuntimeException("unhandled case");
135
						// This just represents going back to the unset state,
134
              }
136
						// but that doesn't affect the contents of the list.
135
            }
137
						//
136
            getRealm().exec
138
						return;
137
             (new Runnable()
139
					}
138
              {
140
					default: {
139
                public void run()
141
						throw new RuntimeException("unhandled case");
140
                {
142
					}
141
                  fireListChange(diff);
143
					}
142
                }
144
					getRealm().exec(new Runnable() {
143
              });
145
						public void run() {
144
          }
146
							fireListChange(diff);
145
        }
147
						}
146
      };
148
					});
147
    eObject.eAdapters().add(listener);
149
				}
148
  }
150
			}
149
  
151
		};
150
  @Override
152
		eObject.eAdapters().add(listener);
151
  protected void lastListenerRemoved()
153
	}
152
  {
154
153
    eObject.eAdapters().remove(listener);
155
	@Override
154
    listener = null;
156
	protected void lastListenerRemoved() {
155
  }
157
		eObject.eAdapters().remove(listener);
156
158
		listener = null;
157
  @Override
159
	}
158
  public synchronized void dispose()
160
159
  {
161
	@Override
160
    if (listener != null)
162
	public synchronized void dispose() {
161
    {
163
		if (listener != null) {
162
      eObject.eAdapters().remove(listener);
164
			eObject.eAdapters().remove(listener);
163
      listener = null;
165
			listener = null;
164
    }
166
		}
165
    eObject = null;
167
		eObject = null;
166
    eStructuralFeature = null;
168
		eStructuralFeature = null;
167
    super.dispose();
169
		super.dispose();
168
  }
170
	}
169
171
170
  @SuppressWarnings("unchecked")
172
	@SuppressWarnings("unchecked")
171
  protected final List<Object> wrappedList()
173
	protected final List<Object> wrappedList() {
172
  {
174
		return wrappedList;
173
    return wrappedList;
175
	}
174
  }
176
175
177
	public Object getObserved() {
176
  public Object getObserved()
178
		return eObject;
177
  {
179
	}
178
    return eObject;
180
179
  }
181
	@Override
180
182
	public boolean add(Object object) {
181
  @Override
183
		checkRealm();
182
  public boolean add(Object object)
184
		return wrappedList().add(object);
183
  {
185
	}
184
    checkRealm();
186
185
    return wrappedList().add(object);
187
	@Override
186
  }
188
	public void add(int index, Object object) {
187
189
		checkRealm();
188
  @Override
190
		wrappedList().add(index, object);
189
  public void add(int index, Object object)
191
	}
190
  {
192
191
    checkRealm();
193
	@SuppressWarnings("unchecked")
192
    wrappedList().add(index, object);
194
	@Override
193
  }
195
	public boolean addAll(Collection collection) {
194
196
		checkRealm();
195
  @SuppressWarnings("unchecked")
197
		return wrappedList().addAll(collection);
196
  @Override
198
	}
197
  public boolean addAll(Collection collection)
199
198
  {
200
	@SuppressWarnings("unchecked")
199
    checkRealm();
201
	@Override
200
    return wrappedList().addAll(collection);
202
	public boolean addAll(int index, Collection collection) {
201
  }
203
		checkRealm();
202
204
		return wrappedList().addAll(index, collection);
203
  @SuppressWarnings("unchecked")
205
	}
204
  @Override
206
205
  public boolean addAll(int index, Collection collection)
207
	@Override
206
  {
208
	public Object set(int index, Object element) {
207
    checkRealm();
209
		checkRealm();
208
    return wrappedList().addAll(index, collection);
210
		return wrappedList().set(index, element);
209
  }
211
	}
210
212
211
  @Override
213
	@Override
212
  public Object set(int index, Object element)
214
	public Object remove(int index) {
213
  {
215
		checkRealm();
214
    checkRealm();
216
		return wrappedList.remove(index);
215
    return wrappedList().set(index, element);
217
	}
216
  }
218
217
219
	@Override
218
  @Override
220
	public boolean remove(Object element) {
219
  public Object remove(int index)
221
		checkRealm();
220
  {
222
		return wrappedList.remove(element);
221
    checkRealm();
223
	}
222
    return wrappedList.remove(index);
224
223
  }
225
	@SuppressWarnings("unchecked")
224
226
	@Override
225
  @Override
227
	public boolean removeAll(Collection collection) {
226
  public boolean remove(Object element)
228
		checkRealm();
227
  {
229
		return wrappedList().removeAll(collection);
228
    checkRealm();
230
	}
229
    return wrappedList.remove(element);
231
230
  }
232
	@SuppressWarnings("unchecked")
231
233
	@Override
232
  @SuppressWarnings("unchecked")
234
	public boolean retainAll(Collection collection) {
233
  @Override
235
		checkRealm();
234
  public boolean removeAll(Collection collection)
236
		return wrappedList().retainAll(collection);
235
  {
237
	}
236
    checkRealm();
238
237
    return wrappedList().removeAll(collection);
239
	@Override
238
  }
240
	public void clear() {
239
241
		checkRealm();
240
  @SuppressWarnings("unchecked")
242
		wrappedList.clear();
241
  @Override
243
	}
242
  public boolean retainAll(Collection collection)
244
243
  {
245
	@Override
244
    checkRealm();
246
	public Object move(int newPosition, int oldPosition) {
245
    return wrappedList().retainAll(collection);
247
		checkRealm();
246
  }
248
		return ((EList<?>) wrappedList).move(newPosition, oldPosition);
247
249
	}
248
  @Override
250
249
  public void clear()
251
	public void move(int newPosition, Object object) {
250
  {
252
		move(newPosition, indexOf(object));
251
    checkRealm();
253
	}
252
    wrappedList.clear();
254
253
  }
255
	@Override
254
256
	public String toString() {
255
  @Override
257
		StringBuilder result = new StringBuilder(getClass().getName());
256
  public Object move(int newPosition, int oldPosition)
258
		result.append('@');
257
  {
259
		result.append(Integer.toHexString(hashCode()));
258
    checkRealm();
260
259
    return ((EList<?>)wrappedList).move(newPosition, oldPosition);
261
		result.append(" (eObject:");
260
  }
262
		result.append(eObject);
261
263
		result.append(")");
262
  public void move(int newPosition, Object object)
264
263
  {
265
		result.append(" (eStructuralFeature: ");
264
    move(newPosition, indexOf(object));
266
		result.append(eStructuralFeature);
265
  }
267
		result.append(")");
266
268
267
  @Override
269
		result.append(" (wrappedList: ");
268
  public String toString()
270
		result.append(wrappedList);
269
  {
271
		result.append(")");
270
    StringBuilder result = new StringBuilder(getClass().getName());
271
    result.append('@');
272
    result.append(Integer.toHexString(hashCode()));
273
274
    result.append(" (eObject:");
275
    result.append(eObject);
276
    result.append(")");
277
278
    result.append(" (eStructuralFeature: ");
279
    result.append(eStructuralFeature);
280
    result.append(")");
281
282
    result.append(" (wrappedList: ");
283
    result.append(wrappedList);
284
    result.append(")");
285
272
286
    return result.toString();
273
		return result.toString();
287
  }
274
	}
288
}
275
}
289
276
290
@SuppressWarnings("unchecked")
277
@SuppressWarnings("unchecked")
291
interface InternalRawEList extends EList
278
interface InternalRawEList extends EList {
292
{
279
	// This is only at avoid needing an @SuppressWarnings("unchecked") on the
293
  // This is only at avoid needing an @SuppressWarnings("unchecked") on the EMFObservableList
280
	// EMFObservableList
294
}
281
}
(-)src/org/eclipse/emf/databinding/EObjectObservableMap.java (-67 / +60 lines)
Lines 9-15 Link Here
9
 * 
9
 * 
10
 * Contributors: 
10
 * Contributors: 
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EObjectObservableMap.java,v 1.4 2008/10/21 11:03:56 emerks Exp $
15
 * $Id: EObjectObservableMap.java,v 1.4 2008/10/21 11:03:56 emerks Exp $
Lines 28-98 Link Here
28
import org.eclipse.emf.ecore.util.ExtendedMetaData;
28
import org.eclipse.emf.ecore.util.ExtendedMetaData;
29
29
30
/**
30
/**
31
 * PROVISIONAL
31
 * <p>
32
 * This API is subject to arbitrary change, including renaming or removal.
32
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
33
 * removal.</b>
34
 * </p>
33
 */
35
 */
34
public class EObjectObservableMap extends ComputedObservableMap
36
public class EObjectObservableMap extends ComputedObservableMap {
35
{
37
	protected EStructuralFeature eStructuralFeature;
36
  protected EStructuralFeature eStructuralFeature;
38
37
39
	private Adapter elementListener = new AdapterImpl() {
38
  private Adapter elementListener = 
40
		@Override
39
    new AdapterImpl()
41
		public void notifyChanged(Notification notification) {
40
    {
42
			if (eStructuralFeature == notification.getFeature()
41
      @Override
43
					&& !notification.isTouch()) {
42
      public void notifyChanged(Notification notification)
44
				// TODO
43
      {
45
				// This assumes we only get a SET notification, which isn't a
44
        if (eStructuralFeature == notification.getFeature() && !notification.isTouch())
46
				// good assumption.
45
        {
47
				//
46
          // TODO
48
				final MapDiff diff = Diffs.createMapDiffSingleChange(
47
          // This assumes we only get a SET notification, which isn't a good assumption.
49
						notification.getNotifier(), notification.getOldValue(),
48
          //
50
						notification.getNewValue());
49
          final MapDiff diff = Diffs.createMapDiffSingleChange(notification.getNotifier(), notification.getOldValue(), notification.getNewValue());
51
				getRealm().exec(new Runnable() {
50
          getRealm().exec
52
					public void run() {
51
            (new Runnable()
53
						fireMapChange(diff);
52
             {
54
					}
53
               public void run()
55
				});
54
               {
56
			}
55
                 fireMapChange(diff);
57
		}
56
               }
58
	};
57
             });
59
58
        }
60
	public EObjectObservableMap(IObservableSet objects,
59
      }
61
			EStructuralFeature feature) {
60
    };
62
		super(objects);
61
63
		this.eStructuralFeature = feature;
62
  public EObjectObservableMap(IObservableSet objects, EStructuralFeature feature)
64
	}
63
  {
65
64
    super(objects);
66
	@Override
65
    this.eStructuralFeature = feature;
67
	protected void hookListener(Object domainElement) {
66
  }
68
		((EObject) domainElement).eAdapters().add(elementListener);
67
69
	}
68
  @Override
70
69
  protected void hookListener(Object domainElement)
71
	@Override
70
  {
72
	protected void unhookListener(Object domainElement) {
71
    ((EObject)domainElement).eAdapters().add(elementListener);
73
		((EObject) domainElement).eAdapters().remove(elementListener);
72
  }
74
	}
73
75
74
  @Override
76
	@Override
75
  protected void unhookListener(Object domainElement)
77
	protected Object doGet(Object key) {
76
  {
78
		EObject eObject = (EObject) key;
77
    ((EObject)domainElement).eAdapters().remove(elementListener);
79
		return ExtendedMetaData.INSTANCE.getAffiliation(eObject.eClass(),
78
  }
80
				eStructuralFeature) == null ? null : eObject
79
81
				.eGet(eStructuralFeature);
80
  @Override
82
	}
81
  protected Object doGet(Object key)
83
82
  {
84
	@Override
83
    EObject eObject = (EObject)key;
85
	protected Object doPut(Object key, Object value) {
84
    return  
86
		EObject eObject = (EObject) key;
85
      ExtendedMetaData.INSTANCE.getAffiliation(eObject.eClass(), eStructuralFeature) == null ?
87
		Object result = eObject.eGet(eStructuralFeature);
86
        null :
88
		eObject.eSet(eStructuralFeature, value);
87
        eObject.eGet(eStructuralFeature);
89
		return result;
88
  }
90
	}
89
90
  @Override
91
  protected Object doPut(Object key, Object value)
92
  {
93
    EObject eObject = (EObject)key;
94
    Object result = eObject.eGet(eStructuralFeature);
95
    eObject.eSet(eStructuralFeature, value);
96
    return result;
97
  }
98
}
91
}
(-)src/org/eclipse/emf/databinding/EMFUpdateValueStrategy.java (-89 / +150 lines)
Lines 9-15 Link Here
9
 * 
9
 * 
10
 * Contributors: 
10
 * Contributors: 
11
 *   IBM - Initial API and implementation
11
 *   IBM - Initial API and implementation
12
 *
12
 *   Tom Schindl<tom.schindl@bestsolution.at>
13
 * </copyright>
13
 * </copyright>
14
 *
14
 *
15
 * $Id: EMFUpdateValueStrategy.java,v 1.2 2008/02/22 12:10:18 emerks Exp $
15
 * $Id: EMFUpdateValueStrategy.java,v 1.2 2008/02/22 12:10:18 emerks Exp $
Lines 19-121 Link Here
19
import java.util.ArrayList;
19
import java.util.ArrayList;
20
import java.util.List;
20
import java.util.List;
21
21
22
import org.eclipse.core.databinding.Binding;
23
import org.eclipse.core.databinding.DataBindingContext;
22
import org.eclipse.core.databinding.UpdateValueStrategy;
24
import org.eclipse.core.databinding.UpdateValueStrategy;
23
import org.eclipse.core.databinding.conversion.Converter;
25
import org.eclipse.core.databinding.conversion.Converter;
24
import org.eclipse.core.databinding.conversion.IConverter;
26
import org.eclipse.core.databinding.conversion.IConverter;
27
import org.eclipse.core.databinding.observable.value.IObservableValue;
28
import org.eclipse.core.databinding.validation.IValidator;
25
import org.eclipse.emf.ecore.EAttribute;
29
import org.eclipse.emf.ecore.EAttribute;
26
import org.eclipse.emf.ecore.EDataType;
30
import org.eclipse.emf.ecore.EDataType;
27
import org.eclipse.emf.ecore.EFactory;
31
import org.eclipse.emf.ecore.EFactory;
28
32
29
/**
33
/**
30
 * PROVISIONAL
34
 * <p>
31
 * This API is subject to arbitrary change, including renaming or removal.
35
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
36
 * removal.</b>
37
 * </p>
38
 * Customizes a {@link Binding} between two {@link IObservableValue observable
39
 * values}. The following behaviors can be customized via the strategy:
40
 * <ul>
41
 * <li>Validation</li>
42
 * <li>Conversion</li>
43
 * <li>Automatic processing</li>
44
 * </ul>
45
 * <p>
46
 * The update phases are:
47
 * <ol>
48
 * <li>Validate after get - {@link #validateAfterGet(Object)}</li>
49
 * <li>Conversion - {@link #convert(Object)}</li>
50
 * <li>Validate after conversion - {@link #validateAfterConvert(Object)}</li>
51
 * <li>Validate before set - {@link #validateBeforeSet(Object)}</li>
52
 * <li>Value set - {@link #doSet(IObservableValue, Object)}</li>
53
 * </ol>
54
 * </p>
55
 * <p>
56
 * Validation:<br/>
57
 * {@link IValidator Validators} validate the value at multiple phases in the
58
 * update process. Statuses returned from validators are aggregated into a
59
 * <code>MultiStatus</code> until a status of <code>ERROR</code> or
60
 * <code>CANCEL</code> is encountered. Either of these statuses will abort the
61
 * update process. These statuses are available as the
62
 * {@link Binding#getValidationStatus() binding validation status}.
63
 * </p>
64
 * <p>
65
 * Conversion:<br/>
66
 * A {@link IConverter converter} will convert the value from the type of the
67
 * source observable into the type of the destination. The strategy has the
68
 * ability to default converters for common scenarios.
69
 * </p>
70
 * <p>
71
 * Automatic processing:<br/>
72
 * The processing to perform when the source observable changes. This behavior
73
 * is configured via policies provided on construction of the strategy (e.g.
74
 * {@link #POLICY_NEVER}, {@link #POLICY_CONVERT}, {@link #POLICY_ON_REQUEST},
75
 * {@link #POLICY_UPDATE}).
76
 * </p>
77
 * 
78
 * @see DataBindingContext#bindValue(IObservableValue, IObservableValue,
79
 *      UpdateValueStrategy, UpdateValueStrategy)
80
 * @see Binding#getValidationStatus()
81
 * @see IValidator
82
 * @see IConverter
83
 * @since 1.0
32
 */
84
 */
33
public class EMFUpdateValueStrategy extends UpdateValueStrategy
85
public class EMFUpdateValueStrategy extends UpdateValueStrategy {
34
{
86
	/**
35
  public EMFUpdateValueStrategy()
87
	 * Creates a new update value strategy for automatically updating the
36
  {
88
	 * destination observable value whenever the source observable value
37
    this(true, POLICY_UPDATE);
89
	 * changes. Default validators and a default converter will be provided. The
38
  }
90
	 * defaults can be changed by calling one of the setter methods.
91
	 */
92
	public EMFUpdateValueStrategy() {
93
		this(true, POLICY_UPDATE);
94
	}
95
	
96
	/**
97
	 * Creates a new update value strategy with a configurable update policy.
98
	 * Default validators and a default converter will be provided. The defaults
99
	 * can be changed by calling one of the setter methods.
100
	 *
101
	 * @param updatePolicy
102
	 *            one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST},
103
	 *            {@link #POLICY_CONVERT}, or {@link #POLICY_UPDATE}
104
	 */
105
	public EMFUpdateValueStrategy(int updatePolicy) {
106
		this(true, updatePolicy);
107
	}
39
108
40
  public EMFUpdateValueStrategy(int updatePolicy)
109
	/**
41
  {
110
	 * Creates a new update value strategy with a configurable update policy.
42
    this(true, updatePolicy);
111
	 * Default validators and a default converter will be provided if
43
  }
112
	 * <code>provideDefaults</code> is <code>true</code>. The defaults can
113
	 * be changed by calling one of the setter methods.
114
	 *
115
	 * @param provideDefaults
116
	 *            if <code>true</code>, default validators and a default
117
	 *            converter will be provided based on the observable value's
118
	 *            type.
119
	 * @param updatePolicy
120
	 *            one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST},
121
	 *            {@link #POLICY_CONVERT}, or {@link #POLICY_UPDATE}
122
	 */
123
	public EMFUpdateValueStrategy(boolean provideDefaults, int updatePolicy) {
124
		super(provideDefaults, updatePolicy);
125
	}
44
126
45
  public EMFUpdateValueStrategy(boolean provideDefaults, int updatePolicy)
127
	@Override
46
  {
128
	protected IConverter createConverter(Object fromType, Object toType) {
47
    super(provideDefaults, updatePolicy);
129
		if (fromType == String.class) {
48
  }
130
			if (toType instanceof EAttribute) {
49
  
131
				final EAttribute eAttribute = (EAttribute) toType;
50
  @Override
132
				final EDataType eDataType = eAttribute.getEAttributeType();
51
  protected IConverter createConverter(Object fromType, Object toType)
133
				final EFactory eFactory = eDataType.getEPackage()
52
  {
134
						.getEFactoryInstance();
53
    if (fromType == String.class)
135
				return new Converter(fromType, toType) {
54
    {
136
					public Object convert(Object fromObject) {
55
      if (toType instanceof EAttribute)
137
						String value = fromObject == null ? null : fromObject
56
      {
138
								.toString();
57
        final EAttribute eAttribute = (EAttribute)toType;
139
						if (eAttribute.isMany()) {
58
        final EDataType eDataType = eAttribute.getEAttributeType();
140
							List<Object> result = new ArrayList<Object>();
59
        final EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
141
							if (value != null) {
60
        return
142
								for (String element : value.split(" ")) {
61
          new Converter(fromType, toType)
143
									result.add(eFactory.createFromString(
62
          {
144
											eDataType, element));
63
            public Object convert(Object fromObject)
145
								}
64
            {
146
							}
65
              String value = fromObject == null ? null : fromObject.toString();
147
							return result;
66
              if (eAttribute.isMany())
148
						} else {
67
              {
149
							return eFactory.createFromString(eDataType, value);
68
                List<Object> result = new ArrayList<Object>();
150
						}
69
                if (value != null)
151
					}
70
                {
152
				};
71
                  for (String element : value.split(" "))
153
			}
72
                  {
154
		} else if (toType == String.class) {
73
                    result.add(eFactory.createFromString(eDataType, element));
155
			if (fromType instanceof EAttribute) {
74
                  }
156
				final EAttribute eAttribute = (EAttribute) fromType;
75
                }
157
				final EDataType eDataType = eAttribute.getEAttributeType();
76
                return result;
158
				final EFactory eFactory = eDataType.getEPackage()
77
              }
159
						.getEFactoryInstance();
78
              else
160
				return new Converter(fromType, toType) {
79
              {
161
					public Object convert(Object fromObject) {
80
                return eFactory.createFromString(eDataType, value);
162
						if (eAttribute.isMany()) {
81
              }
163
							StringBuilder result = new StringBuilder();
82
            }
164
							for (Object value : (List<?>) fromObject) {
83
          };
165
								if (result.length() == 0) {
84
      }
166
									result.append(' ');
85
    }
167
								}
86
    else if (toType == String.class)
168
								result.append(eFactory.convertToString(
87
    {
169
										eDataType, value));
88
      if (fromType instanceof EAttribute)
170
							}
89
      {
171
							return result.toString();
90
        final EAttribute eAttribute = (EAttribute)fromType;
172
						} else {
91
        final EDataType eDataType = eAttribute.getEAttributeType();
173
							return eFactory.convertToString(eDataType,
92
        final EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
174
									fromObject);
93
        return
175
						}
94
          new Converter(fromType, toType)
176
					}
95
          {
177
				};
96
            public Object convert(Object fromObject)
178
			}
97
            {
179
		}
98
              if (eAttribute.isMany())
180
		return super.createConverter(fromType, toType);
99
              {
181
	}
100
                StringBuilder result = new StringBuilder();
101
                for (Object value : (List<?>)fromObject)
102
                {
103
                  if (result.length() == 0)
104
                  {
105
                    result.append(' ');
106
                  }
107
                  result.append(eFactory.convertToString(eDataType, value));
108
                }
109
                return result.toString();
110
              }
111
              else
112
              {
113
                return eFactory.convertToString(eDataType, fromObject);
114
              }
115
            }
116
          };
117
      }
118
    }
119
    return super.createConverter(fromType, toType);
120
  }
121
}
182
}
(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 8-14 Link Here
8
Bundle-Vendor: %providerName
8
Bundle-Vendor: %providerName
9
Bundle-Localization: plugin
9
Bundle-Localization: plugin
10
Bundle-RequiredExecutionEnvironment: J2SE-1.5
10
Bundle-RequiredExecutionEnvironment: J2SE-1.5
11
Export-Package: org.eclipse.emf.databinding
11
Export-Package: org.eclipse.emf.databinding,
12
 org.eclipse.emf.databinding.properties
12
Require-Bundle: org.eclipse.core.runtime,
13
Require-Bundle: org.eclipse.core.runtime,
13
 org.eclipse.emf.ecore;visibility:=reexport,
14
 org.eclipse.emf.ecore;visibility:=reexport,
14
 org.eclipse.core.databinding;visibility:=reexport
15
 org.eclipse.core.databinding;visibility:=reexport
(-)src/org/eclipse/emf/databinding/internal/EWritableList.java (+303 lines)
Added Link Here
1
/**
2
 * <copyright> 
3
 *
4
 * Copyright (c) 2007 BestSolution.at and others.
5
 * All rights reserved.   This program and the accompanying materials
6
 * are made available under the terms of the Eclipse Public License v1.0
7
 * which accompanies this distribution, and is available at
8
 * http://www.eclipse.org/legal/epl-v10.html
9
 * 
10
 * Contributors: 
11
 *   Tom Schindl<tom.schindl@bestsolution.at> - Initial API and implementation
12
 *
13
 * </copyright>
14
 *
15
 * $Id: $
16
 */
17
package org.eclipse.emf.databinding.internal;
18
19
import java.util.Collection;
20
import java.util.Iterator;
21
import java.util.List;
22
import java.util.ListIterator;
23
24
import org.eclipse.core.databinding.observable.Diffs;
25
import org.eclipse.core.databinding.observable.ObservableTracker;
26
import org.eclipse.core.databinding.observable.Realm;
27
import org.eclipse.core.databinding.observable.list.AbstractObservableList;
28
import org.eclipse.core.databinding.observable.list.IObservableList;
29
import org.eclipse.core.databinding.observable.list.ListDiff;
30
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
31
import org.eclipse.emf.common.notify.Adapter;
32
import org.eclipse.emf.common.notify.Notification;
33
import org.eclipse.emf.common.notify.Notifier;
34
import org.eclipse.emf.common.notify.NotifyingList;
35
import org.eclipse.emf.common.notify.impl.AdapterImpl;
36
import org.eclipse.emf.ecore.resource.Resource;
37
38
public class EWritableList<Type> extends AbstractObservableList implements IObservableList {
39
	private NotifyingList<Type> wrappedList;
40
	private Object elementType;
41
	private boolean stale = false;
42
	
43
	private class Listener extends AdapterImpl {
44
		private Object feature;
45
		
46
		public Listener(Object feature) {
47
			this.feature = feature;
48
		}
49
		
50
		@Override
51
		public void notifyChanged(Notification msg) {
52
			
53
			if( feature == null && msg.getFeature() == null && msg.getFeatureID(Resource.class) != Resource.RESOURCE__CONTENTS ) {
54
				return;
55
			}
56
			
57
			if (feature == msg.getFeature() && !msg.isTouch()) {
58
				final ListDiff diff;
59
				switch (msg.getEventType()) {
60
				case Notification.ADD: {
61
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
62
							.getPosition(), true, msg.getNewValue()));
63
					fireListChange(diff);
64
					break;
65
				}
66
				case Notification.ADD_MANY: {
67
					Collection<?> newValues = (Collection<?>) msg.getNewValue();
68
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[newValues
69
							.size()];
70
					int position = msg.getPosition();
71
					int index = 0;
72
					for (Object newValue : newValues) {
73
						listDiffEntries[index++] = Diffs.createListDiffEntry(
74
								position++, true, newValue);
75
					}
76
					diff = Diffs.createListDiff(listDiffEntries);
77
					fireListChange(diff);
78
					break;
79
				}
80
				case Notification.REMOVE: {
81
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
82
							.getPosition(), false, msg.getOldValue()));
83
					fireListChange(diff);
84
					break;
85
				}
86
				case Notification.REMOVE_MANY: {
87
					Collection<?> oldValues = (Collection<?>) msg.getOldValue();
88
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues
89
							.size()];
90
					int position = msg.getPosition();
91
					int index = 0;
92
					for (Object oldValue : oldValues) {
93
						listDiffEntries[index++] = Diffs.createListDiffEntry(
94
								position++, false, oldValue);
95
					}
96
					diff = Diffs.createListDiff(listDiffEntries);
97
					fireListChange(diff);
98
					break;
99
				}
100
				case Notification.MOVE: {
101
					Object movedValue = msg.getNewValue();
102
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
103
					listDiffEntries[0] = Diffs.createListDiffEntry(
104
							(Integer) msg.getOldValue(), false, movedValue);
105
					listDiffEntries[1] = Diffs.createListDiffEntry(msg
106
							.getPosition(), true, movedValue);
107
					diff = Diffs.createListDiff(listDiffEntries);
108
					fireListChange(diff);
109
					break;
110
				}
111
				case Notification.UNSET: {
112
					// This just represents going back to the unset state, but
113
					// that doesn't affect the contents of the list.
114
					//
115
					return;
116
				}
117
				}
118
				
119
//				System.err.println("CHANGE: " + diff.getDifferences()[0].getElement());
120
				
121
//				fireListChange(diff);
122
//				listener.handlePropertyChange(new SimplePropertyEvent(msg
123
//						.getNotifier(), EMFListProperty.this, diff));
124
			}
125
		}
126
		
127
	}
128
	
129
	private Adapter listener;
130
	
131
	public EWritableList(NotifyingList<Type> wrappedList) {
132
		this(Realm.getDefault(), wrappedList);
133
	}
134
	
135
	public EWritableList(Realm realm, NotifyingList<Type> wrappedList) {
136
		this(realm, wrappedList, null);
137
	}
138
139
	public EWritableList(Realm realm, NotifyingList<Type> wrappedList, Class<Type> elementType) {
140
		super(realm);
141
		this.wrappedList = wrappedList; 
142
		this.elementType = elementType;
143
		if( wrappedList.getNotifier() instanceof Notifier ) {
144
			Notifier notifier = (Notifier) wrappedList.getNotifier();
145
			listener = new Listener(wrappedList.getFeature());
146
			notifier.eAdapters().add(listener);
147
		} else {
148
			throw new IllegalArgumentException("Wrapped list must have a notifier attached!");
149
		}		
150
	}
151
	
152
	@Override
153
	public synchronized void dispose() {
154
		((Notifier)wrappedList.getNotifier()).eAdapters().remove(listener);
155
		super.dispose();
156
	}
157
	
158
	protected void getterCalled() {
159
		ObservableTracker.getterCalled(this);
160
	}
161
162
	public boolean add(Object o) {
163
		checkRealm();
164
		return wrappedList.add((Type) o);
165
	}
166
167
	public boolean addAll(Collection c) {
168
		checkRealm();
169
		return wrappedList.addAll(c);
170
	}
171
172
	public boolean addAll(int index, Collection c) {
173
		checkRealm();
174
		return wrappedList.addAll(index, c);
175
	}
176
177
	public boolean contains(Object o) {
178
		getterCalled();
179
		return wrappedList.contains(o);
180
	}
181
182
	public boolean containsAll(Collection c) {
183
		getterCalled();
184
		return wrappedList.containsAll(c);
185
	}
186
187
	public Object get(int index) {
188
		getterCalled();
189
		return wrappedList.get(index);
190
	}
191
192
	public Object getElementType() {
193
		checkRealm();
194
		return elementType;
195
	}
196
197
	public int indexOf(Object o) {
198
		getterCalled();
199
		return wrappedList.indexOf(o);
200
	}
201
202
	public boolean isEmpty() {
203
		getterCalled();
204
		return wrappedList.isEmpty();
205
	}
206
207
	public Iterator<Type> iterator() {
208
		getterCalled();
209
		return wrappedList.iterator();
210
	}
211
212
	public int lastIndexOf(Object o) {
213
		getterCalled();
214
		return wrappedList.lastIndexOf(o);
215
	}
216
217
	public ListIterator<Type> listIterator() {
218
		getterCalled();
219
		return wrappedList.listIterator();
220
	}
221
222
	public ListIterator<Type> listIterator(int index) {
223
		getterCalled();
224
		return wrappedList.listIterator(index);
225
	}
226
227
	public Object move(int oldIndex, int newIndex) {
228
		checkRealm();
229
		return wrappedList.move(oldIndex, newIndex);
230
	}
231
232
	public boolean remove(Object o) {
233
		checkRealm();
234
		return wrappedList.remove(o);
235
	}
236
237
	public Object remove(int index) {
238
		checkRealm();
239
		return wrappedList.remove(index);
240
	}
241
242
	public boolean removeAll(Collection c) {
243
		checkRealm();
244
		return wrappedList.removeAll(c);
245
	}
246
247
	@SuppressWarnings("unchecked")
248
	public boolean retainAll(Collection c) {
249
		checkRealm();
250
		return wrappedList.retainAll(c);
251
	}
252
253
	@SuppressWarnings("unchecked")
254
	public Object set(int index, Object element) {
255
		checkRealm();
256
		return wrappedList.set(index, (Type) element);
257
	}
258
259
	public int doGetSize() {
260
		getterCalled();
261
		return wrappedList.size();
262
	}
263
264
	public List<Type> subList(int fromIndex, int toIndex) {
265
		getterCalled();
266
		return wrappedList.subList(fromIndex, toIndex);
267
	}
268
269
	public Object[] toArray() {
270
		getterCalled();
271
		return wrappedList.toArray();
272
	}
273
274
	public Object[] toArray(Object[] a) {
275
		getterCalled();
276
		return wrappedList.toArray();
277
	}
278
279
	public void add(int index, Object element) {
280
		checkRealm();
281
		wrappedList.add(index, (Type) element);
282
	}
283
284
	public void clear() {
285
		checkRealm();
286
		wrappedList.clear();
287
	}
288
289
	public boolean isStale() {
290
		getterCalled();
291
		return stale;
292
	}	
293
	
294
//	public void setStale(boolean stale) {
295
//		checkRealm();
296
//
297
//		boolean wasStale = this.stale;
298
//		this.stale = stale;
299
//		if (!wasStale && stale) {
300
//			fireStale();
301
//		}
302
//	}
303
}
(-)src/org/eclipse/emf/databinding/properties/IEMFValueProperty.java (+184 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.properties;
14
15
import org.eclipse.core.databinding.property.value.IValueProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * An {@link IValueProperty} extension interface with convenience methods for
24
 * creating nested bean properties.
25
 * 
26
 * @since 1.1
27
 * @noextend This interface is not intended to be extended by clients.
28
 * @noimplement This interface is not intended to be implemented by clients.
29
 */
30
public interface IEMFValueProperty extends IEMFProperty, IValueProperty {
31
	/**
32
	 * Returns a master-detail combination of this property and the specified
33
	 * value property.
34
	 * 
35
	 * @param featurePath
36
	 *            the value property to observe. May be nested e.g.
37
	 * 
38
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
39
	 * @return a master-detail combination of this property and the specified
40
	 *         value property.
41
	 * @see #value(IEMFValueProperty)
42
	 */
43
	public IEMFValueProperty value(EStructuralFeature... featurePath);
44
45
	/**
46
	 * Returns a master-detail combination of this property and the specified
47
	 * value property. The returned property will observe the specified detail
48
	 * value property for the value of the master value property.
49
	 * <p>
50
	 * Example:
51
	 * 
52
	 * <pre>
53
	 * // Observes the Node-typed &quot;parent&quot; property of a Node object
54
	 * IBeanValueProperty parent = BeanProperties.value(Node.class, &quot;parent&quot;);
55
	 * // Observes the string-typed &quot;name&quot; property of a Node object
56
	 * IBeanValueProperty name = BeanProperties.value(Node.class, &quot;name&quot;);
57
	 * // Observes the name of the parent of a Node object.
58
	 * IBeanValueProperty parentName = parent.value(name);
59
	 * </pre>
60
	 * 
61
	 * @param property
62
	 *            the detail property to observe
63
	 * @return a master-detail combination of this property and the specified
64
	 *         value property.
65
	 */
66
	public IEMFValueProperty value(IEMFValueProperty property);
67
68
	/**
69
	 * Returns a master-detail combination of this property and the specified
70
	 * list property.
71
	 * 
72
	 * @param feature
73
	 *            the list property to observe
74
	 * @return a master-detail combination of this property and the specified
75
	 *         list property.
76
	 * @see #list(IEMFListProperty)
77
	 */
78
	public IEMFListProperty list(EStructuralFeature feature);
79
80
	/**
81
	 * Returns a master-detail combination of this property and the specified
82
	 * list property. The returned property will observe the specified list
83
	 * property for the value of the master property.
84
	 * <p>
85
	 * Example:
86
	 * 
87
	 * <pre>
88
	 * // Observes the Node-typed &quot;parent&quot; property of a Node object.
89
	 * IBeanValueProperty parent = BeanProperties.value(Node.class, &quot;parent&quot;);
90
	 * // Observes the List-typed &quot;children&quot; property of a Node object
91
	 * // where the elements are Node objects
92
	 * IBeanListProperty children = BeanProperties.list(Node.class, &quot;children&quot;,
93
	 * 		Node.class);
94
	 * // Observes the children of the parent (siblings) of a Node object.
95
	 * IBeanListProperty siblings = parent.list(children);
96
	 * </pre>
97
	 * 
98
	 * @param property
99
	 *            the detail property to observe
100
	 * @return a master-detail combination of this property and the specified
101
	 *         list property.
102
	 */
103
	public IEMFListProperty list(IEMFListProperty property);
104
105
	// /**
106
	// * Returns a master-detail combination of this property and the specified
107
	// * set property.
108
	// *
109
	// * @param propertyName
110
	// * the set property to observe
111
	// * @return a master-detail combination of this property and the specified
112
	// * set property.
113
	// * @see #set(IEMFSetProperty)
114
	// */
115
	// public IEMFSetProperty set(EStructuralFeature featurePath);
116
	//
117
	// /**
118
	// * Returns a master-detail combination of this property and the specified
119
	// * set property. The returned property will observe the specified set
120
	// * property for the value of the master property.
121
	// * <p>
122
	// * Example:
123
	// *
124
	// * <pre>
125
	// * // Observes the Node-typed &quot;parent&quot; property of a Node
126
	// object.
127
	// * IBeanValueProperty parent = BeanProperties.value(Node.class,
128
	// &quot;parent&quot;);
129
	// * // Observes the Set-typed &quot;children&quot; property of a Node
130
	// object
131
	// * // where the elements are Node objects
132
	// * IBeanSetProperty children = BeanProperties.set(Node.class,
133
	// &quot;children&quot;,
134
	// * Node.class);
135
	// * // Observes the children of the parent (siblings) of a Node object.
136
	// * IBeanSetProperty siblings = parent.set(children);
137
	// * </pre>
138
	// *
139
	// * @param property
140
	// * the detail property to observe
141
	// * @return a master-detail combination of this property and the specified
142
	// * set property.
143
	// */
144
	// public IEMFSetProperty set(IEMFSetProperty property);
145
146
	/**
147
	 * Returns a master-detail combination of this property and the specified
148
	 * map property.
149
	 * 
150
	 * @param feature
151
	 *            the map property to observe
152
	 * @return a master-detail combination of this property and the specified
153
	 *         map property.
154
	 * @see #map(IEMFMapProperty)
155
	 */
156
	public IEMFMapProperty map(EStructuralFeature feature);
157
158
	/**
159
	 * Returns a master-detail combination of this property and the specified
160
	 * map property. The returned property will observe the specified map
161
	 * property for the value of the master property.
162
	 * <p>
163
	 * Example:
164
	 * 
165
	 * <pre>
166
	 * // Observes the Contact-typed &quot;supervisor&quot; property of a
167
	 * // Contact class 
168
	 * IBeanValueProperty supervisor = BeanProperties.value(Contact.class,
169
	 * 		&quot;supervisor&quot;);
170
	 * // Observes the property &quot;phoneNumbers&quot; of a Contact object--a property mapping
171
	 * // from PhoneNumberType to PhoneNumber &quot;set-typed &quot;children&quot;,
172
	 * IBeanMapProperty phoneNumbers = BeanProperties.map(Contact.class,
173
	 * 		&quot;phoneNumbers&quot;, PhoneNumberType.class, PhoneNumber.class);
174
	 * // Observes the phone numbers of a contact's supervisor:
175
	 * IBeanMapProperty supervisorPhoneNumbers = supervisor.map(phoneNumbers);
176
	 * </pre>
177
	 * 
178
	 * @param property
179
	 *            the detail property to observe
180
	 * @return a master-detail combination of this property and the specified
181
	 *         map property.
182
	 */
183
	public IEMFMapProperty map(IEMFMapProperty property);
184
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFMapProperty.java (+126 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.map.MapDiff;
19
import org.eclipse.core.databinding.property.INativePropertyListener;
20
import org.eclipse.core.databinding.property.ISimplePropertyListener;
21
import org.eclipse.core.databinding.property.SimplePropertyEvent;
22
import org.eclipse.core.databinding.property.map.SimpleMapProperty;
23
import org.eclipse.emf.common.notify.Adapter;
24
import org.eclipse.emf.common.notify.Notification;
25
import org.eclipse.emf.common.notify.impl.AdapterImpl;
26
import org.eclipse.emf.ecore.EObject;
27
import org.eclipse.emf.ecore.EStructuralFeature;
28
29
/**
30
 * <p>
31
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
32
 * removal.</b>
33
 * </p>
34
 * 
35
 * @since 1.1
36
 */
37
public class EMFMapProperty extends SimpleMapProperty {
38
39
	private final EStructuralFeature feature;
40
	private final Class<?> keyType;
41
	private final Class<?> valueType;
42
43
	/**
44
	 * @param feature
45
	 * @param keyType
46
	 * @param valueType
47
	 */
48
	public EMFMapProperty(EStructuralFeature feature, Class<?> keyType,
49
			Class<?> valueType) {
50
		this.feature = feature;
51
		this.keyType = keyType;
52
		this.valueType = valueType;
53
	}
54
55
	public Object getKeyType() {
56
		return keyType;
57
	}
58
59
	public Object getValueType() {
60
		return valueType;
61
	}
62
63
	@Override
64
	protected Map<?, ?> doGetMap(Object source) {
65
		EObject eObj = (EObject) source;
66
		return (Map<?, ?>) eObj.eGet(feature);
67
	}
68
69
	@SuppressWarnings("unchecked")
70
	@Override
71
	protected void doSetMap(Object source, Map map, MapDiff diff) {
72
		EObject eObject = (EObject) source;
73
		eObject.eSet(feature, map);
74
	}
75
76
	@Override
77
	public INativePropertyListener adaptListener(
78
			ISimplePropertyListener listener) {
79
		return new Listener(listener);
80
	}
81
82
	private class Listener extends AdapterImpl implements
83
			INativePropertyListener {
84
		private final ISimplePropertyListener listener;
85
86
		private Listener(ISimplePropertyListener listener) {
87
			this.listener = listener;
88
		}
89
90
		@Override
91
		public void notifyChanged(Notification msg) {
92
			if (feature == msg.getFeature() && !msg.isTouch()) {
93
				// TODO
94
				// This assumes we only get a SET notification, which isn't a
95
				// good assumption.
96
				//
97
				final MapDiff diff = Diffs.createMapDiffSingleChange(msg
98
						.getNotifier(), msg.getOldValue(), msg.getNewValue());
99
				listener.handlePropertyChange(new SimplePropertyEvent(msg
100
						.getNotifier(), EMFMapProperty.this, diff));
101
			}
102
		}
103
	}
104
105
	@Override
106
	protected void doAddListener(Object source, INativePropertyListener listener) {
107
		EObject eObj = (EObject) source;
108
		eObj.eAdapters().add((Adapter) listener);
109
	}
110
111
	@Override
112
	protected void doRemoveListener(Object source,
113
			INativePropertyListener listener) {
114
		EObject eObj = (EObject) source;
115
		eObj.eAdapters().remove((Adapter) listener);
116
	}
117
118
	@Override
119
	public String toString() {
120
		String s = feature.getName() + "{:}"; //$NON-NLS-1$
121
		if (keyType != null || valueType != null)
122
			s += "<" + (keyType != null ? keyType.getName() : "null") + ", " //$NON-NLS-1$ //$NON-NLS-2$
123
					+ (valueType != null ? valueType.getName() : "null") + ">"; //$NON-NLS-1$
124
		return super.toString();
125
	}
126
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFMapPropertyDecorator.java (+92 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.map.IObservableMap;
16
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
import org.eclipse.core.databinding.property.map.IMapProperty;
19
import org.eclipse.core.databinding.property.map.MapProperty;
20
import org.eclipse.emf.databinding.properties.EMFProperties;
21
import org.eclipse.emf.databinding.properties.IEMFMapProperty;
22
import org.eclipse.emf.databinding.properties.IEMFValueProperty;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
25
/**
26
 * <p>
27
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
28
 * removal.</b>
29
 * </p>
30
 * @since 1.1
31
 */
32
public class EMFMapPropertyDecorator extends MapProperty implements
33
		IEMFMapProperty {
34
	private final IMapProperty delegate;
35
	private final EStructuralFeature feature;
36
37
	/**
38
	 * @param delegate
39
	 * @param feature
40
	 */
41
	public EMFMapPropertyDecorator(IMapProperty delegate, EStructuralFeature feature) {
42
		this.delegate = delegate;
43
		this.feature = feature;
44
	}
45
	
46
	public EStructuralFeature getFeature() {
47
		return feature;
48
	}
49
50
	public Object getKeyType() {
51
		return delegate.getKeyType();
52
	}
53
54
	public Object getValueType() {
55
		return delegate.getValueType();
56
	}
57
	
58
	public IEMFMapProperty values(EStructuralFeature... featurePath) { 
59
		return values(EMFProperties.value(featurePath));
60
	}
61
62
	public IEMFMapProperty values(IEMFValueProperty property) {
63
		return new EMFMapPropertyDecorator(super.values(property),property.getFeature());
64
	}
65
66
	public IObservableMap observe(Object source) {
67
		return new EMFObservableMapDecorator(delegate.observe(source),
68
				feature);
69
	}
70
	
71
	public IObservableMap observe(Realm realm, Object source) {
72
		return new EMFObservableMapDecorator(delegate.observe(realm, source),
73
				feature);
74
	}
75
	
76
	public IObservableFactory mapFactory() {
77
		return delegate.mapFactory();
78
	}
79
80
	public IObservableFactory mapFactory(Realm realm) {
81
		return delegate.mapFactory(realm);
82
	}
83
84
	public IObservableMap observeDetail(IObservableValue master) {
85
		return new EMFObservableMapDecorator(delegate.observeDetail(master),
86
				feature);
87
	}
88
	
89
	public String toString() {
90
		return delegate.toString();
91
	}
92
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFObservableListDecorator.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 208858, 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.list.DecoratingObservableList;
18
import org.eclipse.core.databinding.observable.list.IObservableList;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
22
/**
23
 * <p>
24
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
25
 * removal.</b>
26
 * </p>
27
 * {@link IEMFObservable} decorator for an {@link IObservableList}.
28
 * 
29
 * @since 1.1
30
 */
31
public class EMFObservableListDecorator extends DecoratingObservableList
32
		implements IEMFObservable {
33
	private EStructuralFeature feature;
34
	
35
	/**
36
	 * @param decorated
37
	 * @param feature
38
	 */
39
	public EMFObservableListDecorator(IObservableList decorated, EStructuralFeature feature) {
40
		super(decorated, true);
41
		this.feature = feature;
42
	}
43
44
	public synchronized void dispose() {
45
		this.feature = null;
46
		super.dispose();
47
	}
48
	
49
	public EStructuralFeature getFeature() {
50
		return feature;
51
	}
52
53
	public Object getObserved() {
54
		IObservable decorated = getDecorated();
55
		if (decorated instanceof IObserving)
56
			return ((IObserving) decorated).getObserved();
57
		return null;
58
	}
59
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFListProperty.java (+174 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import java.util.Collection;
16
import java.util.List;
17
18
import org.eclipse.core.databinding.observable.Diffs;
19
import org.eclipse.core.databinding.observable.list.ListDiff;
20
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
21
import org.eclipse.core.databinding.property.INativePropertyListener;
22
import org.eclipse.core.databinding.property.ISimplePropertyListener;
23
import org.eclipse.core.databinding.property.SimplePropertyEvent;
24
import org.eclipse.core.databinding.property.list.SimpleListProperty;
25
import org.eclipse.emf.common.notify.Adapter;
26
import org.eclipse.emf.common.notify.Notification;
27
import org.eclipse.emf.common.notify.impl.AdapterImpl;
28
import org.eclipse.emf.ecore.EObject;
29
import org.eclipse.emf.ecore.EStructuralFeature;
30
31
/**
32
 * <p>
33
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
34
 * removal.</b>
35
 * </p>
36
 * @since 1.1
37
 */
38
public class EMFListProperty extends SimpleListProperty {
39
	private final EStructuralFeature feature;
40
41
	/**
42
	 * @param feature
43
	 */
44
	public EMFListProperty(EStructuralFeature feature) {
45
		this.feature = feature;
46
	}
47
48
	public Object getElementType() {
49
		return feature;
50
	}
51
52
	@Override
53
	protected List<?> doGetList(Object source) {
54
		EObject eObj = (EObject) source;
55
		return (List<?>) eObj.eGet(feature);
56
	}
57
58
	@SuppressWarnings("unchecked")
59
	@Override
60
	protected void doSetList(Object source, List list, ListDiff diff) {
61
		List<?> currentList = doGetList(source);
62
		diff.applyTo(currentList);
63
	}
64
65
	@Override
66
	public INativePropertyListener adaptListener(
67
			ISimplePropertyListener listener) {
68
		return new Listener(listener);
69
	}
70
71
	private class Listener extends AdapterImpl implements
72
			INativePropertyListener {
73
		private final ISimplePropertyListener listener;
74
75
		private Listener(ISimplePropertyListener listener) {
76
			this.listener = listener;
77
		}
78
79
		@Override
80
		public void notifyChanged(Notification msg) {
81
			if (feature == msg.getFeature() && !msg.isTouch()) {
82
				final ListDiff diff;
83
				switch (msg.getEventType()) {
84
				case Notification.ADD: {
85
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
86
							.getPosition(), true, msg.getNewValue()));
87
					break;
88
				}
89
				case Notification.ADD_MANY: {
90
					Collection<?> newValues = (Collection<?>) msg.getNewValue();
91
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[newValues
92
							.size()];
93
					int position = msg.getPosition();
94
					int index = 0;
95
					for (Object newValue : newValues) {
96
						listDiffEntries[index++] = Diffs.createListDiffEntry(
97
								position++, true, newValue);
98
					}
99
					diff = Diffs.createListDiff(listDiffEntries);
100
					break;
101
				}
102
				case Notification.REMOVE: {
103
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
104
							.getPosition(), false, msg.getOldValue()));
105
					break;
106
				}
107
				case Notification.REMOVE_MANY: {
108
					Collection<?> oldValues = (Collection<?>) msg.getOldValue();
109
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues
110
							.size()];
111
					int position = msg.getPosition();
112
					int index = 0;
113
					for (Object oldValue : oldValues) {
114
						listDiffEntries[index++] = Diffs.createListDiffEntry(
115
								position++, false, oldValue);
116
					}
117
					diff = Diffs.createListDiff(listDiffEntries);
118
					break;
119
				}
120
				case Notification.SET:
121
				case Notification.RESOLVE: {
122
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
123
					listDiffEntries[0] = Diffs.createListDiffEntry(msg
124
							.getPosition(), false, msg.getOldValue());
125
					listDiffEntries[1] = Diffs.createListDiffEntry(msg
126
							.getPosition(), true, msg.getNewValue());
127
					diff = Diffs.createListDiff(listDiffEntries);
128
					break;
129
				}
130
				case Notification.MOVE: {
131
					Object movedValue = msg.getNewValue();
132
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
133
					listDiffEntries[0] = Diffs.createListDiffEntry(
134
							(Integer) msg.getOldValue(), false, movedValue);
135
					listDiffEntries[1] = Diffs.createListDiffEntry(msg
136
							.getPosition(), true, movedValue);
137
					diff = Diffs.createListDiff(listDiffEntries);
138
					break;
139
				}
140
				case Notification.UNSET: {
141
					// This just represents going back to the unset state, but
142
					// that doesn't affect the contents of the list.
143
					//
144
					return;
145
				}
146
				default: {
147
					throw new RuntimeException("unhandled case");
148
				}
149
				}
150
				listener.handlePropertyChange(new SimplePropertyEvent(msg
151
						.getNotifier(), EMFListProperty.this, diff));
152
			}
153
		}
154
	}
155
156
	@Override
157
	protected void doAddListener(Object source, INativePropertyListener listener) {
158
		EObject eObj = (EObject) source;
159
		eObj.eAdapters().add((Adapter) listener);
160
	}
161
162
	@Override
163
	protected void doRemoveListener(Object source,
164
			INativePropertyListener listener) {
165
		EObject eObj = (EObject) source;
166
		eObj.eAdapters().remove((Adapter) listener);
167
	}
168
	
169
	public String toString() {
170
		String s = feature.getName() + "[]";
171
		s += "<" + feature.getEType().getInstanceClassName() + ">";
172
		return s;
173
	}
174
}
(-)src/org/eclipse/emf/databinding/properties/EMFProperties.java (+116 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222, 247997, 261843
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties;
14
15
import org.eclipse.core.databinding.property.list.IListProperty;
16
import org.eclipse.core.databinding.property.map.IMapProperty;
17
import org.eclipse.core.databinding.property.value.IValueProperty;
18
import org.eclipse.emf.databinding.properties.internal.EMFListProperty;
19
import org.eclipse.emf.databinding.properties.internal.EMFListPropertyDecorator;
20
import org.eclipse.emf.databinding.properties.internal.EMFMapProperty;
21
import org.eclipse.emf.databinding.properties.internal.EMFMapPropertyDecorator;
22
import org.eclipse.emf.databinding.properties.internal.EMFValueProperty;
23
import org.eclipse.emf.databinding.properties.internal.EMFValuePropertyDecorator;
24
import org.eclipse.emf.ecore.EObject;
25
import org.eclipse.emf.ecore.EStructuralFeature;
26
27
/**
28
 * <p>
29
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
30
 * removal.</b>
31
 * </p>
32
 * A factory for creating properties for {@link EObject} objects
33
 * 
34
 * @since 1.1
35
 */
36
public class EMFProperties {
37
	/**
38
	 * Returns a value property for the given property name of an arbitrary bean
39
	 * class. Objects lacking the named property are treated the same as if the
40
	 * property always contains null.
41
	 * 
42
	 * @param featurePath
43
	 *            the property name. May be nested e.g.
44
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
45
	 * @return a value property for the given property name of an arbitrary bean
46
	 *         class.
47
	 */
48
	public static IEMFValueProperty value(EStructuralFeature... featurePath) {
49
		IValueProperty property = new EMFValueProperty(featurePath[0]);
50
51
		IEMFValueProperty emfProperty = new EMFValuePropertyDecorator(property,
52
				featurePath[0]);
53
		for (int i = 1; i < featurePath.length; i++) {
54
			emfProperty = emfProperty.value(featurePath[i]);
55
		}
56
		return emfProperty;
57
	}
58
59
	// public static IEMFValueProperty[] values(EStructuralFeature[]...
60
	// features) {
61
	// return null;
62
	// }
63
64
	// public static IEMFSetProperty set(EStructuralFeature feature) {
65
	// ISetProperty property = new EMFSetProperty(feature, elementType);
66
	// return new EMFSetPropertyDecorator(property, feature);
67
	// }
68
69
	/**
70
	 * Returns a list property for the given property name of an arbitrary bean
71
	 * class. Objects lacking the named property are treated the same as if the
72
	 * property always contains an empty list.
73
	 * 
74
	 * @param feature
75
	 *            the property name
76
	 * @return a list property for the given property name of an arbitrary bean
77
	 *         class.
78
	 */
79
	public static IEMFListProperty list(EStructuralFeature feature) {
80
		IListProperty property = new EMFListProperty(feature);
81
		return new EMFListPropertyDecorator(property, feature);
82
	}
83
84
	/**
85
	 * Returns a map property for the given property name of an arbitrary bean
86
	 * class. Objects lacking the named property are treated the same as if the
87
	 * property always contains an empty map.
88
	 * 
89
	 * @param feature
90
	 *            the property name
91
	 * @return a map property for the given property name of an arbitrary bean
92
	 *         class.
93
	 */
94
	public static IEMFMapProperty map(EStructuralFeature feature) {
95
		return map(feature, null, null);
96
	}
97
98
	/**
99
	 * Returns a map property for the given property name of the given bean
100
	 * class.
101
	 * 
102
	 * @param feature
103
	 *            the property name
104
	 * @param keyType
105
	 *            the key type for the returned map property
106
	 * @param valueType
107
	 *            the value type for the returned map property
108
	 * @return a map property for the given property name of the given bean
109
	 *         class.
110
	 */
111
	public static IEMFMapProperty map(EStructuralFeature feature,
112
			Class<?> keyType, Class<?> valueType) {
113
		IMapProperty property = new EMFMapProperty(feature, keyType, valueType);
114
		return new EMFMapPropertyDecorator(property, feature);
115
	}
116
}
(-)src/org/eclipse/emf/databinding/properties/IEMFMapProperty.java (+60 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.properties;
14
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.property.map.IMapProperty;
18
import org.eclipse.emf.ecore.EStructuralFeature;
19
20
/**
21
 * <p>
22
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
23
 * removal.</b>
24
 * </p>
25
 * An {@link IMapProperty} extension interface with convenience methods for
26
 * creating nested bean properties.
27
 * 
28
 * @since 1.1
29
 * @noextend This interface is not intended to be extended by clients.
30
 * @noimplement This interface is not intended to be implemented by clients.
31
 */
32
public interface IEMFMapProperty extends IEMFProperty, IMapProperty {
33
	/**
34
	 * Returns a master-detail combination of this property and the specified
35
	 * value property.
36
	 * 
37
	 * @param featurePath
38
	 *            the value property to observe. May be nested e.g.
39
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
40
	 * @return a master-detail combination of this property and the specified
41
	 *         value property.
42
	 * @see #values(IEMFValueProperty)
43
	 */
44
	public IEMFMapProperty values(EStructuralFeature... featurePath);
45
46
	/**
47
	 * Returns a master-detail combination of this property and the specified
48
	 * value property. The returned property will observe the specified value
49
	 * property for all {@link Map#values() values} observed by this map
50
	 * property, mapping from this map property's {@link Map#keySet() key set}
51
	 * to the specified value property's value for each element in the master
52
	 * property's {@link Map#values() values} collection.
53
	 * 
54
	 * @param property
55
	 *            the detail property to observe
56
	 * @return a master-detail combination of this property and the specified
57
	 *         value property.
58
	 */
59
	public IEMFMapProperty values(IEMFValueProperty property);
60
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFListPropertyDecorator.java (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
import org.eclipse.core.databinding.property.list.IListProperty;
19
import org.eclipse.core.databinding.property.list.ListProperty;
20
import org.eclipse.emf.databinding.properties.EMFProperties;
21
import org.eclipse.emf.databinding.properties.IEMFListProperty;
22
import org.eclipse.emf.databinding.properties.IEMFValueProperty;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
25
/**
26
 * <p>
27
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
28
 * removal.</b>
29
 * </p>
30
 * @since 1.1
31
 */
32
public class EMFListPropertyDecorator extends ListProperty implements IEMFListProperty {
33
	private final IListProperty delegate;
34
	private final EStructuralFeature feature;
35
	
36
	/**
37
	 * @param delegate
38
	 * @param feature
39
	 */
40
	public EMFListPropertyDecorator(IListProperty delegate, EStructuralFeature feature) {
41
		this.delegate = delegate;
42
		this.feature = feature;
43
	}
44
	
45
	public Object getElementType() {
46
		return feature.getEType().getInstanceClass();
47
	}
48
	
49
	public IEMFListProperty values(EStructuralFeature... feature) {
50
		return values(EMFProperties.value(feature));
51
	}
52
	public IEMFListProperty values(IEMFValueProperty property) {
53
		return new EMFListPropertyDecorator(super.values(property),property.getFeature());
54
	}
55
	public EStructuralFeature getFeature() {
56
		return feature;
57
	}
58
	
59
	public IObservableList observe(Object source) {
60
		return new EMFObservableListDecorator(delegate.observe(source),
61
				feature);
62
	}
63
	
64
	public IObservableList observe(Realm realm, Object source) {
65
		return new EMFObservableListDecorator(delegate.observe(realm, source),
66
				feature);
67
	}
68
	
69
	public IObservableFactory listFactory() {
70
		return delegate.listFactory();
71
	}
72
	
73
	public IObservableFactory listFactory(Realm realm) {
74
		return delegate.listFactory(realm);
75
	}
76
77
	public IObservableList observeDetail(IObservableValue master) {
78
		return new EMFObservableListDecorator(delegate.observeDetail(master),
79
				feature);
80
	}
81
	
82
	public String toString() {
83
		return delegate.toString();
84
	}
85
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFValuePropertyDecorator.java (+127 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.core.databinding.observable.map.IObservableMap;
17
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
18
import org.eclipse.core.databinding.observable.set.IObservableSet;
19
import org.eclipse.core.databinding.observable.value.IObservableValue;
20
import org.eclipse.core.databinding.property.value.IValueProperty;
21
import org.eclipse.core.databinding.property.value.ValueProperty;
22
import org.eclipse.emf.databinding.properties.EMFProperties;
23
import org.eclipse.emf.databinding.properties.IEMFListProperty;
24
import org.eclipse.emf.databinding.properties.IEMFMapProperty;
25
import org.eclipse.emf.databinding.properties.IEMFValueProperty;
26
import org.eclipse.emf.ecore.EStructuralFeature;
27
28
/**
29
 * <p>
30
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
31
 * removal.</b>
32
 * </p>
33
 * @since 1.1
34
 */
35
public class EMFValuePropertyDecorator extends ValueProperty implements IEMFValueProperty {
36
	private final IValueProperty delegate;
37
	private final EStructuralFeature feature;
38
	
39
	/**
40
	 * @param delegate
41
	 * @param feature
42
	 */
43
	public EMFValuePropertyDecorator(IValueProperty delegate, EStructuralFeature feature) {
44
		this.delegate = delegate;
45
		this.feature = feature;
46
	}
47
	
48
	public Object getValueType() {
49
		return delegate.getValueType();
50
	}
51
	
52
	public EStructuralFeature getFeature() {
53
		return feature;
54
	}
55
	
56
	public IEMFValueProperty value(EStructuralFeature... featurePath) {
57
		return value(EMFProperties.value(featurePath));
58
	}
59
60
	public IEMFValueProperty value(IEMFValueProperty property) {
61
		return new EMFValuePropertyDecorator(super.value(property),property.getFeature());
62
	}
63
	
64
	public IEMFListProperty list(EStructuralFeature featurePath) {
65
		return list(EMFProperties.list(featurePath));
66
	}
67
68
	public IEMFListProperty list(IEMFListProperty property) {
69
		return new EMFListPropertyDecorator(super.list(property),property.getFeature());
70
	}
71
	
72
//	public IEMFSetProperty set(EStructuralFeature featurePath) {
73
//		// TODO Auto-generated method stub
74
//		return null;
75
//	}
76
//
77
//	public IEMFSetProperty set(IEMFSetProperty property) {
78
//		// TODO Auto-generated method stub
79
//		return null;
80
//	}
81
82
	public IEMFMapProperty map(EStructuralFeature featurePath) {
83
		return map(EMFProperties.map(featurePath));
84
	}
85
86
	public IEMFMapProperty map(IEMFMapProperty property) {
87
		return new EMFMapPropertyDecorator(super.map(property),property.getFeature());
88
	}
89
90
	public IObservableValue observe(Object source) {
91
		return new EMFObservableValueDecorator(delegate.observe(source),
92
				feature);
93
	}
94
	
95
	public IObservableValue observe(Realm realm, Object source) {
96
		return new EMFObservableValueDecorator(
97
				delegate.observe(realm, source), feature);
98
	}
99
	
100
	public IObservableFactory valueFactory() {
101
		return delegate.valueFactory();
102
	}
103
104
	public IObservableFactory valueFactory(Realm realm) {
105
		return delegate.valueFactory(realm);
106
	}
107
108
	public IObservableValue observeDetail(IObservableValue master) {
109
		return new EMFObservableValueDecorator(delegate.observeDetail(master),
110
				feature);
111
	}
112
113
	public IObservableList observeDetail(IObservableList master) {
114
		return new EMFObservableListDecorator(delegate.observeDetail(master),
115
				feature);
116
	}
117
	
118
	public IObservableMap observeDetail(IObservableSet master) {
119
		return new EMFObservableMapDecorator(delegate.observeDetail(master),
120
				feature);
121
	}
122
123
	public IObservableMap observeDetail(IObservableMap master) {
124
		return new EMFObservableMapDecorator(delegate.observeDetail(master),
125
				feature);
126
	}
127
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFObservableValueDecorator.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.value.DecoratingObservableValue;
18
import org.eclipse.core.databinding.observable.value.IObservableValue;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
22
/**
23
 * <p>
24
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
25
 * removal.</b>
26
 * </p>
27
 * {@link IEMFObservable} decorator for an {@link IObservableValue}.
28
 * 
29
 * @since 1.1
30
 */
31
public class EMFObservableValueDecorator extends DecoratingObservableValue
32
		implements IEMFObservable {
33
	private EStructuralFeature feature;
34
	
35
	/**
36
	 * @param decorated
37
	 * @param feature
38
	 */
39
	public EMFObservableValueDecorator(IObservableValue decorated, EStructuralFeature feature) {
40
		super(decorated, true);
41
		this.feature = feature;
42
	}
43
	
44
	public synchronized void dispose() {
45
		this.feature = null;
46
		super.dispose();
47
	}
48
49
	public EStructuralFeature getFeature() {
50
		return feature;
51
	}
52
53
	public Object getObserved() {
54
		IObservable decorated = getDecorated();
55
		if (decorated instanceof IObserving)
56
			return ((IObserving) decorated).getObserved();
57
		return null;
58
	}
59
}
(-)src/org/eclipse/emf/databinding/properties/IEMFListProperty.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.properties;
14
15
import org.eclipse.core.databinding.property.list.IListProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * An {@link IListProperty} extension interface with convenience methods for
24
 * creating nested bean properties.
25
 * 
26
 * @since 1.1
27
 * @noextend This interface is not intended to be extended by clients.
28
 * @noimplement This interface is not intended to be implemented by clients.
29
 */
30
public interface IEMFListProperty extends IEMFProperty, IListProperty {
31
	/**
32
	 * Returns a master-detail combination of this property and the specified
33
	 * value property.
34
	 * 
35
	 * @param featurePath
36
	 *            the value property to observe. May be nested e.g.
37
	 * 
38
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
39
	 * @return a nested combination of this property and the specified value
40
	 *         property.
41
	 * @see #values(IEMFValueProperty)
42
	 */
43
	public IEMFListProperty values(EStructuralFeature... featurePath);
44
45
	/**
46
	 * Returns a master-detail combination of this property and the specified
47
	 * value property. The returned property will observe the specified value
48
	 * property for all elements observed by this list property.
49
	 * <p>
50
	 * Example:
51
	 * 
52
	 * <pre>
53
	 * // Observes the list-typed &quot;children&quot; property of a Person object,
54
	 * // where the elements are Person objects
55
	 * IBeanListProperty children = BeanProperties.list(Person.class, &quot;children&quot;,
56
	 * 		Person.class);
57
	 * // Observes the string-typed &quot;name&quot; property of a Person object
58
	 * IBeanValueProperty name = BeanProperties.value(Person.class, &quot;name&quot;);
59
	 * // Observes the names of children of a Person object.
60
	 * IBeanListProperty childrenNames = children.values(name);
61
	 * </pre>
62
	 * 
63
	 * @param property
64
	 *            the detail property to observe
65
	 * @return a master-detail combination of this property and the specified
66
	 *         value property.
67
	 */
68
	public IEMFListProperty values(IEMFValueProperty property);
69
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFObservableMapDecorator.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 221704)
10
 *     Matthew Hall - bug 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.map.DecoratingObservableMap;
18
import org.eclipse.core.databinding.observable.map.IObservableMap;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
22
/**
23
 * <p>
24
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
25
 * removal.</b>
26
 * </p>
27
 * {@link IEMFObservable} decorator for an {@link IObservableMap}.
28
 * 
29
 * @since 1.1
30
 */
31
public class EMFObservableMapDecorator extends DecoratingObservableMap
32
		implements IEMFObservable {
33
	private EStructuralFeature feature;
34
35
	/**
36
	 * @param decorated
37
	 * @param feature
38
	 */
39
	public EMFObservableMapDecorator(IObservableMap decorated, EStructuralFeature feature) {
40
		super(decorated, true);
41
		this.feature = feature;
42
	}
43
44
	public synchronized void dispose() {
45
		this.feature = null;
46
		super.dispose();
47
	}
48
	
49
	public EStructuralFeature getFeature() {
50
		return feature;
51
	}
52
53
	public Object getObserved() {
54
		IObservable decorated = getDecorated();
55
		if (decorated instanceof IObserving)
56
			return ((IObserving) decorated).getObserved();
57
		return null;
58
	}
59
}
(-).settings/org.eclipse.jdt.core.prefs (+15 lines)
Added Link Here
1
#Sat Jan 24 17:20:53 CET 2009
2
eclipse.preferences.version=1
3
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
4
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
5
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
6
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
7
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
8
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
9
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
10
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
11
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
12
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
13
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
14
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
15
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
(-)src/org/eclipse/emf/databinding/properties/internal/EMFValueProperty.java (+109 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties.internal;
14
15
import org.eclipse.core.databinding.observable.Diffs;
16
import org.eclipse.core.databinding.observable.value.ValueDiff;
17
import org.eclipse.core.databinding.property.INativePropertyListener;
18
import org.eclipse.core.databinding.property.ISimplePropertyListener;
19
import org.eclipse.core.databinding.property.SimplePropertyEvent;
20
import org.eclipse.core.databinding.property.value.SimpleValueProperty;
21
import org.eclipse.emf.common.notify.Adapter;
22
import org.eclipse.emf.common.notify.Notification;
23
import org.eclipse.emf.common.notify.impl.AdapterImpl;
24
import org.eclipse.emf.ecore.EObject;
25
import org.eclipse.emf.ecore.EStructuralFeature;
26
27
/**
28
 * <p>
29
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
30
 * removal.</b>
31
 * </p>
32
 * @since 1.1
33
 */
34
public class EMFValueProperty extends SimpleValueProperty {
35
	private EStructuralFeature feature;
36
	
37
	/**
38
	 * @param feature
39
	 */
40
	public EMFValueProperty(EStructuralFeature feature) {
41
		this.feature = feature;
42
	}
43
	
44
	public Object getValueType() {
45
		return feature.getEType().getInstanceClass();
46
	}
47
	
48
	@Override
49
	protected Object doGetValue(Object source) {
50
		EObject eObj = (EObject) source;
51
		return eObj.eGet(feature);
52
	}
53
54
	
55
	@Override
56
	protected void doSetValue(Object source, Object value) {
57
		EObject eObj = (EObject) source;
58
		eObj.eSet(feature, value);
59
	}
60
	
61
	@Override
62
	public INativePropertyListener adaptListener(
63
			ISimplePropertyListener listener) {
64
		return new Listener(listener);
65
	}
66
	
67
	private class Listener extends AdapterImpl implements INativePropertyListener {
68
		private final ISimplePropertyListener listener;
69
		
70
		private Listener(ISimplePropertyListener listener) {
71
			this.listener = listener;
72
		}
73
74
		@Override
75
		public void notifyChanged(Notification msg) {
76
			if( feature == msg.getFeature() && !msg.isTouch() ) {
77
				ValueDiff diff;
78
				Object oldValue = msg.getOldValue();
79
				Object newValue = msg.getNewValue();
80
				if (oldValue != null && newValue != null) {
81
					diff = Diffs.createValueDiff(oldValue, newValue);
82
				} else {
83
					diff = null;
84
				}
85
				listener.handlePropertyChange(new SimplePropertyEvent(msg.getNotifier(), EMFValueProperty.this, diff));				
86
			}
87
		}
88
	}
89
90
	@Override
91
	protected void doAddListener(Object source, INativePropertyListener listener) {
92
		EObject eObj = (EObject) source;
93
		eObj.eAdapters().add((Adapter) listener);
94
	}
95
96
	
97
	@Override
98
	protected void doRemoveListener(Object source,
99
			INativePropertyListener listener) {
100
		EObject eObj = (EObject) source;
101
		eObj.eAdapters().remove((Adapter) listener);
102
	}	
103
	
104
	public String toString() {
105
		String s = feature.getName();
106
		s += "<" + feature.getEType().getInstanceClassName() + ">"; //$NON-NLS-1$//$NON-NLS-2$
107
		return s;
108
	}
109
}
(-)src/org/eclipse/emf/databinding/properties/IEMFProperty.java (+35 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.properties;
14
15
import org.eclipse.core.databinding.property.IProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * An IProperty extension interface providing access to details of bean
24
 * properties.
25
 * 
26
 * @since 1.1
27
 * @noextend This interface is not intended to be extended by clients.
28
 * @noimplement This interface is not intended to be implemented by clients.
29
 */
30
public interface IEMFProperty extends IProperty {
31
	/**
32
	 * @return the feature observed
33
	 */
34
	public EStructuralFeature getFeature();
35
}
(-)src/org/eclipse/emf/databinding/properties/IEMFObservable.java (+36 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Brad Reynolds - bug 147515
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.properties;
14
15
import org.eclipse.core.databinding.observable.IObserving;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * Provides access to details of EMF observables.
24
 * <p>
25
 * This interface is not meant to be implemented by clients.
26
 * </p>
27
 * 
28
 * @since 1.1
29
 * @noimplement This interface is not intended to be implemented by clients.
30
 */
31
public interface IEMFObservable extends IObserving {
32
	/**
33
	 * @return the feature observed
34
	 */
35
	public EStructuralFeature getFeature();
36
}
(-)src/org/eclipse/emf/databinding/edit/EMFEditObservables.java (-1 / +1 lines)
Lines 105-111 Link Here
105
   * @param eStructuralFeatures the features for which to track the value.
105
   * @param eStructuralFeatures the features for which to track the value.
106
   * @return an array of observable maps tracking the current value of the given features for each object in the given set.
106
   * @return an array of observable maps tracking the current value of the given features for each object in the given set.
107
   */
107
   */
108
  public static IObservableMap[] observeMaps(EditingDomain domain, IObservableSet objects, EStructuralFeature[] eStructuralFeatures)
108
  public static IObservableMap[] observeMaps(EditingDomain domain, IObservableSet objects, EStructuralFeature... eStructuralFeatures)
109
  {
109
  {
110
    IObservableMap[] result = new IObservableMap [eStructuralFeatures.length];
110
    IObservableMap[] result = new IObservableMap [eStructuralFeatures.length];
111
    for (int i = 0; i < eStructuralFeatures.length; i++)
111
    for (int i = 0; i < eStructuralFeatures.length; i++)
(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 8-14 Link Here
8
Bundle-Vendor: %providerName
8
Bundle-Vendor: %providerName
9
Bundle-Localization: plugin
9
Bundle-Localization: plugin
10
Bundle-RequiredExecutionEnvironment: J2SE-1.5
10
Bundle-RequiredExecutionEnvironment: J2SE-1.5
11
Export-Package: org.eclipse.emf.databinding.edit
11
Export-Package: org.eclipse.emf.databinding.edit,
12
 org.eclipse.emf.databinding.edit.properties
12
Require-Bundle: org.eclipse.core.runtime,
13
Require-Bundle: org.eclipse.core.runtime,
13
 org.eclipse.emf.databinding;visibility:=reexport,
14
 org.eclipse.emf.databinding;visibility:=reexport,
14
 org.eclipse.emf.edit;visibility:=reexport
15
 org.eclipse.emf.edit;visibility:=reexport
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditValuePropertyDecorator.java (+134 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.edit.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.core.databinding.observable.map.IObservableMap;
17
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
18
import org.eclipse.core.databinding.observable.set.IObservableSet;
19
import org.eclipse.core.databinding.observable.value.IObservableValue;
20
import org.eclipse.core.databinding.property.value.IValueProperty;
21
import org.eclipse.core.databinding.property.value.ValueProperty;
22
import org.eclipse.emf.databinding.edit.properties.EMFEditProperties;
23
import org.eclipse.emf.databinding.edit.properties.IEMFEditListProperty;
24
import org.eclipse.emf.databinding.edit.properties.IEMFEditMapProperty;
25
import org.eclipse.emf.databinding.edit.properties.IEMFEditValueProperty;
26
import org.eclipse.emf.ecore.EStructuralFeature;
27
import org.eclipse.emf.edit.domain.EditingDomain;
28
29
/**
30
 * <p>
31
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
32
 * removal.</b>
33
 * </p>
34
 * @since 1.1
35
 */
36
public class EMFEditValuePropertyDecorator extends ValueProperty implements IEMFEditValueProperty {
37
	private final IValueProperty delegate;
38
	private final EStructuralFeature feature;
39
	private EditingDomain domain;
40
	
41
	/**
42
	 * @param delegate
43
	 * @param feature
44
	 */
45
	public EMFEditValuePropertyDecorator(EditingDomain domain, IValueProperty delegate, EStructuralFeature feature) {
46
		this.delegate = delegate;
47
		this.feature = feature;
48
		this.domain = domain;
49
	}
50
	
51
	public Object getValueType() {
52
		return delegate.getValueType();
53
	}
54
	
55
	public EStructuralFeature getFeature() {
56
		return feature;
57
	}
58
	
59
	public IEMFEditValueProperty value(EStructuralFeature... featurePath) {
60
		return value(EMFEditProperties.value(domain, featurePath));
61
	}
62
63
	public IEMFEditValueProperty value(IEMFEditValueProperty property) {
64
		return new EMFEditValuePropertyDecorator(property.getDomain(), super.value(property),property.getFeature());
65
	}
66
	
67
	public IEMFEditListProperty list(EStructuralFeature featurePath) {
68
		return list(EMFEditProperties.list(domain, featurePath));
69
	}
70
71
	public IEMFEditListProperty list(IEMFEditListProperty property) {
72
		return new EMFEditListPropertyDecorator(property.getDomain(), super.list(property),property.getFeature());
73
	}
74
	
75
//	public IEMFSetProperty set(EStructuralFeature featurePath) {
76
//		// TODO Auto-generated method stub
77
//		return null;
78
//	}
79
//
80
//	public IEMFSetProperty set(IEMFSetProperty property) {
81
//		// TODO Auto-generated method stub
82
//		return null;
83
//	}
84
85
	public IEMFEditMapProperty map(EStructuralFeature featurePath) {
86
		return map(EMFEditProperties.map(domain, featurePath));
87
	}
88
89
	public IEMFEditMapProperty map(IEMFEditMapProperty property) {
90
		return new EMFEditMapPropertyDecorator(property.getDomain(), super.map(property),property.getFeature());
91
	}
92
93
	public IObservableValue observe(Object source) {
94
		return new EMFEditObservableValueDecorator(domain, delegate.observe(source),
95
				feature);
96
	}
97
	
98
	public IObservableValue observe(Realm realm, Object source) {
99
		return new EMFEditObservableValueDecorator(domain,
100
				delegate.observe(realm, source), feature);
101
	}
102
	
103
	public IObservableFactory valueFactory() {
104
		return delegate.valueFactory();
105
	}
106
107
	public IObservableFactory valueFactory(Realm realm) {
108
		return delegate.valueFactory(realm);
109
	}
110
111
	public IObservableValue observeDetail(IObservableValue master) {
112
		return new EMFEditObservableValueDecorator(domain,delegate.observeDetail(master),
113
				feature);
114
	}
115
116
	public IObservableList observeDetail(IObservableList master) {
117
		return new EMFEditObservableListDecorator(domain, delegate.observeDetail(master),
118
				feature);
119
	}
120
	
121
	public IObservableMap observeDetail(IObservableSet master) {
122
		return new EMFEditObservableMapDecorator(domain, delegate.observeDetail(master),
123
				feature);
124
	}
125
126
	public IObservableMap observeDetail(IObservableMap master) {
127
		return new EMFEditObservableMapDecorator(domain, delegate.observeDetail(master),
128
				feature);
129
	}
130
131
	public EditingDomain getDomain() {
132
		return domain;
133
	}
134
}
(-)src/org/eclipse/emf/databinding/edit/properties/IEMFEditObservable.java (+38 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Brad Reynolds - bug 147515
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import org.eclipse.core.databinding.observable.IObserving;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
import org.eclipse.emf.edit.domain.EditingDomain;
18
19
/**
20
 * <p>
21
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
22
 * removal.</b>
23
 * </p>
24
 * Provides access to details of EMF observables.
25
 * <p>
26
 * This interface is not meant to be implemented by clients.
27
 * </p>
28
 * 
29
 * @since 1.1
30
 * @noimplement This interface is not intended to be implemented by clients.
31
 */
32
public interface IEMFEditObservable extends IObserving {
33
	/**
34
	 * @return the feature observed
35
	 */
36
	public EStructuralFeature getFeature();
37
	public EditingDomain getDomain();
38
}
(-)src/org/eclipse/emf/databinding/edit/properties/IEMFEditListProperty.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import org.eclipse.core.databinding.property.list.IListProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * An {@link IListProperty} extension interface with convenience methods for
24
 * creating nested bean properties.
25
 * 
26
 * @since 1.1
27
 * @noextend This interface is not intended to be extended by clients.
28
 * @noimplement This interface is not intended to be implemented by clients.
29
 */
30
public interface IEMFEditListProperty extends IEMFEditProperty, IListProperty {
31
	/**
32
	 * Returns a master-detail combination of this property and the specified
33
	 * value property.
34
	 * 
35
	 * @param featurePath
36
	 *            the value property to observe. May be nested e.g.
37
	 * 
38
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
39
	 * @return a nested combination of this property and the specified value
40
	 *         property.
41
	 * @see #values(IEMFEditValueProperty)
42
	 */
43
	public IEMFEditListProperty values(EStructuralFeature... featurePath);
44
45
	/**
46
	 * Returns a master-detail combination of this property and the specified
47
	 * value property. The returned property will observe the specified value
48
	 * property for all elements observed by this list property.
49
	 * <p>
50
	 * Example:
51
	 * 
52
	 * <pre>
53
	 * // Observes the list-typed &quot;children&quot; property of a Person object,
54
	 * // where the elements are Person objects
55
	 * IBeanListProperty children = BeanProperties.list(Person.class, &quot;children&quot;,
56
	 * 		Person.class);
57
	 * // Observes the string-typed &quot;name&quot; property of a Person object
58
	 * IBeanValueProperty name = BeanProperties.value(Person.class, &quot;name&quot;);
59
	 * // Observes the names of children of a Person object.
60
	 * IBeanListProperty childrenNames = children.values(name);
61
	 * </pre>
62
	 * 
63
	 * @param property
64
	 *            the detail property to observe
65
	 * @return a master-detail combination of this property and the specified
66
	 *         value property.
67
	 */
68
	public IEMFEditListProperty values(IEMFEditValueProperty property);
69
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditObservableListDecorator.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 208858, 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.list.DecoratingObservableList;
18
import org.eclipse.core.databinding.observable.list.IObservableList;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
import org.eclipse.emf.edit.domain.EditingDomain;
22
23
/**
24
 * <p>
25
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
26
 * removal.</b>
27
 * </p>
28
 * {@link IEMFObservable} decorator for an {@link IObservableList}.
29
 * 
30
 * @since 1.1
31
 */
32
public class EMFEditObservableListDecorator extends DecoratingObservableList
33
		implements IEMFObservable {
34
	private EStructuralFeature feature;
35
	private EditingDomain domain;
36
	
37
	/**
38
	 * @param decorated
39
	 * @param feature
40
	 */
41
	public EMFEditObservableListDecorator(EditingDomain domain, IObservableList decorated, EStructuralFeature feature) {
42
		super(decorated, true);
43
		this.feature = feature;
44
		this.domain = domain;
45
	}
46
47
	public synchronized void dispose() {
48
		this.feature = null;
49
		super.dispose();
50
	}
51
	
52
	public EStructuralFeature getFeature() {
53
		return feature;
54
	}
55
56
	public Object getObserved() {
57
		IObservable decorated = getDecorated();
58
		if (decorated instanceof IObserving)
59
			return ((IObserving) decorated).getObserved();
60
		return null;
61
	}
62
}
(-)src/org/eclipse/emf/databinding/edit/properties/IEMFEditProperty.java (+37 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import org.eclipse.core.databinding.property.IProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
import org.eclipse.emf.edit.domain.EditingDomain;
18
19
/**
20
 * <p>
21
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
22
 * removal.</b>
23
 * </p>
24
 * An IProperty extension interface providing access to details of bean
25
 * properties.
26
 * 
27
 * @since 1.1
28
 * @noextend This interface is not intended to be extended by clients.
29
 * @noimplement This interface is not intended to be implemented by clients.
30
 */
31
public interface IEMFEditProperty extends IProperty {
32
	/**
33
	 * @return the feature observed
34
	 */
35
	public EStructuralFeature getFeature();
36
	public EditingDomain getDomain();
37
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditListProperty.java (+214 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import java.util.Collection;
16
import java.util.List;
17
18
import org.eclipse.core.databinding.observable.Diffs;
19
import org.eclipse.core.databinding.observable.list.ListDiff;
20
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
21
import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
22
import org.eclipse.core.databinding.property.INativePropertyListener;
23
import org.eclipse.core.databinding.property.ISimplePropertyListener;
24
import org.eclipse.core.databinding.property.SimplePropertyEvent;
25
import org.eclipse.core.databinding.property.list.SimpleListProperty;
26
import org.eclipse.emf.common.command.Command;
27
import org.eclipse.emf.common.notify.Adapter;
28
import org.eclipse.emf.common.notify.Notification;
29
import org.eclipse.emf.common.notify.impl.AdapterImpl;
30
import org.eclipse.emf.ecore.EObject;
31
import org.eclipse.emf.ecore.EStructuralFeature;
32
import org.eclipse.emf.edit.command.AddCommand;
33
import org.eclipse.emf.edit.command.RemoveCommand;
34
import org.eclipse.emf.edit.domain.EditingDomain;
35
36
/**
37
 * <p>
38
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
39
 * removal.</b>
40
 * </p>
41
 * @since 1.1
42
 */
43
public class EMFEditListProperty extends SimpleListProperty {
44
	
45
	private class ListVisitorImpl extends ListDiffVisitor {
46
		private EditingDomain domain;
47
		private EObject eObj;
48
		private EStructuralFeature feature;
49
		
50
		private ListVisitorImpl(EditingDomain domain, EObject eObj, EStructuralFeature feature) {
51
			this.domain = domain;
52
			this.eObj = eObj;
53
			this.feature = feature;
54
		}
55
		
56
		@Override
57
		public void handleAdd(int index, Object element) {
58
			execute(AddCommand.create(domain, eObj, feature, element, index));
59
		}
60
61
		@Override
62
		public void handleRemove(int index, Object element) {
63
			execute(RemoveCommand.create(domain, eObj, feature, element));
64
		}
65
		
66
		private  boolean execute(Command command)
67
		  {
68
		    if (command.canExecute())
69
		    {
70
		      domain.getCommandStack().execute(command);
71
		      return true;
72
		    }
73
		    else
74
		    {
75
		      return false;
76
		    }
77
		  }
78
	}
79
	
80
	private EditingDomain domain;
81
	private final EStructuralFeature feature;
82
83
	/**
84
	 * @param feature
85
	 */
86
	public EMFEditListProperty(EditingDomain domain, EStructuralFeature feature) {
87
		this.feature = feature;
88
		this.domain = domain;
89
	}
90
	
91
	protected EStructuralFeature getFeature() {
92
		return feature;
93
	}
94
95
	public Object getElementType() {
96
		return feature;
97
	}
98
99
	@Override
100
	protected List<?> doGetList(Object source) {
101
		EObject eObj = (EObject) source;
102
		return (List<?>) eObj.eGet(feature);
103
	}
104
105
	@SuppressWarnings("unchecked")
106
	@Override
107
	protected void doSetList(Object source, List list, ListDiff diff) {
108
		diff.accept(new ListVisitorImpl(domain,(EObject) source,getFeature()));
109
	}
110
111
	@Override
112
	public INativePropertyListener adaptListener(
113
			ISimplePropertyListener listener) {
114
		return new Listener(listener);
115
	}
116
117
	private class Listener extends AdapterImpl implements
118
			INativePropertyListener {
119
		private final ISimplePropertyListener listener;
120
121
		private Listener(ISimplePropertyListener listener) {
122
			this.listener = listener;
123
		}
124
125
		@Override
126
		public void notifyChanged(Notification msg) {
127
			if (feature == msg.getFeature() && !msg.isTouch()) {
128
				final ListDiff diff;
129
				switch (msg.getEventType()) {
130
				case Notification.ADD: {
131
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
132
							.getPosition(), true, msg.getNewValue()));
133
					break;
134
				}
135
				case Notification.ADD_MANY: {
136
					Collection<?> newValues = (Collection<?>) msg.getNewValue();
137
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[newValues
138
							.size()];
139
					int position = msg.getPosition();
140
					int index = 0;
141
					for (Object newValue : newValues) {
142
						listDiffEntries[index++] = Diffs.createListDiffEntry(
143
								position++, true, newValue);
144
					}
145
					diff = Diffs.createListDiff(listDiffEntries);
146
					break;
147
				}
148
				case Notification.REMOVE: {
149
					diff = Diffs.createListDiff(Diffs.createListDiffEntry(msg
150
							.getPosition(), false, msg.getOldValue()));
151
					break;
152
				}
153
				case Notification.REMOVE_MANY: {
154
					Collection<?> oldValues = (Collection<?>) msg.getOldValue();
155
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues
156
							.size()];
157
					int position = msg.getPosition();
158
					int index = 0;
159
					for (Object oldValue : oldValues) {
160
						listDiffEntries[index++] = Diffs.createListDiffEntry(
161
								position++, false, oldValue);
162
					}
163
					diff = Diffs.createListDiff(listDiffEntries);
164
					break;
165
				}
166
				case Notification.SET:
167
				case Notification.RESOLVE: {
168
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
169
					listDiffEntries[0] = Diffs.createListDiffEntry(msg
170
							.getPosition(), false, msg.getOldValue());
171
					listDiffEntries[1] = Diffs.createListDiffEntry(msg
172
							.getPosition(), true, msg.getNewValue());
173
					diff = Diffs.createListDiff(listDiffEntries);
174
					break;
175
				}
176
				case Notification.MOVE: {
177
					Object movedValue = msg.getNewValue();
178
					ListDiffEntry[] listDiffEntries = new ListDiffEntry[2];
179
					listDiffEntries[0] = Diffs.createListDiffEntry(
180
							(Integer) msg.getOldValue(), false, movedValue);
181
					listDiffEntries[1] = Diffs.createListDiffEntry(msg
182
							.getPosition(), true, movedValue);
183
					diff = Diffs.createListDiff(listDiffEntries);
184
					break;
185
				}
186
				case Notification.UNSET: {
187
					// This just represents going back to the unset state, but
188
					// that doesn't affect the contents of the list.
189
					//
190
					return;
191
				}
192
				default: {
193
					throw new RuntimeException("unhandled case");
194
				}
195
				}
196
				listener.handlePropertyChange(new SimplePropertyEvent(msg
197
						.getNotifier(), EMFEditListProperty.this, diff));
198
			}
199
		}
200
	}
201
202
	@Override
203
	protected void doAddListener(Object source, INativePropertyListener listener) {
204
		EObject eObj = (EObject) source;
205
		eObj.eAdapters().add((Adapter) listener);
206
	}
207
208
	@Override
209
	protected void doRemoveListener(Object source,
210
			INativePropertyListener listener) {
211
		EObject eObj = (EObject) source;
212
		eObj.eAdapters().remove((Adapter) listener);
213
	}
214
}
(-)src/org/eclipse/emf/databinding/edit/properties/IEMFEditValueProperty.java (+184 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import org.eclipse.core.databinding.property.value.IValueProperty;
16
import org.eclipse.emf.ecore.EStructuralFeature;
17
18
/**
19
 * <p>
20
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
21
 * removal.</b>
22
 * </p>
23
 * An {@link IValueProperty} extension interface with convenience methods for
24
 * creating nested bean properties.
25
 * 
26
 * @since 1.1
27
 * @noextend This interface is not intended to be extended by clients.
28
 * @noimplement This interface is not intended to be implemented by clients.
29
 */
30
public interface IEMFEditValueProperty extends IEMFEditProperty, IValueProperty {
31
	/**
32
	 * Returns a master-detail combination of this property and the specified
33
	 * value property.
34
	 * 
35
	 * @param featurePath
36
	 *            the value property to observe. May be nested e.g.
37
	 * 
38
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
39
	 * @return a master-detail combination of this property and the specified
40
	 *         value property.
41
	 * @see #value(IEMFEditValueProperty)
42
	 */
43
	public IEMFEditValueProperty value(EStructuralFeature... featurePath);
44
45
	/**
46
	 * Returns a master-detail combination of this property and the specified
47
	 * value property. The returned property will observe the specified detail
48
	 * value property for the value of the master value property.
49
	 * <p>
50
	 * Example:
51
	 * 
52
	 * <pre>
53
	 * // Observes the Node-typed &quot;parent&quot; property of a Node object
54
	 * IBeanValueProperty parent = BeanProperties.value(Node.class, &quot;parent&quot;);
55
	 * // Observes the string-typed &quot;name&quot; property of a Node object
56
	 * IBeanValueProperty name = BeanProperties.value(Node.class, &quot;name&quot;);
57
	 * // Observes the name of the parent of a Node object.
58
	 * IBeanValueProperty parentName = parent.value(name);
59
	 * </pre>
60
	 * 
61
	 * @param property
62
	 *            the detail property to observe
63
	 * @return a master-detail combination of this property and the specified
64
	 *         value property.
65
	 */
66
	public IEMFEditValueProperty value(IEMFEditValueProperty property);
67
68
	/**
69
	 * Returns a master-detail combination of this property and the specified
70
	 * list property.
71
	 * 
72
	 * @param feature
73
	 *            the list property to observe
74
	 * @return a master-detail combination of this property and the specified
75
	 *         list property.
76
	 * @see #list(IEMFEditListProperty)
77
	 */
78
	public IEMFEditListProperty list(EStructuralFeature feature);
79
80
	/**
81
	 * Returns a master-detail combination of this property and the specified
82
	 * list property. The returned property will observe the specified list
83
	 * property for the value of the master property.
84
	 * <p>
85
	 * Example:
86
	 * 
87
	 * <pre>
88
	 * // Observes the Node-typed &quot;parent&quot; property of a Node object.
89
	 * IBeanValueProperty parent = BeanProperties.value(Node.class, &quot;parent&quot;);
90
	 * // Observes the List-typed &quot;children&quot; property of a Node object
91
	 * // where the elements are Node objects
92
	 * IBeanListProperty children = BeanProperties.list(Node.class, &quot;children&quot;,
93
	 * 		Node.class);
94
	 * // Observes the children of the parent (siblings) of a Node object.
95
	 * IBeanListProperty siblings = parent.list(children);
96
	 * </pre>
97
	 * 
98
	 * @param property
99
	 *            the detail property to observe
100
	 * @return a master-detail combination of this property and the specified
101
	 *         list property.
102
	 */
103
	public IEMFEditListProperty list(IEMFEditListProperty property);
104
105
	// /**
106
	// * Returns a master-detail combination of this property and the specified
107
	// * set property.
108
	// *
109
	// * @param propertyName
110
	// * the set property to observe
111
	// * @return a master-detail combination of this property and the specified
112
	// * set property.
113
	// * @see #set(IEMFSetProperty)
114
	// */
115
	// public IEMFSetProperty set(EStructuralFeature featurePath);
116
	//
117
	// /**
118
	// * Returns a master-detail combination of this property and the specified
119
	// * set property. The returned property will observe the specified set
120
	// * property for the value of the master property.
121
	// * <p>
122
	// * Example:
123
	// *
124
	// * <pre>
125
	// * // Observes the Node-typed &quot;parent&quot; property of a Node
126
	// object.
127
	// * IBeanValueProperty parent = BeanProperties.value(Node.class,
128
	// &quot;parent&quot;);
129
	// * // Observes the Set-typed &quot;children&quot; property of a Node
130
	// object
131
	// * // where the elements are Node objects
132
	// * IBeanSetProperty children = BeanProperties.set(Node.class,
133
	// &quot;children&quot;,
134
	// * Node.class);
135
	// * // Observes the children of the parent (siblings) of a Node object.
136
	// * IBeanSetProperty siblings = parent.set(children);
137
	// * </pre>
138
	// *
139
	// * @param property
140
	// * the detail property to observe
141
	// * @return a master-detail combination of this property and the specified
142
	// * set property.
143
	// */
144
	// public IEMFSetProperty set(IEMFSetProperty property);
145
146
	/**
147
	 * Returns a master-detail combination of this property and the specified
148
	 * map property.
149
	 * 
150
	 * @param feature
151
	 *            the map property to observe
152
	 * @return a master-detail combination of this property and the specified
153
	 *         map property.
154
	 * @see #map(IEMFEditMapProperty)
155
	 */
156
	public IEMFEditMapProperty map(EStructuralFeature feature);
157
158
	/**
159
	 * Returns a master-detail combination of this property and the specified
160
	 * map property. The returned property will observe the specified map
161
	 * property for the value of the master property.
162
	 * <p>
163
	 * Example:
164
	 * 
165
	 * <pre>
166
	 * // Observes the Contact-typed &quot;supervisor&quot; property of a
167
	 * // Contact class 
168
	 * IBeanValueProperty supervisor = BeanProperties.value(Contact.class,
169
	 * 		&quot;supervisor&quot;);
170
	 * // Observes the property &quot;phoneNumbers&quot; of a Contact object--a property mapping
171
	 * // from PhoneNumberType to PhoneNumber &quot;set-typed &quot;children&quot;,
172
	 * IBeanMapProperty phoneNumbers = BeanProperties.map(Contact.class,
173
	 * 		&quot;phoneNumbers&quot;, PhoneNumberType.class, PhoneNumber.class);
174
	 * // Observes the phone numbers of a contact's supervisor:
175
	 * IBeanMapProperty supervisorPhoneNumbers = supervisor.map(phoneNumbers);
176
	 * </pre>
177
	 * 
178
	 * @param property
179
	 *            the detail property to observe
180
	 * @return a master-detail combination of this property and the specified
181
	 *         map property.
182
	 */
183
	public IEMFEditMapProperty map(IEMFEditMapProperty property);
184
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditMapProperty.java (+124 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.map.MapDiff;
19
import org.eclipse.core.databinding.property.INativePropertyListener;
20
import org.eclipse.core.databinding.property.ISimplePropertyListener;
21
import org.eclipse.core.databinding.property.SimplePropertyEvent;
22
import org.eclipse.core.databinding.property.map.SimpleMapProperty;
23
import org.eclipse.emf.common.command.Command;
24
import org.eclipse.emf.common.notify.Adapter;
25
import org.eclipse.emf.common.notify.Notification;
26
import org.eclipse.emf.common.notify.impl.AdapterImpl;
27
import org.eclipse.emf.ecore.EObject;
28
import org.eclipse.emf.ecore.EStructuralFeature;
29
import org.eclipse.emf.edit.command.SetCommand;
30
import org.eclipse.emf.edit.domain.EditingDomain;
31
32
/**
33
 * <p>
34
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
35
 * removal.</b>
36
 * </p>
37
 * @since 1.1
38
 */
39
public class EMFEditMapProperty extends SimpleMapProperty {
40
	
41
	private final EStructuralFeature feature;
42
	private final Class<?> keyType;
43
	private final Class<?> valueType;
44
	private EditingDomain domain;
45
	
46
	/**
47
	 * @param feature
48
	 * @param keyType
49
	 * @param valueType
50
	 */
51
	public EMFEditMapProperty(EditingDomain domain, EStructuralFeature feature, Class<?> keyType, Class<?> valueType) {
52
		this.feature = feature;
53
		this.keyType = keyType;
54
		this.valueType = valueType;
55
		this.domain = domain;
56
	}
57
	
58
	public Object getKeyType() {
59
		return keyType;
60
	}
61
62
	public Object getValueType() {
63
		return valueType;
64
	}
65
66
	@Override
67
	protected Map<?,?> doGetMap(Object source) {
68
		EObject eObj = (EObject) source;
69
		return (Map<?,?>) eObj.eGet(feature);
70
	}
71
	
72
	@SuppressWarnings("unchecked")
73
	@Override
74
	protected void doSetMap(Object source, Map map, MapDiff diff) {
75
		EObject eObject = (EObject)source;
76
	    Command command = SetCommand.create(domain, eObject, feature, map);
77
	    domain.getCommandStack().execute(command);
78
	}
79
	
80
	@Override
81
	public INativePropertyListener adaptListener(
82
			ISimplePropertyListener listener) {
83
		return new Listener(listener);
84
	}
85
	
86
	private class Listener extends AdapterImpl implements INativePropertyListener {
87
		private final ISimplePropertyListener listener;
88
89
		private Listener(ISimplePropertyListener listener) {
90
			this.listener = listener;
91
		}
92
		
93
		@Override
94
		public void notifyChanged(Notification msg) {
95
			if (feature == msg.getFeature() && !msg.isTouch())
96
	        {
97
	          // TODO
98
	          // This assumes we only get a SET notification, which isn't a good assumption.
99
	          //
100
	          final MapDiff diff = Diffs.createMapDiffSingleChange(msg.getNotifier(), msg.getOldValue(), msg.getNewValue());
101
	          listener.handlePropertyChange(new SimplePropertyEvent(msg
102
						.getNotifier(), EMFEditMapProperty.this, diff));
103
	        }
104
		}
105
	}
106
107
	@Override
108
	protected void doAddListener(Object source, INativePropertyListener listener) {
109
		EObject eObj = (EObject) source;
110
		eObj.eAdapters().add((Adapter) listener);
111
	}
112
113
	@Override
114
	protected void doRemoveListener(Object source,
115
			INativePropertyListener listener) {
116
		EObject eObj = (EObject) source;
117
		eObj.eAdapters().remove((Adapter) listener);
118
	}
119
120
	
121
122
	
123
124
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditObservableMapDecorator.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 221704)
10
 *     Matthew Hall - bug 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.map.DecoratingObservableMap;
18
import org.eclipse.core.databinding.observable.map.IObservableMap;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
import org.eclipse.emf.edit.domain.EditingDomain;
22
23
/**
24
 * <p>
25
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
26
 * removal.</b>
27
 * </p>
28
 * {@link IEMFObservable} decorator for an {@link IObservableMap}.
29
 * 
30
 * @since 1.1
31
 */
32
public class EMFEditObservableMapDecorator extends DecoratingObservableMap
33
		implements IEMFObservable {
34
	private EStructuralFeature feature;
35
	private EditingDomain domain;
36
37
	/**
38
	 * @param decorated
39
	 * @param feature
40
	 */
41
	public EMFEditObservableMapDecorator(EditingDomain domain, IObservableMap decorated, EStructuralFeature feature) {
42
		super(decorated, true);
43
		this.feature = feature;
44
		this.domain = domain;
45
	}
46
47
	public synchronized void dispose() {
48
		this.feature = null;
49
		super.dispose();
50
	}
51
	
52
	public EStructuralFeature getFeature() {
53
		return feature;
54
	}
55
56
	public Object getObserved() {
57
		IObservable decorated = getDecorated();
58
		if (decorated instanceof IObserving)
59
			return ((IObserving) decorated).getObserved();
60
		return null;
61
	}
62
}
(-)src/org/eclipse/emf/databinding/edit/properties/EMFEditProperties.java (+117 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222, 247997, 261843
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import org.eclipse.core.databinding.property.list.IListProperty;
16
import org.eclipse.core.databinding.property.map.IMapProperty;
17
import org.eclipse.core.databinding.property.value.IValueProperty;
18
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditListProperty;
19
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditListPropertyDecorator;
20
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditMapProperty;
21
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditMapPropertyDecorator;
22
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditValueProperty;
23
import org.eclipse.emf.databinding.edit.properties.internal.EMFEditValuePropertyDecorator;
24
import org.eclipse.emf.ecore.EObject;
25
import org.eclipse.emf.ecore.EStructuralFeature;
26
import org.eclipse.emf.edit.domain.EditingDomain;
27
28
/**
29
 * <p>
30
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
31
 * removal.</b>
32
 * </p>
33
 * A factory for creating properties for {@link EObject} objects
34
 * 
35
 * @since 1.1
36
 */
37
public class EMFEditProperties {
38
	/**
39
	 * Returns a value property for the given property name of an arbitrary bean
40
	 * class. Objects lacking the named property are treated the same as if the
41
	 * property always contains null.
42
	 * 
43
	 * @param featurePath
44
	 *            the property name. May be nested e.g.
45
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
46
	 * @return a value property for the given property name of an arbitrary bean
47
	 *         class.
48
	 */
49
	public static IEMFEditValueProperty value(EditingDomain domain, EStructuralFeature... featurePath) {
50
		IValueProperty property = new EMFEditValueProperty(domain,featurePath[0]);
51
52
		IEMFEditValueProperty emfProperty = new EMFEditValuePropertyDecorator(domain, property,
53
				featurePath[0]);
54
		for (int i = 1; i < featurePath.length; i++) {
55
			emfProperty = emfProperty.value(featurePath[i]);
56
		}
57
		return emfProperty;
58
	}
59
60
	// public static IEMFValueProperty[] values(EStructuralFeature[]...
61
	// features) {
62
	// return null;
63
	// }
64
65
	// public static IEMFSetProperty set(EStructuralFeature feature) {
66
	// ISetProperty property = new EMFSetProperty(feature, elementType);
67
	// return new EMFSetPropertyDecorator(property, feature);
68
	// }
69
70
	/**
71
	 * Returns a list property for the given property name of an arbitrary bean
72
	 * class. Objects lacking the named property are treated the same as if the
73
	 * property always contains an empty list.
74
	 * 
75
	 * @param feature
76
	 *            the property name
77
	 * @return a list property for the given property name of an arbitrary bean
78
	 *         class.
79
	 */
80
	public static IEMFEditListProperty list(EditingDomain domain, EStructuralFeature feature) {
81
		IListProperty property = new EMFEditListProperty(domain, feature);
82
		return new EMFEditListPropertyDecorator(domain, property, feature);
83
	}
84
85
	/**
86
	 * Returns a map property for the given property name of an arbitrary bean
87
	 * class. Objects lacking the named property are treated the same as if the
88
	 * property always contains an empty map.
89
	 * 
90
	 * @param feature
91
	 *            the property name
92
	 * @return a map property for the given property name of an arbitrary bean
93
	 *         class.
94
	 */
95
	public static IEMFEditMapProperty map(EditingDomain domain,EStructuralFeature feature) {
96
		return map(domain, feature, null, null);
97
	}
98
99
	/**
100
	 * Returns a map property for the given property name of the given bean
101
	 * class.
102
	 * 
103
	 * @param feature
104
	 *            the property name
105
	 * @param keyType
106
	 *            the key type for the returned map property
107
	 * @param valueType
108
	 *            the value type for the returned map property
109
	 * @return a map property for the given property name of the given bean
110
	 *         class.
111
	 */
112
	public static IEMFEditMapProperty map(EditingDomain domain, EStructuralFeature feature,
113
			Class<?> keyType, Class<?> valueType) {
114
		IMapProperty property = new EMFEditMapProperty(domain, feature, keyType, valueType);
115
		return new EMFEditMapPropertyDecorator(domain, property, feature);
116
	}
117
}
(-)src/org/eclipse/emf/databinding/edit/properties/IEMFEditMapProperty.java (+60 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - port to EMF
11
 ******************************************************************************/
12
13
package org.eclipse.emf.databinding.edit.properties;
14
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.property.map.IMapProperty;
18
import org.eclipse.emf.ecore.EStructuralFeature;
19
20
/**
21
 * <p>
22
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
23
 * removal.</b>
24
 * </p>
25
 * An {@link IMapProperty} extension interface with convenience methods for
26
 * creating nested bean properties.
27
 * 
28
 * @since 1.1
29
 * @noextend This interface is not intended to be extended by clients.
30
 * @noimplement This interface is not intended to be implemented by clients.
31
 */
32
public interface IEMFEditMapProperty extends IEMFEditProperty, IMapProperty {
33
	/**
34
	 * Returns a master-detail combination of this property and the specified
35
	 * value property.
36
	 * 
37
	 * @param featurePath
38
	 *            the value property to observe. May be nested e.g.
39
	 *            <code>property.values(MyPackage.Literals.OBJ_PARENT, MyPackage.Literals.PARENT_NAME)</code>
40
	 * @return a master-detail combination of this property and the specified
41
	 *         value property.
42
	 * @see #values(IEMFEditValueProperty)
43
	 */
44
	public IEMFEditMapProperty values(EStructuralFeature... featurePath);
45
46
	/**
47
	 * Returns a master-detail combination of this property and the specified
48
	 * value property. The returned property will observe the specified value
49
	 * property for all {@link Map#values() values} observed by this map
50
	 * property, mapping from this map property's {@link Map#keySet() key set}
51
	 * to the specified value property's value for each element in the master
52
	 * property's {@link Map#values() values} collection.
53
	 * 
54
	 * @param property
55
	 *            the detail property to observe
56
	 * @return a master-detail combination of this property and the specified
57
	 *         value property.
58
	 */
59
	public IEMFEditMapProperty values(IEMFEditValueProperty property);
60
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditListPropertyDecorator.java (+88 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.edit.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
import org.eclipse.core.databinding.property.list.IListProperty;
19
import org.eclipse.core.databinding.property.list.ListProperty;
20
import org.eclipse.emf.databinding.edit.properties.EMFEditProperties;
21
import org.eclipse.emf.databinding.edit.properties.IEMFEditListProperty;
22
import org.eclipse.emf.databinding.edit.properties.IEMFEditValueProperty;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
import org.eclipse.emf.edit.domain.EditingDomain;
25
26
/**
27
 * <p>
28
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
29
 * removal.</b>
30
 * </p>
31
 * @since 1.1
32
 */
33
public class EMFEditListPropertyDecorator extends ListProperty implements IEMFEditListProperty {
34
	private final IListProperty delegate;
35
	private final EStructuralFeature feature;
36
	private EditingDomain domain;
37
	
38
	/**
39
	 * @param delegate
40
	 * @param feature
41
	 */
42
	public EMFEditListPropertyDecorator(EditingDomain domain, IListProperty delegate, EStructuralFeature feature) {
43
		this.delegate = delegate;
44
		this.feature = feature;
45
		this.domain = domain;
46
	}
47
	
48
	public Object getElementType() {
49
		return feature.getEType().getInstanceClass();
50
	}
51
	
52
	public IEMFEditListProperty values(EStructuralFeature... feature) {
53
		return values(EMFEditProperties.value(domain, feature));
54
	}
55
	public IEMFEditListProperty values(IEMFEditValueProperty property) {
56
		return new EMFEditListPropertyDecorator(property.getDomain(), super.values(property),property.getFeature());
57
	}
58
	public EStructuralFeature getFeature() {
59
		return feature;
60
	}
61
	
62
	public IObservableList observe(Object source) {
63
		return new EMFEditObservableListDecorator(domain, delegate.observe(source),
64
				feature);
65
	}
66
	
67
	public IObservableList observe(Realm realm, Object source) {
68
		return new EMFEditObservableListDecorator(domain, delegate.observe(realm, source),
69
				feature);
70
	}
71
	
72
	public IObservableFactory listFactory() {
73
		return delegate.listFactory();
74
	}
75
	
76
	public IObservableFactory listFactory(Realm realm) {
77
		return delegate.listFactory(realm);
78
	}
79
80
	public IObservableList observeDetail(IObservableValue master) {
81
		return new EMFEditObservableListDecorator(domain, delegate.observeDetail(master),
82
				feature);
83
	}
84
85
	public EditingDomain getDomain() {
86
		return domain;
87
	}
88
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditObservableValueDecorator.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 Brad Reynolds and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 246625
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import org.eclipse.core.databinding.observable.IObservable;
16
import org.eclipse.core.databinding.observable.IObserving;
17
import org.eclipse.core.databinding.observable.value.DecoratingObservableValue;
18
import org.eclipse.core.databinding.observable.value.IObservableValue;
19
import org.eclipse.emf.databinding.properties.IEMFObservable;
20
import org.eclipse.emf.ecore.EStructuralFeature;
21
import org.eclipse.emf.edit.domain.EditingDomain;
22
23
/**
24
 * <p>
25
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
26
 * removal.</b>
27
 * </p>
28
 * {@link IEMFObservable} decorator for an {@link IObservableValue}.
29
 * 
30
 * @since 1.1
31
 */
32
public class EMFEditObservableValueDecorator extends DecoratingObservableValue
33
		implements IEMFObservable {
34
	private EStructuralFeature feature;
35
	private EditingDomain domain;
36
	
37
	/**
38
	 * @param decorated
39
	 * @param feature
40
	 */
41
	public EMFEditObservableValueDecorator(EditingDomain domain, IObservableValue decorated, EStructuralFeature feature) {
42
		super(decorated, true);
43
		this.feature = feature;
44
		this.domain = domain;
45
	}
46
	
47
	public synchronized void dispose() {
48
		this.feature = null;
49
		super.dispose();
50
	}
51
52
	public EStructuralFeature getFeature() {
53
		return feature;
54
	}
55
56
	public Object getObserved() {
57
		IObservable decorated = getDecorated();
58
		if (decorated instanceof IObserving)
59
			return ((IObserving) decorated).getObserved();
60
		return null;
61
	}
62
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditValueProperty.java (+109 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 *     Matthew Hall - bug 195222
11
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
12
 ******************************************************************************/
13
package org.eclipse.emf.databinding.edit.properties.internal;
14
15
import org.eclipse.core.databinding.observable.Diffs;
16
import org.eclipse.core.databinding.observable.value.ValueDiff;
17
import org.eclipse.core.databinding.property.INativePropertyListener;
18
import org.eclipse.core.databinding.property.ISimplePropertyListener;
19
import org.eclipse.core.databinding.property.SimplePropertyEvent;
20
import org.eclipse.core.databinding.property.value.SimpleValueProperty;
21
import org.eclipse.emf.common.command.Command;
22
import org.eclipse.emf.common.notify.Adapter;
23
import org.eclipse.emf.common.notify.Notification;
24
import org.eclipse.emf.common.notify.impl.AdapterImpl;
25
import org.eclipse.emf.ecore.EObject;
26
import org.eclipse.emf.ecore.EStructuralFeature;
27
import org.eclipse.emf.edit.command.SetCommand;
28
import org.eclipse.emf.edit.domain.EditingDomain;
29
30
/**
31
 * <p>
32
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
33
 * removal.</b>
34
 * </p>
35
 * @since 1.1
36
 */
37
public class EMFEditValueProperty extends SimpleValueProperty {
38
	private EStructuralFeature feature;
39
	private EditingDomain domain;
40
	
41
	/**
42
	 * @param feature
43
	 */
44
	public EMFEditValueProperty(EditingDomain domain, EStructuralFeature feature) {
45
		this.feature = feature;
46
		this.domain = domain;
47
	}
48
	
49
	public Object getValueType() {
50
		return feature.getEType().getInstanceClass();
51
	}
52
	
53
	@Override
54
	protected Object doGetValue(Object source) {
55
		EObject eObj = (EObject) source;
56
		return eObj.eGet(feature);
57
	}
58
59
	
60
	@Override
61
	protected void doSetValue(Object source, Object value) {
62
		EObject eObj = (EObject) source;
63
		Command command = SetCommand.create(domain, eObj, feature, value);
64
	    domain.getCommandStack().execute(command);
65
	}
66
	
67
	@Override
68
	public INativePropertyListener adaptListener(
69
			ISimplePropertyListener listener) {
70
		return new Listener(listener);
71
	}
72
	
73
	private class Listener extends AdapterImpl implements INativePropertyListener {
74
		private final ISimplePropertyListener listener;
75
		
76
		private Listener(ISimplePropertyListener listener) {
77
			this.listener = listener;
78
		}
79
80
		@Override
81
		public void notifyChanged(Notification msg) {
82
			if( feature == msg.getFeature() && !msg.isTouch() ) {
83
				ValueDiff diff;
84
				Object oldValue = msg.getOldValue();
85
				Object newValue = msg.getNewValue();
86
				if (oldValue != null && newValue != null) {
87
					diff = Diffs.createValueDiff(oldValue, newValue);
88
				} else {
89
					diff = null;
90
				}
91
				listener.handlePropertyChange(new SimplePropertyEvent(msg.getNotifier(), EMFEditValueProperty.this, diff));				
92
			}
93
		}
94
	}
95
96
	@Override
97
	protected void doAddListener(Object source, INativePropertyListener listener) {
98
		EObject eObj = (EObject) source;
99
		eObj.eAdapters().add((Adapter) listener);
100
	}
101
102
	
103
	@Override
104
	protected void doRemoveListener(Object source,
105
			INativePropertyListener listener) {
106
		EObject eObj = (EObject) source;
107
		eObj.eAdapters().remove((Adapter) listener);
108
	}	
109
}
(-)src/org/eclipse/emf/databinding/edit/properties/internal/EMFEditMapPropertyDecorator.java (+95 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 195222)
10
 *     Tom Schindl<tom.schindl@bestsolution.at> - Port to EMF
11
 ******************************************************************************/
12
package org.eclipse.emf.databinding.edit.properties.internal;
13
14
import org.eclipse.core.databinding.observable.Realm;
15
import org.eclipse.core.databinding.observable.map.IObservableMap;
16
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
import org.eclipse.core.databinding.property.map.IMapProperty;
19
import org.eclipse.core.databinding.property.map.MapProperty;
20
import org.eclipse.emf.databinding.edit.properties.EMFEditProperties;
21
import org.eclipse.emf.databinding.edit.properties.IEMFEditMapProperty;
22
import org.eclipse.emf.databinding.edit.properties.IEMFEditValueProperty;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
import org.eclipse.emf.edit.domain.EditingDomain;
25
26
/**
27
 * <p>
28
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
29
 * removal.</b>
30
 * </p>
31
 * @since 1.1
32
 */
33
public class EMFEditMapPropertyDecorator extends MapProperty implements
34
		IEMFEditMapProperty {
35
	private final IMapProperty delegate;
36
	private final EStructuralFeature feature;
37
	private EditingDomain domain;
38
39
	/**
40
	 * @param delegate
41
	 * @param feature
42
	 */
43
	public EMFEditMapPropertyDecorator(EditingDomain domain, IMapProperty delegate, EStructuralFeature feature) {
44
		this.delegate = delegate;
45
		this.feature = feature;
46
		this.domain = domain;
47
	}
48
	
49
	public EStructuralFeature getFeature() {
50
		return feature;
51
	}
52
53
	public Object getKeyType() {
54
		return delegate.getKeyType();
55
	}
56
57
	public Object getValueType() {
58
		return delegate.getValueType();
59
	}
60
	
61
	public IEMFEditMapProperty values(EStructuralFeature... featurePath) { 
62
		return values(EMFEditProperties.value(domain, featurePath));
63
	}
64
65
	public IEMFEditMapProperty values(IEMFEditValueProperty property) {
66
		return new EMFEditMapPropertyDecorator(property.getDomain(), super.values(property),property.getFeature());
67
	}
68
69
	public IObservableMap observe(Object source) {
70
		return new EMFEditObservableMapDecorator(domain, delegate.observe(source),
71
				feature);
72
	}
73
	
74
	public IObservableMap observe(Realm realm, Object source) {
75
		return new EMFEditObservableMapDecorator(domain, delegate.observe(realm, source),
76
				feature);
77
	}
78
	
79
	public IObservableFactory mapFactory() {
80
		return delegate.mapFactory();
81
	}
82
83
	public IObservableFactory mapFactory(Realm realm) {
84
		return delegate.mapFactory(realm);
85
	}
86
87
	public IObservableMap observeDetail(IObservableValue master) {
88
		return new EMFEditObservableMapDecorator(domain, delegate.observeDetail(master),
89
				feature);
90
	}
91
92
	public EditingDomain getDomain() {
93
		return domain;
94
	}
95
}

Return to bug 262160