KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > util > JavaModelUtil


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Matt Chapman, mpchapman@gmail.com - 89977 Make JDT .java agnostic
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.corext.util;
13
14 import java.util.Arrays JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.text.edits.MalformedTreeException;
19 import org.eclipse.text.edits.TextEdit;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.NullProgressMonitor;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29
30 import org.eclipse.core.filebuffers.FileBuffers;
31 import org.eclipse.core.filebuffers.ITextFileBufferManager;
32 import org.eclipse.core.filebuffers.LocationKind;
33
34 import org.eclipse.core.resources.IFile;
35 import org.eclipse.core.resources.IResource;
36 import org.eclipse.core.resources.IStorage;
37
38 import org.eclipse.jface.text.BadLocationException;
39 import org.eclipse.jface.text.Document;
40 import org.eclipse.jface.text.IDocument;
41 import org.eclipse.jface.text.RewriteSessionEditProcessor;
42
43 import org.eclipse.jdt.core.ClasspathContainerInitializer;
44 import org.eclipse.jdt.core.Flags;
45 import org.eclipse.jdt.core.IClasspathContainer;
46 import org.eclipse.jdt.core.IClasspathEntry;
47 import org.eclipse.jdt.core.ICompilationUnit;
48 import org.eclipse.jdt.core.IField;
49 import org.eclipse.jdt.core.IJarEntryResource;
50 import org.eclipse.jdt.core.IJavaElement;
51 import org.eclipse.jdt.core.IJavaProject;
52 import org.eclipse.jdt.core.ILocalVariable;
53 import org.eclipse.jdt.core.IMember;
54 import org.eclipse.jdt.core.IMethod;
55 import org.eclipse.jdt.core.IPackageFragment;
56 import org.eclipse.jdt.core.IPackageFragmentRoot;
57 import org.eclipse.jdt.core.IType;
58 import org.eclipse.jdt.core.ITypeHierarchy;
59 import org.eclipse.jdt.core.JavaCore;
60 import org.eclipse.jdt.core.JavaModelException;
61 import org.eclipse.jdt.core.Signature;
62 import org.eclipse.jdt.core.WorkingCopyOwner;
63 import org.eclipse.jdt.core.compiler.CharOperation;
64
65 import org.eclipse.jdt.internal.corext.CorextMessages;
66 import org.eclipse.jdt.internal.corext.ValidateEditException;
67
68 import org.eclipse.jdt.launching.IVMInstall;
69 import org.eclipse.jdt.launching.IVMInstall2;
70 import org.eclipse.jdt.launching.JavaRuntime;
71 import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
72
73 import org.eclipse.jdt.internal.ui.JavaUIStatus;
74
75 /**
76  * Utility methods for the Java Model.
77  */

78 public final class JavaModelUtil {
79     
80     /**
81      * Only use this suffix for creating new .java files.
82      * In general, use one of the three *JavaLike*(..) methods in JavaCore or create
83      * a name from an existing compilation unit with {@link #getRenamedCUName(ICompilationUnit, String)}
84      * <p>
85      * Note: Unlike {@link JavaCore#getJavaLikeExtensions()}, this suffix includes a leading ".".
86      * </p>
87      *
88      * @see JavaCore#getJavaLikeExtensions()
89      * @see JavaCore#isJavaLikeFileName(String)
90      * @see JavaCore#removeJavaLikeExtension(String)
91      * @see #getRenamedCUName(ICompilationUnit, String)
92      */

93     public static final String JavaDoc DEFAULT_CU_SUFFIX= ".java"; //$NON-NLS-1$
94

95     /**
96      * Finds a type by its qualified type name (dot separated).
97      * @param jproject The java project to search in
98      * @param fullyQualifiedName The fully qualified name (type name with enclosing type names and package (all separated by dots))
99      * @return The type found, or null if not existing
100      */

101     public static IType findType(IJavaProject jproject, String JavaDoc fullyQualifiedName) throws JavaModelException {
102         //workaround for bug 22883
103
IType type= jproject.findType(fullyQualifiedName);
104         if (type != null)
105             return type;
106         IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
107         for (int i= 0; i < roots.length; i++) {
108             IPackageFragmentRoot root= roots[i];
109             type= findType(root, fullyQualifiedName);
110             if (type != null && type.exists())
111                 return type;
112         }
113         return null;
114     }
115     
116     /**
117      * Finds a type by its qualified type name (dot separated).
118      * @param jproject The java project to search in
119      * @param fullyQualifiedName The fully qualified name (type name with enclosing type names and package (all separated by dots))
120      * @param owner the working copy owner
121      * @return The type found, or null if not existing
122      */

123     public static IType findType(IJavaProject jproject, String JavaDoc fullyQualifiedName, WorkingCopyOwner owner) throws JavaModelException {
124         //workaround for bug 22883
125
IType type= jproject.findType(fullyQualifiedName, owner);
126         if (type != null)
127             return type;
128         IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
129         for (int i= 0; i < roots.length; i++) {
130             IPackageFragmentRoot root= roots[i];
131             type= findType(root, fullyQualifiedName);
132             if (type != null && type.exists())
133                 return type;
134         }
135         return null;
136     }
137     
138
139     
140     private static IType findType(IPackageFragmentRoot root, String JavaDoc fullyQualifiedName) throws JavaModelException{
141         IJavaElement[] children= root.getChildren();
142         for (int i= 0; i < children.length; i++) {
143             IJavaElement element= children[i];
144             if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT){
145                 IPackageFragment pack= (IPackageFragment)element;
146                 if (! fullyQualifiedName.startsWith(pack.getElementName()))
147                     continue;
148                 IType type= findType(pack, fullyQualifiedName);
149                 if (type != null && type.exists())
150                     return type;
151             }
152         }
153         return null;
154     }
155     
156     private static IType findType(IPackageFragment pack, String JavaDoc fullyQualifiedName) throws JavaModelException{
157         ICompilationUnit[] cus= pack.getCompilationUnits();
158         for (int i= 0; i < cus.length; i++) {
159             ICompilationUnit unit= cus[i];
160             IType type= findType(unit, fullyQualifiedName);
161             if (type != null && type.exists())
162                 return type;
163         }
164         return null;
165     }
166     
167     private static IType findType(ICompilationUnit cu, String JavaDoc fullyQualifiedName) throws JavaModelException{
168         IType[] types= cu.getAllTypes();
169         for (int i= 0; i < types.length; i++) {
170             IType type= types[i];
171             if (getFullyQualifiedName(type).equals(fullyQualifiedName))
172                 return type;
173         }
174         return null;
175     }
176     
177     /**
178      * Finds a type container by container name.
179      * The returned element will be of type <code>IType</code> or a <code>IPackageFragment</code>.
180      * <code>null</code> is returned if the type container could not be found.
181      * @param jproject The Java project defining the context to search
182      * @param typeContainerName A dot separated name of the type container
183      * @see #getTypeContainerName(IType)
184      */

