cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2006 Sybase, Inc. and others. |
| 3 | * |
| 4 | * All rights reserved. This program and the accompanying materials |
| 5 | * are made available under the terms of the Eclipse Public License v1.0 |
| 6 | * which accompanies this distribution, and is available at |
| 7 | * http://www.eclipse.org/legal/epl-v10.html |
| 8 | * |
| 9 | * Contributors: |
| 10 | * Sybase, Inc. - initial API and implementation |
| 11 | *******************************************************************************/ |
| 12 | package org.eclipse.jst.jsf.common.ui.internal.utils; |
| 13 | |
| 14 | import java.util.Arrays; |
| 15 | import java.util.HashSet; |
| 16 | import java.util.Set; |
| 17 | |
| 18 | import org.eclipse.core.resources.IProject; |
| 19 | import org.eclipse.core.resources.IResource; |
| 20 | import org.eclipse.core.runtime.CoreException; |
| 21 | import org.eclipse.core.runtime.IPath; |
| 22 | import org.eclipse.core.runtime.IProgressMonitor; |
| 23 | import org.eclipse.core.runtime.Path; |
| 24 | import org.eclipse.jdt.core.ClasspathContainerInitializer; |
| 25 | import org.eclipse.jdt.core.Flags; |
| 26 | import org.eclipse.jdt.core.IClasspathContainer; |
| 27 | import org.eclipse.jdt.core.IClasspathEntry; |
| 28 | import org.eclipse.jdt.core.ICompilationUnit; |
| 29 | import org.eclipse.jdt.core.IField; |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 30 | import org.eclipse.jdt.core.IImportDeclaration; |
| 31 | import org.eclipse.jdt.core.IJavaElement; |
| 32 | import org.eclipse.jdt.core.IJavaProject; |
| 33 | import org.eclipse.jdt.core.IMember; |
| 34 | import org.eclipse.jdt.core.IMethod; |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 35 | import org.eclipse.jdt.core.IPackageFragment; |
| 36 | import org.eclipse.jdt.core.IPackageFragmentRoot; |
| 37 | import org.eclipse.jdt.core.IType; |
| 38 | import org.eclipse.jdt.core.ITypeHierarchy; |
| 39 | import org.eclipse.jdt.core.JavaCore; |
| 40 | import org.eclipse.jdt.core.JavaModelException; |
| 41 | import org.eclipse.jdt.core.Signature; |
| 42 | import org.eclipse.jdt.core.compiler.CharOperation; |
| 43 | |
| 44 | /** |
| 45 | * Original code is from JDT Utility methods for the Java Model. |
| 46 | */ |
| 47 | public final class JavaModelUtil { |
| 48 | |
| 49 | /** |
| 50 | * Finds a type by its qualified type name (dot separated). |
| 51 | * |
| 52 | * @param jproject |
| 53 | * The java project to search in |
| 54 | * @param fullyQualifiedName |
| 55 | * The fully qualified name (type name with enclosing type names |
| 56 | * and package (all separated by dots)) |
| 57 | * @return The type found, or null if not existing |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 58 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 59 | */ |
| 60 | public static IType findType(IJavaProject jproject, |
| 61 | String fullyQualifiedName) throws JavaModelException { |
| 62 | // workaround for bug 22883 |
| 63 | IType type = jproject.findType(fullyQualifiedName); |
| 64 | if (type != null) { |
| 65 | return type; |
| 66 | } |
| 67 | IPackageFragmentRoot[] roots = jproject.getPackageFragmentRoots(); |
| 68 | for (int i = 0; i < roots.length; i++) { |
| 69 | IPackageFragmentRoot root = roots[i]; |
| 70 | type = findType(root, fullyQualifiedName); |
| 71 | if (type != null && type.exists()) { |
| 72 | return type; |
| 73 | } |
| 74 | } |
| 75 | return null; |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Returns <code>true</code> if the given package fragment root is |
| 80 | * referenced. This means it is own by a different project but is referenced |
| 81 | * by the root's parent. Returns <code>false</code> if the given root |
| 82 | * doesn't have an underlying resource. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 83 | * @param root |
| 84 | * @return true if root is referenced |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 85 | */ |
| 86 | public static boolean isReferenced(IPackageFragmentRoot root) { |
| 87 | IResource resource = root.getResource(); |
| 88 | if (resource != null) { |
| 89 | IProject jarProject = resource.getProject(); |
| 90 | IProject container = root.getJavaProject().getProject(); |
| 91 | return !container.equals(jarProject); |
| 92 | } |
| 93 | return false; |
| 94 | } |
| 95 | |
| 96 | private static IType findType(IPackageFragmentRoot root, |
| 97 | String fullyQualifiedName) throws JavaModelException { |
| 98 | IJavaElement[] children = root.getChildren(); |
| 99 | for (int i = 0; i < children.length; i++) { |
| 100 | IJavaElement element = children[i]; |
| 101 | if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { |
| 102 | IPackageFragment pack = (IPackageFragment) element; |
| 103 | if (!fullyQualifiedName.startsWith(pack.getElementName())) { |
| 104 | continue; |
| 105 | } |
| 106 | IType type = findType(pack, fullyQualifiedName); |
| 107 | if (type != null && type.exists()) { |
| 108 | return type; |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | return null; |
| 113 | } |
| 114 | |
| 115 | private static IType findType(IPackageFragment pack, |
| 116 | String fullyQualifiedName) throws JavaModelException { |
| 117 | ICompilationUnit[] cus = pack.getCompilationUnits(); |
| 118 | for (int i = 0; i < cus.length; i++) { |
| 119 | ICompilationUnit unit = cus[i]; |
| 120 | IType type = findType(unit, fullyQualifiedName); |
| 121 | if (type != null && type.exists()) { |
| 122 | return type; |
| 123 | } |
| 124 | } |
| 125 | return null; |
| 126 | } |
| 127 | |
| 128 | private static IType findType(ICompilationUnit cu, String fullyQualifiedName) |
| 129 | throws JavaModelException { |
| 130 | IType[] types = cu.getAllTypes(); |
| 131 | for (int i = 0; i < types.length; i++) { |
| 132 | IType type = types[i]; |
| 133 | if (getFullyQualifiedName(type).equals(fullyQualifiedName)) { |
| 134 | return type; |
| 135 | } |
| 136 | } |
| 137 | return null; |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Finds a type by package and type name. |
| 142 | * |
| 143 | * @param jproject |
| 144 | * the java project to search in |
| 145 | * @param pack |
| 146 | * The package name |
| 147 | * @param typeQualifiedName |
| 148 | * the type qualified name (type name with enclosing type names |
| 149 | * (separated by dots)) |
| 150 | * @return the type found, or null if not existing |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 151 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 152 | * @deprecated Use IJavaProject.findType(String, String) instead |
| 153 | */ |
| 154 | public static IType findType(IJavaProject jproject, String pack, |
| 155 | String typeQualifiedName) throws JavaModelException { |
| 156 | return jproject.findType(pack, typeQualifiedName); |
| 157 | } |
| 158 | |
| 159 | /** |
| 160 | * Finds a type container by container name. The returned element will be of |
| 161 | * type <code>IType</code> or a <code>IPackageFragment</code>. |
| 162 | * <code>null</code> is returned if the type container could not be found. |
| 163 | * |
| 164 | * @param jproject |
| 165 | * The Java project defining the context to search |
| 166 | * @param typeContainerName |
| 167 | * A dot separarted name of the type container |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 168 | * @return the java element |
| 169 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 170 | * @see #getTypeContainerName(IType) |
| 171 | */ |
| 172 | public static IJavaElement findTypeContainer(IJavaProject jproject, |
| 173 | String typeContainerName) throws JavaModelException { |
| 174 | // try to find it as type |
| 175 | IJavaElement result = jproject.findType(typeContainerName); |
| 176 | if (result == null) { |
| 177 | // find it as package |
| 178 | IPath path = new Path(typeContainerName.replace('.', '/')); |
| 179 | result = jproject.findElement(path); |
| 180 | if (!(result instanceof IPackageFragment)) { |
| 181 | result = null; |
| 182 | } |
| 183 | |
| 184 | } |
| 185 | return result; |
| 186 | } |
| 187 | |
| 188 | /** |
| 189 | * Finds a type in a compilation unit. Typical usage is to find the |
| 190 | * corresponding type in a working copy. |
| 191 | * |
| 192 | * @param cu |
| 193 | * the compilation unit to search in |
| 194 | * @param typeQualifiedName |
| 195 | * the type qualified name (type name with enclosing type names |
| 196 | * (separated by dots)) |
| 197 | * @return the type found, or null if not existing |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 198 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 199 | */ |
| 200 | public static IType findTypeInCompilationUnit(ICompilationUnit cu, |
| 201 | String typeQualifiedName) throws JavaModelException { |
| 202 | IType[] types = cu.getAllTypes(); |
| 203 | for (int i = 0; i < types.length; i++) { |
| 204 | String currName = getTypeQualifiedName(types[i]); |
| 205 | if (typeQualifiedName.equals(currName)) { |
| 206 | return types[i]; |
| 207 | } |
| 208 | } |
| 209 | return null; |
| 210 | } |
| 211 | |
| 212 | /** |
| 213 | * Finds a a member in a compilation unit. Typical usage is to find the |
| 214 | * corresponding member in a working copy. |
| 215 | * |
| 216 | * @param cu |
| 217 | * the compilation unit (eg. working copy) to search in |
| 218 | * @param member |
| 219 | * the member (eg. from the original) |
| 220 | * @return the member found, or null if not existing |
| 221 | */ |
| 222 | public static IMember findMemberInCompilationUnit(ICompilationUnit cu, |
| 223 | IMember member) { |
| 224 | IJavaElement[] elements = cu.findElements(member); |
| 225 | if (elements != null && elements.length > 0) { |
| 226 | return (IMember) elements[0]; |
| 227 | } |
| 228 | return null; |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * Returns the element of the given compilation unit which is "equal" to the |
| 233 | * given element. Note that the given element usually has a parent different |
| 234 | * from the given compilation unit. |
| 235 | * |
| 236 | * @param cu |
| 237 | * the cu to search in |
| 238 | * @param element |
| 239 | * the element to look for |
| 240 | * @return an element of the given cu "equal" to the given element |
| 241 | */ |
| 242 | public static IJavaElement findInCompilationUnit(ICompilationUnit cu, |
| 243 | IJavaElement element) { |
| 244 | IJavaElement[] elements = cu.findElements(element); |
| 245 | if (elements != null && elements.length > 0) { |
| 246 | return elements[0]; |
| 247 | } |
| 248 | return null; |
| 249 | } |
| 250 | |
| 251 | /** |
| 252 | * Returns the qualified type name of the given type using '.' as |
| 253 | * separators. This is a replace for IType.getTypeQualifiedName() which uses |
| 254 | * '$' as separators. As '$' is also a valid character in an id this is |
| 255 | * ambiguous. JavaCore PR: 1GCFUNT |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 256 | * @param type |
| 257 | * @return the type qualified name |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 258 | */ |
| 259 | public static String getTypeQualifiedName(IType type) { |
| 260 | return type.getTypeQualifiedName('.'); |
| 261 | } |
| 262 | |
| 263 | /** |
| 264 | * Returns the fully qualified name of the given type using '.' as |
| 265 | * separators. This is a replace for IType.getFullyQualifiedTypeName which |
| 266 | * uses '$' as separators. As '$' is also a valid character in an id this is |
| 267 | * ambiguous. JavaCore PR: 1GCFUNT |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 268 | * @param type |
| 269 | * @return the fully qualified name using . as the separator |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 270 | */ |
| 271 | public static String getFullyQualifiedName(IType type) { |
| 272 | return type.getFullyQualifiedName('.'); |
| 273 | } |
| 274 | |
| 275 | /** |
| 276 | * Returns the fully qualified name of a type's container. (package name or |
| 277 | * enclosing type name) |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 278 | * @param type |
| 279 | * @return the container name |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 280 | */ |
| 281 | public static String getTypeContainerName(IType type) { |
| 282 | IType outerType = type.getDeclaringType(); |
| 283 | if (outerType != null) { |
| 284 | return outerType.getFullyQualifiedName('.'); |
| 285 | } |
| 286 | return type.getPackageFragment().getElementName(); |
| 287 | } |
| 288 | |
| 289 | /** |
| 290 | * Concatenates two names. Uses a dot for separation. Both strings can be |
| 291 | * empty or <code>null</code>. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 292 | * @param name1 |
| 293 | * @param name2 |
| 294 | * @return name1 + name2 |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 295 | */ |
| 296 | public static String concatenateName(String name1, String name2) { |
| 297 | StringBuffer buf = new StringBuffer(); |
| 298 | if (name1 != null && name1.length() > 0) { |
| 299 | buf.append(name1); |
| 300 | } |
| 301 | if (name2 != null && name2.length() > 0) { |
| 302 | if (buf.length() > 0) { |
| 303 | buf.append('.'); |
| 304 | } |
| 305 | buf.append(name2); |
| 306 | } |
| 307 | return buf.toString(); |
| 308 | } |
| 309 | |
| 310 | /** |
| 311 | * Concatenates two names. Uses a dot for separation. Both strings can be |
| 312 | * empty or <code>null</code>. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 313 | * @param name1 |
| 314 | * @param name2 |
| 315 | * @return name1 + name2 |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 316 | */ |
| 317 | public static String concatenateName(char[] name1, char[] name2) { |
| 318 | StringBuffer buf = new StringBuffer(); |
| 319 | if (name1 != null && name1.length > 0) { |
| 320 | buf.append(name1); |
| 321 | } |
| 322 | if (name2 != null && name2.length > 0) { |
| 323 | if (buf.length() > 0) { |
| 324 | buf.append('.'); |
| 325 | } |
| 326 | buf.append(name2); |
| 327 | } |
| 328 | return buf.toString(); |
| 329 | } |
| 330 | |
| 331 | /** |
| 332 | * Evaluates if a member (possible from another package) is visible from |
| 333 | * elements in a package. |
| 334 | * |
| 335 | * @param member |
| 336 | * The member to test the visibility for |
| 337 | * @param pack |
| 338 | * The package in focus |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 339 | * @return true if visible |
| 340 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 341 | */ |
| 342 | public static boolean isVisible(IMember member, IPackageFragment pack) |
| 343 | throws JavaModelException { |
| 344 | |
| 345 | int type = member.getElementType(); |
| 346 | if (type == IJavaElement.INITIALIZER |
| 347 | || (type == IJavaElement.METHOD && member.getElementName() |
gkessler | cfc5308 | 2008-11-18 22:25:04 +0000 | [diff] [blame] | 348 | .startsWith("<"))) { //$NON-NLS-1$ |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 349 | //$NON-NLS-1$ |
| 350 | return false; |
| 351 | } |
| 352 | |
| 353 | int otherflags = member.getFlags(); |
| 354 | IType declaringType = member.getDeclaringType(); |
| 355 | if (Flags.isPublic(otherflags) |
| 356 | || (declaringType != null && declaringType.isInterface())) { |
| 357 | return true; |
| 358 | } else if (Flags.isPrivate(otherflags)) { |
| 359 | return false; |
| 360 | } |
| 361 | |
| 362 | IPackageFragment otherpack = (IPackageFragment) findParentOfKind( |
| 363 | member, IJavaElement.PACKAGE_FRAGMENT); |
| 364 | return (pack != null && otherpack != null && isSamePackage(pack, |
| 365 | otherpack)); |
| 366 | } |
| 367 | |
| 368 | /** |
| 369 | * Evaluates if a member in the focus' element hierarchy is visible from |
| 370 | * elements in a package. |
| 371 | * |
| 372 | * @param member |
| 373 | * The member to test the visibility for |
| 374 | * @param pack |
| 375 | * The package of the focus element focus |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 376 | * @return true if is visible in hiearchy |
| 377 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 378 | */ |
| 379 | public static boolean isVisibleInHierarchy(IMember member, |
| 380 | IPackageFragment pack) throws JavaModelException { |
| 381 | int type = member.getElementType(); |
| 382 | if (type == IJavaElement.INITIALIZER |
| 383 | || (type == IJavaElement.METHOD && member.getElementName() |
gkessler | cfc5308 | 2008-11-18 22:25:04 +0000 | [diff] [blame] | 384 | .startsWith("<"))) { //$NON-NLS-1$ |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 385 | //$NON-NLS-1$ |
| 386 | return false; |
| 387 | } |
| 388 | |
| 389 | int otherflags = member.getFlags(); |
| 390 | |
| 391 | IType declaringType = member.getDeclaringType(); |
| 392 | if (Flags.isPublic(otherflags) || Flags.isProtected(otherflags) |
| 393 | || (declaringType != null && declaringType.isInterface())) { |
| 394 | return true; |
| 395 | } else if (Flags.isPrivate(otherflags)) { |
| 396 | return false; |
| 397 | } |
| 398 | |
| 399 | IPackageFragment otherpack = (IPackageFragment) findParentOfKind( |
| 400 | member, IJavaElement.PACKAGE_FRAGMENT); |
| 401 | return (pack != null && pack.equals(otherpack)); |
| 402 | } |
| 403 | |
| 404 | /** |
| 405 | * Returns the package fragment root of <code>IJavaElement</code>. If the |
| 406 | * given element is already a package fragment root, the element itself is |
| 407 | * returned. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 408 | * @param element |
| 409 | * @return the package fragment root |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 410 | */ |
| 411 | public static IPackageFragmentRoot getPackageFragmentRoot( |
| 412 | IJavaElement element) { |
| 413 | return (IPackageFragmentRoot) element |
| 414 | .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); |
| 415 | } |
| 416 | |
| 417 | /** |
| 418 | * Returns the parent of the supplied java element that conforms to the |
| 419 | * given parent type or <code>null</code>, if such a parent doesn't exit. |
| 420 | * |
| 421 | * @deprecated Use element.getParent().getAncestor(kind); |
| 422 | */ |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 423 | private static IJavaElement findParentOfKind(IJavaElement element, int kind) { |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 424 | if (element != null && element.getParent() != null) { |
| 425 | return element.getParent().getAncestor(kind); |
| 426 | } |
| 427 | return null; |
| 428 | } |
| 429 | |
| 430 | /** |
| 431 | * Finds a method in a type. This searches for a method with the same name |
| 432 | * and signature. Parameter types are only compared by the simple name, no |
| 433 | * resolving for the fully qualified type name is done. Constructors are |
| 434 | * only compared by parameters, not the name. |
| 435 | * |
| 436 | * @param name |
| 437 | * The name of the method to find |
| 438 | * @param paramTypes |
| 439 | * The type signatures of the parameters e.g. |
| 440 | * <code>{"QString;","I"}</code> |
| 441 | * @param isConstructor |
| 442 | * If the method is a constructor |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 443 | * @param type |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 444 | * @return The first found method or <code>null</code>, if nothing found |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 445 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 446 | */ |
| 447 | public static IMethod findMethod(String name, String[] paramTypes, |
| 448 | boolean isConstructor, IType type) throws JavaModelException { |
| 449 | return findMethod(name, paramTypes, isConstructor, type.getMethods()); |
| 450 | } |
| 451 | |
| 452 | /** |
| 453 | * Finds a method by name. This searches for a method with a name and |
| 454 | * signature. Parameter types are only compared by the simple name, no |
| 455 | * resolving for the fully qualified type name is done. Constructors are |
| 456 | * only compared by parameters, not the name. |
| 457 | * |
| 458 | * @param name |
| 459 | * The name of the method to find |
| 460 | * @param paramTypes |
| 461 | * The type signatures of the parameters e.g. |
| 462 | * <code>{"QString;","I"}</code> |
| 463 | * @param isConstructor |
| 464 | * If the method is a constructor |
| 465 | * @param methods |
| 466 | * The methods to search in |
| 467 | * @return The found method or <code>null</code>, if nothing found |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 468 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 469 | */ |
| 470 | public static IMethod findMethod(String name, String[] paramTypes, |
| 471 | boolean isConstructor, IMethod[] methods) throws JavaModelException { |
| 472 | for (int i = methods.length - 1; i >= 0; i--) { |
| 473 | if (isSameMethodSignature(name, paramTypes, isConstructor, |
| 474 | methods[i])) { |
| 475 | return methods[i]; |
| 476 | } |
| 477 | } |
| 478 | return null; |
| 479 | } |
| 480 | |
| 481 | /** |
| 482 | * Finds a method declararion in a type's hierarchy. The search is top down, |
| 483 | * so this returns the first declaration of the method in the hierarchy. |
| 484 | * This searches for a method with a name and signature. Parameter types are |
| 485 | * only compared by the simple name, no resolving for the fully qualified |
| 486 | * type name is done. Constructors are only compared by parameters, not the |
| 487 | * name. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 488 | * @param hierarchy |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 489 | * |
| 490 | * @param type |
| 491 | * Searches in this type's supertypes. |
| 492 | * @param name |
| 493 | * The name of the method to find |
| 494 | * @param paramTypes |
| 495 | * The type signatures of the parameters e.g. |
| 496 | * <code>{"QString;","I"}</code> |
| 497 | * @param isConstructor |
| 498 | * If the method is a constructor |
| 499 | * @return The first method found or null, if nothing found |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 500 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 501 | */ |
| 502 | public static IMethod findMethodDeclarationInHierarchy( |
| 503 | ITypeHierarchy hierarchy, IType type, String name, |
| 504 | String[] paramTypes, boolean isConstructor) |
| 505 | throws JavaModelException { |
| 506 | IType[] superTypes = hierarchy.getAllSupertypes(type); |
| 507 | for (int i = superTypes.length - 1; i >= 0; i--) { |
| 508 | IMethod first = findMethod(name, paramTypes, isConstructor, |
| 509 | superTypes[i]); |
| 510 | if (first != null && !Flags.isPrivate(first.getFlags())) { |
| 511 | // the order getAllSupertypes does make assumptions of the order |
| 512 | // of inner elements -> search recursivly |
| 513 | IMethod res = findMethodDeclarationInHierarchy(hierarchy, first |
| 514 | .getDeclaringType(), name, paramTypes, isConstructor); |
| 515 | if (res != null) { |
| 516 | return res; |
| 517 | } |
| 518 | return first; |
| 519 | } |
| 520 | } |
| 521 | return null; |
| 522 | } |
| 523 | |
| 524 | /** |
| 525 | * Finds a method implementation in a type's classhierarchy. The search is |
| 526 | * bottom-up, so this returns the nearest overridden method. Does not find |
| 527 | * methods in interfaces or abstract methods. This searches for a method |
| 528 | * with a name and signature. Parameter types are only compared by the |
| 529 | * simple name, no resolving for the fully qualified type name is done. |
| 530 | * Constructors are only compared by parameters, not the name. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 531 | * @param hierarchy |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 532 | * |
| 533 | * @param type |
| 534 | * Type to search the superclasses |
| 535 | * @param name |
| 536 | * The name of the method to find |
| 537 | * @param paramTypes |
| 538 | * The type signatures of the parameters e.g. |
| 539 | * <code>{"QString;","I"}</code> |
| 540 | * @param isConstructor |
| 541 | * If the method is a constructor |
| 542 | * @return The first method found or null, if nothing found |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 543 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 544 | */ |
| 545 | public static IMethod findMethodImplementationInHierarchy( |
| 546 | ITypeHierarchy hierarchy, IType type, String name, |
| 547 | String[] paramTypes, boolean isConstructor) |
| 548 | throws JavaModelException { |
| 549 | IType[] superTypes = hierarchy.getAllSuperclasses(type); |
| 550 | for (int i = 0; i < superTypes.length; i++) { |
| 551 | IMethod found = findMethod(name, paramTypes, isConstructor, |
| 552 | superTypes[i]); |
| 553 | if (found != null) { |
| 554 | if (Flags.isAbstract(found.getFlags())) { |
| 555 | return null; |
| 556 | } |
| 557 | return found; |
| 558 | } |
| 559 | } |
| 560 | return null; |
| 561 | } |
| 562 | |
| 563 | private static IMethod findMethodInHierarchy(ITypeHierarchy hierarchy, |
| 564 | IType type, String name, String[] paramTypes, boolean isConstructor) |
| 565 | throws JavaModelException { |
| 566 | IMethod method = findMethod(name, paramTypes, isConstructor, type); |
| 567 | if (method != null) { |
| 568 | return method; |
| 569 | } |
| 570 | IType superClass = hierarchy.getSuperclass(type); |
| 571 | if (superClass != null) { |
| 572 | IMethod res = findMethodInHierarchy(hierarchy, superClass, name, |
| 573 | paramTypes, isConstructor); |
| 574 | if (res != null) { |
| 575 | return res; |
| 576 | } |
| 577 | } |
| 578 | if (!isConstructor) { |
| 579 | IType[] superInterfaces = hierarchy.getSuperInterfaces(type); |
| 580 | for (int i = 0; i < superInterfaces.length; i++) { |
| 581 | IMethod res = findMethodInHierarchy(hierarchy, |
| 582 | superInterfaces[i], name, paramTypes, false); |
| 583 | if (res != null) { |
| 584 | return res; |
| 585 | } |
| 586 | } |
| 587 | } |
| 588 | return method; |
| 589 | } |
| 590 | |
| 591 | /** |
| 592 | * Finds the method that is defines/declares the given method. The search is |
| 593 | * bottom-up, so this returns the nearest defining/declaring method. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 594 | * @param typeHierarchy |
| 595 | * @param type |
| 596 | * @param methodName |
| 597 | * @param paramTypes |
| 598 | * @param isConstructor |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 599 | * |
| 600 | * @param testVisibility |
| 601 | * If true the result is tested on visibility. Null is returned |
| 602 | * if the method is not visible. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 603 | * @return the method or null |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 604 | * @throws JavaModelException |
| 605 | */ |
| 606 | public static IMethod findMethodDefininition(ITypeHierarchy typeHierarchy, |
| 607 | IType type, String methodName, String[] paramTypes, |
| 608 | boolean isConstructor, boolean testVisibility) |
| 609 | throws JavaModelException { |
| 610 | IType superClass = typeHierarchy.getSuperclass(type); |
| 611 | if (superClass != null) { |
| 612 | IMethod res = findMethodInHierarchy(typeHierarchy, superClass, |
| 613 | methodName, paramTypes, isConstructor); |
| 614 | if (res != null && !Flags.isPrivate(res.getFlags())) { |
| 615 | if (!testVisibility |
| 616 | || isVisibleInHierarchy(res, type.getPackageFragment())) { |
| 617 | return res; |
| 618 | } |
| 619 | } |
| 620 | } |
| 621 | if (!isConstructor) { |
| 622 | IType[] interfaces = typeHierarchy.getSuperInterfaces(type); |
| 623 | for (int i = 0; i < interfaces.length; i++) { |
| 624 | IMethod res = findMethodInHierarchy(typeHierarchy, |
| 625 | interfaces[i], methodName, paramTypes, false); |
| 626 | if (res != null) { |
| 627 | return res; // methods from interfaces are always public and |
| 628 | // therefore visible |
| 629 | } |
| 630 | } |
| 631 | } |
| 632 | return null; |
| 633 | } |
| 634 | |
| 635 | /** |
| 636 | * Tests if a method equals to the given signature. Parameter types are only |
| 637 | * compared by the simple name, no resolving for the fully qualified type |
| 638 | * name is done. Constructors are only compared by parameters, not the name. |
| 639 | * |
| 640 | * @param name |
| 641 | * Name of the method |
| 642 | * @param paramTypes |
| 643 | * The type signatures of the parameters e.g. |
| 644 | * <code>{"QString;","I"}</code> |
| 645 | * @param isConstructor |
| 646 | * Specifies if the method is a constructor |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 647 | * @param curr |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 648 | * @return Returns <code>true</code> if the method has the given name and |
| 649 | * parameter types and constructor state. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 650 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 651 | */ |
| 652 | public static boolean isSameMethodSignature(String name, |
| 653 | String[] paramTypes, boolean isConstructor, IMethod curr) |
| 654 | throws JavaModelException { |
| 655 | if (isConstructor || name.equals(curr.getElementName())) { |
| 656 | if (isConstructor == curr.isConstructor()) { |
| 657 | String[] currParamTypes = curr.getParameterTypes(); |
| 658 | if (paramTypes.length == currParamTypes.length) { |
| 659 | for (int i = 0; i < paramTypes.length; i++) { |
| 660 | String t1 = Signature.getSimpleName(Signature |
| 661 | .toString(paramTypes[i])); |
| 662 | String t2 = Signature.getSimpleName(Signature |
| 663 | .toString(currParamTypes[i])); |
| 664 | if (!t1.equals(t2)) { |
| 665 | return false; |
| 666 | } |
| 667 | } |
| 668 | return true; |
| 669 | } |
| 670 | } |
| 671 | } |
| 672 | return false; |
| 673 | } |
| 674 | |
| 675 | /** |
| 676 | * Tests if two <code>IPackageFragment</code>s represent the same logical |
| 677 | * java package. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 678 | * @param pack1 |
| 679 | * @param pack2 |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 680 | * |
| 681 | * @return <code>true</code> if the package fragments' names are equal. |
| 682 | */ |
| 683 | public static boolean isSamePackage(IPackageFragment pack1, |
| 684 | IPackageFragment pack2) { |
| 685 | return pack1.getElementName().equals(pack2.getElementName()); |
| 686 | } |
| 687 | |
| 688 | /** |
| 689 | * Checks whether the given type has a valid main method or not. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 690 | * @param type |
| 691 | * @return true if type has a main method |
| 692 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 693 | */ |
| 694 | public static boolean hasMainMethod(IType type) throws JavaModelException { |
| 695 | IMethod[] methods = type.getMethods(); |
| 696 | for (int i = 0; i < methods.length; i++) { |
| 697 | if (methods[i].isMainMethod()) { |
| 698 | return true; |
| 699 | } |
| 700 | } |
| 701 | return false; |
| 702 | } |
| 703 | |
| 704 | /** |
| 705 | * Checks if the field is boolean. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 706 | * @param field |
| 707 | * @return true if the file is of primitive boolean type |
| 708 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 709 | */ |
| 710 | public static boolean isBoolean(IField field) throws JavaModelException { |
| 711 | return field.getTypeSignature().equals(Signature.SIG_BOOLEAN); |
| 712 | } |
| 713 | |
| 714 | /** |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 715 | * Tests if the given element is on the class path of its containing |
| 716 | * project. Handles the case that the containing project isn't a Java |
| 717 | * project. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 718 | * @param element |
| 719 | * @return true if element in on the class path? |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 720 | */ |
| 721 | public static boolean isOnClasspath(IJavaElement element) { |
| 722 | IJavaProject project = element.getJavaProject(); |
| 723 | if (!project.exists()) |
| 724 | return false; |
| 725 | return project.isOnClasspath(element); |
| 726 | } |
| 727 | |
| 728 | /** |
| 729 | * Resolves a type name in the context of the declaring type. |
| 730 | * |
| 731 | * @param refTypeSig |
| 732 | * the type name in signature notation (for example 'QVector') |
| 733 | * this can also be an array type, but dimensions will be |
| 734 | * ignored. |
| 735 | * @param declaringType |
| 736 | * the context for resolving (type where the reference was made |
| 737 | * in) |
| 738 | * @return returns the fully qualified type name or build-in-type name. if a |
| 739 | * unresoved type couldn't be resolved null is returned |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 740 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 741 | */ |
| 742 | public static String getResolvedTypeName(String refTypeSig, |
| 743 | IType declaringType) throws JavaModelException { |
| 744 | int arrayCount = Signature.getArrayCount(refTypeSig); |
| 745 | char type = refTypeSig.charAt(arrayCount); |
| 746 | if (type == Signature.C_UNRESOLVED) { |
| 747 | int semi = refTypeSig |
| 748 | .indexOf(Signature.C_SEMICOLON, arrayCount + 1); |
| 749 | if (semi == -1) { |
| 750 | throw new IllegalArgumentException(); |
| 751 | } |
| 752 | String name = refTypeSig.substring(arrayCount + 1, semi); |
| 753 | |
| 754 | String[][] resolvedNames = declaringType.resolveType(name); |
| 755 | if (resolvedNames != null && resolvedNames.length > 0) { |
| 756 | return JavaModelUtil.concatenateName(resolvedNames[0][0], |
| 757 | resolvedNames[0][1]); |
| 758 | } |
| 759 | return null; |
| 760 | } |
| 761 | return Signature.toString(refTypeSig.substring(arrayCount)); |
| 762 | } |
| 763 | |
| 764 | /** |
| 765 | * Returns if a CU can be edited. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 766 | * @param cu |
| 767 | * @return true if cu is editable |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 768 | */ |
| 769 | public static boolean isEditable(ICompilationUnit cu) { |
| 770 | IResource resource = toOriginal(cu).getResource(); |
| 771 | return (resource.exists() && !resource.getResourceAttributes() |
| 772 | .isReadOnly()); |
| 773 | } |
| 774 | |
| 775 | /** |
| 776 | * Finds a qualified import for a type name. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 777 | * @param cu |
| 778 | * @param simpleName |
| 779 | * @return the import declaration or null |
| 780 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 781 | */ |
| 782 | public static IImportDeclaration findImport(ICompilationUnit cu, |
| 783 | String simpleName) throws JavaModelException { |
| 784 | IImportDeclaration[] existing = cu.getImports(); |
| 785 | for (int i = 0; i < existing.length; i++) { |
| 786 | String curr = existing[i].getElementName(); |
| 787 | if (curr.endsWith(simpleName)) { |
| 788 | int dotPos = curr.length() - simpleName.length() - 1; |
| 789 | if ((dotPos == -1) |
| 790 | || (dotPos > 0 && curr.charAt(dotPos) == '.')) { |
| 791 | return existing[i]; |
| 792 | } |
| 793 | } |
| 794 | } |
| 795 | return null; |
| 796 | } |
| 797 | |
| 798 | /** |
| 799 | * Returns the original if the given member. If the member is already an |
| 800 | * original the input is returned. The returned member might not exist |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 801 | * @param member |
| 802 | * @return the original IMember |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 803 | */ |
| 804 | public static IMember toOriginal(IMember member) { |
| 805 | if (member instanceof IMethod) { |
| 806 | return toOriginalMethod((IMethod) member); |
| 807 | } |
| 808 | |
| 809 | return (IMember) member.getPrimaryElement(); |
| 810 | /* |
| 811 | * ICompilationUnit cu= member.getCompilationUnit(); if (cu != null && |
| 812 | * cu.isWorkingCopy()) return (IMember)cu.getOriginal(member); return |
| 813 | * member; |
| 814 | */ |
| 815 | } |
| 816 | |
| 817 | /* |
| 818 | * XXX workaround for bug 18568 |
| 819 | * http://bugs.eclipse.org/bugs/show_bug.cgi?id=18568 to be removed once the |
| 820 | * bug is fixed |
| 821 | */ |
| 822 | private static IMethod toOriginalMethod(IMethod method) { |
| 823 | ICompilationUnit cu = method.getCompilationUnit(); |
| 824 | if (cu == null || isPrimary(cu)) { |
| 825 | return method; |
| 826 | } |
| 827 | try { |
| 828 | // use the workaround only if needed |
| 829 | if (!method.getElementName().equals( |
| 830 | method.getDeclaringType().getElementName())) |
| 831 | return (IMethod) method.getPrimaryElement(); |
| 832 | |
| 833 | IType originalType = (IType) toOriginal(method.getDeclaringType()); |
| 834 | IMethod[] methods = originalType.findMethods(method); |
| 835 | boolean isConstructor = method.isConstructor(); |
| 836 | for (int i = 0; i < methods.length; i++) { |
| 837 | if (methods[i].isConstructor() == isConstructor) |
| 838 | return methods[i]; |
| 839 | } |
| 840 | return null; |
| 841 | } catch (JavaModelException e) { |
| 842 | return null; |
| 843 | } |
| 844 | } |
| 845 | |
| 846 | // private static boolean PRIMARY_ONLY = false; |
| 847 | |
| 848 | /** |
| 849 | * Returns the original cu if the given cu is a working copy. If the cu is |
| 850 | * already an original the input cu is returned. The returned cu might not |
| 851 | * exist |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 852 | * @param cu |
| 853 | * @return the original compiliation unit |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 854 | */ |
| 855 | public static ICompilationUnit toOriginal(ICompilationUnit cu) { |
| 856 | // To stay compatible with old version returned null |
| 857 | // if cu is null |
| 858 | if (cu == null) |
| 859 | return cu; |
| 860 | return cu.getPrimary(); |
| 861 | } |
| 862 | |
| 863 | /** |
| 864 | * Returns the original element if the given element is a working copy. If |
| 865 | * the cu is already an original the input element is returned. The returned |
| 866 | * element might not exist |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 867 | * @param element |
| 868 | * @return element's primary element |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 869 | */ |
| 870 | public static IJavaElement toOriginal(IJavaElement element) { |
| 871 | return element.getPrimaryElement(); |
| 872 | } |
| 873 | |
| 874 | /** |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 875 | * Returns true if a cu is a primary cu (original or shared working copy) |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 876 | * @param cu |
| 877 | * @return true if cu is primary |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 878 | */ |
| 879 | public static boolean isPrimary(ICompilationUnit cu) { |
| 880 | return cu.getOwner() == null; |
| 881 | } |
| 882 | |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 883 | /** |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 884 | * http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253 |
| 885 | * |
| 886 | * Reconciling happens in a separate thread. This can cause a situation |
| 887 | * where the Java element gets disposed after an exists test has been done. |
| 888 | * So we should not log not present exceptions when they happen in working |
| 889 | * copies. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 890 | * @param exception |
| 891 | * @return true if filter not present |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 892 | */ |
| 893 | public static boolean filterNotPresentException(CoreException exception) { |
| 894 | if (!(exception instanceof JavaModelException)) { |
| 895 | return true; |
| 896 | } |
| 897 | JavaModelException je = (JavaModelException) exception; |
| 898 | if (!je.isDoesNotExist()) { |
| 899 | return true; |
| 900 | } |
| 901 | IJavaElement[] elements = je.getJavaModelStatus().getElements(); |
| 902 | for (int i = 0; i < elements.length; i++) { |
| 903 | IJavaElement element = elements[i]; |
| 904 | ICompilationUnit unit = (ICompilationUnit) element |
| 905 | .getAncestor(IJavaElement.COMPILATION_UNIT); |
| 906 | if (unit == null) { |
| 907 | return true; |
| 908 | } |
| 909 | if (!unit.isWorkingCopy()) { |
| 910 | return true; |
| 911 | } |
| 912 | } |
| 913 | return false; |
| 914 | } |
| 915 | |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 916 | /** |
| 917 | * @param type |
| 918 | * @param pm |
| 919 | * @return all supertypes of type |
| 920 | * @throws JavaModelException |
| 921 | */ |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 922 | public static IType[] getAllSuperTypes(IType type, IProgressMonitor pm) |
| 923 | throws JavaModelException { |
| 924 | // workaround for 23656 |
| 925 | Set types = new HashSet(Arrays.asList(type.newSupertypeHierarchy(pm) |
| 926 | .getAllSupertypes(type))); |
| 927 | IType objekt = type.getJavaProject().findType("java.lang.Object");//$NON-NLS-1$ |
| 928 | if (objekt != null) { |
| 929 | types.add(objekt); |
| 930 | } |
| 931 | return (IType[]) types.toArray(new IType[types.size()]); |
| 932 | } |
| 933 | |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 934 | /** |
| 935 | * @param resourcePath |
| 936 | * @param exclusionPatterns |
| 937 | * @return true if resourcePath is excluded by exclusion patterns |
| 938 | */ |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 939 | public static boolean isExcludedPath(IPath resourcePath, |
| 940 | IPath[] exclusionPatterns) { |
| 941 | char[] path = resourcePath.toString().toCharArray(); |
| 942 | for (int i = 0, length = exclusionPatterns.length; i < length; i++) { |
| 943 | char[] pattern = exclusionPatterns[i].toString().toCharArray(); |
| 944 | if (CharOperation.pathMatch(pattern, path, true, '/')) { |
| 945 | return true; |
| 946 | } |
| 947 | } |
| 948 | return false; |
| 949 | } |
| 950 | |
| 951 | /* |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 952 | |
| 953 | * @see IClasspathEntry#getExclusionPatterns |
| 954 | */ |
| 955 | /** |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 956 | * Returns whether the given resource path matches one of the exclusion |
| 957 | * patterns. |
| 958 | * |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 959 | * @param resourcePath |
| 960 | * @param exclusionPatterns |
| 961 | * @return true if resourcePath is excluded |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 962 | */ |
| 963 | public static boolean isExcluded(IPath resourcePath, |
| 964 | char[][] exclusionPatterns) { |
| 965 | if (exclusionPatterns == null) { |
| 966 | return false; |
| 967 | } |
| 968 | char[] path = resourcePath.toString().toCharArray(); |
| 969 | for (int i = 0, length = exclusionPatterns.length; i < length; i++) { |
| 970 | if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/')) { |
| 971 | return true; |
| 972 | } |
| 973 | } |
| 974 | return false; |
| 975 | } |
| 976 | |
| 977 | private static Boolean fgIsJDTCore_1_5 = null; |
| 978 | |
| 979 | /** |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 980 | * @return true if JRE 1.5 in enabled. |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 981 | */ |
| 982 | public static boolean isJDTCore_1_5() { |
| 983 | if (fgIsJDTCore_1_5 == null) { |
| 984 | fgIsJDTCore_1_5 = JavaCore |
| 985 | .getDefaultOptions() |
| 986 | .containsKey( |
gkessler | cfc5308 | 2008-11-18 22:25:04 +0000 | [diff] [blame] | 987 | "org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation") ? Boolean.TRUE //$NON-NLS-1$ |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 988 | : Boolean.FALSE; |
| 989 | } |
| 990 | return fgIsJDTCore_1_5.booleanValue(); |
| 991 | } |
| 992 | |
| 993 | /** |
| 994 | * Helper method that tests if an classpath entry can be found in a |
| 995 | * container. <code>null</code> is returned if the entry can not be found |
| 996 | * or if the container does not allows the configuration of source |
| 997 | * attachments |
| 998 | * |
| 999 | * @param jproject |
| 1000 | * The container's parent project |
| 1001 | * @param containerPath |
| 1002 | * The path of the container |
| 1003 | * @param libPath |
| 1004 | * The path of the library to be found |
| 1005 | * @return IClasspathEntry A classpath entry from the container of |
| 1006 | * <code>null</code> if the container can not be modified. |
cbateman | 259f2d6 | 2007-10-02 21:51:21 +0000 | [diff] [blame] | 1007 | * @throws JavaModelException |
cbateman | 3d52a61 | 2006-11-28 20:02:40 +0000 | [diff] [blame] | 1008 | */ |
| 1009 | public static IClasspathEntry getClasspathEntryToEdit( |
| 1010 | IJavaProject jproject, IPath containerPath, IPath libPath) |
| 1011 | throws JavaModelException { |
| 1012 | IClasspathContainer container = JavaCore.getClasspathContainer( |
| 1013 | containerPath, jproject); |
| 1014 | ClasspathContainerInitializer initializer = JavaCore |
| 1015 | .getClasspathContainerInitializer(containerPath.segment(0)); |
| 1016 | if (container != null |
| 1017 | && initializer != null |
| 1018 | && initializer.canUpdateClasspathContainer(containerPath, |
| 1019 | jproject)) { |
| 1020 | IClasspathEntry[] entries = container.getClasspathEntries(); |
| 1021 | for (int i = 0; i < entries.length; i++) { |
| 1022 | IClasspathEntry curr = entries[i]; |
| 1023 | IClasspathEntry resolved = JavaCore |
| 1024 | .getResolvedClasspathEntry(curr); |
| 1025 | if (resolved != null && libPath.equals(resolved.getPath())) { |
| 1026 | return curr; // return the real entry |
| 1027 | } |
| 1028 | } |
| 1029 | } |
| 1030 | return null; // attachment not possible |
| 1031 | } |
| 1032 | } |