a2e6fccbcae2c8c559cda2995484f57d90069f6a
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / util / JavaModelUtil.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.corext.util;
12
13 import java.util.StringTokenizer;
14
15 import net.sourceforge.phpdt.core.Flags;
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IField;
18 import net.sourceforge.phpdt.core.IJavaElement;
19 import net.sourceforge.phpdt.core.IMember;
20 import net.sourceforge.phpdt.core.IMethod;
21 import net.sourceforge.phpdt.core.IPackageFragment;
22 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
23 import net.sourceforge.phpdt.core.IType;
24 import net.sourceforge.phpdt.core.JavaModelException;
25 import net.sourceforge.phpdt.core.Signature;
26 import net.sourceforge.phpdt.core.compiler.CharOperation;
27 import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
28
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.core.runtime.IPath;
32
33
34
35 /**
36  * Utility methods for the Java Model.
37  */
38 public class JavaModelUtil {
39         
40         /** 
41          * Finds a type by its qualified type name (dot separated).
42          * @param jproject The java project to search in
43          * @param str The fully qualified name (type name with enclosing type names and package (all separated by dots))
44          * @return The type found, or null if not existing
45          */     
46 //      public static IType findType(IJavaProject jproject, String fullyQualifiedName) throws JavaModelException {
47 //              //workaround for bug 22883
48 //              IType type= jproject.findType(fullyQualifiedName);
49 //              if (type != null)
50 //                      return type;
51 //              IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
52 //              for (int i= 0; i < roots.length; i++) {
53 //                      IPackageFragmentRoot root= roots[i];
54 //                      type= findType(root, fullyQualifiedName);
55 //                      if (type != null && type.exists())
56 //                              return type;
57 //              }       
58 //              return null;
59 //      }
60         
61         /**
62          * Returns <code>true</code> if the given package fragment root is
63          * referenced. This means it is own by a different project but is referenced
64          * by the root's parent. Returns <code>false</code> if the given root
65          * doesn't have an underlying resource.
66          */
67         public static boolean isReferenced(IPackageFragmentRoot root) {
68 //              IResource resource= root.getResource();
69 //              if (resource != null) {
70 //                      IProject jarProject= resource.getProject();
71 //                      IProject container= root.getJavaProject().getProject();
72 //                      return !container.equals(jarProject);
73 //              }
74                 return false;
75         }
76         
77 //      private static IType findType(IPackageFragmentRoot root, String fullyQualifiedName) throws JavaModelException{
78 //              IJavaElement[] children= root.getChildren();
79 //              for (int i= 0; i < children.length; i++) {
80 //                      IJavaElement element= children[i];
81 //                      if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT){
82 //                              IPackageFragment pack= (IPackageFragment)element;
83 //                              if (! fullyQualifiedName.startsWith(pack.getElementName()))
84 //                                      continue;
85 //                              IType type= findType(pack, fullyQualifiedName);
86 //                              if (type != null && type.exists())
87 //                                      return type;
88 //                      }
89 //              }               
90 //              return null;
91 //      }
92         
93 //      private static IType findType(IPackageFragment pack, String fullyQualifiedName) throws JavaModelException{
94 //              ICompilationUnit[] cus= pack.getCompilationUnits();
95 //              for (int i= 0; i < cus.length; i++) {
96 //                      ICompilationUnit unit= cus[i];
97 //                      ICompilationUnit wc= WorkingCopyUtil.getWorkingCopyIfExists(unit);
98 //                      IType type= findType(wc, fullyQualifiedName);
99 //                      if (type != null && type.exists())
100 //                              return type;
101 //              }
102 //              return null;
103 //      }
104         
105 //      private static IType findType(ICompilationUnit cu, String fullyQualifiedName) throws JavaModelException{
106 //              IType[] types= cu.getAllTypes();
107 //              for (int i= 0; i < types.length; i++) {
108 //                      IType type= types[i];
109 //                      if (getFullyQualifiedName(type).equals(fullyQualifiedName))
110 //                              return type;
111 //              }
112 //              return null;
113 //      }
114         
115         /** 
116          * Finds a type by package and type name.
117          * @param jproject the java project to search in
118          * @param pack The package name
119          * @param typeQualifiedName the type qualified name (type name with enclosing type names (separated by dots))
120          * @return the type found, or null if not existing
121          * @deprecated Use IJavaProject.findType(String, String) instead
122          */     
123 //      public static IType findType(IJavaProject jproject, String pack, String typeQualifiedName) throws JavaModelException {
124 //              return jproject.findType(pack, typeQualifiedName);
125 //      }
126
127         /**
128          * Finds a type container by container name.
129          * The returned element will be of type <code>IType</code> or a <code>IPackageFragment</code>.
130          * <code>null</code> is returned if the type container could not be found.
131          * @param jproject The Java project defining the context to search
132          * @param typeContainerName A dot separarted name of the type container
133          * @see #getTypeContainerName(IType)
134          */
135 //      public static IJavaElement findTypeContainer(IJavaProject jproject, String typeContainerName) throws JavaModelException {
136 //              // try to find it as type
137 //              IJavaElement result= jproject.findType(typeContainerName);
138 //              if (result == null) {
139 //                      // find it as package
140 //                      IPath path= new Path(typeContainerName.replace('.', '/'));
141 //                      result= jproject.findElement(path);
142 //                      if (!(result instanceof IPackageFragment)) {
143 //                              result= null;
144 //                      }
145 //                      
146 //              }
147 //              return result;
148 //      }       
149         
150         /** 
151          * Finds a type in a compilation unit. Typical usage is to find the corresponding
152          * type in a working copy.
153          * @param cu the compilation unit to search in
154          * @param typeQualifiedName the type qualified name (type name with enclosing type names (separated by dots))
155          * @return the type found, or null if not existing
156          */             
157         public static IType findTypeInCompilationUnit(ICompilationUnit cu, String typeQualifiedName) throws JavaModelException {
158                 IType[] types= cu.getAllTypes();
159                 for (int i= 0; i < types.length; i++) {
160                         String currName= getTypeQualifiedName(types[i]);
161                         if (typeQualifiedName.equals(currName)) {
162                                 return types[i];
163                         }
164                 }
165                 return null;
166         }
167                 
168         /** 
169          * Finds a a member in a compilation unit. Typical usage is to find the corresponding
170          * member in a working copy.
171          * @param cu the compilation unit (eg. working copy) to search in
172          * @param member the member (eg. from the original)
173          * @return the member found, or null if not existing
174          */             
175         public static IMember findMemberInCompilationUnit(ICompilationUnit cu, IMember member) throws JavaModelException {
176                 IJavaElement[] elements= cu.findElements(member);
177                 if (elements != null && elements.length > 0) {
178                         return (IMember) elements[0];
179                 }
180                 return null;
181         }
182         
183         
184         /** 
185          * Returns the element of the given compilation unit which is "equal" to the
186          * given element. Note that the given element usually has a parent different
187          * from the given compilation unit.
188          * 
189          * @param cu the cu to search in
190          * @param element the element to look for
191          * @return an element of the given cu "equal" to the given element
192          */             
193         public static IJavaElement findInCompilationUnit(ICompilationUnit cu, IJavaElement element) throws JavaModelException {
194                 IJavaElement[] elements= cu.findElements(element);
195                 if (elements != null && elements.length > 0) {
196                         return elements[0];
197                 }
198                 return null;
199         }
200         
201         /**
202          * Returns the qualified type name of the given type using '.' as separators.
203          * This is a replace for IType.getTypeQualifiedName()
204          * which uses '$' as separators. As '$' is also a valid character in an id
205          * this is ambiguous. JavaCore PR: 1GCFUNT
206          */
207         public static String getTypeQualifiedName(IType type) {
208                 return type.getTypeQualifiedName('.');
209         }
210         
211         private static void getTypeQualifiedName(IType type, StringBuffer buf) {
212                 IType outerType= type.getDeclaringType();
213                 if (outerType != null) {
214                         getTypeQualifiedName(outerType, buf);
215                         buf.append('.');
216                 }
217                 buf.append(type.getElementName());
218         }       
219
220         /**
221          * Returns the fully qualified name of the given type using '.' as separators.
222          * This is a replace for IType.getFullyQualifiedTypeName
223          * which uses '$' as separators. As '$' is also a valid character in an id
224          * this is ambiguous. JavaCore PR: 1GCFUNT
225          */
226         public static String getFullyQualifiedName(IType type) {
227                 return type.getFullyQualifiedName('.');
228         }
229         
230         /**
231          * Returns the fully qualified name of a type's container. (package name or enclosing type name)
232          */
233         public static String getTypeContainerName(IType type) {
234                 IType outerType= type.getDeclaringType();
235                 if (outerType != null) {
236                         return outerType.getFullyQualifiedName('.');
237                 } else {
238                         return type.getPackageFragment().getElementName();
239                 }
240         }
241         
242         
243         /**
244          * Concatenates two names. Uses a dot for separation.
245          * Both strings can be empty or <code>null</code>.
246          */
247         public static String concatenateName(String name1, String name2) {
248                 StringBuffer buf= new StringBuffer();
249                 if (name1 != null && name1.length() > 0) {
250                         buf.append(name1);
251                 }
252                 if (name2 != null && name2.length() > 0) {
253                         if (buf.length() > 0) {
254                                 buf.append('.');
255                         }
256                         buf.append(name2);
257                 }               
258                 return buf.toString();
259         }
260         
261         /**
262          * Concatenates two names. Uses a dot for separation.
263          * Both strings can be empty or <code>null</code>.
264          */
265         public static String concatenateName(char[] name1, char[] name2) {
266                 StringBuffer buf= new StringBuffer();
267                 if (name1 != null && name1.length > 0) {
268                         buf.append(name1);
269                 }
270                 if (name2 != null && name2.length > 0) {
271                         if (buf.length() > 0) {
272                                 buf.append('.');
273                         }
274                         buf.append(name2);
275                 }               
276                 return buf.toString();
277         }       
278         
279         /**
280          * Evaluates if a member (possible from another package) is visible from
281          * elements in a package.
282          * @param member The member to test the visibility for
283          * @param pack The package in focus
284          */
285         public static boolean isVisible(IMember member, IPackageFragment pack) throws JavaModelException {
286                 int otherflags= member.getFlags();
287                 
288                 if (Flags.isPublic(otherflags)) {
289                         return true;
290                 } else if (Flags.isPrivate(otherflags)) {
291                         return false;
292                 }               
293                 
294                 IPackageFragment otherpack= (IPackageFragment) findParentOfKind(member, IJavaElement.PACKAGE_FRAGMENT);
295                 return (pack != null && pack.equals(otherpack));
296         }
297                 
298         /**
299          * Returns the package fragment root of <code>IJavaElement</code>. If the given
300          * element is already a package fragment root, the element itself is returned.
301          */
302         public static IPackageFragmentRoot getPackageFragmentRoot(IJavaElement element) {
303                 return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
304         }
305
306         /**
307          * Returns the parent of the supplied java element that conforms to the given 
308          * parent type or <code>null</code>, if such a parent doesn't exit.
309          * @deprecated Use element.getParent().getAncestor(kind);
310          */
311         public static IJavaElement findParentOfKind(IJavaElement element, int kind) {
312                 if (element != null && element.getParent() != null) {
313                         return element.getParent().getAncestor(kind);
314                 }
315                 return null;
316         }
317         
318         /**
319          * Finds a method in a type.
320          * This searches for a method with the same name and signature. Parameter types are only
321          * compared by the simple name, no resolving for the fully qualified type name is done.
322          * Constructors are only compared by parameters, not the name.
323          * @param name The name of the method to find
324          * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
325          * @param isConstructor If the method is a constructor
326          * @return The first found method or <code>null</code>, if nothing found
327          */
328         public static IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IType type) throws JavaModelException {
329                 return findMethod(name, paramTypes, isConstructor, type.getMethods());
330         }
331
332         /**
333          * Finds a method by name.
334          * This searches for a method with a name and signature. Parameter types are only
335          * compared by the simple name, no resolving for the fully qualified type name is done.
336          * Constructors are only compared by parameters, not the name.
337          * @param name The name of the method to find
338          * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
339          * @param isConstructor If the method is a constructor
340          * @param methods The methods to search in
341          * @return The found method or <code>null</code>, if nothing found
342          */
343         public static IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IMethod[] methods) throws JavaModelException {
344                 for (int i= methods.length - 1; i >= 0; i--) {
345                         if (isSameMethodSignature(name, paramTypes, isConstructor, methods[i])) {
346                                 return methods[i];
347                         }
348                 }
349                 return null;
350         }
351         
352
353         /**
354          * Finds a method declararion in a type's hierarchy. The search is top down, so this
355          * returns the first declaration of the method in the hierarchy.
356          * This searches for a method with a name and signature. Parameter types are only
357          * compared by the simple name, no resolving for the fully qualified type name is done.
358          * Constructors are only compared by parameters, not the name.
359          * @param type Searches in this type's supertypes.
360          * @param name The name of the method to find
361          * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
362          * @param isConstructor If the method is a constructor
363          * @return The first method found or null, if nothing found
364          */
365 //      public static IMethod findMethodDeclarationInHierarchy(ITypeHierarchy hierarchy, IType type, String name, String[] paramTypes, boolean isConstructor) throws JavaModelException {
366 //              IType[] superTypes= hierarchy.getAllSupertypes(type);
367 //              for (int i= superTypes.length - 1; i >= 0; i--) {
368 //                      IMethod first= findMethod(name, paramTypes, isConstructor, superTypes[i]);
369 //                      if (first != null && !Flags.isPrivate(first.getFlags())) {
370 //                              // the order getAllSupertypes does make assumptions of the order of inner elements -> search recursivly
371 //                              IMethod res= findMethodDeclarationInHierarchy(hierarchy, first.getDeclaringType(), name, paramTypes, isConstructor);
372 //                              if (res != null) {
373 //                                      return res;
374 //                              }
375 //                              return first;
376 //                      }
377 //              }
378 //              return null;
379 //      }
380         
381         /**
382          * Finds a method implementation in a type's classhierarchy. The search is bottom-up, so this
383          * returns the nearest overridden method. Does not find methods in interfaces or abstract methods.
384          * This searches for a method with a name and signature. Parameter types are only
385          * compared by the simple name, no resolving for the fully qualified type name is done.
386          * Constructors are only compared by parameters, not the name.
387          * @param type Type to search the superclasses
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 method found or null, if nothing found
392          */
393 //      public static IMethod findMethodImplementationInHierarchy(ITypeHierarchy hierarchy, IType type, String name, String[] paramTypes, boolean isConstructor) throws JavaModelException {
394 //              IType[] superTypes= hierarchy.getAllSuperclasses(type);
395 //              for (int i= 0; i < superTypes.length; i++) {
396 //                      IMethod found= findMethod(name, paramTypes, isConstructor, superTypes[i]);
397 //                      if (found != null) {
398 //                              if (Flags.isAbstract(found.getFlags())) {
399 //                                      return null;
400 //                              }
401 //                              return found;
402 //                      }
403 //              }
404 //              return null;
405 //      }       
406         
407         /**
408          * Tests if a method equals to the given signature.
409          * Parameter types are only compared by the simple name, no resolving for
410          * the fully qualified type name is done. Constructors are only compared by
411          * parameters, not the name.
412          * @param Name of the method
413          * @param The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
414          * @param Specifies if the method is a constructor
415          * @return Returns <code>true</code> if the method has the given name and parameter types and constructor state.
416          */
417         public static boolean isSameMethodSignature(String name, String[] paramTypes, boolean isConstructor, IMethod curr) throws JavaModelException {
418                 if (isConstructor || name.equals(curr.getElementName())) {
419                         if (isConstructor == curr.isConstructor()) {
420                                 String[] currParamTypes= curr.getParameterTypes();
421                                 if (paramTypes.length == currParamTypes.length) {
422                                         for (int i= 0; i < paramTypes.length; i++) {
423                                                 String t1= Signature.getSimpleName(Signature.toString(paramTypes[i]));
424                                                 String t2= Signature.getSimpleName(Signature.toString(currParamTypes[i]));
425                                                 if (!t1.equals(t2)) {
426                                                         return false;
427                                                 }
428                                         }
429                                         return true;
430                                 }
431                         }
432                 }
433                 return false;
434         }
435         
436         /**
437          * Checks whether the given type has a valid main method or not.
438          */
439         public static boolean hasMainMethod(IType type) throws JavaModelException {
440                 IMethod[] methods= type.getMethods();
441                 for (int i= 0; i < methods.length; i++) {
442                         if (methods[i].isMainMethod()) {
443                                 return true;
444                         }
445                 }
446                 return false;
447         }
448         
449         /**
450          * Checks if the field is boolean.
451          */
452         public static boolean isBoolean(IField field) throws JavaModelException{
453                 return field.getTypeSignature().equals(Signature.SIG_BOOLEAN);
454         }
455         
456         /**
457          * Returns true if the element is on the build path of the given project
458          * @deprecated Use jproject.isOnClasspath(element);
459          */     
460 //      public static boolean isOnBuildPath(IJavaProject jproject, IJavaElement element) throws JavaModelException {
461 //              return jproject.isOnClasspath(element);
462 //      }
463         
464         /**
465          * Tests if the given element is on the class path of its containing project. Handles the case
466          * that the containing project isn't a Java project.
467          */
468 //      public static boolean isOnClasspath(IJavaElement element) {
469 //              IJavaProject project= element.getJavaProject();
470 //              if (!project.exists())
471 //                      return false;
472 //              return project.isOnClasspath(element);
473 //      }
474
475         /**
476          * Resolves a type name in the context of the declaring type.
477          * @param refTypeSig the type name in signature notation (for example 'QVector')
478          *                   this can also be an array type, but dimensions will be ignored.
479          * @param declaringType the context for resolving (type where the reference was made in)
480          * @return returns the fully qualified type name or build-in-type name. 
481          *                      if a unresoved type couldn't be resolved null is returned
482          */
483         public static String getResolvedTypeName(String refTypeSig, IType declaringType) throws JavaModelException {
484                 int arrayCount= Signature.getArrayCount(refTypeSig);
485                 char type= refTypeSig.charAt(arrayCount);
486                 if (type == Signature.C_UNRESOLVED) {
487                         int semi= refTypeSig.indexOf(Signature.C_SEMICOLON, arrayCount + 1);
488                         if (semi == -1) {
489                                 throw new IllegalArgumentException();
490                         }
491                         String name= refTypeSig.substring(arrayCount + 1, semi);                                
492                         
493 //                      String[][] resolvedNames= declaringType.resolveType(name);
494 //                      if (resolvedNames != null && resolvedNames.length > 0) {
495 //                              return JavaModelUtil.concatenateName(resolvedNames[0][0], resolvedNames[0][1]);
496 //                      }
497                         return null;
498                 } else {
499                         return Signature.toString(refTypeSig.substring(arrayCount));
500                 }
501         }
502         
503         /**
504          * Returns if a CU can be edited.
505          */
506         public static boolean isEditable(ICompilationUnit cu)  {
507                 if (cu.isWorkingCopy()) {
508                         cu= (ICompilationUnit) cu.getOriginalElement();
509                 }
510                 IResource resource= cu.getResource();
511                 return (resource.exists() && !resource.isReadOnly());
512         }
513
514         /**
515          * Finds a qualified import for a type name.
516          */     
517 //      public static IImportDeclaration findImport(ICompilationUnit cu, String simpleName) throws JavaModelException {
518 //              IImportDeclaration[] existing= cu.getImports();
519 //              for (int i= 0; i < existing.length; i++) {
520 //                      String curr= existing[i].getElementName();
521 //                      if (curr.endsWith(simpleName)) {
522 //                              int dotPos= curr.length() - simpleName.length() - 1;
523 //                              if ((dotPos == -1) || (dotPos > 0 && curr.charAt(dotPos) == '.')) {
524 //                                      return existing[i];
525 //                              }
526 //                      }
527 //              }       
528 //              return null;
529 //      }
530         
531         /**
532          * Returns the original if the given member. If the member is already
533          * an original the input is returned. The returned member must not exist
534          */
535         public static IMember toOriginal(IMember member) {
536                 if (member instanceof IMethod)
537                         return toOriginalMethod((IMethod)member);
538                 ICompilationUnit cu= member.getCompilationUnit();
539                 if (cu != null && cu.isWorkingCopy())
540                         return (IMember)cu.getOriginal(member);
541                 return member;
542         }
543         
544         /*
545          * XXX workaround for bug 18568
546          * http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568
547          * to be removed once the bug is fixed
548          */
549         private static IMethod toOriginalMethod(IMethod method) {
550                 try{
551                         ICompilationUnit cu= method.getCompilationUnit();
552                         if (cu == null || ! cu.isWorkingCopy())
553                                 return method;
554                         //use the workaround only if needed     
555                         if (! method.getElementName().equals(method.getDeclaringType().getElementName()))
556                                 return (IMethod)cu.getOriginal(method);
557                         
558                         IType originalType = (IType)toOriginal(method.getDeclaringType());
559                         IMethod[] methods = originalType.findMethods(method);
560                         boolean isConstructor = method.isConstructor();
561                         for (int i=0; i < methods.length; i++) {
562                           if (methods[i].isConstructor() == isConstructor) 
563                                 return methods[i];
564                         }
565                         return null;
566                 } catch(JavaModelException e){
567                         return null;
568                 }       
569         }
570
571         /**
572          * Returns the original cu if the given cu. If the cu is already
573          * an original the input cu is returned. The returned cu must not exist
574          */
575         public static ICompilationUnit toOriginal(ICompilationUnit cu) {
576                 if (cu != null && cu.isWorkingCopy())
577                         return (ICompilationUnit) cu.getOriginal(cu);
578                 return cu;
579         }       
580         
581         /**
582          * Returns the working copy of the given member. If the member is already in a
583          * working copy or the member does not exist in the working copy the input is returned.
584          */
585         public static IMember toWorkingCopy(IMember member) {
586                 ICompilationUnit cu= member.getCompilationUnit();
587                 if (cu != null && !cu.isWorkingCopy()) {
588                         ICompilationUnit workingCopy= EditorUtility.getWorkingCopy(cu);
589                         if (workingCopy != null) {
590                                 IJavaElement[] members= workingCopy.findElements(member);
591                                 if (members != null && members.length > 0) {
592                                         return (IMember) members[0];
593                                 }
594                         }
595                 }
596                 return member;
597         }
598
599
600         /**
601          * Returns the working copy CU of the given CU. If the CU is already a
602          * working copy or the CU has no working copy the input CU is returned.
603          */     
604         public static ICompilationUnit toWorkingCopy(ICompilationUnit cu) {
605                 if (!cu.isWorkingCopy()) {
606                         ICompilationUnit workingCopy= EditorUtility.getWorkingCopy(cu);
607                         if (workingCopy != null) {
608                                 return workingCopy;
609                         }
610                 }
611                 return cu;
612         }
613         
614         /*
615          * http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253
616          * 
617          * Reconciling happens in a separate thread. This can cause a situation where the
618          * Java element gets disposed after an exists test has been done. So we should not
619          * log not present exceptions when they happen in working copies.
620          */
621         public static boolean filterNotPresentException(CoreException exception) {
622                 if (!(exception instanceof JavaModelException))
623                         return true;
624                 JavaModelException je= (JavaModelException)exception;
625                 if (!je.isDoesNotExist())
626                         return true;
627                 IJavaElement[] elements= je.getJavaModelStatus().getElements();
628                 for (int i= 0; i < elements.length; i++) {
629                         IJavaElement element= elements[i];
630                         ICompilationUnit unit= (ICompilationUnit)element.getAncestor(IJavaElement.COMPILATION_UNIT);
631                         if (unit == null)
632                                 return true;
633                         if (!unit.isWorkingCopy())
634                                 return true;
635                 }
636                 return false;           
637         }
638
639 //      public static IType[] getAllSuperTypes(IType type, IProgressMonitor pm) throws JavaModelException {
640 //              //workaround for bugs 23644 and 23656
641 //              try{
642 //                      pm.beginTask("", 3); //$NON-NLS-1$
643 //                      ITypeHierarchy hierarchy= type.newSupertypeHierarchy(new SubProgressMonitor(pm, 1));
644 //                      
645 //                      IProgressMonitor subPm= new SubProgressMonitor(pm, 2);
646 //                      List typeList= Arrays.asList(hierarchy.getAllSupertypes(type));
647 //                      subPm.beginTask("", typeList.size()); //$NON-NLS-1$
648 //                      Set types= new HashSet(typeList);
649 //                      for (Iterator iter= typeList.iterator(); iter.hasNext();) {
650 //                              IType superType= (IType)iter.next();
651 //                              IType[] superTypes= getAllSuperTypes(superType, new SubProgressMonitor(subPm, 1));
652 //                              types.addAll(Arrays.asList(superTypes));
653 //                      }
654 //                      types.add(type.getJavaProject().findType("java.lang.Object"));//$NON-NLS-1$
655 //                      subPm.done();
656 //                      return (IType[]) types.toArray(new IType[types.size()]);
657 //              } finally {
658 //                      pm.done();
659 //              }       
660 //      }
661         
662         
663         public static boolean isExcludedPath(IPath resourcePath, IPath[] exclusionPatterns) {
664                 char[] path = resourcePath.toString().toCharArray();
665                 for (int i = 0, length = exclusionPatterns.length; i < length; i++) {
666                         char[] pattern= exclusionPatterns[i].toString().toCharArray();
667                         if (CharOperation.pathMatch(pattern, path, true, '/')) {
668                                 return true;
669                         }
670                 }
671                 return false;   
672         }
673
674
675         /*
676          * Returns whether the given resource path matches one of the exclusion
677          * patterns.
678          * 
679          * @see IClasspathEntry#getExclusionPatterns
680          */
681         public final static boolean isExcluded(IPath resourcePath, char[][] exclusionPatterns) {
682                 if (exclusionPatterns == null) return false;
683                 char[] path = resourcePath.toString().toCharArray();
684                 for (int i = 0, length = exclusionPatterns.length; i < length; i++)
685                         if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/'))
686                                 return true;
687                 return false;
688         }       
689         
690
691         private static final String ARGUMENTS_DELIMITER = "#"; //$NON-NLS-1$
692         private static final String EMPTY_ARGUMENT = "   "; //$NON-NLS-1$
693         
694         /**
695          * Copied from org.eclipse.jdt.internal.core.Util;
696          */
697         public static String[] getProblemArgumentsFromMarker(String argumentsString){
698                 if (argumentsString == null) return null;
699                 int index = argumentsString.indexOf(':');
700                 if(index == -1)
701                         return null;
702                 
703                 int length = argumentsString.length();
704                 int numberOfArg;
705                 try{
706                         numberOfArg = Integer.parseInt(argumentsString.substring(0 , index));
707                 } catch (NumberFormatException e) {
708                         return null;
709                 }
710                 argumentsString = argumentsString.substring(index + 1, length);
711                 
712                 String[] args = new String[length];
713                 int count = 0;
714                 
715                 StringTokenizer tokenizer = new StringTokenizer(argumentsString, ARGUMENTS_DELIMITER);
716                 while(tokenizer.hasMoreTokens()) {
717                         String argument = tokenizer.nextToken();
718                         if(argument.equals(EMPTY_ARGUMENT))
719                                 argument = "";  //$NON-NLS-1$
720                         args[count++] = argument;
721                 }
722                 
723                 if(count != numberOfArg)
724                         return null;
725                 
726                 System.arraycopy(args, 0, args = new String[count], 0, count);
727                 return args;
728         }
729 }