1 11 package org.eclipse.jdt.internal.launching; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import org.eclipse.core.expressions.PropertyTester; 22 import org.eclipse.core.resources.IContainer; 23 import org.eclipse.core.resources.IProject; 24 import org.eclipse.core.resources.IResource; 25 import org.eclipse.core.resources.ResourcesPlugin; 26 import org.eclipse.core.runtime.CoreException; 27 import org.eclipse.core.runtime.IAdaptable; 28 import org.eclipse.core.runtime.IPath; 29 import org.eclipse.core.runtime.NullProgressMonitor; 30 import org.eclipse.jdt.core.Flags; 31 import org.eclipse.jdt.core.IBuffer; 32 import org.eclipse.jdt.core.IClassFile; 33 import org.eclipse.jdt.core.IClasspathEntry; 34 import org.eclipse.jdt.core.ICompilationUnit; 35 import org.eclipse.jdt.core.IJavaElement; 36 import org.eclipse.jdt.core.IJavaProject; 37 import org.eclipse.jdt.core.IMember; 38 import org.eclipse.jdt.core.IMethod; 39 import org.eclipse.jdt.core.IOpenable; 40 import org.eclipse.jdt.core.IPackageFragment; 41 import org.eclipse.jdt.core.IPackageFragmentRoot; 42 import org.eclipse.jdt.core.ISourceRange; 43 import org.eclipse.jdt.core.IType; 44 import org.eclipse.jdt.core.JavaCore; 45 import org.eclipse.jdt.core.JavaModelException; 46 import org.eclipse.jdt.core.Signature; 47 import org.eclipse.jdt.core.ToolFactory; 48 import org.eclipse.jdt.core.compiler.IScanner; 49 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 50 import org.eclipse.jdt.core.compiler.InvalidInputException; 51 52 57 public class JavaLaunchableTester extends PropertyTester { 58 59 62 private static final String PROPERTY_HAS_MAIN = "hasMain"; 64 67 private static final String PROPERTY_HAS_METHOD = "hasMethod"; 69 72 private static final String PROPERTY_HAS_METHOD_WITH_ANNOTATION = "hasMethodWithAnnotation"; 74 77 private static final String PROPERTY_HAS_TYPE_WITH_ANNOTATION = "hasTypeWithAnnotation"; 79 82 private static final String PROPERTY_EXTENDS_CLASS = "extendsClass"; 84 87 private static final String PROPERTY_IS_CONTAINER = "isContainer"; 89 93 private static final String PROPERTY_IS_PACKAGE_FRAGMENT = "isPackageFragment"; 95 99 private static final String PROPERTY_IS_PACKAGE_FRAGMENT_ROOT = "isPackageFragmentRoot"; 101 104 private static final String PROPERTY_PROJECT_NATURE = "hasProjectNature"; 106 109 private static final String PROPERTY_EXTENDS_INTERFACE = "extendsInterface"; 111 114 private static final String PROPERTY_BUILDPATH_REFERENCE = "buildpathReference"; 116 119 private static Map fgModifiers = new HashMap (); 120 121 private static final int FLAGS_MASK= Flags.AccPublic | Flags.AccProtected | Flags.AccPrivate | Flags.AccStatic 122 | Flags.AccFinal | Flags.AccSynchronized | Flags.AccAbstract | Flags.AccNative; 123 124 125 static { 126 fgModifiers.put("public", new Integer (Flags.AccPublic)); fgModifiers.put("protected", new Integer (Flags.AccProtected)); fgModifiers.put("private", new Integer (Flags.AccPrivate)); fgModifiers.put("static", new Integer (Flags.AccStatic)); fgModifiers.put("final", new Integer (Flags.AccFinal)); fgModifiers.put("synchronized", new Integer (Flags.AccSynchronized)); fgModifiers.put("abstract", new Integer (Flags.AccAbstract)); fgModifiers.put("native", new Integer (Flags.AccNative)); } 135 136 142 private IType getType(IJavaElement element) { 143 IType type = null; 144 if (element instanceof ICompilationUnit) { 145 type= ((ICompilationUnit) element).findPrimaryType(); 146 } 147 else if (element instanceof IClassFile) { 148 type = ((IClassFile)element).getType(); 149 } 150 else if (element instanceof IType) { 151 type = (IType) element; 152 } 153 else if (element instanceof IMember) { 154 type = ((IMember)element).getDeclaringType(); 155 } 156 return type; 157 } 158 159 165 private boolean hasMain(IJavaElement element) { 166 try { 167 IType type = getType(element); 168 if(type != null && type.exists()) { 169 if(hasMainMethod(type)) { 170 return true; 171 } 172 IJavaElement[] children = type.getChildren(); 174 for(int i = 0; i < children.length; i++) { 175 if(hasMainInChildren(getType(children[i]))) { 176 return true; 177 } 178 } 179 } 180 } 181 catch (JavaModelException e) {} 182 catch (CoreException ce){} 183 return false; 184 } 185 186 193 private boolean hasMainMethod(IType type) throws JavaModelException { 194 IMethod[] methods = type.getMethods(); 195 for (int i= 0; i < methods.length; i++) { 196 if(methods[i].isMainMethod()) { 197 return true; 198 } 199 } 200 return false; 201 } 202 203 211 private boolean hasMainInChildren(IType type) throws CoreException { 212 if(type.isClass() & Flags.isStatic(type.getFlags())) { 213 if(hasMainMethod(type)) { 214 return true; 215 } 216 else { 217 IJavaElement[] children = type.getChildren(); 218 for(int i = 0; i < children.length; i++) { 219 if(children[i].getElementType() == IJavaElement.TYPE) { 220 return hasMainInChildren((IType) children[i]); 221 } 222 } 223 } 224 } 225 return false; 226 } 227 228 246 private boolean hasMethod(IJavaElement element, Object [] args) { 247 try { 248 if (args.length > 1) { 249 IType type = getType(element); 250 if (type != null && type.exists()) { 251 String name = (String ) args[0]; 252 String signature = (String ) args[1]; 253 String [] parms = Signature.getParameterTypes(signature); 254 String returnType = Signature.getReturnType(signature); 255 IMethod candidate = type.getMethod(name, parms); 256 if (candidate.exists()) { 257 if (candidate.getReturnType().equals(returnType)) { 259 if (args.length > 2) { 261 String modifierText = (String ) args[2]; 262 String [] modifiers = modifierText.split(" "); int flags = 0; 264 for (int j = 0; j < modifiers.length; j++) { 265 String modifier = modifiers[j]; 266 Integer flag = (Integer ) fgModifiers.get(modifier); 267 if (flag != null) { 268 flags = flags | flag.intValue(); 269 } 270 } 271 if (candidate.getFlags() == flags) { 272 return true; 273 } 274 } 275 } 276 } 277 } 278 } 279 } 280 catch (JavaModelException e) {} 281 return false; 282 } 283 284 295 private boolean hasTypeWithAnnotation(IJavaElement element, String annotationType) { 296 try { 297 IType type= getType(element); 298 if (type == null || !type.exists()) { 299 return false; 300 } 301 302 IBuffer buffer= null; 303 IOpenable openable= type.getOpenable(); 304 if (openable instanceof ICompilationUnit) { 305 buffer= ((ICompilationUnit) openable).getBuffer(); 306 } else if (openable instanceof IClassFile) { 307 buffer= ((IClassFile) openable).getBuffer(); 308 } 309 if (buffer == null) { 310 return false; 311 } 312 313 ISourceRange sourceRange= type.getSourceRange(); 314 ISourceRange nameRange= type.getNameRange(); 315 if (sourceRange != null && nameRange != null) { 316 IScanner scanner= ToolFactory.createScanner(false, false, true, false); 317 scanner.setSource(buffer.getCharacters()); 318 scanner.resetTo(sourceRange.getOffset(), nameRange.getOffset()); 319 if (findAnnotation(scanner, annotationType)) { 320 return true; 321 } 322 } 323 } 324 catch (JavaModelException e) {} 325 catch (InvalidInputException e) {} 326 return false; 327 } 328 329 330 343 private boolean hasMethodWithAnnotation(IJavaElement element, Object [] args) { 344 try { 345 String annotationType= (String ) args[0]; 346 int flags = 0; 347 if (args.length > 1) { 348 String [] modifiers = ((String ) args[1]).split(" "); for (int j = 0; j < modifiers.length; j++) { 350 String modifier = modifiers[j]; 351 Integer flag = (Integer ) fgModifiers.get(modifier); 352 if (flag != null) { 353 flags = flags | flag.intValue(); 354 } 355 } 356 } else { 357 flags= -1; 358 } 359 360 IType type= getType(element); 361 if (type == null || !type.exists()) { 362 return false; 363 } 364 IMethod[] methods= type.getMethods(); 365 if (methods.length == 0) { 366 return false; 367 } 368 369 IBuffer buffer= null; 370 IOpenable openable= type.getOpenable(); 371 if (openable instanceof ICompilationUnit) { 372 buffer= ((ICompilationUnit) openable).getBuffer(); 373 } else if (openable instanceof IClassFile) { 374 buffer= ((IClassFile) openable).getBuffer(); 375 } 376 if (buffer == null) { 377 return false; 378 } 379 IScanner scanner=null; 381 for (int i= 0; i < methods.length; i++) { 382 IMethod curr= methods[i]; 383 if (curr.isConstructor() || (flags != -1 && flags != (curr.getFlags() & FLAGS_MASK))) { 384 continue; 385 } 386 387 388 ISourceRange sourceRange= curr.getSourceRange(); 389 ISourceRange nameRange= curr.getNameRange(); 390 if (sourceRange != null && nameRange != null) { 391 if (scanner == null) { 392 scanner= ToolFactory.createScanner(false, false, true, false); 393 scanner.setSource(buffer.getCharacters()); 394 } 395 scanner.resetTo(sourceRange.getOffset(), nameRange.getOffset()); 396 if (findAnnotation(scanner, annotationType)) { 397 return true; 398 } 399 } 400 } 401 } catch (JavaModelException e) { 402 } catch (InvalidInputException e) { 403 } 404 return false; 405 } 406 407 private boolean findAnnotation(IScanner scanner, String annotationName) throws InvalidInputException { 408 String simpleName= Signature.getSimpleName(annotationName); 409 StringBuffer buf= new StringBuffer (); 410 int tok= scanner.getNextToken(); 411 while (tok != ITerminalSymbols.TokenNameEOF) { 412 if (tok == ITerminalSymbols.TokenNameAT) { 413 buf.setLength(0); 414 tok= readName(scanner, buf); 415 String name= buf.toString(); 416 if (name.equals(annotationName) || name.equals(simpleName) || name.endsWith('.' + simpleName)) { 417 return true; 418 } 419 } else { 420 tok= scanner.getNextToken(); 421 } 422 } 423 return false; 424 } 425 426 private int readName(IScanner scanner, StringBuffer buf) throws InvalidInputException { 427 int tok= scanner.getNextToken(); 428 while (tok == ITerminalSymbols.TokenNameIdentifier) { 429 buf.append(scanner.getCurrentTokenSource()); 430 tok= scanner.getNextToken(); 431 if (tok != ITerminalSymbols.TokenNameDOT) { 432 return tok; 433 } 434 buf.append('.'); 435 tok= scanner.getNextToken(); 436 } 437 return tok; 438 } 439 440 446 private boolean hasProjectNature(IJavaElement element, String ntype) { 447 try { 448 if(element != null) { 449 IJavaProject jproj = element.getJavaProject(); 450 if(jproj != null) { 451 IProject proj = jproj.getProject(); 452 return proj.isAccessible() && proj.hasNature(ntype); 453 } 454 } 455 return false; 456 } 457 catch (CoreException e) {return false;} 458 } 459 460 466 private boolean hasSuperclass(IJavaElement element, String qname) { 467 try { 468 IType type = getType(element); 469 if(type != null) { 470 IType[] stypes = type.newSupertypeHierarchy(new NullProgressMonitor()).getAllSuperclasses(type); 471 for(int i = 0; i < stypes.length; i++) { 472 if(stypes[i].getFullyQualifiedName().equals(qname) || stypes[i].getElementName().equals(qname)) { 473 return true; 474 } 475 } 476 } 477 } 478 catch(JavaModelException e) {} 479 return false; 480 } 481 482 492 private boolean hasItemOnBuildPath(IJavaElement element, Object [] args) { 493 if(element != null && args != null) { 494 IJavaProject project = element.getJavaProject(); 495 Set searched = new HashSet (); 496 searched.add(project); 497 return hasItemsOnBuildPath(project, searched, args); 498 } 499 return false; 500 } 501 502 private boolean hasItemsOnBuildPath(IJavaProject project, Set searched, Object [] args) { 503 try { 504 List projects = new ArrayList (); 505 if(project != null && project.exists()) { 506 IClasspathEntry[] entries = project.getResolvedClasspath(true); 507 for(int i = 0; i < entries.length; i++) { 508 IClasspathEntry entry = entries[i]; 509 IPath path = entry.getPath(); 510 String spath = path.toPortableString(); 511 for(int j = 0; j < args.length; j++) { 512 if(spath.lastIndexOf((String )args[j]) != -1) { 513 return true; 514 } 515 } 516 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { 517 String name = entry.getPath().lastSegment(); 518 IProject dep = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 519 IJavaProject javaProject = JavaCore.create(dep); 520 if (!searched.contains(javaProject)) { 521 projects.add(javaProject); 522 } 523 } 524 } 525 } 526 Iterator iterator = projects.iterator(); 528 while (iterator.hasNext()) { 529 IJavaProject jp = (IJavaProject) iterator.next(); 530 searched.add(jp); 531 if (hasItemsOnBuildPath(jp, searched, args)) { 532 return true; 533 } 534 } 535 } catch (JavaModelException e) {} 536 return false; 537 } 538 539 545 private boolean implementsInterface(IJavaElement element, String qname) { 546 try { 547 IType type = getType(element); 548 if(type != null) { 549 IType[] itypes = type.newSupertypeHierarchy(new NullProgressMonitor()).getAllInterfaces(); 550 for(int i = 0; i < itypes.length; i++) { 551 if(itypes[i].getFullyQualifiedName().equals(qname)) { 552 return true; 553 } 554 } 555 } 556 } 557 catch(JavaModelException e) {} 558 return false; 559 } 560 561 578 public boolean test(Object receiver, String property, Object [] args, Object expectedValue) { 579 if (PROPERTY_IS_CONTAINER.equals(property)) { 580 if (receiver instanceof IAdaptable) { 581 IResource resource = (IResource)((IAdaptable)receiver).getAdapter(IResource.class); 582 if (resource != null) { 583 return resource instanceof IContainer; 584 } 585 } 586 return false; 587 } 588 IJavaElement element = null; 589 if (receiver instanceof IAdaptable) { 590 element = (IJavaElement) ((IAdaptable)receiver).getAdapter(IJavaElement.class); 591 if(element != null) { 592 if(!element.exists()) { 593 return false; 594 } 595 } 596 } 597 if(PROPERTY_HAS_MAIN.equals(property)) { 598 return hasMain(element); 599 } 600 if (PROPERTY_HAS_METHOD.equals(property)) { 601 return hasMethod(element, args); 602 } 603 if (PROPERTY_HAS_METHOD_WITH_ANNOTATION.equals(property)) { 604 return hasMethodWithAnnotation(element, args); 605 } 606 if (PROPERTY_HAS_TYPE_WITH_ANNOTATION.equals(property)) { 607 return hasTypeWithAnnotation(element, (String )args[0]); 608 } 609 if(PROPERTY_BUILDPATH_REFERENCE.equals(property)) { 610 return hasItemOnBuildPath(element, args); 611 } 612 if(PROPERTY_EXTENDS_CLASS.equals(property)) { 613 return hasSuperclass(element, (String )args[0]); 614 } 615 if(PROPERTY_PROJECT_NATURE.equals(property)) { 616 return hasProjectNature(element, (String )args[0]); 617 } 618 if(PROPERTY_EXTENDS_INTERFACE.equals(property)) { 619 return implementsInterface(element, (String )args[0]); 620 } 621 if (PROPERTY_IS_PACKAGE_FRAGMENT.equals(property)) { 622 return element instanceof IPackageFragment; 623 } 624 if (PROPERTY_IS_PACKAGE_FRAGMENT_ROOT.equals(property)) { 625 return element instanceof IPackageFragmentRoot; 626 } 627 return false; 628 } 629 630 } 631 | Popular Tags |