blob: 2c8177382d2fec7d20333833735329a0600e4916 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2009, Stephan Herrmann 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
* $Id$
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Stephan Herrmann - Initial API and implementation
* IBM Corporation - Individual methods and code fragments.
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.ui.compare;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.compare.JavaStructureCreator;
import org.eclipse.jface.text.IDocument;
import org.eclipse.objectteams.otdt.internal.ui.OTDTUIMessages;
import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.team.internal.ui.mapping.AbstractCompareInput;
import org.eclipse.team.internal.ui.mapping.CompareInputChangeNotifier;
import org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter;
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPage;
/**
* The editor input for comparing bound methods.
*
* @author stephan
* @since 1.4.0
*/
public class CompareBoundMethodsEditorInput extends SaveableCompareEditorInput {
// editable LHS:
private ITypedElement left;
private IMethod roleMethod;
// readonly RHS:
private BaseMethodCompareElement right;
CompareInputChangeNotifier notifier = new CompareInputChangeNotifier() {
protected IResource[] getResources(ICompareInput input) {
IResource resource = getResource();
if (resource == null)
return new IResource[0];
return new IResource[] { resource };
}
};
EditableSharedDocumentAdapter sharedDocumentAdapter;
// hold on to a control that we want to hide:
private Composite outline;
class MyJavaStructureCreator extends JavaStructureCreator {
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.StructureCreator#createStructureComparator(java.lang.Object, org.eclipse.jface.text.IDocument, org.eclipse.compare.ISharedDocumentAdapter, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStructureComparator createStructureComparator(Object element,
IDocument document,
ISharedDocumentAdapter sharedDocumentAdapter,
IProgressMonitor monitor)
throws CoreException
{
if (document != null)
return new RoleMethodNode.RootJavaNode(document, element, sharedDocumentAdapter);
return null;
}
}
/*
* Returns <code>true</code> if the other object is of type
* <code>CompareBoundMethodsEditorInput</code> and both of their
* corresponding left and right objects are identical. The content is not
* considered.
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof CompareBoundMethodsEditorInput) {
CompareBoundMethodsEditorInput other = (CompareBoundMethodsEditorInput) obj;
return other.left.equals(this.left)
&& other.right.equals(this.right);
}
return false;
}
public class MyDiffNode extends AbstractCompareInput {
public MyDiffNode(ITypedElement left, ITypedElement right) {
super(Differencer.CHANGE, null, left, right);
}
public void fireChange() {
super.fireChange();
}
protected CompareInputChangeNotifier getChangeNotifier() {
return notifier;
}
public boolean needsUpdate() {
// The base never changes
return false;
}
public void update() {
fireChange();
}
}
/**
* Creates a new CompareBoundMethodsEditorInput.
* @param left
* @param right
* @param page
* @throws JavaModelException
*/
public CompareBoundMethodsEditorInput(IMethod roleMethod, IMethod baseMethod, IWorkbenchPage page) throws CoreException {
super(new CompareConfiguration(), page);
this.roleMethod = roleMethod;
this.left = makeJavaNode();
this.right = new BaseMethodCompareElement(baseMethod, getEncoding(roleMethod));
setTitle(left.getName());
}
private ITypedElement makeJavaNode() throws CoreException
{
// this structure creator is responsible for setup of a sharedDocumentAdapter while building the root node:
MyJavaStructureCreator creator = new MyJavaStructureCreator();
IStructureComparator rootNode = creator.createStructure(this, null);
// create the detail node (role method):
ISourceRange sourceRange = this.roleMethod.getSourceRange();
return new RoleMethodNode((RoleMethodNode)rootNode, RoleMethodNode.METHOD, this.roleMethod.getElementName(), sourceRange.getOffset(), sourceRange.getLength());
}
private String getEncoding(IMethod method) {
IResource resource = method.getResource();
if (resource instanceof IFile) {
IFile file = (IFile) resource;
try {
return file.getCharset();
} catch (CoreException e) {
OTDTUIPlugin.log(e);
}
}
return null;
}
@Override
public Control createOutlineContents(Composite parent, int direction) {
// hold on to a control that we want to hide:
return this.outline = (Composite) super.createOutlineContents(parent, direction);
}
/* (non-Javadoc)
* @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#prepareCompareInput(IProgressMonitor)
*/
protected ICompareInput prepareCompareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
ICompareInput input = createCompareInput();
getCompareConfiguration().setLeftEditable(true);
getCompareConfiguration().setRightEditable(false);
ensureContentsCached(this.right, monitor);
initLabels(input);
return input;
}
private static void ensureContentsCached(BaseMethodCompareElement right, IProgressMonitor monitor)
{
if (right != null) {
try {
right.cacheContents(monitor);
} catch (CoreException e) {
OTDTUIPlugin.log(e);
}
}
}
private IResource getResource() {
return this.roleMethod.getResource();
}
private ICompareInput createCompareInput() {
MyDiffNode input = new MyDiffNode(this.left,this.right);
return input;
}
private void initLabels(ICompareInput input) {
CompareConfiguration cc = getCompareConfiguration();
if (this.left != null) {
String leftLabel = NLS.bind(OTDTUIMessages.CompareBoundMethods_role_method_label,
new Object[]{this.roleMethod.getDeclaringType().getElementName(), this.roleMethod.getElementName()});
cc.setLeftLabel(leftLabel);
}
if (this.right != null) {
String rightLabel = NLS.bind(OTDTUIMessages.CompareBoundMethods_base_method_label,
new Object[]{this.right.getTypeName(), this.right.getName()});
cc.setRightLabel(rightLabel);
}
}
/* (non-Javadoc)
* @see org.eclipse.compare.CompareEditorInput#getToolTipText()
*/
public String getToolTipText() {
Object[] titleObject = new Object[2];
titleObject[0] = this.left.getName();
titleObject[1] = this.right.getName();
return NLS.bind(OTDTUIMessages.CompareBoundMethods_compare_tooltip, titleObject);
}
/* (non-Javadoc)
* @see org.eclipse.compare.CompareEditorInput#getTitle()
*/
public String getTitle() {
Object[] titleObject = new Object[1];
titleObject[0] = this.left.getName();
return NLS.bind(OTDTUIMessages.CompareBoundMethods_compare_title, titleObject);
}
/* (non-Javadoc)
* @see org.eclipse.compare.CompareEditorInput#getAdapter(java.lang.Class)
*/
public <T> T getAdapter(Class<T> adapter) {
if (adapter == IFile.class || adapter == IResource.class) {
return adapter.cast(getResource());
}
if (adapter == ISharedDocumentAdapter.class) {
return adapter.cast(getSharedDocumentAdapter());
}
return super.getAdapter(adapter);
}
private synchronized ISharedDocumentAdapter getSharedDocumentAdapter() {
if (this.sharedDocumentAdapter == null)
this.sharedDocumentAdapter = new EditableSharedDocumentAdapter(new EditableSharedDocumentAdapter.ISharedDocumentAdapterListener() {
public void handleDocumentConnected() { /* ignored */ }
public void handleDocumentFlushed() {
IEditorInput input = sharedDocumentAdapter.getDocumentKey(getResource());
try {
if (input != null)
sharedDocumentAdapter.saveDocument(input, true, new NullProgressMonitor());
} catch (CoreException e) {
OTDTUIPlugin.log(e);
}
}
public void handleDocumentDeleted() { /* ignored */ }
public void handleDocumentSaved() { /* ignored */ }
public void handleDocumentDisconnected() { /* ignored */ }
});
return this.sharedDocumentAdapter;
}
/* (non-Javadoc)
* @see org.eclipse.team.ui.synchronize.LocalResourceCompareEditorInput#fireInputChange()
*/
protected void fireInputChange() {
((MyDiffNode)getCompareResult()).fireChange();
}
/* (non-Javadoc)
* @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()
*/
protected void contentsCreated() {
super.contentsCreated();
this.outline.setVisible(false);
this.notifier.initialize();
}
/* (non-Javadoc)
* @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#handleDispose()
*/
protected void handleDispose() {
super.handleDispose();
this.notifier.dispose();
IEditorInput input = this.sharedDocumentAdapter.getDocumentKey(getResource());
if (input != null)
this.sharedDocumentAdapter.disconnect(input);
this.sharedDocumentAdapter.releaseBuffer();
this.sharedDocumentAdapter = null;
}
}