185     public static IJavaElement findTypeContainer(IJavaProject jproject, String JavaDoc typeContainerName) throws JavaModelException {
186         // try to find it as type
187
IJavaElement result= jproject.findType(typeContainerName);
188         if (result == null) {
189             // find it as package
190
IPath path= new Path(typeContainerName.replace('.', '/'));
191             result= jproject.findElement(path);
192             if (!(result instanceof IPackageFragment)) {
193                 result= null;
194             }
195             
196         }
197         return result;
198     }
199     
200     /**
201      * Finds a type in a compilation unit. Typical usage is to find the corresponding
202      * type in a working copy.
203      * @param cu the compilation unit to search in
204      * @param typeQualifiedName the type qualified name (type name with enclosing type names (separated by dots))
205      * @return the type found, or null if not existing
206      */

207     public static IType findTypeInCompilationUnit(ICompilationUnit cu, String JavaDoc typeQualifiedName) throws JavaModelException {
208         IType[] types= cu.getAllTypes();
209         for (int i= 0; i < types.length; i++) {
210             String JavaDoc currName= getTypeQualifiedName(types[i]);
211             if (typeQualifiedName.equals(currName)) {
212                 return types[i];
213             }
214         }
215         return null;
216     }
217     
218     /**
219      * Returns the element of the given compilation unit which is "equal" to the
220      * given element. Note that the given element usually has a parent different
221      * from the given compilation unit.
222      *
223      * @param cu the cu to search in
224      * @param element the element to look for
225      * @return an element of the given cu "equal" to the given element
226      */

227     public static IJavaElement findInCompilationUnit(ICompilationUnit cu, IJavaElement element) {
228         IJavaElement[] elements= cu.findElements(element);
229         if (elements != null && elements.length > 0) {
230             return elements[0];
231         }
232         return null;
233     }
234     
235     /**
236      * Returns the qualified type name of the given type using '.' as separators.
237      * This is a replace for IType.getTypeQualifiedName()
238      * which uses '$' as separators. As '$' is also a valid character in an id
239      * this is ambiguous. JavaCore PR: 1GCFUNT
240      */

241     public static String JavaDoc getTypeQualifiedName(IType type) {
242         try {
243             if (type.isBinary() && !type.isAnonymous()) {
244                 IType declaringType= type.getDeclaringType();
245                 if (declaringType != null) {
246                     return getTypeQualifiedName(declaringType) + '.' + type.getElementName();
247                 }
248             }
249         } catch (JavaModelException e) {
250             // ignore
251
}
252         return type.getTypeQualifiedName('.');
253     }
254     
255     /**
256      * Returns the fully qualified name of the given type using '.' as separators.
257      * This is a replace for IType.getFullyQualifiedTypeName
258      * which uses '$' as separators. As '$' is also a valid character in an id
259      * this is ambiguous. JavaCore PR: 1GCFUNT
260      */

261     public static String JavaDoc getFullyQualifiedName(IType type) {
262         try {
263             if (type.isBinary() && !type.isAnonymous()) {
264                 IType declaringType= type.getDeclaringType();
265                 if (declaringType != null) {
266                     return getFullyQualifiedName(declaringType) + '.' + type.getElementName();
267                 }
268             }
269         } catch (JavaModelException e) {
270             // ignore
271
}
272         return type.getFullyQualifiedName('.');
273     }
274     
275     /**
276      * Returns the fully qualified name of a type's container. (package name or enclosing type name)
277      */

