diff options
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.java | 223 |
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 |