blob: c37bbcd50e957cd339b0e280c7fb2781eab9f5d2 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2012 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany, 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
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.core;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.Member;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.objectteams.otdt.core.IOTJavaElement;
/**
* OTJavaElement implementation.
*
* @author jwloka
* @version $Id: OTJavaElement.java 23416 2010-02-03 19:59:31Z stephan $
*/
public abstract class OTJavaElement extends Member implements IOTJavaElement
{
// previously, a mapping and its referenced method had the same handle identifier.
// However, cf.
// - JavaElement.JEM_METHOD et al.
// - SourceType.getHandleFromMemento()
// - org.eclipse.objectteams.otdt.metrics.core.internal.OTCore (unused!)
// Used for handle identifier
public static final char OTEM_METHODMAPPING = 'ยง';
public static final String METHODMAPPING = Character.toString(OTEM_METHODMAPPING);
private int type;
private List<IJavaElement> children;
private IJavaElement correspondingJavaElem;
public OTJavaElement(int type, IJavaElement correspondingJavaElem, IJavaElement parent)
{
this(type, correspondingJavaElem, parent, true);
}
/**
* @param addAsChild Set this to false to avoid adding this element as a child of its parent, e.g. for temporary objects.
*/
public OTJavaElement(int type, IJavaElement correspondingJavaElem, IJavaElement parent, boolean addAsChild)
{
super((JavaElement) parent);
this.type = type;
this.correspondingJavaElem = correspondingJavaElem;
this.children = new ArrayList<IJavaElement>();
if (addAsChild && parent instanceof OTJavaElement)
((OTJavaElement)parent).addChild(this);
}
@Override
public boolean hasChildren()
{
return this.children.size() > 0;
}
@Override
public IJavaElement[] getChildren()
{
synchronized(this.children) {
if (this.children.isEmpty() && this.correspondingJavaElem instanceof IType)
// fetch children from the java element (on first access):
try {
for (IJavaElement child : ((IType)this.correspondingJavaElem).getChildren())
this.children.add(child);
} catch (JavaModelException e) { /* noop */ }
return this.children.toArray( new IJavaElement[this.children.size()] );
}
}
public void addChild(IOTJavaElement child)
{
if (child != null)
this.children.add(child);
}
@Override
public IJavaElement getParent()
{
//{OTModelUpdate : if null return the parent of the wrapped java element
//orig: return _parent;
IJavaElement result = this.parent;
if (result == null)
result = getCorrespondingJavaElement().getParent();
return result;
//jwl}
}
@Override
public String getElementName()
{
return getCorrespondingJavaElement().getElementName();
}
@Override
public int getElementType()
{
return this.type;
}
/**
* Assumes instanceof check is done in subclasses!
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if(obj == null)
{
return false;
}
OTJavaElement other = (OTJavaElement)obj;
return getParent().equals(other.getParent())
&& (this.type == other.type)
&& getCorrespondingJavaElement().equals(other.getCorrespondingJavaElement());
}
/**
* COPIED basically from JavaElement
* Returns the hash code for this Java element. By default,
* the hash code for an element is a combination of its name
* and parent's hash code. Elements with other requirements must
* override this method.
*/
@Override
public int hashCode() {
IJavaElement myParent = this.getParent();
if (myParent == null) return super.hashCode();
return Util.combineHashCodes(getElementName().hashCode(), myParent.hashCode());
}
@Override
@SuppressWarnings("nls")
public String toString()
{
return "OTJavaElement " + getElementName();
}
@Override
public IJavaElement getCorrespondingJavaElement()
{
return this.correspondingJavaElem;
}
@Override
public OTJavaElement resolved(Binding binding) {
return this;
}
public void setCorrespondingJavaElement(IJavaElement javaElem)
{
this.correspondingJavaElem = javaElem;
}
// delegated IJavaElement methods
@Override
public boolean exists()
{
return this.correspondingJavaElem.exists();
}
@Override
public void close() throws JavaModelException {
super.close();
((JavaElement) this.correspondingJavaElem).close();
}
@Override
public IJavaElement getAncestor(int ancestorType)
{
// first see if an OT element was requested (COPY&PASTE from JavaElement):
IJavaElement element = this;
while (element != null) {
if (element.getElementType() == ancestorType) return element;
element= element.getParent();
}
// delegate to the java part:
return this.correspondingJavaElem.getAncestor(ancestorType);
}
@Override
public IResource getCorrespondingResource() throws JavaModelException
{
// see SourceRefElement
if (!exists()) throw newNotPresentException();
return null;
}
@Override
public String getHandleIdentifier()
{
return this.correspondingJavaElem.getHandleIdentifier();
}
@Override
public IJavaModel getJavaModel()
{
return this.correspondingJavaElem.getJavaModel();
}
@Override
public IJavaProject getJavaProject()
{
return this.correspondingJavaElem.getJavaProject();
}
@Override
public IOpenable getOpenable()
{
return this.correspondingJavaElem.getOpenable();
}
@Override
public IPath getPath()
{
return this.correspondingJavaElem.getPath();
}
@Override
public IJavaElement getPrimaryElement()
{
return this.correspondingJavaElem.getPrimaryElement();
}
@Override
public IResource getResource()
{
return this.correspondingJavaElem.getResource();
}
@Override
public ISchedulingRule getSchedulingRule()
{
return this.correspondingJavaElem.getSchedulingRule();
}
@Override
public IResource getUnderlyingResource() throws JavaModelException
{
return this.correspondingJavaElem.getUnderlyingResource();
}
@Override
public boolean isReadOnly()
{
return this.correspondingJavaElem.isReadOnly();
}
@Override
public boolean isStructureKnown() throws JavaModelException
{
return this.correspondingJavaElem.isStructureKnown();
}
@Override
public <T> T getAdapter(Class<T> adapter)
{
T result = super.getAdapter(adapter);
if (result == null)
result = this.correspondingJavaElem.getAdapter(adapter);
return result;
}
@Override
public void toString(int tab, StringBuffer buffer) {
for (int i = tab; i > 0; i--)
buffer.append(" "); //$NON-NLS-1$
buffer.append(this.toString());
}
}