278     public static String JavaDoc getTypeContainerName(IType type) {
279         IType outerType= type.getDeclaringType();
280         if (outerType != null) {
281             return getFullyQualifiedName(outerType);
282         } else {
283             return type.getPackageFragment().getElementName();
284         }
285     }
286     
287     
288     /**
289      * Concatenates two names. Uses a dot for separation.
290      * Both strings can be empty or <code>null</code>.
291      */

292     public static String JavaDoc concatenateName(String JavaDoc name1, String JavaDoc name2) {
293         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
294         if (name1 != null && name1.length() > 0) {
295             buf.append(name1);
296         }
297         if (name2 != null && name2.length() > 0) {
298             if (buf.length() > 0) {
299                 buf.append('.');
300             }
301             buf.append(name2);
302         }
303         return buf.toString();
304     }
305     
306     /**
307      * Concatenates two names. Uses a dot for separation.
308      * Both strings can be empty or <code>null</code>.
309      */

310     public static String JavaDoc concatenateName(char[] name1, char[] name2) {
311         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
312         if (name1 != null && name1.length > 0) {
313             buf.append(name1);
314         }
315         if (name2 != null && name2.length > 0) {
316             if (buf.length() > 0) {
317                 buf.append('.');
318             }
319             buf.append(name2);
320         }
321         return buf.toString();
322     }
323     
324     /**
325      * Evaluates if a member (possible from another package) is visible from
326      * elements in a package.
327      * @param member The member to test the visibility for
328      * @param pack The package in focus
329      */

330     public static boolean isVisible(IMember member, IPackageFragment pack) throws JavaModelException {
331         
332         int type= member.getElementType();
333         if (type == IJavaElement.INITIALIZER || (type == IJavaElement.METHOD && member.getElementName().startsWith("<"))) { //$NON-NLS-1$
334
return false;
335         }
336         
337         int otherflags= member.getFlags();
338         IType declaringType= member.getDeclaringType();
339         if (Flags.isPublic(otherflags) || (declaringType != null && isInterfaceOrAnnotation(declaringType))) {
340             return true;
341         } else if (Flags.isPrivate(otherflags)) {
342             return false;
343         }
344         
345         IPackageFragment otherpack= (IPackageFragment) member.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
346         return (pack != null && otherpack != null && isSamePackage(pack, otherpack));
347     }
348     
349     /**
350      * Evaluates if a member in the focus' element hierarchy is visible from
351      * elements in a package.
352      * @param member The member to test the visibility for
353      * @param pack The package of the focus element focus
354      */

355     public static boolean isVisibleInHierarchy(IMember member, IPackageFragment pack) throws JavaModelException {
356         int type= member.getElementType();
357         if (type == IJavaElement.INITIALIZER || (type == IJavaElement.METHOD && member.getElementName().startsWith("<"))) { //$NON-NLS-1$
358
return false;
359         }
360         
361         int otherflags= member.getFlags();
362         
363         IType declaringType= member.getDeclaringType();
364         if (Flags.isPublic(otherflags) || Flags.isProtected(otherflags) || (declaringType != null && isInterfaceOrAnnotation(declaringType))) {
365             return true;
366         } else if (Flags.isPrivate(otherflags)) {
367             return false;
368         }
369         
370         IPackageFragment otherpack= (IPackageFragment) member.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
371         return (pack != null && pack.equals(otherpack));
372     }
373             
374         
375     /**
376      * Returns the package fragment root of <code>IJavaElement</code>. If the given
377      * element is already a package fragment root, the element itself is returned.
378      */

379     public static IPackageFragmentRoot getPackageFragmentRoot(IJavaElement element) {
380         return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
381     }
382     
383     /**
384      * Finds a method in a type.
385      * This searches for a method with the same name and signature. Parameter types are only
386      * compared by the simple name, no resolving for the fully qualified type name is done.
387      * Constructors are only compared by parameters, not the name.
388      * @param name The name of the method to find
389      * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
390      * @param isConstructor If the method is a constructor
391      * @return The first found method or <code>null</code>, if nothing found
392      */

393     public static IMethod findMethod(String JavaDoc name, String JavaDoc[] paramTypes, boolean isConstructor, IType type) throws JavaModelException {
394         IMethod[] methods= type.getMethods();
395         for (int i= 0; i < methods.length; i++) {
396             if (isSameMethodSignature(name, paramTypes, isConstructor, methods[i])) {
397                 return methods[i];
398             }
399         }
400         return null;
401     }
402                 
403     /**
404      * Finds a method in a type and all its super types. The super class hierarchy is searched first, then the super interfaces.
405      * This searches for a method with the same name and signature. Parameter types are only
406      * compared by the simple name, no resolving for the fully qualified type name is done.
407      * Constructors are only compared by parameters, not the name.
408      * NOTE: For finding overridden methods or for finding the declaring method, use {@link MethodOverrideTester}
409      * @param hierarchy The hierarchy containing the type
410      * @param type The type to start the search from
411      * @param name The name of the method to find
412      * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
413      * @param isConstructor If the method is a constructor
414      * @return The first found method or <code>null</code>, if nothing found
415      */

