blob: b0e4cbfe16fbdb1b6c767670af0c84d0c4d4b343 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. 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:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.common.ui.internal.utils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
/**
* Original code is from JDT Utility methods for the Java Model.
*/
public final class JavaModelUtil {
/**
* Finds a type by its qualified type name (dot separated).
*
* @param jproject
* The java project to search in
* @param fullyQualifiedName
* The fully qualified name (type name with enclosing type names
* and package (all separated by dots))
* @return The type found, or null if not existing
* @throws JavaModelException
*/
public static IType findType(IJavaProject jproject,
String fullyQualifiedName) throws JavaModelException {
// workaround for bug 22883
IType type = jproject.findType(fullyQualifiedName);
if (type != null) {
return type;
}
IPackageFragmentRoot[] roots = jproject.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
IPackageFragmentRoot root = roots[i];
type = findType(root, fullyQualifiedName);
if (type != null && type.exists()) {
return type;
}
}
return null;
}
/**
* Returns <code>true</code> if the given package fragment root is
* referenced. This means it is own by a different project but is referenced
* by the root's parent. Returns <code>false</code> if the given root
* doesn't have an underlying resource.
* @param root
* @return true if root is referenced
*/
public static boolean isReferenced(IPackageFragmentRoot root) {
IResource resource = root.getResource();
if (resource != null) {
IProject jarProject = resource.getProject();
IProject container = root.getJavaProject().getProject();
return !container.equals(jarProject);
}
return false;
}
private static IType findType(IPackageFragmentRoot root,
String fullyQualifiedName) throws JavaModelException {
IJavaElement[] children = root.getChildren();
for (int i = 0; i < children.length; i++) {
IJavaElement element = children[i];
if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
IPackageFragment pack = (IPackageFragment) element;
if (!fullyQualifiedName.startsWith(pack.getElementName())) {
continue;
}
IType type = findType(pack, fullyQualifiedName);
if (type != null && type.exists()) {
return type;
}
}
}
return null;
}
private static IType findType(IPackageFragment pack,
String fullyQualifiedName) throws JavaModelException {
ICompilationUnit[] cus = pack.getCompilationUnits();
for (int i = 0; i < cus.length; i++) {
ICompilationUnit unit = cus[i];
IType type = findType(unit, fullyQualifiedName);
if (type != null && type.exists()) {
return type;
}
}
return null;
}
private static IType findType(ICompilationUnit cu, String fullyQualifiedName)
throws JavaModelException {
IType[] types = cu.getAllTypes();
for (int i = 0; i < types.length; i++) {
IType type = types[i];
if (getFullyQualifiedName(type).equals(fullyQualifiedName)) {
return type;
}
}
return null;
}
/**
* Finds a type by package and type name.
*
* @param jproject
* the java project to search in
* @param pack
* The package name
* @param typeQualifiedName
* the type qualified name (type name with enclosing type names
* (separated by dots))
* @return the type found, or null if not existing
* @throws JavaModelException
* @deprecated Use IJavaProject.findType(String, String) instead
*/
public static IType findType(IJavaProject jproject, String pack,
String typeQualifiedName) throws JavaModelException {
return jproject.findType(pack, typeQualifiedName);
}
/**
* Finds a type container by container name. The returned element will be of
* type <code>IType</code> or a <code>IPackageFragment</code>.
* <code>null</code> is returned if the type container could not be found.
*
* @param jproject
* The Java project defining the context to search
* @param typeContainerName
* A dot separarted name of the type container
* @return the java element
* @throws JavaModelException
* @see #getTypeContainerName(IType)
*/
public static IJavaElement findTypeContainer(IJavaProject jproject,
String typeContainerName) throws JavaModelException {
// try to find it as type
IJavaElement result = jproject.findType(typeContainerName);
if (result == null) {
// find it as package
IPath path = new Path(typeContainerName.replace('.', '/'));
result = jproject.findElement(path);
if (!(result instanceof IPackageFragment)) {
result = null;
}
}
return result;
}
/**
* Finds a type in a compilation unit. Typical usage is to find the
* corresponding type in a working copy.
*
* @param cu
* the compilation unit to search in
* @param typeQualifiedName
* the type qualified name (type name with enclosing type names
* (separated by dots))
* @return the type found, or null if not existing
* @throws JavaModelException
*/
public static IType findTypeInCompilationUnit(ICompilationUnit cu,
String typeQualifiedName) throws JavaModelException {
IType[] types = cu.getAllTypes();
for (int i = 0; i < types.length; i++) {
String currName = getTypeQualifiedName(types[i]);
if (typeQualifiedName.equals(currName)) {
return types[i];
}
}
return null;
}
/**
* Finds a a member in a compilation unit. Typical usage is to find the
* corresponding member in a working copy.
*
* @param cu
* the compilation unit (eg. working copy) to search in
* @param member
* the member (eg. from the original)
* @return the member found, or null if not existing
*/
public static IMember findMemberInCompilationUnit(ICompilationUnit cu,
IMember member) {
IJavaElement[] elements = cu.findElements(member);
if (elements != null && elements.length > 0) {
return (IMember) elements[0];
}
return null;
}
/**
* Returns the element of the given compilation unit which is "equal" to the
* given element. Note that the given element usually has a parent different
* from the given compilation unit.
*
* @param cu
* the cu to search in
* @param element
* the element to look for
* @return an element of the given cu "equal" to the given element
*/
public static IJavaElement findInCompilationUnit(ICompilationUnit cu,
IJavaElement element) {
IJavaElement[] elements = cu.findElements(element);
if (elements != null && elements.length > 0) {
return elements[0];
}
return null;
}
/**
* Returns the qualified type name of the given type using '.' as
* separators. This is a replace for IType.getTypeQualifiedName() which uses
* '$' as separators. As '$' is also a valid character in an id this is
* ambiguous. JavaCore PR: 1GCFUNT
* @param type
* @return the type qualified name
*/
public static String getTypeQualifiedName(IType type) {
return type.getTypeQualifiedName('.');
}
/**
* Returns the fully qualified name of the given type using '.' as
* separators. This is a replace for IType.getFullyQualifiedTypeName which
* uses '$' as separators. As '$' is also a valid character in an id this is
* ambiguous. JavaCore PR: 1GCFUNT
* @param type
* @return the fully qualified name using . as the separator
*/
public static String getFullyQualifiedName(IType type) {
return type.getFullyQualifiedName('.');
}
/**
* Returns the fully qualified name of a type's container. (package name or
* enclosing type name)
* @param type
* @return the container name
*/
public static String getTypeContainerName(IType type) {
IType outerType = type.getDeclaringType();
if (outerType != null) {
return outerType.getFullyQualifiedName('.');
}
return type.getPackageFragment().getElementName();
}
/**
* Concatenates two names. Uses a dot for separation. Both strings can be
* empty or <code>null</code>.
* @param name1
* @param name2
* @return name1 + name2
*/
public static String concatenateName(String name1, String name2) {
StringBuffer buf = new StringBuffer();
if (name1 != null && name1.length() > 0) {
buf.append(name1);
}
if (name2 != null && name2.length() > 0) {
if (buf.length() > 0) {
buf.append('.');
}
buf.append(name2);
}
return buf.toString();
}
/**
* Concatenates two names. Uses a dot for separation. Both strings can be
* empty or <code>null</code>.
* @param name1
* @param name2
* @return name1 + name2
*/
public static String concatenateName(char[] name1, char[] name2) {
StringBuffer buf = new StringBuffer();
if (name1 != null && name1.length > 0) {
buf.append(name1);
}
if (name2 != null && name2.length > 0) {
if (buf.length() > 0) {
buf.append('.');
}
buf.append(name2);
}
return buf.toString();
}
/**
* Evaluates if a member (possible from another package) is visible from
* elements in a package.
*
* @param member
* The member to test the visibility for
* @param pack
* The package in focus
* @return true if visible
* @throws JavaModelException
*/
public static boolean isVisible(IMember member, IPackageFragment pack)
throws JavaModelException {
int type = member.getElementType();
if (type == IJavaElement.INITIALIZER
|| (type == IJavaElement.METHOD && member.getElementName()
.startsWith("<"))) {
//$NON-NLS-1$
return false;
}
int otherflags = member.getFlags();
IType declaringType = member.getDeclaringType();
if (Flags.isPublic(otherflags)
|| (declaringType != null && declaringType.isInterface())) {
return true;
} else if (Flags.isPrivate(otherflags)) {
return false;
}
IPackageFragment otherpack = (IPackageFragment) findParentOfKind(
member, IJavaElement.PACKAGE_FRAGMENT);
return (pack != null && otherpack != null && isSamePackage(pack,
otherpack));
}
/**
* Evaluates if a member in the focus' element hierarchy is visible from
* elements in a package.
*
* @param member
* The member to test the visibility for
* @param pack
* The package of the focus element focus
* @return true if is visible in hiearchy
* @throws JavaModelException
*/
public static boolean isVisibleInHierarchy(IMember member,
IPackageFragment pack) throws JavaModelException {
int type = member.getElementType();
if (type == IJavaElement.INITIALIZER
|| (type == IJavaElement.METHOD && member.getElementName()
.startsWith("<"))) {
//$NON-NLS-1$
return false;
}
int otherflags = member.getFlags();
IType declaringType = member.getDeclaringType();
if (Flags.isPublic(otherflags) || Flags.isProtected(otherflags)
|| (declaringType != null && declaringType.isInterface())) {
return true;
} else if (Flags.isPrivate(otherflags)) {
return false;
}
IPackageFragment otherpack = (IPackageFragment) findParentOfKind(
member, IJavaElement.PACKAGE_FRAGMENT);
return (pack != null && pack.equals(otherpack));
}
/**
* Returns the package fragment root of <code>IJavaElement</code>. If the
* given element is already a package fragment root, the element itself is
* returned.
* @param element
* @return the package fragment root
*/
public static IPackageFragmentRoot getPackageFragmentRoot(
IJavaElement element) {
return (IPackageFragmentRoot) element
.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
}
/**
* Returns the parent of the supplied java element that conforms to the
* given parent type or <code>null</code>, if such a parent doesn't exit.
*
* @deprecated Use element.getParent().getAncestor(kind);
*/
private static IJavaElement findParentOfKind(IJavaElement element, int kind) {
if (element != null && element.getParent() != null) {
return element.getParent().getAncestor(kind);
}
return null;
}
/**
* Finds a method in a type. This searches for a method with the same name
* and signature. Parameter types are only compared by the simple name, no
* resolving for the fully qualified type name is done. Constructors are
* only compared by parameters, not the name.
*
* @param name
* The name of the method to find
* @param paramTypes
* The type signatures of the parameters e.g.
* <code>{"QString;","I"}</code>
* @param isConstructor
* If the method is a constructor
* @param type
* @return The first found method or <code>null</code>, if nothing found
* @throws JavaModelException
*/
public static IMethod findMethod(String name, String[] paramTypes,
boolean isConstructor, IType type) throws JavaModelException {
return findMethod(name, paramTypes, isConstructor, type.getMethods());
}
/**
* Finds a method by name. This searches for a method with a name and
* signature. Parameter types are only compared by the simple name, no
* resolving for the fully qualified type name is done. Constructors are
* only compared by parameters, not the name.
*
* @param name
* The name of the method to find
* @param paramTypes
* The type signatures of the parameters e.g.
* <code>{"QString;","I"}</code>
* @param isConstructor
* If the method is a constructor
* @param methods
* The methods to search in
* @return The found method or <code>null</code>, if nothing found
* @throws JavaModelException
*/
public static IMethod findMethod(String name, String[] paramTypes,
boolean isConstructor, IMethod[] methods) throws JavaModelException {
for (int i = methods.length - 1; i >= 0; i--) {
if (isSameMethodSignature(name, paramTypes, isConstructor,
methods[i])) {
return methods[i];
}
}
return null;
}
/**
* Finds a method declararion in a type's hierarchy. The search is top down,
* so this returns the first declaration of the method in the hierarchy.
* This searches for a method with a name and signature. Parameter types are
* only compared by the simple name, no resolving for the fully qualified
* type name is done. Constructors are only compared by parameters, not the
* name.
* @param hierarchy
*
* @param type
* Searches in this type's supertypes.
* @param name
* The name of the method to find
* @param paramTypes
* The type signatures of the parameters e.g.
* <code>{"QString;","I"}</code>
* @param isConstructor
* If the method is a constructor
* @return The first method found or null, if nothing found
* @throws JavaModelException
*/
public static IMethod findMethodDeclarationInHierarchy(
ITypeHierarchy hierarchy, IType type, String name,
String[] paramTypes, boolean isConstructor)
throws JavaModelException {
IType[] superTypes = hierarchy.getAllSupertypes(type);
for (int i = superTypes.length - 1; i >= 0; i--) {
IMethod first = findMethod(name, paramTypes, isConstructor,
superTypes[i]);
if (first != null && !Flags.isPrivate(first.getFlags())) {
// the order getAllSupertypes does make assumptions of the order
// of inner elements -> search recursivly
IMethod res = findMethodDeclarationInHierarchy(hierarchy, first
.getDeclaringType(), name, paramTypes, isConstructor);
if (res != null) {
return res;
}
return first;
}
}
return null;
}
/**
* Finds a method implementation in a type's classhierarchy. The search is
* bottom-up, so this returns the nearest overridden method. Does not find
* methods in interfaces or abstract methods. This searches for a method
* with a name and signature. Parameter types are only compared by the
* simple name, no resolving for the fully qualified type name is done.
* Constructors are only compared by parameters, not the name.
* @param hierarchy
*
* @param type
* Type to search the superclasses
* @param name
* The name of the method to find
* @param paramTypes
* The type signatures of the parameters e.g.
* <code>{"QString;","I"}</code>
* @param isConstructor
* If the method is a constructor
* @return The first method found or null, if nothing found
* @throws JavaModelException
*/
public static IMethod findMethodImplementationInHierarchy(
ITypeHierarchy hierarchy, IType type, String name,
String[] paramTypes, boolean isConstructor)
throws JavaModelException {
IType[] superTypes = hierarchy.getAllSuperclasses(type);
for (int i = 0; i < superTypes.length; i++) {
IMethod found = findMethod(name, paramTypes, isConstructor,
superTypes[i]);
if (found != null) {
if (Flags.isAbstract(found.getFlags())) {
return null;
}
return found;
}
}
return null;
}
private static IMethod findMethodInHierarchy(ITypeHierarchy hierarchy,
IType type, String name, String[] paramTypes, boolean isConstructor)
throws JavaModelException {
IMethod method = findMethod(name, paramTypes, isConstructor, type);
if (method != null) {
return method;
}
IType superClass = hierarchy.getSuperclass(type);
if (superClass != null) {
IMethod res = findMethodInHierarchy(hierarchy, superClass, name,
paramTypes, isConstructor);
if (res != null) {
return res;
}
}
if (!isConstructor) {
IType[] superInterfaces = hierarchy.getSuperInterfaces(type);
for (int i = 0; i < superInterfaces.length; i++) {
IMethod res = findMethodInHierarchy(hierarchy,
superInterfaces[i], name, paramTypes, false);
if (res != null) {
return res;
}
}
}
return method;
}
/**
* Finds the method that is defines/declares the given method. The search is
* bottom-up, so this returns the nearest defining/declaring method.
* @param typeHierarchy
* @param type
* @param methodName
* @param paramTypes
* @param isConstructor
*
* @param testVisibility
* If true the result is tested on visibility. Null is returned
* if the method is not visible.
* @return the method or null
* @throws JavaModelException
*/
public static IMethod findMethodDefininition(ITypeHierarchy typeHierarchy,
IType type, String methodName, String[] paramTypes,
boolean isConstructor, boolean testVisibility)
throws JavaModelException {
IType superClass = typeHierarchy.getSuperclass(type);
if (superClass != null) {
IMethod res = findMethodInHierarchy(typeHierarchy, superClass,
methodName, paramTypes, isConstructor);
if (res != null && !Flags.isPrivate(res.getFlags())) {
if (!testVisibility
|| isVisibleInHierarchy(res, type.getPackageFragment())) {
return res;
}
}
}
if (!isConstructor) {
IType[] interfaces = typeHierarchy.getSuperInterfaces(type);
for (int i = 0; i < interfaces.length; i++) {
IMethod res = findMethodInHierarchy(typeHierarchy,
interfaces[i], methodName, paramTypes, false);
if (res != null) {
return res; // methods from interfaces are always public and
// therefore visible
}
}
}
return null;
}
/**
* Tests if a method equals to the given signature. Parameter types are only
* compared by the simple name, no resolving for the fully qualified type
* name is done. Constructors are only compared by parameters, not the name.
*
* @param name
* Name of the method
* @param paramTypes
* The type signatures of the parameters e.g.
* <code>{"QString;","I"}</code>
* @param isConstructor
* Specifies if the method is a constructor
* @param curr
* @return Returns <code>true</code> if the method has the given name and
* parameter types and constructor state.
* @throws JavaModelException
*/
public static boolean isSameMethodSignature(String name,
String[] paramTypes, boolean isConstructor, IMethod curr)
throws JavaModelException {
if (isConstructor || name.equals(curr.getElementName())) {
if (isConstructor == curr.isConstructor()) {
String[] currParamTypes = curr.getParameterTypes();
if (paramTypes.length == currParamTypes.length) {
for (int i = 0; i < paramTypes.length; i++) {
String t1 = Signature.getSimpleName(Signature
.toString(paramTypes[i]));
String t2 = Signature.getSimpleName(Signature
.toString(currParamTypes[i]));
if (!t1.equals(t2)) {
return false;
}
}
return true;
}
}
}
return false;
}
/**
* Tests if two <code>IPackageFragment</code>s represent the same logical
* java package.
* @param pack1
* @param pack2
*
* @return <code>true</code> if the package fragments' names are equal.
*/
public static boolean isSamePackage(IPackageFragment pack1,
IPackageFragment pack2) {
return pack1.getElementName().equals(pack2.getElementName());
}
/**
* Checks whether the given type has a valid main method or not.
* @param type
* @return true if type has a main method
* @throws JavaModelException
*/
public static boolean hasMainMethod(IType type) throws JavaModelException {
IMethod[] methods = type.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isMainMethod()) {
return true;
}
}
return false;
}
/**
* Checks if the field is boolean.
* @param field
* @return true if the file is of primitive boolean type
* @throws JavaModelException
*/
public static boolean isBoolean(IField field) throws JavaModelException {
return field.getTypeSignature().equals(Signature.SIG_BOOLEAN);
}
/**
* Tests if the given element is on the class path of its containing
* project. Handles the case that the containing project isn't a Java
* project.
* @param element
* @return true if element in on the class path?
*/
public static boolean isOnClasspath(IJavaElement element) {
IJavaProject project = element.getJavaProject();
if (!project.exists())
return false;
return project.isOnClasspath(element);
}
/**
* Resolves a type name in the context of the declaring type.
*
* @param refTypeSig
* the type name in signature notation (for example 'QVector')
* this can also be an array type, but dimensions will be
* ignored.
* @param declaringType
* the context for resolving (type where the reference was made
* in)
* @return returns the fully qualified type name or build-in-type name. if a
* unresoved type couldn't be resolved null is returned
* @throws JavaModelException
*/
public static String getResolvedTypeName(String refTypeSig,
IType declaringType) throws JavaModelException {
int arrayCount = Signature.getArrayCount(refTypeSig);
char type = refTypeSig.charAt(arrayCount);
if (type == Signature.C_UNRESOLVED) {
int semi = refTypeSig
.indexOf(Signature.C_SEMICOLON, arrayCount + 1);
if (semi == -1) {
throw new IllegalArgumentException();
}
String name = refTypeSig.substring(arrayCount + 1, semi);
String[][] resolvedNames = declaringType.resolveType(name);
if (resolvedNames != null && resolvedNames.length > 0) {
return JavaModelUtil.concatenateName(resolvedNames[0][0],
resolvedNames[0][1]);
}
return null;
}
return Signature.toString(refTypeSig.substring(arrayCount));
}
/**
* Returns if a CU can be edited.
* @param cu
* @return true if cu is editable
*/
public static boolean isEditable(ICompilationUnit cu) {
IResource resource = toOriginal(cu).getResource();
return (resource.exists() && !resource.getResourceAttributes()
.isReadOnly());
}
/**
* Finds a qualified import for a type name.
* @param cu
* @param simpleName
* @return the import declaration or null
* @throws JavaModelException
*/
public static IImportDeclaration findImport(ICompilationUnit cu,
String simpleName) throws JavaModelException {
IImportDeclaration[] existing = cu.getImports();
for (int i = 0; i < existing.length; i++) {
String curr = existing[i].getElementName();
if (curr.endsWith(simpleName)) {
int dotPos = curr.length() - simpleName.length() - 1;
if ((dotPos == -1)
|| (dotPos > 0 && curr.charAt(dotPos) == '.')) {
return existing[i];
}
}
}
return null;
}
/**
* Returns the original if the given member. If the member is already an
* original the input is returned. The returned member might not exist
* @param member
* @return the original IMember
*/
public static IMember toOriginal(IMember member) {
if (member instanceof IMethod) {
return toOriginalMethod((IMethod) member);
}
return (IMember) member.getPrimaryElement();
/*
* ICompilationUnit cu= member.getCompilationUnit(); if (cu != null &&
* cu.isWorkingCopy()) return (IMember)cu.getOriginal(member); return
* member;
*/
}
/*
* XXX workaround for bug 18568
* http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568 to be removed once the
* bug is fixed
*/
private static IMethod toOriginalMethod(IMethod method) {
ICompilationUnit cu = method.getCompilationUnit();
if (cu == null || isPrimary(cu)) {
return method;
}
try {
// use the workaround only if needed
if (!method.getElementName().equals(
method.getDeclaringType().getElementName()))
return (IMethod) method.getPrimaryElement();
IType originalType = (IType) toOriginal(method.getDeclaringType());
IMethod[] methods = originalType.findMethods(method);
boolean isConstructor = method.isConstructor();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isConstructor() == isConstructor)
return methods[i];
}
return null;
} catch (JavaModelException e) {
return null;
}
}
// private static boolean PRIMARY_ONLY = false;
/**
* Returns the original cu if the given cu is a working copy. If the cu is
* already an original the input cu is returned. The returned cu might not
* exist
* @param cu
* @return the original compiliation unit
*/
public static ICompilationUnit toOriginal(ICompilationUnit cu) {
// To stay compatible with old version returned null
// if cu is null
if (cu == null)
return cu;
return cu.getPrimary();
}
/**
* Returns the original element if the given element is a working copy. If
* the cu is already an original the input element is returned. The returned
* element might not exist
* @param element
* @return element's primary element
*/
public static IJavaElement toOriginal(IJavaElement element) {
return element.getPrimaryElement();
}
/**
* Returns true if a cu is a primary cu (original or shared working copy)
* @param cu
* @return true if cu is primary
*/
public static boolean isPrimary(ICompilationUnit cu) {
return cu.getOwner() == null;
}
/**
* http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253
*
* Reconciling happens in a separate thread. This can cause a situation
* where the Java element gets disposed after an exists test has been done.
* So we should not log not present exceptions when they happen in working
* copies.
* @param exception
* @return true if filter not present
*/
public static boolean filterNotPresentException(CoreException exception) {
if (!(exception instanceof JavaModelException)) {
return true;
}
JavaModelException je = (JavaModelException) exception;
if (!je.isDoesNotExist()) {
return true;
}
IJavaElement[] elements = je.getJavaModelStatus().getElements();
for (int i = 0; i < elements.length; i++) {
IJavaElement element = elements[i];
ICompilationUnit unit = (ICompilationUnit) element
.getAncestor(IJavaElement.COMPILATION_UNIT);
if (unit == null) {
return true;
}
if (!unit.isWorkingCopy()) {
return true;
}
}
return false;
}
/**
* @param type
* @param pm
* @return all supertypes of type
* @throws JavaModelException
*/
public static IType[] getAllSuperTypes(IType type, IProgressMonitor pm)
throws JavaModelException {
// workaround for 23656
Set types = new HashSet(Arrays.asList(type.newSupertypeHierarchy(pm)
.getAllSupertypes(type)));
IType objekt = type.getJavaProject().findType("java.lang.Object");//$NON-NLS-1$
if (objekt != null) {
types.add(objekt);
}
return (IType[]) types.toArray(new IType[types.size()]);
}
/**
* @param resourcePath
* @param exclusionPatterns
* @return true if resourcePath is excluded by exclusion patterns
*/
public static boolean isExcludedPath(IPath resourcePath,
IPath[] exclusionPatterns) {
char[] path = resourcePath.toString().toCharArray();
for (int i = 0, length = exclusionPatterns.length; i < length; i++) {
char[] pattern = exclusionPatterns[i].toString().toCharArray();
if (CharOperation.pathMatch(pattern, path, true, '/')) {
return true;
}
}
return false;
}
/*
* @see IClasspathEntry#getExclusionPatterns
*/
/**
* Returns whether the given resource path matches one of the exclusion
* patterns.
*
* @param resourcePath
* @param exclusionPatterns
* @return true if resourcePath is excluded
*/
public static boolean isExcluded(IPath resourcePath,
char[][] exclusionPatterns) {
if (exclusionPatterns == null) {
return false;
}
char[] path = resourcePath.toString().toCharArray();
for (int i = 0, length = exclusionPatterns.length; i < length; i++) {
if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/')) {
return true;
}
}
return false;
}
private static Boolean fgIsJDTCore_1_5 = null;
/**
* @return true if JRE 1.5 in enabled.
*/
public static boolean isJDTCore_1_5() {
if (fgIsJDTCore_1_5 == null) {
fgIsJDTCore_1_5 = JavaCore
.getDefaultOptions()
.containsKey(
"org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation") ? Boolean.TRUE
: Boolean.FALSE;
}
return fgIsJDTCore_1_5.booleanValue();
}
/**
* Helper method that tests if an classpath entry can be found in a
* container. <code>null</code> is returned if the entry can not be found
* or if the container does not allows the configuration of source
* attachments
*
* @param jproject
* The container's parent project
* @param containerPath
* The path of the container
* @param libPath
* The path of the library to be found
* @return IClasspathEntry A classpath entry from the container of
* <code>null</code> if the container can not be modified.
* @throws JavaModelException
*/
public static IClasspathEntry getClasspathEntryToEdit(
IJavaProject jproject, IPath containerPath, IPath libPath)
throws JavaModelException {
IClasspathContainer container = JavaCore.getClasspathContainer(
containerPath, jproject);
ClasspathContainerInitializer initializer = JavaCore
.getClasspathContainerInitializer(containerPath.segment(0));
if (container != null
&& initializer != null
&& initializer.canUpdateClasspathContainer(containerPath,
jproject)) {
IClasspathEntry[] entries = container.getClasspathEntries();
for (int i = 0; i < entries.length; i++) {
IClasspathEntry curr = entries[i];
IClasspathEntry resolved = JavaCore
.getResolvedClasspathEntry(curr);
if (resolved != null && libPath.equals(resolved.getPath())) {
return curr; // return the real entry
}
}
}
return null; // attachment not possible
}
}