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
.IEditableContent
;
15 import org
.eclipse
.compare
.IResourceProvider
;
16 import org
.eclipse
.compare
.ITypedElement
;
17 import org
.eclipse
.compare
.structuremergeviewer
.DiffNode
;
18 import org
.eclipse
.compare
.structuremergeviewer
.Differencer
;
19 import org
.eclipse
.compare
.structuremergeviewer
.ICompareInput
;
20 import org
.eclipse
.compare
.structuremergeviewer
.IDiffElement
;
21 import org
.eclipse
.compare
.structuremergeviewer
.IStructureComparator
;
22 import org
.eclipse
.core
.resources
.IFile
;
23 import org
.eclipse
.core
.resources
.IFileState
;
24 import org
.eclipse
.core
.resources
.IResource
;
25 import org
.eclipse
.core
.resources
.IStorage
;
26 import org
.eclipse
.core
.runtime
.CoreException
;
27 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
28 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
29 import org
.eclipse
.osgi
.util
.NLS
;
30 import org
.eclipse
.team
.internal
.core
.history
.LocalFileRevision
;
31 import org
.eclipse
.team
.internal
.ui
.TeamUIMessages
;
32 import org
.eclipse
.team
.internal
.ui
.TeamUIPlugin
;
33 import org
.eclipse
.team
.internal
.ui
.Utils
;
34 import org
.eclipse
.team
.internal
.ui
.history
.FileRevisionTypedElement
;
35 import org
.eclipse
.team
.internal
.ui
.synchronize
.LocalResourceTypedElement
;
36 import org
.eclipse
.team
.ui
.synchronize
.SaveableCompareEditorInput
;
37 import org
.eclipse
.ui
.IWorkbenchPage
;
38 import org
.spearce
.egit
.core
.Activator
;
41 * The input provider for the compare editor when working on resources
44 public class GitCompareFileRevisionEditorInput
extends SaveableCompareEditorInput
{
46 private ITypedElement left
;
47 private ITypedElement right
;
50 * Creates a new CompareFileRevisionEditorInput.
55 public GitCompareFileRevisionEditorInput(ITypedElement left
, ITypedElement right
, IWorkbenchPage page
) {
56 super(new CompareConfiguration(), page
);
61 FileRevisionTypedElement
getRightRevision() {
62 if (right
instanceof FileRevisionTypedElement
) {
63 return (FileRevisionTypedElement
) right
;
68 FileRevisionTypedElement
getLeftRevision() {
69 if (left
instanceof FileRevisionTypedElement
) {
70 return (FileRevisionTypedElement
) left
;
75 private static void ensureContentsCached(FileRevisionTypedElement left
, FileRevisionTypedElement right
,
76 IProgressMonitor monitor
) {
79 left
.cacheContents(monitor
);
80 } catch (CoreException e
) {
86 right
.cacheContents(monitor
);
87 } catch (CoreException e
) {
93 private boolean isLeftEditable(ICompareInput input
) {
94 Object tmpLeft
= input
.getLeft();
95 return isEditable(tmpLeft
);
98 private boolean isRightEditable(ICompareInput input
) {
99 Object tmpRight
= input
.getRight();
100 return isEditable(tmpRight
);
103 private boolean isEditable(Object object
) {
104 if (object
instanceof IEditableContent
) {
105 return ((IEditableContent
) object
).isEditable();
110 private IResource
getResource(ICompareInput input
) {
111 if (getLocalElement() != null) {
112 return ((IResourceProvider
) getLocalElement()).getResource();
117 private ICompareInput
createCompareInput() {
118 return compare(left
, right
);
121 private DiffNode
compare(ITypedElement left
, ITypedElement right
) {
122 if (left
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
123 // return new MyDiffContainer(null, left,right);
124 DiffNode diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
125 ITypedElement
[] lc
= (ITypedElement
[])((IStructureComparator
)left
).getChildren();
126 ITypedElement
[] rc
= (ITypedElement
[])((IStructureComparator
)right
).getChildren();
129 while (li
<lc
.length
&& ri
<rc
.length
) {
130 ITypedElement ln
= lc
[li
];
131 ITypedElement rn
= rc
[ri
];
132 int compareTo
= ln
.getName().compareTo(rn
.getName());
133 // TODO: Git ordering!
134 if (compareTo
== 0) {
136 diffNode
.add(compare(ln
,rn
));
139 } else if (compareTo
< 0) {
140 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
141 diffNode
.add(childDiffNode
);
142 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
143 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
144 if(children
!= null && children
.length
> 0) {
145 for (ITypedElement child
: children
) {
146 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
152 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
153 diffNode
.add(childDiffNode
);
154 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
155 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
156 if(children
!= null && children
.length
> 0) {
157 for (ITypedElement child
: children
) {
158 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
165 while (li
<lc
.length
) {
166 ITypedElement ln
= lc
[li
];
167 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
168 diffNode
.add(childDiffNode
);
169 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
170 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
171 if(children
!= null && children
.length
> 0) {
172 for (ITypedElement child
: children
) {
173 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
179 while (ri
<rc
.length
) {
180 ITypedElement rn
= rc
[ri
];
181 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
182 diffNode
.add(childDiffNode
);
183 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
184 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
185 if(children
!= null && children
.length
> 0) {
186 for (ITypedElement child
: children
) {
187 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
195 return new DiffNode(left
, right
);
199 private DiffNode
addDirectoryFiles(ITypedElement elem
, int diffType
) {
200 ITypedElement l
= null;
201 ITypedElement r
= null;
202 if (diffType
== Differencer
.DELETION
) {
208 if (elem
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
209 DiffNode diffNode
= null;
210 diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,l
,r
);
211 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)elem
).getChildren();
212 for (ITypedElement child
: children
) {
213 diffNode
.add(addDirectoryFiles(child
, diffType
));
217 return new DiffNode(diffType
, null, l
, r
);
221 private void initLabels(ICompareInput input
) {
222 CompareConfiguration cc
= getCompareConfiguration();
223 if(left
!= null && left
instanceof GitResourceNode
) {
224 String ci
= ((GitResourceNode
)left
).getContentIdentifier();
226 cc
.setLeftLabel(ci
.substring(0, 7) + "..");
229 if(right
!= null && right
instanceof GitResourceNode
) {
230 String ci
= ((GitResourceNode
)right
).getContentIdentifier();
232 cc
.setRightLabel(ci
.substring(0, 7) + "..");
235 if (getLeftRevision() != null) {
236 String leftLabel
= getFileRevisionLabel(getLeftRevision());
237 cc
.setLeftLabel(leftLabel
);
238 } else if (getResource(input
) != null) {
239 String label
= NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_workspace
, new Object
[]{ input
.getLeft().getName() });
240 cc
.setLeftLabel(label
);
242 if (getRightRevision() != null) {
243 String rightLabel
= getFileRevisionLabel(getRightRevision());
244 cc
.setRightLabel(rightLabel
);
248 private String
getFileRevisionLabel(FileRevisionTypedElement element
) {
249 Object fileObject
= element
.getFileRevision();
250 if (fileObject
instanceof LocalFileRevision
){
251 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_localRevision
, new Object
[]{element
.getName(), element
.getTimestamp()});
253 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_repository
, new Object
[]{ element
.getName(), element
.getContentIdentifier()});
258 * @see org.eclipse.compare.CompareEditorInput#getToolTipText()
260 public String
getToolTipText() {
261 Object
[] titleObject
= new Object
[3];
262 titleObject
[0] = getLongName(left
);
263 titleObject
[1] = getContentIdentifier(getLeftRevision());
264 titleObject
[2] = getContentIdentifier(getRightRevision());
265 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_compareResourceAndVersions
, titleObject
);
269 * @see org.eclipse.compare.CompareEditorInput#getTitle()
271 public String
getTitle() {
272 Object
[] titleObject
= new Object
[3];
273 titleObject
[0] = getShortName(left
);
274 titleObject
[1] = getContentIdentifier(getLeftRevision());
275 titleObject
[2] = getContentIdentifier(getRightRevision());
276 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_compareResourceAndVersions
, titleObject
);
280 * @see org.eclipse.compare.CompareEditorInput#getAdapter(java.lang.Class)
282 public Object
getAdapter(Class adapter
) {
283 if (adapter
== IFile
.class || adapter
== IResource
.class) {
284 if (getLocalElement() != null) {
285 return getLocalElement().getResource();
289 return super.getAdapter(adapter
);
292 private String
getShortName(ITypedElement element
) {
293 if (element
instanceof FileRevisionTypedElement
){
294 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
295 return fileRevisionElement
.getName();
297 else if (element
instanceof LocalResourceTypedElement
){
298 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
299 return typedContent
.getResource().getName();
301 return element
.getName();
304 private String
getLongName(ITypedElement element
) {
305 if (element
instanceof FileRevisionTypedElement
){
306 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
307 return fileRevisionElement
.getPath();
309 else if (element
instanceof LocalResourceTypedElement
){
310 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
311 return typedContent
.getResource().getFullPath().toString();
313 return element
.getName();
316 private String
getContentIdentifier(ITypedElement element
){
317 if (element
instanceof FileRevisionTypedElement
){
318 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
319 Object fileObject
= fileRevisionElement
.getFileRevision();
320 if (fileObject
instanceof LocalFileRevision
){
322 IStorage storage
= ((LocalFileRevision
) fileObject
).getStorage(new NullProgressMonitor());
323 if (Utils
.getAdapter(storage
, IFileState
.class) != null){
325 return TeamUIMessages
.CompareFileRevisionEditorInput_0
;
326 } else if (Utils
.getAdapter(storage
, IFile
.class) != null) {
328 return TeamUIMessages
.CompareFileRevisionEditorInput_1
;
330 } catch (CoreException e
) {
331 Activator
.logError("Problem getting content identifier", e
);
334 return fileRevisionElement
.getContentIdentifier();
337 return TeamUIMessages
.CompareFileRevisionEditorInput_2
;
341 protected void fireInputChange() {
345 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()
347 // protected void contentsCreated() {
348 // super.contentsCreated();
349 // notifier.initialize();
353 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#handleDispose()
355 // protected void handleDispose() {
356 // super.handleDispose();
357 // notifier.dispose();
358 // if (getLocalElement() != null) {
359 // getLocalElement().discardBuffer();
363 private LocalResourceTypedElement
getLocalElement() {
364 if (left
instanceof LocalResourceTypedElement
) {
365 return (LocalResourceTypedElement
) left
;
371 protected ICompareInput
prepareCompareInput(IProgressMonitor monitor
)
372 throws InvocationTargetException
, InterruptedException
{
373 ICompareInput input
= createCompareInput();
374 getCompareConfiguration().setLeftEditable(isLeftEditable(input
));
375 getCompareConfiguration().setRightEditable(isRightEditable(input
));
376 ensureContentsCached(getLeftRevision(), getRightRevision(), monitor
);
378 setTitle(NLS
.bind(TeamUIMessages
.SyncInfoCompareInput_title
, new String
[] { input
.getName() }));
380 // The compare editor (Structure Compare) will show the diff filenames
381 // with their project relative path. So, no need to also show directory entries.
382 DiffNode flatDiffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
383 flatDiffView(flatDiffNode
, (DiffNode
) input
);
388 private void flatDiffView(DiffNode rootNode
, DiffNode currentNode
) {
389 if(currentNode
!= null) {
390 IDiffElement
[] dElems
= currentNode
.getChildren();
392 for(IDiffElement dElem
: dElems
) {
393 DiffNode dNode
= (DiffNode
) dElem
;
394 if(dNode
.getChildren() != null && dNode
.getChildren().length
> 0) {
395 flatDiffView(rootNode
, dNode
);