416     public static IMethod findMethodInHierarchy(ITypeHierarchy hierarchy, IType type, String JavaDoc name, String JavaDoc[] paramTypes, boolean isConstructor) throws JavaModelException {
417         IMethod method= findMethod(name, paramTypes, isConstructor, type);
418         if (method != null) {
419             return method;
420         }
421         IType superClass= hierarchy.getSuperclass(type);
422         if (superClass != null) {
423             IMethod res= findMethodInHierarchy(hierarchy, superClass, name, paramTypes, isConstructor);
424             if (res != null) {
425                 return res;
426             }
427         }
428         if (!isConstructor) {
429             IType[] superInterfaces= hierarchy.getSuperInterfaces(type);
430             for (int i= 0; i < superInterfaces.length; i++) {
431                 IMethod res= findMethodInHierarchy(hierarchy, superInterfaces[i], name, paramTypes, false);
432                 if (res != null) {
433                     return res;
434                 }
435             }
436         }
437         return method;
438     }
439         
440     
441     /**
442      * Tests if a method equals to the given signature.
443      * Parameter types are only compared by the simple name, no resolving for
444      * the fully qualified type name is done. Constructors are only compared by
445      * parameters, not the name.
446      * @param name Name of the method
447      * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
448      * @param isConstructor Specifies if the method is a constructor
449      * @return Returns <code>true</code> if the method has the given name and parameter types and constructor state.
450      */

451     public static boolean isSameMethodSignature(String JavaDoc name, String JavaDoc[] paramTypes, boolean isConstructor, IMethod curr) throws JavaModelException {
452         if (isConstructor || name.equals(curr.getElementName())) {
453             if (isConstructor == curr.isConstructor()) {
454                 String JavaDoc[] currParamTypes= curr.getParameterTypes();
455                 if (paramTypes.length == currParamTypes.length) {
456                     for (int i= 0; i < paramTypes.length; i++) {
457                         String JavaDoc t1= Signature.getSimpleName(Signature.toString(paramTypes[i]));
458                         String JavaDoc t2= Signature.getSimpleName(Signature.toString(currParamTypes[i]));
459                         if (!t1.equals(t2)) {
460                             return false;
461                         }
462                     }
463                     return true;
464                 }
465             }
466         }
467         return false;
468     }
469
470     /**
471      * Tests if two <code>IPackageFragment</code>s represent the same logical java package.
472      * @return <code>true</code> if the package fragments' names are equal.
473      */

474     public static boolean isSamePackage(IPackageFragment pack1, IPackageFragment pack2) {
475         return pack1.getElementName().equals(pack2.getElementName());
476     }
477     
478     /**
479      * Checks whether the given type has a valid main method or not.
480      */

481     public static boolean hasMainMethod(IType type) throws JavaModelException {
482         IMethod[] methods= type.getMethods();
483         for (int i= 0; i < methods.length; i++) {
484             if (methods[i].isMainMethod()) {
485                 return true;
486             }
487         }
488         return false;
489     }
490     
491     /**
492      * Checks if the field is boolean.
493      */

494     public static boolean isBoolean(IField field) throws JavaModelException{
495         return field.getTypeSignature().equals(Signature.SIG_BOOLEAN);
496     }
497     
498     /**
499      * @return <code>true</code> iff the type is an interface or an annotation
500      */

501     public static boolean isInterfaceOrAnnotation(IType type) throws JavaModelException {
502         return type.isInterface();
503     }
504         
505     /**
506      * Resolves a type name in the context of the declaring type.
507      *
508      * @param refTypeSig the type name in signature notation (for example 'QVector') this can also be an array type, but dimensions will be ignored.
509      * @param declaringType the context for resolving (type where the reference was made in)
510      * @return returns the fully qualified type name or build-in-type name. if a unresolved type couldn't be resolved null is returned
511      */

512     public static String JavaDoc getResolvedTypeName(String JavaDoc refTypeSig, IType declaringType) throws JavaModelException {
513         int arrayCount= Signature.getArrayCount(refTypeSig);
514         char type= refTypeSig.charAt(arrayCount);
515         if (type == Signature.C_UNRESOLVED) {
516             String JavaDoc name= ""; //$NON-NLS-1$
517
int bracket= refTypeSig.indexOf(Signature.C_GENERIC_START, arrayCount + 1);
518             if (bracket > 0)
519                 name= refTypeSig.substring(arrayCount + 1, bracket);
520             else {
521                 int semi= refTypeSig.indexOf(Signature.C_SEMICOLON, arrayCount + 1);
522                 if (semi == -1) {
523                     throw new IllegalArgumentException JavaDoc();
524                 }
525                 name= refTypeSig.substring(arrayCount + 1, semi);
526             }
527             String JavaDoc[][] resolvedNames= declaringType.resolveType(name);
528             if (resolvedNames != null && resolvedNames.length > 0) {
529                 return JavaModelUtil.concatenateName(resolvedNames[0][0], resolvedNames[0][1]);
530             }
531             return null;
532         } else {
533             return Signature.toString(refTypeSig.substring(arrayCount));
534         }
535     }
536     
537     /**
538      * Returns if a CU can be edited.
539      */

