KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > databinding > ListBinding


1 /*******************************************************************************
2  * Copyright (c) 2007 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  ******************************************************************************/

11
12 package org.eclipse.core.databinding;
13
14 import java.util.Collections JavaDoc;
15
16 import org.eclipse.core.databinding.observable.Diffs;
17 import org.eclipse.core.databinding.observable.list.IListChangeListener;
18 import org.eclipse.core.databinding.observable.list.IObservableList;
19 import org.eclipse.core.databinding.observable.list.ListChangeEvent;
20 import org.eclipse.core.databinding.observable.list.ListDiff;
21 import org.eclipse.core.databinding.observable.list.ListDiffEntry;
22 import org.eclipse.core.databinding.observable.value.IObservableValue;
23 import org.eclipse.core.databinding.observable.value.WritableValue;
24 import org.eclipse.core.internal.databinding.BindingStatus;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.MultiStatus;
27 import org.eclipse.core.runtime.Status;
28
29 /**
30  * @since 1.0
31  *
32  */

33 public class ListBinding extends Binding {
34
35     private UpdateListStrategy targetToModel;
36     private UpdateListStrategy modelToTarget;
37     private IObservableValue validationStatusObservable;
38     private boolean updatingTarget;
39     private boolean updatingModel;
40
41     private IListChangeListener targetChangeListener = new IListChangeListener() {
42         public void handleListChange(ListChangeEvent event) {
43             if (!updatingTarget) {
44                 doUpdate((IObservableList) getTarget(),
45                         (IObservableList) getModel(), event.diff,
46                         targetToModel, false, false);
47             }
48         }
49     };
50     private IListChangeListener modelChangeListener = new IListChangeListener() {
51         public void handleListChange(ListChangeEvent event) {
52             if (!updatingModel) {
53                 doUpdate((IObservableList) getModel(),
54                         (IObservableList) getTarget(), event.diff,
55                         modelToTarget, false, false);
56             }
57         }
58     };
59
60     /**
61      * @param target
62      * @param model
63      * @param modelToTargetStrategy
64      * @param targetToModelStrategy
65      */

66     public ListBinding(IObservableList target, IObservableList model,
67             UpdateListStrategy targetToModelStrategy,
68             UpdateListStrategy modelToTargetStrategy) {
69         super(target, model);
70         this.targetToModel = targetToModelStrategy;
71         this.modelToTarget = modelToTargetStrategy;
72         if ((targetToModel.getUpdatePolicy() & UpdateValueStrategy.POLICY_UPDATE) != 0) {
73             target.addListChangeListener(targetChangeListener);
74         } else {
75             targetChangeListener = null;
76         }
77         if ((modelToTarget.getUpdatePolicy() & UpdateValueStrategy.POLICY_UPDATE) != 0) {
78             model.addListChangeListener(modelChangeListener);
79         } else {
80             modelChangeListener = null;
81         }
82     }
83
84     public IObservableValue getValidationStatus() {
85         return validationStatusObservable;
86     }
87
88     protected void preInit() {
89         validationStatusObservable = new WritableValue(context
90                 .getValidationRealm(), Status.OK_STATUS, IStatus.class);
91     }
92
93     protected void postInit() {
94         if (modelToTarget.getUpdatePolicy() == UpdateListStrategy.POLICY_UPDATE) {
95             updateModelToTarget();
96         }
97         if (targetToModel.getUpdatePolicy() != UpdateListStrategy.POLICY_NEVER) {
98             validateTargetToModel();
99         }
100     }
101
102     public void updateModelToTarget() {
103         final IObservableList modelList = (IObservableList) getModel();
104         modelList.getRealm().exec(new Runnable JavaDoc() {
105             public void run() {
106                 ListDiff diff = Diffs.computeListDiff(Collections.EMPTY_LIST,
107                         modelList);
108                 doUpdate(modelList, (IObservableList) getTarget(), diff,
109                         modelToTarget, true, true);
110             }
111         });
112     }
113
114     public void updateTargetToModel() {
115         final IObservableList targetList = (IObservableList) getTarget();
116         targetList.getRealm().exec(new Runnable JavaDoc() {
117             public void run() {
118                 ListDiff diff = Diffs.computeListDiff(Collections.EMPTY_LIST,
119                         targetList);
120                 doUpdate(targetList, (IObservableList) getModel(), diff,
121                         targetToModel, true, true);
122             }
123         });
124     }
125
126     public void validateModelToTarget() {
127         // nothing for now
128
}
129
130     public void validateTargetToModel() {
131         // nothing for now
132
}
133
134     /*
135      * This method may be moved to UpdateListStrategy in the future if clients
136      * need more control over how the two lists are kept in sync.
137      */

138     private void doUpdate(final IObservableList source,
139             final IObservableList destination, final ListDiff diff,
140             final UpdateListStrategy updateListStrategy,
141             final boolean explicit, final boolean clearDestination) {
142         final int policy = updateListStrategy.getUpdatePolicy();
143         if (policy != UpdateListStrategy.POLICY_NEVER) {
144             if (policy != UpdateListStrategy.POLICY_ON_REQUEST || explicit) {
145                 destination.getRealm().exec(new Runnable JavaDoc() {
146                     public void run() {
147                         if (destination == getTarget()) {
148                             updatingTarget = true;
149                         } else {
150                             updatingModel = true;
151                         }
152                         MultiStatus multiStatus = BindingStatus.ok();
153
154                         try {
155                             if (clearDestination) {
156                                 destination.clear();
157                             }
158                             ListDiffEntry[] diffEntries = diff.getDifferences();
159                             for (int i = 0; i < diffEntries.length; i++) {
160                                 ListDiffEntry listDiffEntry = diffEntries[i];
161                                 if (listDiffEntry.isAddition()) {
162                                     IStatus setterStatus = updateListStrategy
163                                             .doAdd(
164                                                     destination,
165                                                     updateListStrategy
166                                                             .convert(listDiffEntry
167                                                                     .getElement()),
168                                                     listDiffEntry.getPosition());
169
170                                     mergeStatus(multiStatus, setterStatus);
171                                     // TODO - at this point, the two lists
172
// will be out of sync if an error occurred...
173
} else {
174                                     IStatus setterStatus = updateListStrategy
175                                             .doRemove(destination,
176                                                     listDiffEntry.getPosition());
177                                     
178                                     mergeStatus(multiStatus, setterStatus);
179                                     // TODO - at this point, the two lists
180
// will be out of sync if an error occurred...
181
}
182                             }
183                         } finally {
184                             validationStatusObservable.setValue(multiStatus);
185
186                             if (destination == getTarget()) {
187                                 updatingTarget = false;
188                             } else {
189                                 updatingModel = false;
190                             }
191                         }
192                     }
193                 });
194             }
195         }
196     }
197
198     /**
199      * Merges the provided <code>newStatus</code> into the
200      * <code>multiStatus</code>.
201      *
202      * @param multiStatus
203      * @param newStatus
204      */

205     /* package */void mergeStatus(MultiStatus multiStatus, IStatus newStatus) {
206         if (!newStatus.isOK()) {
207             multiStatus.add(newStatus);
208         }
209     }
210
211     public void dispose() {
212         if (targetChangeListener != null) {
213             ((IObservableList)getTarget()).removeListChangeListener(targetChangeListener);
214             targetChangeListener = null;
215         }
216         if (modelChangeListener != null) {
217             ((IObservableList)getModel()).removeListChangeListener(modelChangeListener);
218             modelChangeListener = null;
219         }
220         super.dispose();
221     }
222 }
223
Popular Tags