| /******************************************************************************* |
| * 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$ |
| //$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$ |
| //$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 //$NON-NLS-1$ |
| : 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 |
| } |
| } |