78
|
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 124684)
|
|
10 * IBM Corporation - through UpdateListStrategy.java
|
|
11 ******************************************************************************/
|
|
12
|
|
13 module org.eclipse.core.databinding.UpdateSetStrategy;
|
81
|
14 import org.eclipse.core.databinding.UpdateStrategy;
|
78
|
15
|
|
16 import java.lang.all;
|
|
17
|
|
18 import org.eclipse.core.databinding.conversion.IConverter;
|
|
19 import org.eclipse.core.databinding.observable.set.IObservableSet;
|
|
20 import org.eclipse.core.databinding.validation.ValidationStatus;
|
|
21 import org.eclipse.core.internal.databinding.BindingMessages;
|
|
22 import org.eclipse.core.runtime.IStatus;
|
|
23 import org.eclipse.core.runtime.Status;
|
|
24
|
85
|
25 /**
|
|
26 * Helper method allowing API evolution of the above constant values. The
|
|
27 * compiler will not inline constant values into client code if values are
|
|
28 * "computed" using this helper.
|
|
29 *
|
|
30 * @param i
|
|
31 * an integer
|
|
32 * @return the same integer
|
|
33 */
|
|
34 private int notInlined(int i) {
|
|
35 return i;
|
|
36 }
|
|
37
|
78
|
38 /**
|
|
39 * Customizes a {@link Binding} between two
|
|
40 * {@link IObservableSet observable sets}. The following behaviors can be
|
|
41 * customized via the strategy:
|
|
42 * <ul>
|
|
43 * <li>Conversion</li>
|
|
44 * <li>Automatic processing</li>
|
|
45 * </ul>
|
|
46 * <p>
|
|
47 * Conversion:<br/> When elements are added they can be
|
|
48 * {@link #convertcast(Object) converted} to the destination element type.
|
|
49 * </p>
|
|
50 * <p>
|
|
51 * Automatic processing:<br/> The processing to perform when the source
|
|
52 * observable changes. This behavior is configured via policies provided on
|
|
53 * construction of the strategy (e.g. {@link #POLICY_NEVER},
|
|
54 * {@link #POLICY_ON_REQUEST}, {@link #POLICY_UPDATE}).
|
|
55 * </p>
|
|
56 *
|
|
57 *
|
|
58 * @see DataBindingContext#bindSet(IObservableSet, IObservableSet,
|
|
59 * UpdateSetStrategy, UpdateSetStrategy)
|
|
60 * @see IConverter
|
|
61 * @since 1.1
|
|
62 */
|
|
63 public class UpdateSetStrategy : UpdateStrategy {
|
|
64
|
|
65 /**
|
|
66 * Policy constant denoting that the source observable's state should not be
|
|
67 * tracked and that the destination observable's state should never be
|
|
68 * updated.
|
|
69 */
|
|
70 public final static int POLICY_NEVER = notInlined(1);
|
|
71
|
|
72 /**
|
|
73 * Policy constant denoting that the source observable's state should not be
|
|
74 * tracked, but that conversion and updating the destination observable's
|
|
75 * state should be performed when explicitly requested.
|
|
76 */
|
|
77 public final static int POLICY_ON_REQUEST = notInlined(2);
|
|
78
|
|
79 /**
|
|
80 * Policy constant denoting that the source observable's state should be
|
|
81 * tracked, and that conversion and updating the destination observable's
|
|
82 * state should be performed automatically on every change of the source
|
|
83 * observable state.
|
|
84 */
|
|
85 public final static int POLICY_UPDATE = notInlined(8);
|
|
86
|
|
87 protected IConverter converter;
|
|
88
|
|
89 private int updatePolicy;
|
|
90
|
|
91 protected bool provideDefaults;
|
|
92
|
|
93 /**
|
|
94 * Creates a new update list strategy for automatically updating the
|
|
95 * destination observable list whenever the source observable list changes.
|
|
96 * A default converter will be provided. The defaults can be changed by
|
|
97 * calling one of the setter methods.
|
|
98 */
|
|
99 public this() {
|
|
100 this(true, POLICY_UPDATE);
|
|
101 }
|
|
102
|
|
103 /**
|
|
104 * Creates a new update list strategy with a configurable update policy. A
|
|
105 * default converter will be provided. The defaults can be changed by
|
|
106 * calling one of the setter methods.
|
|
107 *
|
|
108 * @param updatePolicy
|
|
109 * one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST}, or
|
|
110 * {@link #POLICY_UPDATE}
|
|
111 */
|
|
112 public this(int updatePolicy) {
|
|
113 this(true, updatePolicy);
|
|
114 }
|
|
115
|
|
116 /**
|
|
117 * Creates a new update list strategy with a configurable update policy. A
|
|
118 * default converter will be provided if <code>provideDefaults</code> is
|
|
119 * <code>true</code>. The defaults can be changed by calling one of the
|
|
120 * setter methods.
|
|
121 *
|
|
122 * @param provideDefaults
|
|
123 * if <code>true</code>, default validators and a default
|
|
124 * converter will be provided based on the observable list's
|
|
125 * type.
|
|
126 * @param updatePolicy
|
|
127 * one of {@link #POLICY_NEVER}, {@link #POLICY_ON_REQUEST}, or
|
|
128 * {@link #POLICY_UPDATE}
|
|
129 */
|
|
130 public this(bool provideDefaults, int updatePolicy) {
|
|
131 this.provideDefaults = provideDefaults;
|
|
132 this.updatePolicy = updatePolicy;
|
|
133 }
|
|
134
|
|
135 /**
|
|
136 * When an element is added to the destination converts the element from the
|
|
137 * source element type to the destination element type.
|
|
138 * <p>
|
|
139 * Default implementation will use the
|
|
140 * {@link #setConvertercast(IConverter) converter} if one exists. If no
|
|
141 * converter exists no conversion occurs.
|
|
142 * </p>
|
|
143 *
|
|
144 * @param element
|
|
145 * @return the converted element
|
|
146 */
|
|
147 public Object convert(Object element) {
|
|
148 return converter is null ? element : converter.convert(element);
|
|
149 }
|
|
150
|
|
151 /**
|
|
152 *
|
|
153 * @param source
|
|
154 * @param destination
|
|
155 */
|
|
156 protected void fillDefaults(IObservableSet source,
|
|
157 IObservableSet destination) {
|
|
158 Object sourceType = source.getElementType();
|
|
159 Object destinationType = destination.getElementType();
|
|
160 if (provideDefaults && sourceType !is null && destinationType !is null) {
|
|
161 if (converter is null) {
|
|
162 setConverter(createConverter(sourceType, destinationType));
|
|
163 }
|
|
164 }
|
|
165 if (converter !is null) {
|
|
166 if (sourceType !is null) {
|
|
167 checkAssignable(converter.getFromType(), sourceType,
|
85
|
168 "converter does not convert from type " ~ String_valueOf(sourceType)); //$NON-NLS-1$
|
78
|
169 }
|
|
170 if (destinationType !is null) {
|
|
171 checkAssignable(converter.getToType(), destinationType,
|
85
|
172 "converter does not convert to type " ~ String_valueOf(destinationType)); //$NON-NLS-1$
|
78
|
173 }
|
|
174 }
|
|
175 }
|
85
|
176 package void fillDefaults_package(IObservableSet source, IObservableSet destination) {
|
|
177 fillDefaults(source, destination);
|
|
178 }
|
78
|
179
|
|
180 /**
|
|
181 * @return the update policy
|
|
182 */
|
|
183 public int getUpdatePolicy() {
|
|
184 return updatePolicy;
|
|
185 }
|
|
186
|
|
187 /**
|
|
188 * Sets the converter to be invoked when converting added elements from the
|
|
189 * source element type to the destination element type.
|
|
190 *
|
|
191 * @param converter
|
|
192 * @return the receiver, to enable method call chaining
|
|
193 */
|
|
194 public UpdateSetStrategy setConverter(IConverter converter) {
|
|
195 this.converter = converter;
|
|
196 return this;
|
|
197 }
|
|
198
|
|
199 /**
|
|
200 * Adds the given element at the given index to the given observable list.
|
|
201 * Clients may extend but must call the super implementation.
|
|
202 *
|
|
203 * @param observableSet
|
|
204 * @param element
|
|
205 * @return a status
|
|
206 */
|
|
207 protected IStatus doAdd(IObservableSet observableSet, Object element) {
|
|
208 try {
|
|
209 observableSet.add(element);
|
|
210 } catch (Exception ex) {
|
|
211 return ValidationStatus.error(BindingMessages
|
|
212 .getString("ValueBinding_ErrorWhileSettingValue"), //$NON-NLS-1$
|
|
213 ex);
|
|
214 }
|
|
215 return Status.OK_STATUS;
|
|
216 }
|
85
|
217 package IStatus doAdd_package( IObservableSet observableSet, Object element) {
|
|
218 return doAdd(observableSet, element);
|
|
219 }
|
78
|
220
|
|
221 /**
|
|
222 * Removes the element at the given index from the given observable list.
|
|
223 * Clients may extend but must call the super implementation.
|
|
224 *
|
|
225 * @param observableSet
|
|
226 * @param element
|
|
227 * @return a status
|
|
228 */
|
|
229 protected IStatus doRemove(IObservableSet observableSet, Object element) {
|
|
230 try {
|
|
231 observableSet.remove(element);
|
|
232 } catch (Exception ex) {
|
|
233 return ValidationStatus.error(BindingMessages
|
|
234 .getString("ValueBinding_ErrorWhileSettingValue"), //$NON-NLS-1$
|
|
235 ex);
|
|
236 }
|
|
237 return Status.OK_STATUS;
|
|
238 }
|
85
|
239 package IStatus doRemove_package(IObservableSet observableSet, Object element) {
|
|
240 return doRemove(observableSet, element );
|
|
241 }
|
78
|
242 }
|