540     public static boolean isEditable(ICompilationUnit cu) {
541         Assert.isNotNull(cu);
542         IResource resource= cu.getPrimary().getResource();
543         return (resource.exists() && !resource.getResourceAttributes().isReadOnly());
544     }
545
546     /**
547      * Returns the original if the given member. If the member is already
548      * an original the input is returned. The returned member might not exist
549      *
550      * @deprecated Replace by IMember#getPrimaryElement() if <code>member</code> is not part
551      * of a shared working copy owner. Also have a look at http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568
552      */

553     public static IMember toOriginal(IMember member) {
554         if (member instanceof IMethod)
555             return toOriginalMethod((IMethod)member);
556
557         // TODO: remove toOriginalMethod(IMethod)
558

559         return (IMember) member.getPrimaryElement();
560         /*ICompilationUnit cu= member.getCompilationUnit();
561         if (cu != null && cu.isWorkingCopy())
562             return (IMember)cu.getOriginal(member);
563         return member;*/

564     }
565     
566     /*
567      * TODO remove if toOriginal(IMember) can be removed
568      * XXX workaround for bug 18568
569      * http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568
570      * to be removed once the bug is fixed
571      */

572     private static IMethod toOriginalMethod(IMethod method) {
573         ICompilationUnit cu= method.getCompilationUnit();
574         if (cu == null || isPrimary(cu)) {
575             return method;
576         }
577         try{
578             //use the workaround only if needed
579
if (! method.getElementName().equals(method.getDeclaringType().getElementName()))
580                 return (IMethod) method.getPrimaryElement();
581             
582             IType originalType = (IType) toOriginal(method.getDeclaringType());
583             IMethod[] methods = originalType.findMethods(method);
584             boolean isConstructor = method.isConstructor();
585             for (int i=0; i < methods.length; i++) {
586               if (methods[i].isConstructor() == isConstructor)
587                 return methods[i];
588             }
589             return null;
590         } catch (JavaModelException e){
591             return null;
592         }
593     }
594
595     /**
596      * Returns true if a cu is a primary cu (original or shared working copy)
597      */

598     public static boolean isPrimary(ICompilationUnit cu) {
599         return cu.getOwner() == null;
600     }
601
602     /*
603      * http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253
604      *
605      * Reconciling happens in a separate thread. This can cause a situation where the
606      * Java element gets disposed after an exists test has been done. So we should not
607      * log not present exceptions when they happen in working copies.
608      */

609     public static boolean isExceptionToBeLogged(CoreException exception) {
610         if (!(exception instanceof JavaModelException))
611             return true;
612         JavaModelException je= (JavaModelException)exception;
613         if (!je.isDoesNotExist())
614             return true;
615         IJavaElement[] elements= je.getJavaModelStatus().getElements();
616         for (int i= 0; i < elements.length; i++) {
617             IJavaElement element= elements[i];
618             // if the element is already a compilation unit don't log
619
// does not exist exceptions. See bug
620
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=75894
621
// for more details
622
if (element.getElementType() == IJavaElement.COMPILATION_UNIT)
623                 continue;
624             ICompilationUnit unit= (ICompilationUnit)element.getAncestor(IJavaElement.COMPILATION_UNIT);
625             if (unit == null)
626                 return true;
627             if (!unit.isWorkingCopy())
628                 return true;
629         }
630         return false;
631     }
632
633     public static IType[] getAllSuperTypes(IType type, IProgressMonitor pm) throws JavaModelException {
634         // workaround for 23656
635
IType[] superTypes= SuperTypeHierarchyCache.getTypeHierarchy(type).getAllSupertypes(type);
636         if (type.isInterface()) {
637             IType objekt= type.getJavaProject().findType("java.lang.Object");//$NON-NLS-1$
638
if (objekt != null) {
639                 IType[] superInterfacesAndObject= new IType[superTypes.length + 1];
640                 System.arraycopy(superTypes, 0, superInterfacesAndObject, 0, superTypes.length);
641                 superInterfacesAndObject[superTypes.length]= objekt;
642                 return superInterfacesAndObject;
643             }
644         }
645         return superTypes;
646     }
647     
648     public static boolean isSuperType(ITypeHierarchy hierarchy, IType possibleSuperType, IType type) {
649         // filed bug 112635 to add this method to ITypeHierarchy
650
IType superClass= hierarchy.getSuperclass(type);
651         if (superClass != null && (possibleSuperType.equals(superClass) || isSuperType(hierarchy, possibleSuperType, superClass))) {
652             return true;
653         }
654         if (Flags.isInterface(hierarchy.getCachedFlags(possibleSuperType))) {
655             IType[] superInterfaces= hierarchy.getSuperInterfaces(type);
656             for (int i= 0; i < superInterfaces.length; i++) {
657                 IType curr= superInterfaces[i];
658                 if (possibleSuperType.equals(curr) || isSuperType(hierarchy, possibleSuperType, curr)) {
659                     return true;
660                 }
661             }
662         }
663         return false;
664     }
665     
666     public static boolean isExcludedPath(IPath resourcePath, IPath[] exclusionPatterns) {
667         char[] path = resourcePath.toString().toCharArray();
668         for (int i = 0, length = exclusionPatterns.length; i < length; i++) {
669             char[] pattern= exclusionPatterns[i].toString().toCharArray();
670             if (CharOperation.pathMatch(pattern, path, true, '/')) {
671                 return true;
672             }
673         }
674         return false;
675     }
676
677
678     /*
679      * Returns whether the given resource path matches one of the exclusion
680      * patterns.
681      *
682      * @see IClasspathEntry#getExclusionPatterns
683      */

