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 / +212 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 30-194 Link Here
30
import org.eclipse.emf.ecore.EStructuralFeature;
29
import org.eclipse.emf.ecore.EStructuralFeature;
31
30
32
/**
31
/**
33
 * PROVISIONAL
32
 * <p>
34
 * This API is subject to arbitrary change, including renaming or removal.
33
 * <b>PROVISIONAL This API is subject to arbitrary change, including renaming or
34
 * removal.</b>
35
 * </p>
36
 * A factory for creating observable objects of Java objects that conform to the
37
 * <a href="http://java.sun.com/products/javabeans/docs/spec.html">JavaBean
38
 * specification</a> for bound properties.
39
 * 
40
 * @since 1.0
35
 */
41
 */
36
public class EMFObservables
42
public class EMFObservables {
37
{
43
	/**
38
  /**
44
	 * 
39
   * Returns an observable value for the given feature of the object.
45
	 */
40
   * @param eObject the object to observe.
46
	public static final boolean DEBUG = false;
41
   * @param eStructuralFeature the feature of the object to observe.
47
42
   * @return an observable value for the given feature of the object.
48
	/**
43
   */
49
	 * Returns an observable value for the given feature of the object.
44
  public static IObservableValue observeValue(EObject eObject, EStructuralFeature eStructuralFeature)
50
	 * 
45
  {
51
	 * @param eObject
46
    return new EObjectObservableValue(eObject, eStructuralFeature);
52
	 *            the object to observe.
47
  }
53
	 * @param eStructuralFeature
48
54
	 *            the feature of the object to observe.
49
  /**
55
	 * @return an observable value for the given feature of the object.
50
   * Returns an observable value for the given feature of the object.
56
	 */
51
   * @param realm the realm in which to observe.
57
	public static IObservableValue observeValue(EObject eObject,
52
   * @param eObject the object to observe.
58
			EStructuralFeature eStructuralFeature) {
53
   * @param eStructuralFeature the feature of the object to observe.
59
		return new EObjectObservableValue(eObject, eStructuralFeature);
54
   * @return an observable value for the given feature of the object.
60
	}
55
   */
61
56
  public static IObservableValue observeValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
62
	/**
57
  {
63
	 * Returns an observable value for the given feature of the object.
58
    return new EObjectObservableValue(realm, eObject, eStructuralFeature);
64
	 * 
59
  }
65
	 * @param realm
60
66
	 *            the realm in which to observe.
61
  /**
67
	 * @param eObject
62
   * Returns an observable list for the given multi-valued feature of the object.
68
	 *            the object to observe.
63
   * @param eObject the object to observe.
69
	 * @param eStructuralFeature
64
   * @param eStructuralFeature the feature of the object to observe.
70
	 *            the feature of the object to observe.
65
   * @return an observable list for the given multi-valued feature of the object.
71
	 * @return an observable value for the given feature of the object.
66
   */
72
	 */
67
  public static IObservableList observeList(EObject eObject, EStructuralFeature eStructuralFeature)
73
	public static IObservableValue observeValue(Realm realm, EObject eObject,
68
  {
74
			EStructuralFeature eStructuralFeature) {
69
    return new EObjectObservableList(eObject, eStructuralFeature);
75
		return new EObjectObservableValue(realm, eObject, eStructuralFeature);
70
  }
76
	}
71
77
72
  /**
78
	/**
73
   * Returns an observable list for the given multi-valued feature of the object.
79
	 * Returns an observable list for the given multi-valued feature of the
74
   * @param realm the realm in which to observe.
80
	 * object.
75
   * @param eObject the object to observe.
81
	 * 
76
   * @param eStructuralFeature the feature of the object to observe.
82
	 * @param eObject
77
   * @return an observable list for the given multi-valued feature of the object.
83
	 *            the object to observe.
78
   */
84
	 * @param eStructuralFeature
79
  public static IObservableList observeList(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature)
85
	 *            the feature of the object to observe.
80
  {
86
	 * @return an observable list for the given multi-valued feature of the
81
    return new EObjectObservableList(realm, eObject, eStructuralFeature);
87
	 *         object.
82
  }
88
	 */
83
89
	public static IObservableList observeList(EObject eObject,
84
  /**
90
			EStructuralFeature eStructuralFeature) {
85
   * Returns an observable map in the default realm 
91
		return new EObjectObservableList(eObject, eStructuralFeature);
86
   * tracking the current value of the given feature for each object in the given set.
92
	}
87
   * @param objects the objects to track.
93
88
   * @param eStructuralFeature the feature for which to track the value.
94
	/**
89
   * @return an observable map tracking the current value of the given feature for each object in the given set.
95
	 * Returns an observable list for the given multi-valued feature of the
90
   */
96
	 * object.
91
  public static IObservableMap observeMap(IObservableSet objects, EStructuralFeature eStructuralFeature)
97
	 * 
92
  {
98
	 * @param realm
93
    return new EObjectObservableMap(objects, eStructuralFeature);
99
	 *            the realm in which to observe.
94
  }
100
	 * @param eObject
95
101
	 *            the object to observe.
96
  /**
102
	 * @param eStructuralFeature
97
   * Returns an array of observable maps in the default realm 
103
	 *            the feature of the object to observe.
98
   * tracking the current value of the given features for each object in the given set.
104
	 * @return an observable list for the given multi-valued feature of the
99
   * @param objects the objects to track.
105
	 *         object.
100
   * @param eStructuralFeatures the features for which to track the value.
106
	 */
101
   * @return an array of observable maps tracking the current value of the given features for each object in the given set.
107
	public static IObservableList observeList(Realm realm, EObject eObject,
102
   */
108
			EStructuralFeature eStructuralFeature) {
103
  public static IObservableMap[] observeMaps(IObservableSet objects, EStructuralFeature[] eStructuralFeatures)
109
		return new EObjectObservableList(realm, eObject, eStructuralFeature);
104
  {
110
	}
105
    IObservableMap[] result = new IObservableMap [eStructuralFeatures.length];
111
106
    for (int i = 0; i < eStructuralFeatures.length; i++)
112
	/**
107
    {
113
	 * Returns an observable map in the default realm tracking the current value
108
      result[i] = observeMap(objects, eStructuralFeatures[i]);
114
	 * of the given feature for each object in the given set.
109
    }
115
	 * 
110
    return result;
116
	 * @param objects
111
  }
117
	 *            the objects to track.
112
118
	 * @param eStructuralFeature
113
  /**
119
	 *            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.
120
	 * @return an observable map tracking the current value of the given feature
115
   * @param realm the realm in which to observe.
121
	 *         for each object in the given set.
116
   * @param value the master observable value.
122
	 */
117
   * @param eStructuralFeature the feature for which to track the value.
123
	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
124
			EStructuralFeature eStructuralFeature) {
119
   * @see MasterDetailObservables#detailValue(IObservableValue, IObservableFactory, Object)
125
		return new EObjectObservableMap(objects, eStructuralFeature);
120
   */
126
	}
121
  public static IObservableValue observeDetailValue(Realm realm, IObservableValue value, EStructuralFeature eStructuralFeature)
127
122
  {
128
	/**
123
    return MasterDetailObservables.detailValue(value, valueFactory(realm, eStructuralFeature), eStructuralFeature);
129
	 * Returns an array of observable maps in the default realm tracking the
124
  }
130
	 * current value of the given features for each object in the given set.
125
131
	 * 
126
  /**
132
	 * @param objects
127
   * Returns a factory for creating observable values
133
	 *            the objects to track.
128
   * tracking the value of the given feature of a particular {@link EObject object}.
134
	 * @param eStructuralFeatures
129
   * @param realm the realm in which to observe.
135
	 *            the features for which to track the value.
130
   * @param eStructuralFeature the feature for which to track the value.
136
	 * @return an array of observable maps tracking the current value of the
131
   * @return an observable factory.
137
	 *         given features for each object in the given set.
132
   */
138
	 */
133
  public static IObservableFactory valueFactory(final Realm realm, final EStructuralFeature eStructuralFeature)
139
	public static IObservableMap[] observeMaps(IObservableSet objects,
134
  {
140
			EStructuralFeature[] eStructuralFeatures) {
135
    return 
141
		IObservableMap[] result = new IObservableMap[eStructuralFeatures.length];
136
      new IObservableFactory()
142
		for (int i = 0; i < eStructuralFeatures.length; i++) {
137
      {
143
			result[i] = observeMap(objects, eStructuralFeatures[i]);
138
        public IObservable createObservable(Object target)
144
		}
139
        {
145
		return result;
140
          return observeValue(realm, (EObject)target, eStructuralFeature);
146
	}
141
        }
147
142
      };
148
	/**
143
  }
149
	 * Returns an observable value that tracks the current value of the feature
144
150
	 * of the current value of the master observable value.
145
  /**
151
	 * 
146
   * Returns an observable list that tracks the current value of the feature of the current value of the master observable value.
152
	 * @param realm
147
   * @param realm the realm in which to observe.
153
	 *            the realm in which to observe.
148
   * @param value the master observable value.
154
	 * @param value
149
   * @param eStructuralFeature the feature for which to track the value.
155
	 *            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
156
	 * @param eStructuralFeature
151
   * @see MasterDetailObservables#detailList(IObservableValue, IObservableFactory, Object)
157
	 *            the feature for which to track the value.
152
   */
158
	 * @return an observable value that tracks the current value of the named
153
  public static IObservableList observeDetailList(Realm realm, IObservableValue value, EStructuralFeature eStructuralFeature)
159
	 *         property for the current value of the master observable value
154
  {
160
	 * @see MasterDetailObservables#detailValue(IObservableValue,
155
    return MasterDetailObservables.detailList(value, listFactory(realm, eStructuralFeature), eStructuralFeature);
161
	 *      IObservableFactory, Object)
156
  }
162
	 */
157
163
	public static IObservableValue observeDetailValue(Realm realm,
158
  /**
164
			IObservableValue value, EStructuralFeature eStructuralFeature) {
159
   * Returns a factory for creating observable lists
165
		return MasterDetailObservables.detailValue(value, valueFactory(realm,
160
   * tracking the value of the given feature of a particular {@link EObject object}.
166
				eStructuralFeature), eStructuralFeature);
161
   * @param realm the realm in which to observe.
167
	}
162
   * @param eStructuralFeature the feature for which to track the value.
168
163
   * @return an observable factory.
169
	/**
164
   */
170
	 * Returns a factory for creating observable values tracking the value of
165
  public static IObservableFactory listFactory(final Realm realm, final EStructuralFeature eStructuralFeature)
171
	 * the given feature of a particular {@link EObject object}.
166
  {
172
	 * 
167
    return 
173
	 * @param realm
168
      new IObservableFactory()
174
	 *            the realm in which to observe.
169
      {
175
	 * @param eStructuralFeature
170
        public IObservable createObservable(Object target)
176
	 *            the feature for which to track the value.
171
        {
177
	 * @return an observable factory.
172
          return observeList(realm, (EObject)target, eStructuralFeature);
178
	 */
173
        }
179
	public static IObservableFactory valueFactory(final Realm realm,
174
      };
180
			final EStructuralFeature eStructuralFeature) {
175
  }
181
		return new IObservableFactory() {
176
  
182
			public IObservable createObservable(Object target) {
177
  /**
183
				return observeValue(realm, (EObject) target, eStructuralFeature);
178
   * Returns a factory for creating observable maps
184
			}
179
   * tracking the value of the given feature of a particular {@link EObject object}.
185
		};
180
   * @param eStructuralFeature the feature for which to track the value.
186
	}
181
   * @return an observable factory.
187
182
   */
188
	/**
183
  public static IObservableFactory mapFactory(final EStructuralFeature eStructuralFeature)
189
	 * Returns an observable list that tracks the current value of the feature
184
  {
190
	 * of the current value of the master observable value.
185
    return
191
	 * 
186
      new IObservableFactory()
192
	 * @param realm
187
      {
193
	 *            the realm in which to observe.
188
        public IObservable createObservable(Object target)
194
	 * @param value
189
        {
195
	 *            the master observable value.
190
          return observeMap((IObservableSet)target, eStructuralFeature);
196
	 * @param eStructuralFeature
191
        }
197
	 *            the feature for which to track the value.
192
      };
198
	 * @return an observable value that tracks the current value of the named
193
   }
199
	 *         property for the current value of the master observable value
200
	 * @see MasterDetailObservables#detailList(IObservableValue,
201
	 *      IObservableFactory, Object)
202
	 */
203
	public static IObservableList observeDetailList(Realm realm,
204
			IObservableValue value, EStructuralFeature eStructuralFeature) {
205
		return MasterDetailObservables.detailList(value, listFactory(realm,
206
				eStructuralFeature), eStructuralFeature);
207
	}
208
209
	/**
210
	 * Returns a factory for creating observable lists tracking the value of the
211
	 * given feature of a particular {@link EObject object}.
212
	 * 
213
	 * @param realm
214
	 *            the realm in which to observe.
215
	 * @param eStructuralFeature
216
	 *            the feature for which to track the value.
217
	 * @return an observable factory.
218
	 */
219
	public static IObservableFactory listFactory(final Realm realm,
220
			final EStructuralFeature eStructuralFeature) {
221
		return new IObservableFactory() {
222
			public IObservable createObservable(Object target) {
223
				return observeList(realm, (EObject) target, eStructuralFeature);
224
			}
225
		};
226
	}
227
228
	/**
229
	 * Returns a factory for creating observable maps tracking the value of the
230
	 * given feature of a particular {@link EObject object}.
231
	 * 
232
	 * @param eStructuralFeature
233
	 *            the feature for which to track the value.
234
	 * @return an observable factory.
235
	 */
236
	public static IObservableFactory mapFactory(
237
			final EStructuralFeature eStructuralFeature) {
238
		return new IObservableFactory() {
239
			public IObservable createObservable(Object target) {
240
				return observeMap((IObservableSet) target, eStructuralFeature);
241
			}
242
		};
243
	}
194
}
244
}
(-)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 / +1 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %pluginName
3
Bundle-Name: %pluginName
4
Bundle-SymbolicName: org.eclipse.emf.databinding; singleton:=true
4
Bundle-SymbolicName: org.eclipse.emf.databinding; singleton:=true
5
Bundle-Version: 1.1.0.qualifier
5
Bundle-Version: 1.2.0.qualifier
6
Bundle-ClassPath: .
6
Bundle-ClassPath: .
7
Bundle-Activator: org.eclipse.emf.databinding.DataBindingPlugin$Implementation
7
Bundle-Activator: org.eclipse.emf.databinding.DataBindingPlugin$Implementation
8
Bundle-Vendor: %providerName
8
Bundle-Vendor: %providerName
(-)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 (+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
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
 * @since 1.1
35
 */
36
public class EMFMapProperty extends SimpleMapProperty {
37
	
38
	private final EStructuralFeature feature;
39
	private final Class<?> keyType;
40
	private final Class<?> valueType;
41
	
42
	/**
43
	 * @param feature
44
	 * @param keyType
45
	 * @param valueType
46
	 */
47
	public EMFMapProperty(EStructuralFeature feature, Class<?> keyType, Class<?> valueType) {
48
		this.feature = feature;
49
		this.keyType = keyType;
50
		this.valueType = valueType;
51
	}
52
	
53
	public Object getKeyType() {
54
		return keyType;
55
	}
56
57
	public Object getValueType() {
58
		return valueType;
59
	}
60
61
	@Override
62
	protected Map<?,?> doGetMap(Object source) {
63
		EObject eObj = (EObject) source;
64
		return (Map<?,?>) eObj.eGet(feature);
65
	}
66
	
67
	@SuppressWarnings("unchecked")
68
	@Override
69
	protected void doSetMap(Object source, Map map, MapDiff diff) {
70
		diff.applyTo(doGetMap(source));
71
	}
72
	
73
	@Override
74
	public INativePropertyListener adaptListener(
75
			ISimplePropertyListener listener) {
76
		return new Listener(listener);
77
	}
78
	
79
	private class Listener extends AdapterImpl implements INativePropertyListener {
80
		private final ISimplePropertyListener listener;
81
82
		private Listener(ISimplePropertyListener listener) {
83
			this.listener = listener;
84
		}
85
		
86
		@Override
87
		public void notifyChanged(Notification msg) {
88
			if (feature == msg.getFeature() && !msg.isTouch())
89
	        {
90
	          // TODO
91
	          // This assumes we only get a SET notification, which isn't a good assumption.
92
	          //
93
	          final MapDiff diff = Diffs.createMapDiffSingleChange(msg.getNotifier(), msg.getOldValue(), msg.getNewValue());
94
	          listener.handlePropertyChange(new SimplePropertyEvent(msg
95
						.getNotifier(), EMFMapProperty.this, diff));
96
	        }
97
		}
98
	}
99
100
	@Override
101
	protected void doAddListener(Object source, INativePropertyListener listener) {
102
		EObject eObj = (EObject) source;
103
		eObj.eAdapters().add((Adapter) listener);
104
	}
105
106
	@Override
107
	protected void doRemoveListener(Object source,
108
			INativePropertyListener listener) {
109
		EObject eObj = (EObject) source;
110
		eObj.eAdapters().remove((Adapter) listener);
111
	}
112
113
	
114
115
	
116
117
}
(-)src/org/eclipse/emf/databinding/properties/internal/EMFMapPropertyDecorator.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.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
}
(-)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 (+168 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
}
(-)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 (+81 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
}
(-)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 (+103 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
}
(-)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
}

Return to bug 262160