Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'framework/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/internal/crucible/ui/operations/CrucibleFileInfoCompareEditorInput.java')
-rw-r--r--framework/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/internal/crucible/ui/operations/CrucibleFileInfoCompareEditorInput.java223
1 files changed, 223 insertions, 0 deletions
diff --git a/framework/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/internal/crucible/ui/operations/CrucibleFileInfoCompareEditorInput.java b/framework/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/internal/crucible/ui/operations/CrucibleFileInfoCompareEditorInput.java
new file mode 100644
index 0000000..2bb3739
--- /dev/null
+++ b/framework/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/internal/crucible/ui/operations/CrucibleFileInfoCompareEditorInput.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Atlassian and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Atlassian - initial API and implementation
+ ******************************************************************************/
+
+package com.atlassian.connector.eclipse.internal.crucible.ui.operations;
+
+import com.atlassian.connector.eclipse.internal.crucible.ui.annotations.CrucibleCompareAnnotationModel;
+import com.atlassian.connector.eclipse.team.ui.AtlassianTeamUiPlugin;
+import com.atlassian.theplugin.commons.VersionedVirtualFile;
+import com.atlassian.theplugin.commons.crucible.api.model.CrucibleFileInfo;
+
+import org.apache.commons.io.FilenameUtils;
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.compare.internal.MergeSourceViewer;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class CrucibleFileInfoCompareEditorInput extends CompareEditorInput {
+
+ static class ByteArrayInput implements ITypedElement, IStreamContentAccessor {
+
+ byte[] content;
+
+ private final String name;
+
+ public ByteArrayInput(byte[] content, String name) {
+ this.content = content;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Image getImage() {
+ return null;
+ }
+
+ public String getType() {
+ String extension = FilenameUtils.getExtension(name);
+ return extension.length() > 0 ? extension : ITypedElement.TEXT_TYPE;
+ }
+
+ public InputStream getContents() throws CoreException {
+ return new ByteArrayInputStream(content);
+ }
+
+ }
+
+ private final byte[] content1;
+
+ private final byte[] content2;
+
+ private final CrucibleCompareAnnotationModel annotationModel;
+
+ private final CrucibleFileInfo fileInfo;
+
+ public CrucibleFileInfoCompareEditorInput(CrucibleFileInfo fileInfo, byte[] content1, byte[] content2,
+ CrucibleCompareAnnotationModel annotationModel, CompareConfiguration compareConfiguration) {
+ super(compareConfiguration);
+ this.content1 = content1;
+ this.content2 = content2;
+ this.annotationModel = annotationModel;
+ this.fileInfo = fileInfo;
+
+ VersionedVirtualFile oldFile = fileInfo.getOldFileDescriptor();
+ VersionedVirtualFile newFile = fileInfo.getFileDescriptor();
+
+ setTitle("Compare " + oldFile.getName() + " " + newFile.getRevision() + " and " + oldFile.getRevision());
+ }
+
+ @Override
+ protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ Differencer d = new Differencer();
+ Object diff = d.findDifferences(false, monitor, null, null, new ByteArrayInput(content1,
+ fileInfo.getFileDescriptor().getName()), new ByteArrayInput(content2, fileInfo.getOldFileDescriptor()
+ .getName()));
+ return diff;
+ }
+
+ @Override
+ public Viewer findContentViewer(Viewer oldViewer, ICompareInput input, Composite parent) {
+ Viewer contentViewer = super.findContentViewer(oldViewer, input, parent);
+ return CrucibleFileInfoCompareEditorInput.findContentViewer(contentViewer, input, parent, annotationModel);
+ }
+
+ private static Viewer findContentViewer(Viewer contentViewer, ICompareInput input, Composite parent,
+ CrucibleCompareAnnotationModel annotationModel) {
+
+ // FIXME: hack
+ if (contentViewer instanceof TextMergeViewer) {
+ TextMergeViewer textMergeViewer = (TextMergeViewer) contentViewer;
+ try {
+ Class<TextMergeViewer> clazz = TextMergeViewer.class;
+ Field declaredField = clazz.getDeclaredField("fLeft");
+ declaredField.setAccessible(true);
+ final MergeSourceViewer fLeft = (MergeSourceViewer) declaredField.get(textMergeViewer);
+
+ declaredField = clazz.getDeclaredField("fRight");
+ declaredField.setAccessible(true);
+ final MergeSourceViewer fRight = (MergeSourceViewer) declaredField.get(textMergeViewer);
+
+ annotationModel.attachToViewer(textMergeViewer, fLeft, fRight);
+ annotationModel.focusOnComment();
+ annotationModel.registerContextMenu();
+
+ Method setActiveViewer = clazz.getDeclaredMethod("setActiveViewer", MergeSourceViewer.class,
+ boolean.class);
+ setActiveViewer.setAccessible(true);
+ setActiveViewer.invoke(textMergeViewer, fRight, true);
+
+ hackGalileo(contentViewer, textMergeViewer, fLeft, fRight);
+ } catch (Throwable t) {
+ StatusHandler.log(new Status(IStatus.WARNING, AtlassianTeamUiPlugin.PLUGIN_ID,
+ "Could not initialize annotation model for " + input.getName(), t));
+ }
+ }
+ return contentViewer;
+ }
+
+ private static void hackGalileo(Viewer contentViewer, TextMergeViewer textMergeViewer,
+ final MergeSourceViewer fLeft, final MergeSourceViewer fRight) {
+ // FIXME: hack for e3.5
+ try {
+ Method getCompareConfiguration = ContentMergeViewer.class.getDeclaredMethod("getCompareConfiguration");
+ getCompareConfiguration.setAccessible(true);
+ CompareConfiguration cc = (CompareConfiguration) getCompareConfiguration.invoke(textMergeViewer);
+
+ Method getMergeContentProvider = ContentMergeViewer.class.getDeclaredMethod("getMergeContentProvider");
+ getMergeContentProvider.setAccessible(true);
+ IMergeViewerContentProvider cp = (IMergeViewerContentProvider) getMergeContentProvider.invoke(textMergeViewer);
+
+ Method getSourceViewer = MergeSourceViewer.class.getDeclaredMethod("getSourceViewer");
+
+ Method configureSourceViewer = TextMergeViewer.class.getDeclaredMethod("configureSourceViewer",
+ SourceViewer.class, boolean.class);
+ configureSourceViewer.setAccessible(true);
+ configureSourceViewer.invoke(contentViewer, getSourceViewer.invoke(fLeft), cc.isLeftEditable()
+ && cp.isLeftEditable(textMergeViewer.getInput()));
+ configureSourceViewer.invoke(contentViewer, getSourceViewer.invoke(fRight), cc.isRightEditable()
+ && cp.isRightEditable(textMergeViewer.getInput()));
+
+ Field isConfiguredField = TextMergeViewer.class.getDeclaredField("isConfigured");
+ isConfiguredField.setAccessible(true);
+ isConfiguredField.set(contentViewer, true);
+ } catch (Throwable t) {
+ // ignore as it may not exist in other versions
+ }
+ }
+
+ public CrucibleCompareAnnotationModel getAnnotationModelToAttach() {
+ return annotationModel;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((annotationModel == null) ? 0 : annotationModel.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ CrucibleFileInfoCompareEditorInput other = (CrucibleFileInfoCompareEditorInput) obj;
+ if (annotationModel == null) {
+ if (other.annotationModel != null) {
+ return false;
+ }
+ } else if (!annotationModel.equals(other.annotationModel)) {
+ return false;
+ }
+ return true;
+ }
+
+ public CrucibleFileInfo getCrucibleFileInfo() {
+ return fileInfo;
+ }
+
+ @Override
+ protected void contentsCreated() {
+ super.contentsCreated();
+ getAnnotationModelToAttach().focusOnComment();
+ }
+
+} \ No newline at end of file

Back to the top