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