684     public final static boolean isExcluded(IPath resourcePath, char[][] exclusionPatterns) {
685         if (exclusionPatterns == null) return false;
686         char[] path = resourcePath.toString().toCharArray();
687         for (int i = 0, length = exclusionPatterns.length; i < length; i++)
688             if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/'))
689                 return true;
690         return false;
691     }
692         
693
694     /**
695      * Force a reconcile of a compilation unit.
696      * @param unit
697      */

698     public static void reconcile(ICompilationUnit unit) throws JavaModelException {
699         unit.reconcile(
700                 ICompilationUnit.NO_AST,
701                 false /* don't force problem detection */,
702                 null /* use primary owner */,
703                 null /* no progress monitor */);
704     }
705     
706     /**
707      * Helper method that tests if an classpath entry can be found in a
708      * container. <code>null</code> is returned if the entry can not be found
709      * or if the container does not allows the configuration of source
710      * attachments
711      * @param jproject The container's parent project
712      * @param containerPath The path of the container
713      * @param libPath The path of the library to be found
714      * @return IClasspathEntry A classpath entry from the container of
715      * <code>null</code> if the container can not be modified.
716      * @throws JavaModelException thrown if accessing the container failed
717      */

718     public static IClasspathEntry getClasspathEntryToEdit(IJavaProject jproject, IPath containerPath, IPath libPath) throws JavaModelException {
719         IClasspathContainer container= JavaCore.getClasspathContainer(containerPath, jproject);
720         ClasspathContainerInitializer initializer= JavaCore.getClasspathContainerInitializer(containerPath.segment(0));
721         if (container != null && initializer != null && initializer.canUpdateClasspathContainer(containerPath, jproject)) {
722             return findEntryInContainer(container, libPath);
723         }
724         return null; // attachment not possible
725
}
726     
727     /**
728      * Finds an entry in a container. <code>null</code> is returned if the entry can not be found
729      * @param container The container
730      * @param libPath The path of the library to be found
731      * @return IClasspathEntry A classpath entry from the container of
732      * <code>null</code> if the container can not be modified.
733      */

734     public static IClasspathEntry findEntryInContainer(IClasspathContainer container, IPath libPath) {
735         IClasspathEntry[] entries= container.getClasspathEntries();
736         for (int i= 0; i < entries.length; i++) {
737             IClasspathEntry curr= entries[i];
738             IClasspathEntry resolved= JavaCore.getResolvedClasspathEntry(curr);
739             if (resolved != null && libPath.equals(resolved.getPath())) {
740                 return curr; // return the real entry
741
}
742         }
743         return null; // attachment not possible
744
}
745     
746     /**
747      * Get all compilation units of a selection.
748      * @param javaElements the selected java elements
749      * @return all compilation units containing and contained in elements from javaElements
750      * @throws JavaModelException
751      */

752     public static ICompilationUnit[] getAllCompilationUnits(IJavaElement[] javaElements) throws JavaModelException {
753         HashSet JavaDoc result= new HashSet JavaDoc();
754         for (int i= 0; i < javaElements.length; i++) {
755             addAllCus(result, javaElements[i]);
756         }
757         return (ICompilationUnit[]) result.toArray(new ICompilationUnit[result.size()]);
758     }
759
760     private static void addAllCus(HashSet JavaDoc/*<ICompilationUnit>*/ collector, IJavaElement javaElement) throws JavaModelException {
761         switch (javaElement.getElementType()) {
762             case IJavaElement.JAVA_PROJECT:
763                 IJavaProject javaProject= (IJavaProject) javaElement;
764                 IPackageFragmentRoot[] packageFragmentRoots= javaProject.getPackageFragmentRoots();
765                 for (int i= 0; i < packageFragmentRoots.length; i++)
766                     addAllCus(collector, packageFragmentRoots[i]);
767                 return;
768         
769             case IJavaElement.PACKAGE_FRAGMENT_ROOT:
770                 IPackageFragmentRoot packageFragmentRoot= (IPackageFragmentRoot) javaElement;
771                 if (packageFragmentRoot.getKind() != IPackageFragmentRoot.K_SOURCE)
772                     return;
773                 IJavaElement[] packageFragments= packageFragmentRoot.getChildren();
774                 for (int j= 0; j < packageFragments.length; j++)
775                     addAllCus(collector, packageFragments[j]);
776                 return;
777         
778             case IJavaElement.PACKAGE_FRAGMENT:
779                 IPackageFragment packageFragment= (IPackageFragment) javaElement;
780                 collector.addAll(Arrays.asList(packageFragment.getCompilationUnits()));
781                 return;
782             
783             case IJavaElement.COMPILATION_UNIT:
784                 collector.add(javaElement);
785                 return;
786                 
787             default:
788                 IJavaElement cu= javaElement.getAncestor(IJavaElement.COMPILATION_UNIT);
789                 if (cu != null)
790                     collector.add(cu);
791         }
792     }
793
794     
795     /**
796      * Sets all compliance settings in the given map to 5.0
797      */

