1 /*******************************************************************************
2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org
.spearce
.egit
.ui
.internal
;
11 import java
.lang
.reflect
.InvocationTargetException
;
13 import org
.eclipse
.compare
.CompareConfiguration
;
14 import org
.eclipse
.compare
.CompareEditorInput
;
15 import org
.eclipse
.compare
.IEditableContent
;
16 import org
.eclipse
.compare
.IResourceProvider
;
17 import org
.eclipse
.compare
.ITypedElement
;
18 import org
.eclipse
.compare
.structuremergeviewer
.DiffNode
;
19 import org
.eclipse
.compare
.structuremergeviewer
.Differencer
;
20 import org
.eclipse
.compare
.structuremergeviewer
.ICompareInput
;
21 import org
.eclipse
.compare
.structuremergeviewer
.IDiffElement
;
22 import org
.eclipse
.compare
.structuremergeviewer
.IStructureComparator
;
23 import org
.eclipse
.core
.resources
.IFile
;
24 import org
.eclipse
.core
.resources
.IFileState
;
25 import org
.eclipse
.core
.resources
.IResource
;
26 import org
.eclipse
.core
.resources
.IStorage
;
27 import org
.eclipse
.core
.runtime
.CoreException
;
28 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
29 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
30 import org
.eclipse
.osgi
.util
.NLS
;
31 import org
.eclipse
.team
.internal
.core
.history
.LocalFileRevision
;
32 import org
.eclipse
.team
.internal
.ui
.TeamUIMessages
;
33 import org
.eclipse
.team
.internal
.ui
.TeamUIPlugin
;
34 import org
.eclipse
.team
.internal
.ui
.Utils
;
35 import org
.eclipse
.team
.internal
.ui
.history
.FileRevisionTypedElement
;
36 import org
.eclipse
.team
.internal
.ui
.synchronize
.LocalResourceTypedElement
;
37 import org
.eclipse
.ui
.IWorkbenchPage
;
40 * The input provider for the compare editor when working on resources
43 public class GitCompareFileRevisionEditorInput
extends CompareEditorInput
{
45 private ITypedElement left
;
46 private ITypedElement right
;
49 * Creates a new CompareFileRevisionEditorInput.
54 public GitCompareFileRevisionEditorInput(ITypedElement left
, ITypedElement right
, IWorkbenchPage page
) {
55 super(new CompareConfiguration());
60 FileRevisionTypedElement
getRightRevision() {
61 if (right
instanceof FileRevisionTypedElement
) {
62 return (FileRevisionTypedElement
) right
;
67 FileRevisionTypedElement
getLeftRevision() {
68 if (left
instanceof FileRevisionTypedElement
) {
69 return (FileRevisionTypedElement
) left
;
74 private static void ensureContentsCached(FileRevisionTypedElement left
, FileRevisionTypedElement right
,
75 IProgressMonitor monitor
) {
78 left
.cacheContents(monitor
);
79 } catch (CoreException e
) {
85 right
.cacheContents(monitor
);
86 } catch (CoreException e
) {
92 private boolean isLeftEditable(ICompareInput input
) {
93 Object left
= input
.getLeft();
94 if (left
instanceof IEditableContent
) {
95 return ((IEditableContent
) left
).isEditable();
100 private IResource
getResource(ICompareInput input
) {
101 if (getLocalElement() != null) {
102 return ((IResourceProvider
) getLocalElement()).getResource();
107 private ICompareInput
createCompareInput() {
108 return compare(left
, right
);
111 private DiffNode
compare(ITypedElement left
, ITypedElement right
) {
112 if (left
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
113 // return new MyDiffContainer(null, left,right);
114 DiffNode diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
115 ITypedElement
[] lc
= (ITypedElement
[])((IStructureComparator
)left
).getChildren();
116 ITypedElement
[] rc
= (ITypedElement
[])((IStructureComparator
)right
).getChildren();
119 while (li
<lc
.length
&& ri
<rc
.length
) {
120 ITypedElement ln
= lc
[li
];
121 ITypedElement rn
= rc
[ri
];
122 int compareTo
= ln
.getName().compareTo(rn
.getName());
123 // TODO: Git ordering!
124 if (compareTo
== 0) {
126 diffNode
.add(compare(ln
,rn
));
129 } else if (compareTo
< 0) {
130 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
131 diffNode
.add(childDiffNode
);
132 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
133 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
134 if(children
!= null && children
.length
> 0) {
135 for (ITypedElement child
: children
) {
136 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
142 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
143 diffNode
.add(childDiffNode
);
144 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
145 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
146 if(children
!= null && children
.length
> 0) {
147 for (ITypedElement child
: children
) {
148 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
155 while (li
<lc
.length
) {
156 ITypedElement ln
= lc
[li
];
157 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
158 diffNode
.add(childDiffNode
);
159 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
160 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
161 if(children
!= null && children
.length
> 0) {
162 for (ITypedElement child
: children
) {
163 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
169 while (ri
<rc
.length
) {
170 ITypedElement rn
= rc
[ri
];
171 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
172 diffNode
.add(childDiffNode
);
173 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
174 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
175 if(children
!= null && children
.length
> 0) {
176 for (ITypedElement child
: children
) {
177 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
185 return new DiffNode(left
, right
);
189 private DiffNode
addDirectoryFiles(ITypedElement elem
, int diffType
) {
190 ITypedElement l
= null;
191 ITypedElement r
= null;
192 if (diffType
== Differencer
.DELETION
) {
198 if (elem
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
199 DiffNode diffNode
= null;
200 diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,l
,r
);
201 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)elem
).getChildren();
202 for (ITypedElement child
: children
) {
203 diffNode
.add(addDirectoryFiles(child
, diffType
));
207 return new DiffNode(diffType
, null, l
, r
);
211 private void initLabels(ICompareInput input
) {
212 CompareConfiguration cc
= getCompareConfiguration();
213 if(left
!= null && left
instanceof GitResourceNode
) {
214 String ci
= ((GitResourceNode
)left
).getContentIdentifier();
216 cc
.setLeftLabel(ci
.substring(0, 7) + "..");
219 if(right
!= null && right
instanceof GitResourceNode
) {
220 String ci
= ((GitResourceNode
)right
).getContentIdentifier();
222 cc
.setRightLabel(ci
.substring(0, 7) + "..");
225 if (getLeftRevision() != null) {
226 String leftLabel
= getFileRevisionLabel(getLeftRevision());
227 cc
.setLeftLabel(leftLabel
);
228 } else if (getResource(input
) != null) {
229 String label
= NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_workspace
, new Object
[]{ input
.getLeft().getName() });
230 cc
.setLeftLabel(label
);
232 if (getRightRevision() != null) {
233 String rightLabel
= getFileRevisionLabel(getRightRevision());
234 cc
.setRightLabel(rightLabel
);
238 private String
getFileRevisionLabel(FileRevisionTypedElement element
) {
239 Object fileObject
= element
.getFileRevision();
240 if (fileObject
instanceof LocalFileRevision
){
241 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_localRevision
, new Object
[]{element
.getName(), element
.getTimestamp()});
243 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_repository
, new Object
[]{ element
.getName(), element
.getContentIdentifier()});
248 * @see org.eclipse.compare.CompareEditorInput#getToolTipText()
250 public String
getToolTipText() {
251 Object
[] titleObject
= new Object
[3];
252 titleObject
[0] = getLongName(left
);
253 titleObject
[1] = getContentIdentifier(getLeftRevision());
254 titleObject
[2] = getContentIdentifier(getRightRevision());
255 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_compareResourceAndVersions
, titleObject
);
259 * @see org.eclipse.compare.CompareEditorInput#getTitle()
261 public String
getTitle() {
262 Object
[] titleObject
= new Object
[3];
263 titleObject
[0] = getShortName(left
);
264 titleObject
[1] = getContentIdentifier(getLeftRevision());
265 titleObject
[2] = getContentIdentifier(getRightRevision());
266 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_compareResourceAndVersions
, titleObject
);
270 * @see org.eclipse.compare.CompareEditorInput#getAdapter(java.lang.Class)
272 public Object
getAdapter(Class adapter
) {
273 if (adapter
== IFile
.class || adapter
== IResource
.class) {
274 if (getLocalElement() != null) {
275 return getLocalElement().getResource();
279 return super.getAdapter(adapter
);
282 private String
getShortName(ITypedElement element
) {
283 if (element
instanceof FileRevisionTypedElement
){
284 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
285 return fileRevisionElement
.getName();
287 else if (element
instanceof LocalResourceTypedElement
){
288 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
289 return typedContent
.getResource().getName();
291 return element
.getName();
294 private String
getLongName(ITypedElement element
) {
295 if (element
instanceof FileRevisionTypedElement
){
296 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
297 return fileRevisionElement
.getPath();
299 else if (element
instanceof LocalResourceTypedElement
){
300 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
301 return typedContent
.getResource().getFullPath().toString();
303 return element
.getName();
306 private String
getContentIdentifier(ITypedElement element
){
307 if (element
instanceof FileRevisionTypedElement
){
308 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
309 Object fileObject
= fileRevisionElement
.getFileRevision();
310 if (fileObject
instanceof LocalFileRevision
){
312 IStorage storage
= ((LocalFileRevision
) fileObject
).getStorage(new NullProgressMonitor());
313 if (Utils
.getAdapter(storage
, IFileState
.class) != null){
315 return TeamUIMessages
.CompareFileRevisionEditorInput_0
;
316 } else if (Utils
.getAdapter(storage
, IFile
.class) != null) {
318 return TeamUIMessages
.CompareFileRevisionEditorInput_1
;
320 } catch (CoreException e
) {
323 return fileRevisionElement
.getContentIdentifier();
326 return TeamUIMessages
.CompareFileRevisionEditorInput_2
;
330 // * @see org.eclipse.team.ui.synchronize.LocalResourceCompareEditorInput#fireInputChange()
332 // protected void fireInputChange() {
333 // ((DiffNode)getCompareResult()).fireChange();
337 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()
339 // protected void contentsCreated() {
340 // super.contentsCreated();
341 // notifier.initialize();
345 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#handleDispose()
347 // protected void handleDispose() {
348 // super.handleDispose();
349 // notifier.dispose();
350 // if (getLocalElement() != null) {
351 // getLocalElement().discardBuffer();
355 private LocalResourceTypedElement
getLocalElement() {
356 if (left
instanceof LocalResourceTypedElement
) {
357 return (LocalResourceTypedElement
) left
;
362 protected Object
prepareInput(IProgressMonitor monitor
) throws InvocationTargetException
, InterruptedException
{
363 ICompareInput input
= createCompareInput();
364 getCompareConfiguration().setLeftEditable(isLeftEditable(input
));
365 getCompareConfiguration().setRightEditable(false);
366 ensureContentsCached(getLeftRevision(), getRightRevision(), monitor
);
368 setTitle(NLS
.bind(TeamUIMessages
.SyncInfoCompareInput_title
, new String
[] { input
.getName() }));
370 // The compare editor (Structure Compare) will show the diff filenames
371 // with their project relative path. So, no need to also show directory entries.
372 DiffNode flatDiffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
373 flatDiffView(flatDiffNode
, (DiffNode
) input
);
378 private void flatDiffView(DiffNode rootNode
, DiffNode currentNode
) {
379 if(currentNode
!= null) {
380 IDiffElement
[] dElems
= currentNode
.getChildren();
382 for(IDiffElement dElem
: dElems
) {
383 DiffNode dNode
= (DiffNode
) dElem
;
384 if(dNode
.getChildren() != null && dNode
.getChildren().length
> 0) {
385 flatDiffView(rootNode
, dNode
);