KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > CVSCompareEditorInput


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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 package org.eclipse.team.internal.ccvs.ui;
12
13  
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15
16 import org.eclipse.compare.CompareConfiguration;
17 import org.eclipse.compare.CompareEditorInput;
18 import org.eclipse.compare.ITypedElement;
19 import org.eclipse.compare.structuremergeviewer.DiffNode;
20 import org.eclipse.compare.structuremergeviewer.Differencer;
21 import org.eclipse.compare.structuremergeviewer.IDiffContainer;
22 import org.eclipse.compare.structuremergeviewer.IStructureComparator;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.OperationCanceledException;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29 import org.eclipse.jface.viewers.*;
30 import org.eclipse.osgi.util.NLS;
31 import org.eclipse.swt.graphics.Image;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.team.core.TeamException;
34 import org.eclipse.team.internal.ccvs.core.CVSTag;
35 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFile;
36 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
37 import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
38 import org.eclipse.team.internal.ccvs.core.ICVSResource;
39 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
40
41 /**
42  * A compare input for comparing remote resources. Use <code>CVSLocalCompareInput</code>
43  * when comparing resources in the workspace to remote resources.
44  */

45 public class CVSCompareEditorInput extends CompareEditorInput {
46     private ITypedElement left;
47     private ITypedElement right;
48     private ITypedElement ancestor;
49     private Image leftImage;
50     private Image rightImage;
51     private Image ancestorImage;
52     
53     // comparison constants
54
private static final int NODE_EQUAL = 0;
55     private static final int NODE_NOT_EQUAL = 1;
56     private static final int NODE_UNKNOWN = 2;
57     
58     String JavaDoc toolTipText;
59     private String JavaDoc title;
60     
61     /**
62      * Creates a new CVSCompareEditorInput.
63      */

64     public CVSCompareEditorInput(ResourceEditionNode left, ResourceEditionNode right) {
65         this(left, right, null);
66     }
67     
68     public CVSCompareEditorInput(String JavaDoc title, String JavaDoc toolTip, ResourceEditionNode left, ResourceEditionNode right) {
69         this(left, right, null);
70         this.title = title;
71         this.toolTipText = toolTip;
72     }
73     
74     /**
75      * Creates a new CVSCompareEditorInput.
76      */

77     public CVSCompareEditorInput(ResourceEditionNode left, ResourceEditionNode right, ResourceEditionNode ancestor) {
78         super(new CompareConfiguration());
79         // TODO: Invokers of this method should ensure that trees and contents are prefetched
80
this.left = left;
81         this.right = right;
82         this.ancestor = ancestor;
83         if (left != null) {
84             this.leftImage = left.getImage();
85         }
86         if (right != null) {
87             this.rightImage = right.getImage();
88         }
89         if (ancestor != null) {
90             this.ancestorImage = ancestor.getImage();
91         }
92     }
93     
94     /**
95      * Returns the label for the given input element.
96      */

97     private String JavaDoc getLabel(ITypedElement element) {
98         if (element instanceof ResourceEditionNode) {
99             ICVSRemoteResource edition = ((ResourceEditionNode)element).getRemoteResource();
100             ICVSResource resource = edition;
101             if (edition instanceof ICVSRemoteFile) {
102                 try {
103                     return NLS.bind(CVSUIMessages.nameAndRevision, new String JavaDoc[] { resource.getName(), ((ICVSRemoteFile)edition).getRevision() });
104                 } catch (TeamException e) {
105                     // fall through
106
}
107             }
108             try {
109                 if (edition.isContainer()) {
110                     CVSTag tag = ((ICVSRemoteFolder)edition).getTag();
111                     if (tag == null) {
112                         return NLS.bind(CVSUIMessages.CVSCompareEditorInput_inHead, new String JavaDoc[] { edition.getName() });
113                     } else if (tag.getType() == CVSTag.BRANCH) {
114                         return NLS.bind(CVSUIMessages.CVSCompareEditorInput_inBranch, (new Object JavaDoc[] {edition.getName(), tag.getName()}));
115                     } else {
116                         return NLS.bind(CVSUIMessages.CVSCompareEditorInput_repository, (new Object JavaDoc[] {edition.getName(), tag.getName()}));
117                     }
118                 } else {
119                     return NLS.bind(CVSUIMessages.CVSCompareEditorInput_repository, (new Object JavaDoc[] {edition.getName(), resource.getSyncInfo().getRevision()}));
120                 }
121             } catch (TeamException e) {
122                 handle(e);
123                 // Fall through and get the default label
124
}
125         }
126         return element.getName();
127     }
128     
129     /**
130      * Returns the label for the given input element.
131      */

132     private String JavaDoc getVersionLabel(ITypedElement element) {
133         if (element instanceof ResourceEditionNode) {
134             ICVSRemoteResource edition = ((ResourceEditionNode)element).getRemoteResource();
135             ICVSResource resource = edition;
136             try {
137                 if (edition.isContainer()) {
138                     CVSTag tag = ((ICVSRemoteFolder)resource).getTag();
139                     if (tag == null) {
140                         return CVSUIMessages.CVSCompareEditorInput_headLabel;
141                     } else if (tag.getType() == CVSTag.BRANCH) {
142                         return NLS.bind(CVSUIMessages.CVSCompareEditorInput_branchLabel, new String JavaDoc[] { tag.getName() });
143                     } else {
144                         return tag.getName();
145                     }
146                 } else {
147                     return resource.getSyncInfo().getRevision();
148                 }
149             } catch (TeamException e) {
150                 handle(e);
151                 // Fall through and get the default label
152
}
153         }
154         return element.getName();
155     }
156         
157     /*
158      * Returns a guess of the resource name being compared, for display
159      * in the title.
160      */

161     private String JavaDoc guessResourceName() {
162         if (left != null) {
163             return left.getName();
164         }
165         if (right != null) {
166             return right.getName();
167         }
168         if (ancestor != null) {
169             return ancestor.getName();
170         }
171         return ""; //$NON-NLS-1$
172
}
173     
174     /*
175      * Returns a guess of the resource path being compared, for display
176      * in the tooltip.
177      */

178     private Object JavaDoc guessResourcePath() {
179         if (left != null && left instanceof ResourceEditionNode) {
180             return ((ResourceEditionNode)left).getRemoteResource().getRepositoryRelativePath();
181         }
182         if (right != null && right instanceof ResourceEditionNode) {
183             return ((ResourceEditionNode)right).getRemoteResource().getRepositoryRelativePath();
184         }
185         if (ancestor != null && ancestor instanceof ResourceEditionNode) {
186             return ((ResourceEditionNode)ancestor).getRemoteResource().getRepositoryRelativePath();
187         }
188         return guessResourceName();
189     }
190     
191     /**
192      * Handles a random exception and sanitizes it into a reasonable
193      * error message.
194      */

195     private void handle(Exception JavaDoc e) {
196         // create a status
197
Throwable JavaDoc t = e;
198         // unwrap the invocation target exception
199
if (t instanceof InvocationTargetException JavaDoc) {
200             t = ((InvocationTargetException JavaDoc)t).getTargetException();
201         }
202         IStatus error;
203         if (t instanceof CoreException) {
204             error = ((CoreException)t).getStatus();
205         } else if (t instanceof TeamException) {
206             error = ((TeamException)t).getStatus();
207         } else {
208             error = new Status(IStatus.ERROR, CVSUIPlugin.ID, 1, CVSUIMessages.internal, t);
209         }
210         setMessage(error.getMessage());
211         if (!(t instanceof TeamException)) {
212             CVSUIPlugin.log(error.getSeverity(), error.getMessage(), t);
213         }
214     }
215     
216     /**
217      * Sets up the title and pane labels for the comparison view.
218      */

219     private void initLabels() {
220         CompareConfiguration cc = getCompareConfiguration();
221         setLabels(cc, new StructuredSelection());
222         
223         if (title == null) {
224             if (ancestor != null) {
225                 title = NLS.bind(CVSUIMessages.CVSCompareEditorInput_titleAncestor, (new Object JavaDoc[] {guessResourceName(), getVersionLabel(ancestor), getVersionLabel(left), getVersionLabel(right)}));
226                 toolTipText = NLS.bind(CVSUIMessages.CVSCompareEditorInput_titleAncestor, (new Object JavaDoc[] {guessResourcePath(), getVersionLabel(ancestor), getVersionLabel(left), getVersionLabel(right)}));
227             } else {
228                 String JavaDoc leftName = null;
229                 if (left != null) leftName = left.getName();
230                 String JavaDoc rightName = null;
231                 if (right != null) rightName = right.getName();
232                 if (leftName != null && !leftName.equals(rightName)) {
233                     title = NLS.bind(CVSUIMessages.CVSCompareEditorInput_titleNoAncestorDifferent, (new Object JavaDoc[] {leftName, getVersionLabel(left), rightName, getVersionLabel(right)}));
234                 } else {
235                     title = NLS.bind(CVSUIMessages.CVSCompareEditorInput_titleNoAncestor, (new Object JavaDoc[] {guessResourceName(), getVersionLabel(left), getVersionLabel(right)}));
236                     title = NLS.bind(CVSUIMessages.CVSCompareEditorInput_titleNoAncestor, (new Object JavaDoc[] {guessResourcePath(), getVersionLabel(left), getVersionLabel(right)}));
237                 }
238             }
239         }
240         setTitle(title);
241     }
242
243     private void setLabels(CompareConfiguration cc, IStructuredSelection selection) {
244         ITypedElement left = this.left;
245         ITypedElement right = this.right;
246         ITypedElement ancestor = this.ancestor;
247         
248         if (left != null) {
249             cc.setLeftLabel(getLabel(left));
250             cc.setLeftImage(leftImage);
251         }
252     
253         if (right != null) {
254             cc.setRightLabel(getLabel(right));
255             cc.setRightImage(rightImage);
256         }
257         
258         if (ancestor != null) {
259             cc.setAncestorLabel(getLabel(ancestor));
260             cc.setAncestorImage(ancestorImage);
261         }
262     }
263     
264     /* (Non-javadoc)
265      * Method declared on CompareEditorInput
266      */

267     public boolean isSaveNeeded() {
268         return false;
269     }
270
271     /* (non-Javadoc)
272      * Method declared on CompareEditorInput
273      */

274     protected Object JavaDoc prepareInput(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
275         final boolean threeWay = ancestor != null;
276         if (right == null || left == null) {
277             setMessage(CVSUIMessages.CVSCompareEditorInput_different);
278             return null;
279         }
280         
281         initLabels();
282     
283         final Differencer d = new Differencer() {
284             protected boolean contentsEqual(Object JavaDoc input1, Object JavaDoc input2) {
285                 int compare = teamEqual(input1, input2);
286                 if (compare == NODE_EQUAL) {
287                     return true;
288                 }
289                 if (compare == NODE_NOT_EQUAL) {
290                     return false;
291                 }
292                 //revert to slow content comparison
293
return super.contentsEqual(input1, input2);
294             }
295             protected void updateProgress(IProgressMonitor progressMonitor, Object JavaDoc node) {
296                 if (node instanceof ITypedElement) {
297                     ITypedElement element = (ITypedElement)node;
298                     progressMonitor.subTask(NLS.bind(CVSUIMessages.CompareEditorInput_fileProgress, (new String JavaDoc[] {element.getName()})));
299                     progressMonitor.worked(1);
300                 }
301             }
302             protected Object JavaDoc[] getChildren(Object JavaDoc input) {
303                 if (input instanceof IStructureComparator) {
304                     Object JavaDoc[] children= ((IStructureComparator)input).getChildren();
305                     if (children != null)
306                         return children;
307                 }
308                 return null;
309             }
310             protected Object JavaDoc visit(Object JavaDoc data, int result, Object JavaDoc ancestor, Object JavaDoc left, Object JavaDoc right) {
311                 return new DiffNode((IDiffContainer) data, result, (ITypedElement)ancestor, (ITypedElement)left, (ITypedElement)right);
312             }
313         };
314         
315         try {
316             // do the diff
317
Object JavaDoc result = null;
318             monitor.beginTask(CVSUIMessages.CVSCompareEditorInput_comparing, 30);
319             IProgressMonitor sub = new SubProgressMonitor(monitor, 30);
320             sub.beginTask(CVSUIMessages.CVSCompareEditorInput_comparing, 100);
321             try {
322                 result = d.findDifferences(threeWay, sub, null, ancestor, left, right);
323             } finally {
324                 sub.done();
325             }
326             return result;
327         } catch (OperationCanceledException e) {
328             throw new InterruptedException JavaDoc(e.getMessage());
329         } catch (RuntimeException JavaDoc e) {
330             handle(e);
331             return null;
332         } finally {
333             monitor.done();
334         }
335     }
336     
337     /**
338      * Compares two nodes to determine if they are equal. Returns NODE_EQUAL
339      * of they are the same, NODE_NOT_EQUAL if they are different, and
340      * NODE_UNKNOWN if comparison was not possible.
341      */

342     protected int teamEqual(Object JavaDoc left, Object JavaDoc right) {
343         // calculate the type for the left contribution
344
ICVSRemoteResource leftEdition = null;
345         if (left instanceof ResourceEditionNode) {
346             leftEdition = ((ResourceEditionNode)left).getRemoteResource();
347         }
348         
349         // calculate the type for the right contribution
350
ICVSRemoteResource rightEdition = null;
351         if (right instanceof ResourceEditionNode)
352             rightEdition = ((ResourceEditionNode)right).getRemoteResource();
353         
354         
355         // compare them
356

357         if (leftEdition == null || rightEdition == null) {
358             return NODE_UNKNOWN;
359         }
360         // if they're both non-files, they're the same
361
if (leftEdition.isContainer() && rightEdition.isContainer()) {
362             return NODE_EQUAL;
363         }
364         // if they have different types, they're different
365
if (leftEdition.isContainer() != rightEdition.isContainer()) {
366             return NODE_NOT_EQUAL;
367         }
368         
369         String JavaDoc leftLocation = leftEdition.getRepository().getLocation(false);
370         String JavaDoc rightLocation = rightEdition.getRepository().getLocation(false);
371         if (!leftLocation.equals(rightLocation)) {
372             return NODE_UNKNOWN;
373         }
374         try {
375             ResourceSyncInfo leftInfo = ((ICVSResource)leftEdition).getSyncInfo();
376             ResourceSyncInfo rightInfo = ((ICVSResource)rightEdition).getSyncInfo();
377             
378             if (leftEdition.getRepositoryRelativePath().equals(rightEdition.getRepositoryRelativePath()) &&
379                 leftInfo.getRevision().equals(rightInfo.getRevision())) {
380                 return NODE_EQUAL;
381             } else {
382                 if(considerContentIfRevisionOrPathDiffers()) {
383                     return NODE_UNKNOWN;
384                 } else {
385                     return NODE_NOT_EQUAL;
386                 }
387             }
388         } catch (TeamException e) {
389             handle(e);
390             return NODE_UNKNOWN;
391         }
392     }
393     
394     private boolean considerContentIfRevisionOrPathDiffers() {
395         return CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_CONSIDER_CONTENTS);
396     }
397     
398     public Viewer createDiffViewer(Composite parent) {
399         final Viewer viewer = super.createDiffViewer(parent);
400         viewer.addSelectionChangedListener(new ISelectionChangedListener() {
401             public void selectionChanged(SelectionChangedEvent event) {
402                 CompareConfiguration cc = getCompareConfiguration();
403                 setLabels(cc, (IStructuredSelection)event.getSelection());
404             }
405         });
406         ((StructuredViewer)viewer).addOpenListener(new IOpenListener() {
407             public void open(OpenEvent event) {
408                 ISelection selection = event.getSelection();
409                 if (! selection.isEmpty() && selection instanceof IStructuredSelection) {
410                     Object JavaDoc o = ((IStructuredSelection)selection).getFirstElement();
411                     if (o instanceof DiffNode) {
412                         updateLabelsFor((DiffNode)o);
413                     }
414                 }
415             }
416         });
417         ((StructuredViewer)viewer).addDoubleClickListener(new IDoubleClickListener() {
418             public void doubleClick(DoubleClickEvent event) {
419                 ISelection selection = event.getSelection();
420                 if (! selection.isEmpty() && selection instanceof IStructuredSelection) {
421                     Object JavaDoc o = ((IStructuredSelection)selection).getFirstElement();
422                     if (o instanceof DiffNode) {
423                         DiffNode diffNode = ((DiffNode)o);
424                         if (diffNode.hasChildren()) {
425                             AbstractTreeViewer atv = ((AbstractTreeViewer)viewer);
426                             atv.setExpandedState(o, !atv.getExpandedState(o));
427                         }
428                     }
429                 }
430             }
431         });
432         return viewer;
433     }
434     
435     /*
436      * Update the labels for the given DiffNode
437      */

438     protected void updateLabelsFor(DiffNode node) {
439         CompareConfiguration cc = getCompareConfiguration();
440         ITypedElement l = node.getLeft();
441         if (l == null) {
442             cc.setLeftLabel(CVSUIMessages.CVSCompareEditorInput_0);
443             cc.setLeftImage(null);
444         } else {
445             cc.setLeftLabel(getLabel(l));
446             cc.setLeftImage(l.getImage());
447         }
448         ITypedElement r = node.getRight();
449         if (r == null) {
450             cc.setRightLabel(CVSUIMessages.CVSCompareEditorInput_1);
451             cc.setRightImage(null);
452         } else {
453             cc.setRightLabel(getLabel(r));
454             cc.setRightImage(r.getImage());
455         }
456     }
457
458     /* (non-Javadoc)
459      * @see org.eclipse.compare.CompareEditorInput#getToolTipText()
460      */

461     public String JavaDoc getToolTipText() {
462         if (toolTipText != null) {
463             return toolTipText;
464         }
465         return super.getToolTipText();
466     }
467     
468 }
469
Popular Tags