1 11 package org.eclipse.team.internal.ui.mapping; 12 13 import org.eclipse.compare.*; 14 import org.eclipse.compare.structuremergeviewer.*; 15 import org.eclipse.core.resources.*; 16 import org.eclipse.core.runtime.*; 17 import org.eclipse.jface.dialogs.IDialogConstants; 18 import org.eclipse.jface.dialogs.MessageDialog; 19 import org.eclipse.jface.resource.ImageDescriptor; 20 import org.eclipse.jface.util.IPropertyChangeListener; 21 import org.eclipse.jface.util.PropertyChangeEvent; 22 import org.eclipse.osgi.util.NLS; 23 import org.eclipse.swt.graphics.Image; 24 import org.eclipse.team.core.diff.IDiff; 25 import org.eclipse.team.core.diff.IThreeWayDiff; 26 import org.eclipse.team.core.history.IFileRevision; 27 import org.eclipse.team.core.mapping.IResourceDiff; 28 import org.eclipse.team.core.mapping.provider.ResourceDiffTree; 29 import org.eclipse.team.internal.ui.*; 30 import org.eclipse.team.internal.ui.history.FileRevisionTypedElement; 31 import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; 32 import org.eclipse.team.ui.mapping.ISynchronizationCompareInput; 33 import org.eclipse.team.ui.mapping.SaveableComparison; 34 import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; 35 36 39 public class ResourceSaveableComparison extends SaveableComparison implements IPropertyChangeListener { 40 41 ICompareInput input; 42 ISynchronizeParticipant participant; 43 private final CompareEditorInput editorInput; 44 private boolean isSaving; 45 46 public static class ResourceDiffCompareInput extends DiffNode implements ISynchronizationCompareInput, IAdaptable { 47 48 private final IDiff node; 49 private long timestamp; 50 51 public ResourceDiffCompareInput(IDiff node) { 52 super(getCompareKind(node), getAncestor(node), getLeftContributor(node), getRightContributor(node)); 53 this.node = node; 54 } 55 56 60 public void fireChange() { 61 super.fireChange(); 62 } 63 64 private static int getCompareKind(IDiff node) { 65 int kind = 0; 66 switch (node.getKind()) { 67 case IDiff.CHANGE: 68 kind = Differencer.CHANGE; 69 break; 70 case IDiff.ADD: 71 kind = Differencer.ADDITION; 72 break; 73 case IDiff.REMOVE: 74 kind = Differencer.DELETION; 75 break; 76 } 77 if (node instanceof IThreeWayDiff) { 78 IThreeWayDiff twd = (IThreeWayDiff) node; 79 switch (twd.getDirection()) { 80 case IThreeWayDiff.INCOMING: 81 kind |= Differencer.RIGHT; 82 break; 83 case IThreeWayDiff.OUTGOING: 84 kind |= Differencer.LEFT; 85 break; 86 case IThreeWayDiff.CONFLICTING: 87 kind |= Differencer.CONFLICTING; 88 break; 89 } 90 } 91 return kind; 92 } 93 94 private static ITypedElement getRightContributor(IDiff node) { 95 if (node instanceof IResourceDiff) { 97 IResourceDiff rd = (IResourceDiff) node; 98 return asTypedElement(rd.getAfterState(), getLocalEncoding(node)); 99 } 100 if (node instanceof IThreeWayDiff) { 101 IThreeWayDiff twd = (IThreeWayDiff) node; 102 IResourceDiff diff = (IResourceDiff)twd.getRemoteChange(); 103 if (diff != null) 105 return getRightContributor(diff); 106 diff = (IResourceDiff)twd.getLocalChange(); 108 return asTypedElement(diff.getBeforeState(), getLocalEncoding(node)); 109 110 } 111 return null; 112 } 113 114 private static ITypedElement getLeftContributor(final IDiff node) { 115 final IResource resource = ResourceDiffTree.getResourceFor(node); 117 return new LocalResourceTypedElement(resource) { 118 public boolean isEditable() { 119 if(! resource.exists() && isOutgoingDeletion(node)) { 120 return false; 121 } 122 return super.isEditable(); 123 } 124 125 private boolean isOutgoingDeletion(IDiff node) { 126 if (node instanceof IThreeWayDiff) { 127 IThreeWayDiff twd = (IThreeWayDiff) node; 128 return twd.getKind() == IDiff.REMOVE && twd.getDirection() == IThreeWayDiff.OUTGOING; 129 } 130 return false; 131 } 132 }; 133 } 134 135 private static ITypedElement getAncestor(IDiff node) { 136 if (node instanceof IThreeWayDiff) { 137 IThreeWayDiff twd = (IThreeWayDiff) node; 138 IResourceDiff diff = (IResourceDiff)twd.getLocalChange(); 139 if (diff == null) 140 diff = (IResourceDiff)twd.getRemoteChange(); 141 return asTypedElement(diff.getBeforeState(), getLocalEncoding(node)); 142 143 } 144 return null; 145 } 146 147 private static String getLocalEncoding(IDiff node) { 148 IResource resource = ResourceDiffTree.getResourceFor(node); 149 if (resource instanceof IEncodedStorage) { 150 IEncodedStorage es = (IEncodedStorage) resource; 151 try { 152 return es.getCharset(); 153 } catch (CoreException e) { 154 TeamUIPlugin.log(e); 155 } 156 } 157 return null; 158 } 159 160 private static ITypedElement asTypedElement(IFileRevision state, String localEncoding) { 161 if (state == null) 162 return null; 163 return new FileRevisionTypedElement(state, localEncoding); 164 } 165 166 169 public void prepareInput(CompareConfiguration configuration, IProgressMonitor monitor) throws CoreException { 170 Utils.updateLabels(node, configuration, monitor); 171 Object ancestor = getAncestor(); 173 if (ancestor instanceof FileRevisionTypedElement) { 174 FileRevisionTypedElement fste = (FileRevisionTypedElement) ancestor; 175 fste.cacheContents(monitor); 176 } 177 Object right = getRight(); 178 if (right instanceof FileRevisionTypedElement) { 179 FileRevisionTypedElement fste = (FileRevisionTypedElement) right; 180 fste.cacheContents(monitor); 181 } 182 updateTimestamp(); 183 } 184 185 188 public SaveableComparison getSaveable() { 189 return null; 190 } 191 192 195 public Object getAdapter(Class adapter) { 196 if (adapter == IFile.class || adapter == IResource.class) { 197 if (node instanceof IResourceDiff) { 198 IResourceDiff rd = (IResourceDiff) node; 199 return (IFile)rd.getResource(); 200 } 201 if (node instanceof IThreeWayDiff) { 202 IThreeWayDiff twd = (IThreeWayDiff) node; 203 IResourceDiff diff = (IResourceDiff)twd.getRemoteChange(); 204 if (diff != null) 206 return (IFile)diff.getResource(); 207 diff = (IResourceDiff)twd.getLocalChange(); 209 return (IFile)diff.getResource(); 210 211 } 212 } 213 return null; 214 } 215 216 public String getFullPath() { 217 final IResource resource = ResourceDiffTree.getResourceFor(node); 218 if (resource != null) 219 return resource.getFullPath().toString(); 220 return getName(); 221 } 222 223 public boolean isCompareInputFor(Object object) { 224 final IResource resource = ResourceDiffTree.getResourceFor(node); 225 IResource other = Utils.getResource(object); 226 if (resource != null && other != null) 227 return resource.equals(other); 228 return false; 229 } 230 231 public boolean checkUpdateConflict() { 232 long newTimestamp = ResourceDiffTree.getResourceFor(node).getLocalTimeStamp(); 233 if(newTimestamp != timestamp) { 234 final MessageDialog dialog = 235 new MessageDialog(TeamUIPlugin.getStandardDisplay().getActiveShell(), 236 TeamUIMessages.SyncInfoCompareInput_0, 237 null, 238 TeamUIMessages.SyncInfoCompareInput_1, 239 MessageDialog.QUESTION, 240 new String [] { 241 TeamUIMessages.SyncInfoCompareInput_2, 242 IDialogConstants.CANCEL_LABEL}, 243 0); 244 245 int retval = dialog.open(); 246 switch(retval) { 247 case 0: 249 return false; 250 case 1: 252 return true; 253 } 254 } 255 return false; 256 } 257 258 public void updateTimestamp() { 259 timestamp = ResourceDiffTree.getResourceFor(node).getLocalTimeStamp(); 260 } 261 } 262 263 public ResourceSaveableComparison(ICompareInput input, ISynchronizeParticipant participant, ModelCompareEditorInput editorInput) { 264 this.input = input; 265 this.participant = participant; 266 this.editorInput = editorInput; 267 initializeContentChangeListeners(); 268 } 269 270 private void initializeContentChangeListeners() { 271 ITypedElement te = input.getLeft(); 274 if (te instanceof IContentChangeNotifier) { 275 ((IContentChangeNotifier) te).addContentChangeListener(new IContentChangeListener() { 276 public void contentChanged(IContentChangeNotifier source) { 277 try { 278 if(! isSaving) { 279 performSave(new NullProgressMonitor()); 280 } 281 } catch (CoreException e) { 282 TeamUIPlugin.log(e); 283 } 284 } 285 }); 286 } 287 } 288 289 292 protected void performSave(IProgressMonitor monitor) throws CoreException { 293 if (input instanceof ResourceDiffCompareInput) { 294 ResourceDiffCompareInput rdci = (ResourceDiffCompareInput) input; 295 if (rdci.checkUpdateConflict()) 296 return; 297 } 298 try { 299 isSaving = true; 300 monitor.beginTask(null, 100); 301 editorInput.saveChanges(Policy.subMonitorFor(monitor, 40)); 304 ITypedElement left = input.getLeft(); 307 if (left instanceof LocalResourceTypedElement) 308 ((LocalResourceTypedElement) left).commit(Policy.subMonitorFor(monitor, 60)); 309 } finally { 310 if (input instanceof ResourceDiffCompareInput) { 312 ResourceDiffCompareInput rdci = (ResourceDiffCompareInput) input; 313 rdci.updateTimestamp(); 314 rdci.fireChange(); 315 } 316 setDirty(false); 317 isSaving = false; 318 monitor.done(); 319 } 320 } 321 322 325 public boolean isDirty() { 326 return editorInput.isSaveNeeded(); 329 } 330 331 334 protected void setDirty(boolean dirty) { 335 editorInput.setDirty(dirty); 338 } 339 340 343 protected void performRevert(IProgressMonitor monitor) { 344 ITypedElement left = input.getLeft(); 346 if (left instanceof LocalResourceTypedElement) 347 ((LocalResourceTypedElement) left).discardBuffer(); 348 } 349 350 353 public String getName() { 354 return input.getName(); 355 } 356 357 360 public String getToolTipText() { 361 String fullPath; 362 if (input instanceof ISynchronizationCompareInput) { 363 ISynchronizationCompareInput mci = (ISynchronizationCompareInput) input; 364 fullPath = mci.getFullPath(); 365 } else { 366 fullPath = getName(); 367 } 368 return NLS.bind(TeamUIMessages.SyncInfoCompareInput_tooltip, new String [] { Utils.shortenText(30, participant.getName()), fullPath }); 369 } 370 371 374 public ImageDescriptor getImageDescriptor() { 375 Image image = input.getImage(); 376 if (image != null) 377 return ImageDescriptor.createFromImage(image); 378 return TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_SYNC_VIEW); 379 } 380 381 384 public void propertyChange(PropertyChangeEvent e) { 385 String propertyName= e.getProperty(); 386 if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) { 387 boolean changed= false; 388 Object newValue= e.getNewValue(); 389 if (newValue instanceof Boolean ) 390 changed= ((Boolean )newValue).booleanValue(); 391 setDirty(changed); 392 } 393 } 394 395 public boolean equals(Object object) { 396 if (object instanceof ResourceSaveableComparison) { 397 ResourceSaveableComparison rscm = (ResourceSaveableComparison) object; 398 return rscm.input.equals(input); 399 } 400 return false; 401 } 402 403 public int hashCode() { 404 return input.hashCode(); 405 } 406 } 407 | Popular Tags |