798     public static void set50CompilanceOptions(Map JavaDoc map) {
799         setCompilanceOptions(map, JavaCore.VERSION_1_5);
800     }
801     
802     public static void setCompilanceOptions(Map JavaDoc map, String JavaDoc compliance) {
803         if (JavaCore.VERSION_1_6.equals(compliance)) {
804             map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
805             map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
806             map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
807             map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
808             map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
809         } else if (JavaCore.VERSION_1_5.equals(compliance)) {
810             map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
811             map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
812             map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
813             map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
814             map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
815         } else if (JavaCore.VERSION_1_4.equals(compliance)) {
816             map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
817             map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
818             map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2);
819             map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.WARNING);
820             map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.WARNING);
821         } else if (JavaCore.VERSION_1_3.equals(compliance)) {
822             map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_3);
823             map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
824             map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1);
825             map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.IGNORE);
826             map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.IGNORE);
827         } else {
828             throw new IllegalArgumentException JavaDoc("Unsupported compliance: " + compliance); //$NON-NLS-1$
829
}
830     }
831     
832     public static void setDefaultClassfileOptions(Map JavaDoc map, String JavaDoc compliance) {
833         map.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, is50OrHigher(compliance) ? JavaCore.ENABLED : JavaCore.DISABLED);
834         map.put(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.GENERATE);
835         map.put(JavaCore.COMPILER_LINE_NUMBER_ATTR, JavaCore.GENERATE);
836         map.put(JavaCore.COMPILER_SOURCE_FILE_ATTR, JavaCore.GENERATE);
837         map.put(JavaCore.COMPILER_CODEGEN_UNUSED_LOCAL, JavaCore.PRESERVE);
838     }
839     
840     /**
841      * @return returns if version 1 is less than version 2.
842      */

