/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.corext.refactoring.util; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; import org.eclipse.wst.jsdt.core.IIncludePathEntry; import org.eclipse.wst.jsdt.core.IJavaScriptUnit; import org.eclipse.wst.jsdt.core.IField; import org.eclipse.wst.jsdt.core.IJavaScriptElement; import org.eclipse.wst.jsdt.core.IJavaScriptProject; import org.eclipse.wst.jsdt.core.IMember; import org.eclipse.wst.jsdt.core.IFunction; import org.eclipse.wst.jsdt.core.IPackageFragment; import org.eclipse.wst.jsdt.core.IPackageFragmentRoot; import org.eclipse.wst.jsdt.core.ISourceReference; import org.eclipse.wst.jsdt.core.IType; import org.eclipse.wst.jsdt.core.JavaScriptCore; import org.eclipse.wst.jsdt.core.JavaScriptModelException; import org.eclipse.wst.jsdt.core.Signature; import org.eclipse.wst.jsdt.internal.corext.SourceRange; import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil; public class JavaElementUtil { //no instances private JavaElementUtil(){ } public static String createMethodSignature(IFunction method){ try { return Signature.toString(method.getSignature(), method.getElementName(), method.getParameterNames(), false, ! method.isConstructor()); } catch(JavaScriptModelException e) { return method.getElementName(); //fallback } } public static String createFieldSignature(IField field){ return JavaModelUtil.getFullyQualifiedName(field.getDeclaringType()) + "." + field.getElementName(); //$NON-NLS-1$ } public static String createSignature(IMember member){ switch (member.getElementType()){ case IJavaScriptElement.FIELD: return createFieldSignature((IField)member); case IJavaScriptElement.TYPE: return JavaModelUtil.getFullyQualifiedName(((IType)member)); case IJavaScriptElement.INITIALIZER: return RefactoringCoreMessages.JavaElementUtil_initializer; case IJavaScriptElement.METHOD: return createMethodSignature((IFunction)member); default: Assert.isTrue(false); return null; } } public static IJavaScriptElement[] getElementsOfType(IJavaScriptElement[] elements, int type){ Set result= new HashSet(elements.length); for (int i= 0; i < elements.length; i++) { IJavaScriptElement element= elements[i]; if (element.getElementType() == type) result.add(element); } return (IJavaScriptElement[]) result.toArray(new IJavaScriptElement[result.size()]); } public static IType getMainType(IJavaScriptUnit cu) throws JavaScriptModelException{ IType[] types= cu.getTypes(); for (int i = 0; i < types.length; i++) { if (isMainType(types[i])) return types[i]; } return null; } public static boolean isMainType(IType type) throws JavaScriptModelException{ if (! type.exists()) return false; if (type.isBinary()) return false; if (type.getJavaScriptUnit() == null) return false; if (type.getDeclaringType() != null) return false; return isPrimaryType(type) || isCuOnlyType(type); } private static boolean isPrimaryType(IType type){ return type.equals(type.getJavaScriptUnit().findPrimaryType()); } private static boolean isCuOnlyType(IType type) throws JavaScriptModelException{ return type.getJavaScriptUnit().getTypes().length == 1; } /** see org.eclipse.wst.jsdt.internal.core.JavaElement#isAncestorOf(org.eclipse.wst.jsdt.core.IJavaScriptElement) */ public static boolean isAncestorOf(IJavaScriptElement ancestor, IJavaScriptElement child) { IJavaScriptElement parent= child.getParent(); while (parent != null && !parent.equals(ancestor)) { parent= parent.getParent(); } return parent != null; } public static IFunction[] getAllConstructors(IType type) throws JavaScriptModelException { List result= new ArrayList(); IFunction[] methods= type.getFunctions(); for (int i= 0; i < methods.length; i++) { IFunction iMethod= methods[i]; if (iMethod.isConstructor()) result.add(iMethod); } return (IFunction[]) result.toArray(new IFunction[result.size()]); } /** * Returns an array of projects that have the specified root on their * classpaths. */ public static IJavaScriptProject[] getReferencingProjects(IPackageFragmentRoot root) throws JavaScriptModelException { IIncludePathEntry cpe= root.getRawIncludepathEntry(); IJavaScriptProject[] allJavaProjects= JavaScriptCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaScriptProjects(); List result= new ArrayList(allJavaProjects.length); for (int i= 0; i < allJavaProjects.length; i++) { IJavaScriptProject project= allJavaProjects[i]; IPackageFragmentRoot[] roots= project.findPackageFragmentRoots(cpe); if (roots.length > 0) result.add(project); } return (IJavaScriptProject[]) result.toArray(new IJavaScriptProject[result.size()]); } public static IMember[] merge(IMember[] a1, IMember[] a2) { // Don't use hash sets since ordering is important for some refactorings. List result= new ArrayList(a1.length + a2.length); for (int i= 0; i < a1.length; i++) { IMember member= a1[i]; if (!result.contains(member)) result.add(member); } for (int i= 0; i < a2.length; i++) { IMember member= a2[i]; if (!result.contains(member)) result.add(member); } return (IMember[]) result.toArray(new IMember[result.size()]); } public static boolean isDefaultPackage(Object element) { return (element instanceof IPackageFragment) && ((IPackageFragment)element).isDefaultPackage(); } /** * @param pack a package fragment * @return an array containing the given package and all subpackages * @throws JavaScriptModelException */ public static IPackageFragment[] getPackageAndSubpackages(IPackageFragment pack) throws JavaScriptModelException { if (pack.isDefaultPackage()) return new IPackageFragment[] { pack }; IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getParent(); IJavaScriptElement[] allPackages= root.getChildren(); ArrayList subpackages= new ArrayList(); subpackages.add(pack); String prefix= pack.getElementName() + '.'; for (int i= 0; i < allPackages.length; i++) { IPackageFragment currentPackage= (IPackageFragment) allPackages[i]; if (currentPackage.getElementName().startsWith(prefix)) subpackages.add(currentPackage); } return (IPackageFragment[]) subpackages.toArray(new IPackageFragment[subpackages.size()]); } /** * @param pack the package fragment; may not be null * @return the parent package fragment, or null if the given package fragment is the default package or a top level package */ public static IPackageFragment getParentSubpackage(IPackageFragment pack) { if (pack.isDefaultPackage()) return null; final int index= pack.getElementName().lastIndexOf('.'); if (index == -1) return null; final IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getParent(); final String newPackageName= pack.getElementName().substring(0, index); final IPackageFragment parent= root.getPackageFragment(newPackageName); if (parent.exists()) return parent; else return null; } public static IMember[] sortByOffset(IMember[] members){ Comparator comparator= new Comparator(){ public int compare(Object o1, Object o2){ try{ return ((IMember) o1).getNameRange().getOffset() - ((IMember) o2).getNameRange().getOffset(); } catch (JavaScriptModelException e){ return 0; } } }; Arrays.sort(members, comparator); return members; } public static boolean isSourceAvailable(ISourceReference sourceReference) { try { return SourceRange.isAvailable(sourceReference.getSourceRange()); } catch (JavaScriptModelException e) { return false; } } }