Add some logging of GUI errors
[egit/imyousuf.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / GitCompareFileRevisionEditorInput.java
blob88c867d6817d1d16749a7d30746bb1f5b32eac27
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;
40 /**
41 * The input provider for the compare editor when working on resources
42 * under Git control.
44 public class GitCompareFileRevisionEditorInput extends SaveableCompareEditorInput {
46 private ITypedElement left;
47 private ITypedElement right;
49 /**
50 * Creates a new CompareFileRevisionEditorInput.
51 * @param left
52 * @param right
53 * @param page
55 public GitCompareFileRevisionEditorInput(ITypedElement left, ITypedElement right, IWorkbenchPage page) {
56 super(new CompareConfiguration(), page);
57 this.left = left;
58 this.right = right;
61 FileRevisionTypedElement getRightRevision() {
62 if (right instanceof FileRevisionTypedElement) {
63 return (FileRevisionTypedElement) right;
65 return null;
68 FileRevisionTypedElement getLeftRevision() {
69 if (left instanceof FileRevisionTypedElement) {
70 return (FileRevisionTypedElement) left;
72 return null;
75 private static void ensureContentsCached(FileRevisionTypedElement left, FileRevisionTypedElement right,
76 IProgressMonitor monitor) {
77 if (left != null) {
78 try {
79 left.cacheContents(monitor);
80 } catch (CoreException e) {
81 TeamUIPlugin.log(e);
84 if (right != null) {
85 try {
86 right.cacheContents(monitor);
87 } catch (CoreException e) {
88 TeamUIPlugin.log(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();
107 return false;
110 private IResource getResource(ICompareInput input) {
111 if (getLocalElement() != null) {
112 return ((IResourceProvider) getLocalElement()).getResource();
114 return null;
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();
127 int li=0;
128 int ri=0;
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) {
135 if (!ln.equals(rn))
136 diffNode.add(compare(ln,rn));
137 ++li;
138 ++ri;
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));
150 ++li;
151 } else {
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));
162 ++ri;
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));
177 ++li;
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));
191 ++ri;
193 return diffNode;
194 } else {
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) {
203 r = elem;
204 } else {
205 l = elem;
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));
215 return diffNode;
216 } else {
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();
225 if(ci != null) {
226 cc.setLeftLabel(ci.substring(0, 7) + "..");
229 if(right != null && right instanceof GitResourceNode) {
230 String ci = ((GitResourceNode)right).getContentIdentifier();
231 if(ci != null) {
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()});
252 } else {
253 return NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_repository, new Object[]{ element.getName(), element.getContentIdentifier()});
257 /* (non-Javadoc)
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);
268 /* (non-Javadoc)
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);
279 /* (non-Javadoc)
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();
287 return null;
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){
321 try {
322 IStorage storage = ((LocalFileRevision) fileObject).getStorage(new NullProgressMonitor());
323 if (Utils.getAdapter(storage, IFileState.class) != null){
324 //local revision
325 return TeamUIMessages.CompareFileRevisionEditorInput_0;
326 } else if (Utils.getAdapter(storage, IFile.class) != null) {
327 //current revision
328 return TeamUIMessages.CompareFileRevisionEditorInput_1;
330 } catch (CoreException e) {
331 Activator.logError("Problem getting content identifier", e);
333 } else {
334 return fileRevisionElement.getContentIdentifier();
337 return TeamUIMessages.CompareFileRevisionEditorInput_2;
340 @Override
341 protected void fireInputChange() {
344 // /* (non-Javadoc)
345 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()
346 // */
347 // protected void contentsCreated() {
348 // super.contentsCreated();
349 // notifier.initialize();
350 // }
352 // /* (non-Javadoc)
353 // * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#handleDispose()
354 // */
355 // protected void handleDispose() {
356 // super.handleDispose();
357 // notifier.dispose();
358 // if (getLocalElement() != null) {
359 // getLocalElement().discardBuffer();
360 // }
361 // }
363 private LocalResourceTypedElement getLocalElement() {
364 if (left instanceof LocalResourceTypedElement) {
365 return (LocalResourceTypedElement) left;
367 return null;
370 @Override
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);
377 initLabels(input);
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);
385 return flatDiffNode;
388 private void flatDiffView(DiffNode rootNode, DiffNode currentNode) {
389 if(currentNode != null) {
390 IDiffElement[] dElems = currentNode.getChildren();
391 if(dElems != null) {
392 for(IDiffElement dElem : dElems) {
393 DiffNode dNode = (DiffNode) dElem;
394 if(dNode.getChildren() != null && dNode.getChildren().length > 0) {
395 flatDiffView(rootNode, dNode);
396 } else {
397 rootNode.add(dNode);