blob: 0a08d267389d533774bf4d547fb7d26d285a4080 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2009, Stephan Herrmann and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
* $Id$
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Stephan Herrmann - Initial API and implementation
* IBM Corporation - Some individual method and fragments
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.ui.compare;
import java.io.UnsupportedEncodingException;
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IEditableContentExtension;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.SharedDocumentAdapter;
import org.eclipse.compare.contentmergeviewer.IDocumentRange;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.compare.structuremergeviewer.SharedDocumentAdapterWrapper;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.IDocument;
import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.services.IDisposable;
import org.eclipse.ui.texteditor.IDocumentProvider;
/**
* Represents the role method of a bound-methods-comparison.
*
* This class is inspired by class org.eclipse.jdt.internal.ui.compare.JavaNode.
*
* @author stephan
* @since 1.4.0
*/
class RoleMethodNode extends DocumentRangeNode implements ITypedElement {
public static final int CU= 0;
public static final int METHOD= 11;
private static final String COMPILATION_UNIT = "compilationUnit"; //$NON-NLS-1$
private static final char METHOD_ID= '~';
private static final char COMPILATIONUNIT= '{';
static String buildID(int type, String name) {
StringBuffer sb= new StringBuffer();
switch (type) {
case RoleMethodNode.CU:
sb.append(COMPILATIONUNIT);
break;
case RoleMethodNode.METHOD:
sb.append(METHOD_ID);
sb.append(name);
break;
default:
Assert.isTrue(false);
break;
}
return sb.toString();
}
/**
* The root node of the compilation/document unit containing the role method.
* This node is responsible for saving the comparison.
*/
static class RootJavaNode extends RoleMethodNode implements IDisposable {
private final Object fInput;
private final ISharedDocumentAdapter fAdapter;
RootJavaNode(IDocument document, Object input, ISharedDocumentAdapter adapter) {
super(document);
fInput= input;
fAdapter= adapter;
}
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.DocumentRangeNode#isEditable()
*/
public boolean isEditable() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.DocumentRangeNode#nodeChanged(org.eclipse.compare.structuremergeviewer.DocumentRangeNode)
*/
protected void nodeChanged(DocumentRangeNode node) {
save(this, this.fInput);
}
void save(IStructureComparator node, Object input) {
if (node instanceof IDocumentRange && input instanceof IEditableContent) {
IDocument document= ((IDocumentRange)node).getDocument();
// First check to see if we have a shared document
final ISharedDocumentAdapter sda = SharedDocumentAdapterWrapper.getAdapter(input);
if (sda != null) {
IEditorInput key = sda.getDocumentKey(input);
if (key != null) {
IDocumentProvider provider = SharedDocumentAdapter.getDocumentProvider(key);
if (provider != null) {
IDocument providerDoc = provider.getDocument(key);
// We have to make sure that the document we are saving is the same as the shared document
if (providerDoc != null && providerDoc == document) {
if (save(provider, document, input, sda, key))
return;
}
}
}
}
IEditableContent bca= (IEditableContent) input;
String contents= document.get();
String encoding= null;
if (input instanceof IEncodedStreamContentAccessor) {
try {
encoding= ((IEncodedStreamContentAccessor)input).getCharset();
} catch (CoreException e1) {
// ignore
}
}
if (encoding == null)
encoding= ResourcesPlugin.getEncoding();
byte[] bytes;
try {
bytes= contents.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
bytes= contents.getBytes();
}
bca.setContent(bytes);
}
}
boolean save(final IDocumentProvider provider, final IDocument document,
final Object input, final ISharedDocumentAdapter sda, final IEditorInput key) {
try {
sda.flushDocument(provider, key, document, false);
return true;
} catch (CoreException e) {
OTDTUIPlugin.log(e);
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.ui.services.IDisposable#dispose()
*/
public void dispose() {
if (fAdapter != null) {
fAdapter.disconnect(fInput);
}
}
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.DocumentRangeNode#getAdapter(java.lang.Class)
*/
public <T> T getAdapter(Class<T> adapter) {
if (adapter == ISharedDocumentAdapter.class) {
return adapter.cast(fAdapter);
}
return super.getAdapter(adapter);
}
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.DocumentRangeNode#isReadOnly()
*/
public boolean isReadOnly() {
if (fInput instanceof IEditableContentExtension) {
IEditableContentExtension ext = (IEditableContentExtension) fInput;
return ext.isReadOnly();
}
return super.isReadOnly();
}
/* (non-Javadoc)
* @see org.eclipse.compare.structuremergeviewer.DocumentRangeNode#validateEdit(org.eclipse.swt.widgets.Shell)
*/
public IStatus validateEdit(Shell shell) {
if (fInput instanceof IEditableContentExtension) {
IEditableContentExtension ext = (IEditableContentExtension) fInput;
return ext.validateEdit(shell);
}
return super.validateEdit(shell);
}
}
/**
* Creates a RoleMethodNode under the given parent.
* @param parent the parent node
* @param type the Java elements type. Legal values are from the range CU to METHOD of this class.
* @param name the name of the Java element
* @param start the starting position of the java element in the underlying document
* @param length the number of characters of the java element in the underlying document
*/
public RoleMethodNode(RoleMethodNode parent, int type, String name, int start, int length) {
super(parent, type, buildID(type, name), parent.getDocument(), start, length);
parent.addChild(this);
}
/**
* Creates a RoleMethodNode for a CU. It represents the root of a
* RoleMethodNode tree, so its parent is null.
* @param document the document which contains the Java element
*/
public RoleMethodNode(IDocument document) {
super(CU, buildID(CU, "root"), document, 0, document.getLength()); //$NON-NLS-1$
}
/**
* Returns a name which is presented in the UI.
* @see ITypedElement#getName()
*/
public String getName() {
switch (getTypeCode()) {
case CU:
return COMPILATION_UNIT;
}
return getId().substring(1); // we strip away the type character
}
/*
* @see ITypedElement#getType()
*/
public String getType() {
return "java2"; //$NON-NLS-1$
}
/**
* Returns a shared image for this Java element.
*
* see ITypedInput.getImage
*/
public Image getImage() {
return null; // never displayed in the UI
}
/*
* @see java.lang.Object#toString()
*/
public String toString() {
return getType() + ": " + getName() //$NON-NLS-1$
+ "[" + getRange().offset + "+" + getRange().length + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}