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 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
9 *******************************************************************************/
10 package org
.eclipse
.egit
.ui
.internal
;
12 import java
.lang
.reflect
.InvocationTargetException
;
14 import org
.eclipse
.compare
.CompareConfiguration
;
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
.egit
.core
.Activator
;
31 import org
.eclipse
.osgi
.util
.NLS
;
32 import org
.eclipse
.team
.internal
.core
.history
.LocalFileRevision
;
33 import org
.eclipse
.team
.internal
.ui
.TeamUIMessages
;
34 import org
.eclipse
.team
.internal
.ui
.TeamUIPlugin
;
35 import org
.eclipse
.team
.internal
.ui
.Utils
;
36 import org
.eclipse
.team
.internal
.ui
.history
.FileRevisionTypedElement
;
37 import org
.eclipse
.team
.internal
.ui
.synchronize
.LocalResourceTypedElement
;
38 import org
.eclipse
.team
.ui
.synchronize
.SaveableCompareEditorInput
;
39 import org
.eclipse
.ui
.IWorkbenchPage
;
42 * The input provider for the compare editor when working on resources
45 public class GitCompareFileRevisionEditorInput
extends SaveableCompareEditorInput
{
47 private ITypedElement left
;
48 private ITypedElement right
;
51 * Creates a new CompareFileRevisionEditorInput.
56 public GitCompareFileRevisionEditorInput(ITypedElement left
, ITypedElement right
, IWorkbenchPage page
) {
57 super(new CompareConfiguration(), page
);
62 FileRevisionTypedElement
getRightRevision() {
63 if (right
instanceof FileRevisionTypedElement
) {
64 return (FileRevisionTypedElement
) right
;
69 FileRevisionTypedElement
getLeftRevision() {
70 if (left
instanceof FileRevisionTypedElement
) {
71 return (FileRevisionTypedElement
) left
;
76 private static void ensureContentsCached(FileRevisionTypedElement left
, FileRevisionTypedElement right
,
77 IProgressMonitor monitor
) {
80 left
.cacheContents(monitor
);
81 } catch (CoreException e
) {
87 right
.cacheContents(monitor
);
88 } catch (CoreException e
) {
94 private boolean isLeftEditable(ICompareInput input
) {
95 Object tmpLeft
= input
.getLeft();
96 return isEditable(tmpLeft
);
99 private boolean isRightEditable(ICompareInput input
) {
100 Object tmpRight
= input
.getRight();
101 return isEditable(tmpRight
);
104 private boolean isEditable(Object object
) {
105 if (object
instanceof IEditableContent
) {
106 return ((IEditableContent
) object
).isEditable();
111 private IResource
getResource(ICompareInput input
) {
112 if (getLocalElement() != null) {
113 return ((IResourceProvider
) getLocalElement()).getResource();
118 private ICompareInput
createCompareInput() {
119 return compare(left
, right
);
122 private DiffNode
compare(ITypedElement left
, ITypedElement right
) {
123 if (left
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
124 // return new MyDiffContainer(null, left,right);
125 DiffNode diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
126 ITypedElement
[] lc
= (ITypedElement
[])((IStructureComparator
)left
).getChildren();
127 ITypedElement
[] rc
= (ITypedElement
[])((IStructureComparator
)right
).getChildren();
130 while (li
<lc
.length
&& ri
<rc
.length
) {
131 ITypedElement ln
= lc
[li
];
132 ITypedElement rn
= rc
[ri
];
133 int compareTo
= ln
.getName().compareTo(rn
.getName());
134 // TODO: Git ordering!
135 if (compareTo
== 0) {
137 diffNode
.add(compare(ln
,rn
));
140 } else if (compareTo
< 0) {
141 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
142 diffNode
.add(childDiffNode
);
143 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
144 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
145 if(children
!= null && children
.length
> 0) {
146 for (ITypedElement child
: children
) {
147 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
153 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
154 diffNode
.add(childDiffNode
);
155 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
156 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
157 if(children
!= null && children
.length
> 0) {
158 for (ITypedElement child
: children
) {
159 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
166 while (li
<lc
.length
) {
167 ITypedElement ln
= lc
[li
];
168 DiffNode childDiffNode
= new DiffNode(Differencer
.ADDITION
, null, ln
, null);
169 diffNode
.add(childDiffNode
);
170 if (ln
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
171 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)ln
).getChildren();
172 if(children
!= null && children
.length
> 0) {
173 for (ITypedElement child
: children
) {
174 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.ADDITION
));
180 while (ri
<rc
.length
) {
181 ITypedElement rn
= rc
[ri
];
182 DiffNode childDiffNode
= new DiffNode(Differencer
.DELETION
, null, null, rn
);
183 diffNode
.add(childDiffNode
);
184 if (rn
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
185 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)rn
).getChildren();
186 if(children
!= null && children
.length
> 0) {
187 for (ITypedElement child
: children
) {
188 childDiffNode
.add(addDirectoryFiles(child
, Differencer
.DELETION
));
196 return new DiffNode(left
, right
);
200 private DiffNode
addDirectoryFiles(ITypedElement elem
, int diffType
) {
201 ITypedElement l
= null;
202 ITypedElement r
= null;
203 if (diffType
== Differencer
.DELETION
) {
209 if (elem
.getType().equals(ITypedElement
.FOLDER_TYPE
)) {
210 DiffNode diffNode
= null;
211 diffNode
= new DiffNode(null,Differencer
.CHANGE
,null,l
,r
);
212 ITypedElement
[] children
= (ITypedElement
[])((IStructureComparator
)elem
).getChildren();
213 for (ITypedElement child
: children
) {
214 diffNode
.add(addDirectoryFiles(child
, diffType
));
218 return new DiffNode(diffType
, null, l
, r
);
222 private void initLabels(ICompareInput input
) {
223 CompareConfiguration cc
= getCompareConfiguration();
224 if(left
!= null && left
instanceof GitResourceNode
) {
225 String ci
= ((GitResourceNode
)left
).getContentIdentifier();
227 cc
.setLeftLabel(ci
.substring(0, 7) + "..");
230 if(right
!= null && right
instanceof GitResourceNode
) {
231 String ci
= ((GitResourceNode
)right
).getContentIdentifier();
233 cc
.setRightLabel(ci
.substring(0, 7) + "..");
236 if (getLeftRevision() != null) {
237 String leftLabel
= getFileRevisionLabel(getLeftRevision());
238 cc
.setLeftLabel(leftLabel
);
239 } else if (getResource(input
) != null) {
240 String label
= NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_workspace
, new Object
[]{ input
.getLeft().getName() });
241 cc
.setLeftLabel(label
);
243 if (getRightRevision() != null) {
244 String rightLabel
= getFileRevisionLabel(getRightRevision());
245 cc
.setRightLabel(rightLabel
);
249 private String
getFileRevisionLabel(FileRevisionTypedElement element
) {
250 Object fileObject
= element
.getFileRevision();
251 if (fileObject
instanceof LocalFileRevision
){
252 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_localRevision
, new Object
[]{element
.getName(), element
.getTimestamp()});
254 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_repository
, new Object
[]{ element
.getName(), element
.getContentIdentifier()});
259 * @see org.eclipse.compare.CompareEditorInput#getToolTipText()
261 public String
getToolTipText() {
262 Object
[] titleObject
= new Object
[3];
263 titleObject
[0] = getLongName(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#getTitle()
272 public String
getTitle() {
273 Object
[] titleObject
= new Object
[3];
274 titleObject
[0] = getShortName(left
);
275 titleObject
[1] = getContentIdentifier(getLeftRevision());
276 titleObject
[2] = getContentIdentifier(getRightRevision());
277 return NLS
.bind(TeamUIMessages
.CompareFileRevisionEditorInput_compareResourceAndVersions
, titleObject
);
281 * @see org.eclipse.compare.CompareEditorInput#getAdapter(java.lang.Class)
283 public Object
getAdapter(Class adapter
) {
284 if (adapter
== IFile
.class || adapter
== IResource
.class) {
285 if (getLocalElement() != null) {
286 return getLocalElement().getResource();
290 return super.getAdapter(adapter
);
293 private String
getShortName(ITypedElement element
) {
294 if (element
instanceof FileRevisionTypedElement
){
295 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
296 return fileRevisionElement
.getName();
298 else if (element
instanceof LocalResourceTypedElement
){
299 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
300 return typedContent
.getResource().getName();
302 return element
.getName();
305 private String
getLongName(ITypedElement element
) {
306 if (element
instanceof FileRevisionTypedElement
){
307 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
308 return fileRevisionElement
.getPath();
310 else if (element
instanceof LocalResourceTypedElement
){
311 LocalResourceTypedElement typedContent
= (LocalResourceTypedElement
) element
;
312 return typedContent
.getResource().getFullPath().toString();
314 return element
.getName();
317 private String
getContentIdentifier(ITypedElement element
){
318 if (element
instanceof FileRevisionTypedElement
){
319 FileRevisionTypedElement fileRevisionElement
= (FileRevisionTypedElement
) element
;
320 Object fileObject
= fileRevisionElement
.getFileRevision();
321 if (fileObject
instanceof LocalFileRevision
){
323 IStorage storage
= ((LocalFileRevision
) fileObject
).getStorage(new NullProgressMonitor());
324 if (Utils
.getAdapter(storage
, IFileState
.class) != null){
326 return TeamUIMessages
.CompareFileRevisionEditorInput_0
;
327 } else if (Utils
.getAdapter(storage
, IFile
.class) != null) {
329 return TeamUIMessages
.CompareFileRevisionEditorInput_1
;
331 } catch (CoreException e
) {
332 Activator
.logError("Problem getting content identifier", e
);
335 return fileRevisionElement
.getContentIdentifier();
338 return TeamUIMessages
.CompareFileRevisionEditorInput_2
;
342 protected void fireInputChange() {
346 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()
348 // protected void contentsCreated() {
349 // super.contentsCreated();
350 // notifier.initialize();
354 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#handleDispose()
356 // protected void handleDispose() {
357 // super.handleDispose();
358 // notifier.dispose();
359 // if (getLocalElement() != null) {
360 // getLocalElement().discardBuffer();
364 private LocalResourceTypedElement
getLocalElement() {
365 if (left
instanceof LocalResourceTypedElement
) {
366 return (LocalResourceTypedElement
) left
;
372 protected ICompareInput
prepareCompareInput(IProgressMonitor monitor
)
373 throws InvocationTargetException
, InterruptedException
{
374 ICompareInput input
= createCompareInput();
375 getCompareConfiguration().setLeftEditable(isLeftEditable(input
));
376 getCompareConfiguration().setRightEditable(isRightEditable(input
));
377 ensureContentsCached(getLeftRevision(), getRightRevision(), monitor
);
379 setTitle(NLS
.bind(TeamUIMessages
.SyncInfoCompareInput_title
, new String
[] { input
.getName() }));
381 // The compare editor (Structure Compare) will show the diff filenames
382 // with their project relative path. So, no need to also show directory entries.
383 DiffNode flatDiffNode
= new DiffNode(null,Differencer
.CHANGE
,null,left
,right
);
384 flatDiffView(flatDiffNode
, (DiffNode
) input
);
389 private void flatDiffView(DiffNode rootNode
, DiffNode currentNode
) {
390 if(currentNode
!= null) {
391 IDiffElement
[] dElems
= currentNode
.getChildren();
393 for(IDiffElement dElem
: dElems
) {
394 DiffNode dNode
= (DiffNode
) dElem
;
395 if(dNode
.getChildren() != null && dNode
.getChildren().length
> 0) {
396 flatDiffView(rootNode
, dNode
);