1 11 12 package org.eclipse.core.databinding; 13 14 import java.util.Collections ; 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 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 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 () { 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 () { 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 } 129 130 public void validateTargetToModel() { 131 } 133 134 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 () { 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 } else { 174 IStatus setterStatus = updateListStrategy 175 .doRemove(destination, 176 listDiffEntry.getPosition()); 177 178 mergeStatus(multiStatus, setterStatus); 179 } 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 205 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 |