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