843     public static boolean isVersionLessThan(String JavaDoc version1, String JavaDoc version2) {
844         return version1.compareTo(version2) < 0;
845     }
846     
847     public static boolean is50OrHigher(String JavaDoc compliance) {
848         return !isVersionLessThan(compliance, JavaCore.VERSION_1_5);
849     }
850     
851     public static boolean is50OrHigher(IJavaProject project) {
852         return is50OrHigher(project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
853     }
854     
855     public static boolean is50OrHigherJRE(IJavaProject project) throws CoreException {
856         IVMInstall vmInstall= JavaRuntime.getVMInstall(project);
857         if (!(vmInstall instanceof IVMInstall2))
858             return true; // assume 5.0.
859

860         String JavaDoc compliance= getCompilerCompliance((IVMInstall2) vmInstall, null);
861         if (compliance == null)
862             return true; // assume 5.0
863
return compliance.startsWith(JavaCore.VERSION_1_5) || compliance.startsWith(JavaCore.VERSION_1_6);
864     }
865     
866     public static String JavaDoc getCompilerCompliance(IVMInstall2 vMInstall, String JavaDoc defaultCompliance) {
867         String JavaDoc version= vMInstall.getJavaVersion();
868         if (version == null) {
869             return defaultCompliance;
870         } else if (version.startsWith(JavaCore.VERSION_1_6)) {
871             return JavaCore.VERSION_1_6;
872         } else if (version.startsWith(JavaCore.VERSION_1_5)) {
873             return JavaCore.VERSION_1_5;
874         } else if (version.startsWith(JavaCore.VERSION_1_4)) {
875             return JavaCore.VERSION_1_4;
876         } else if (version.startsWith(JavaCore.VERSION_1_3)) {
877             return JavaCore.VERSION_1_3;
878         } else if (version.startsWith(JavaCore.VERSION_1_2)) {
879             return JavaCore.VERSION_1_3;
880         } else if (version.startsWith(JavaCore.VERSION_1_1)) {
881             return JavaCore.VERSION_1_3;
882         }
883         return defaultCompliance;
884     }
885     
886     public static String JavaDoc getExecutionEnvironmentCompliance(IExecutionEnvironment executionEnvironment) {
887         String JavaDoc desc= executionEnvironment.getId();
888         if (desc.indexOf("1.6") != -1) { //$NON-NLS-1$
889
return JavaCore.VERSION_1_6;
890         } else if (desc.indexOf("1.5") != -1) { //$NON-NLS-1$
891
return JavaCore.VERSION_1_5;
892         } else if (desc.indexOf("1.4") != -1) { //$NON-NLS-1$
893
return JavaCore.VERSION_1_4;
894         }
895         return JavaCore.VERSION_1_3;
896     }
897
898     /**
899      * Compute a new name for a compilation unit, given the name of the new main type.
900      * This query tries to maintain the existing extension (e.g. ".java").
901      *
902      * @param cu a compilation unit
903      * @param newMainName the new name of the cu's main type (without extension)
904      * @return the new name for the compilation unit
905      */

906     public static String JavaDoc getRenamedCUName(ICompilationUnit cu, String JavaDoc newMainName) {
907         String JavaDoc oldName = cu.getElementName();
908         int i = oldName.lastIndexOf('.');
909         if (i != -1) {
910             return newMainName + oldName.substring(i);
911         } else {
912             return newMainName;
913         }
914     }
915     
916     /**
917      * Applies an text edit to a compilation unit. Filed bug 117694 against jdt.core.
918      * @param cu the compilation unit to apply the edit to
919      * @param edit the edit to apply
920      * @param save is set, save the CU after the edit has been applied
921      * @param monitor the progress monitor to use
922      * @throws CoreException Thrown when the access to the CU failed
923      * @throws ValidateEditException if validate edit fails
924      */

925     public static void applyEdit(ICompilationUnit cu, TextEdit edit, boolean save, IProgressMonitor monitor) throws CoreException, ValidateEditException {
926         if (monitor == null) {
927             monitor= new NullProgressMonitor();
928         }
929         monitor.beginTask(CorextMessages.JavaModelUtil_applyedit_operation, 3);
930
931         try {
932             IDocument document= null;
933             try {
934                 document= aquireDocument(cu, new SubProgressMonitor(monitor, 1));
935                 if (save) {
936                     commitDocument(cu, document, edit, new SubProgressMonitor(monitor, 1));
937                 } else {
938                     new RewriteSessionEditProcessor(document, edit, TextEdit.UPDATE_REGIONS).performEdits();
939                 }
940             } catch (BadLocationException e) {
941                 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
942             } finally {
943                 releaseDocument(cu, document, new SubProgressMonitor(monitor, 1));
944             }
945         } finally {
946             monitor.done();
947         }
948     }
949
950     private static IDocument aquireDocument(ICompilationUnit cu, IProgressMonitor monitor) throws CoreException {
951         if (JavaModelUtil.isPrimary(cu)) {
952             IFile file= (IFile) cu.getResource();
953             if (file.exists()) {
954                 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager();
955                 IPath path= cu.getPath();
956                 bufferManager.connect(path, LocationKind.IFILE, monitor);
957                 return bufferManager.getTextFileBuffer(path, LocationKind.IFILE).getDocument();
958             }
959         }
960         monitor.done();
961         return new Document(cu.getSource());
962     }
963     
964     private static void commitDocument(ICompilationUnit cu, IDocument document, TextEdit edit, IProgressMonitor monitor) throws CoreException, MalformedTreeException, BadLocationException {
965         if (JavaModelUtil.isPrimary(cu)) {
966             IFile file= (IFile) cu.getResource();
967             if (file.exists()) {
968                 IStatus status= Resources.makeCommittable(file, null);
969                 if (!status.isOK()) {
970                     throw new ValidateEditException(status);
971                 }
972                 new RewriteSessionEditProcessor(document, edit, TextEdit.UPDATE_REGIONS).performEdits(); // apply after file is commitable
973

974                 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager();
975                 bufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE).commit(monitor, true);
976                 return;
977             }
978         }
979         // no commit possible, make sure changes are in
980
new RewriteSessionEditProcessor(document, edit, TextEdit.UPDATE_REGIONS).performEdits();
981     }
982
983     
984     private static void releaseDocument(ICompilationUnit cu, IDocument document, IProgressMonitor monitor) throws CoreException {
985         if (JavaModelUtil.isPrimary(cu)) {
986             IFile file= (IFile) cu.getResource();
987             if (file.exists()) {
988                 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager();
989                 bufferManager.disconnect(file.getFullPath(), LocationKind.IFILE, monitor);
990                 return;
991             }
992         }
993         cu.getBuffer().setContents(document.get());
994         monitor.done();
995     }
996     
997     public static boolean isImplicitImport(String JavaDoc qualifier, ICompilationUnit cu) {
998         if ("java.lang".equals(qualifier)) { //$NON-NLS-1$
999
return true;
1000        }
1001        String JavaDoc packageName= cu.getParent().getElementName();
1002        if (qualifier.equals(packageName)) {
1003            return true;
1004        }
1005        String JavaDoc typeName= JavaCore.removeJavaLikeExtension(cu.getElementName());
1006        String JavaDoc mainTypeName= JavaModelUtil.concatenateName(packageName, typeName);
1007        return qualifier.equals(mainTypeName);
1008    }
1009
1010    public static boolean isOpenableStorage(Object JavaDoc storage) {
1011        if (storage instanceof IJarEntryResource) {
1012            return ((IJarEntryResource) storage).isFile();
1013        } else {
1014            return storage instanceof IStorage;
1015        }
1016    }
1017    
1018    /**
1019     * Returns true iff the given local variable is a parameter of its
1020     * declaring method.
1021     *
1022     * TODO replace this method with new API when available:
1023     * https://bugs.eclipse.org/bugs/show_bug.cgi?id=48420
1024     * @param currentLocal the local variable to test
1025     *
1026     * @return returns true if the variable is a parameter
1027     * @throws JavaModelException
1028     */

1029    public static boolean isParameter(ILocalVariable currentLocal) throws JavaModelException {
1030
1031        final IJavaElement parent= currentLocal.getParent();
1032        if (parent instanceof IMethod) {
1033            final String JavaDoc[] params= ((IMethod) parent).getParameterNames();
1034            for (int i= 0; i < params.length; i++) {
1035                if (params[i].equals(currentLocal.getElementName()))
1036                    return true;
1037            }
1038        }
1039        return false;
1040    }
1041    
1042}
1043
Popular Tags