1 19 20 package org.netbeans.modules.java.navigation; 21 22 import java.awt.Rectangle ; 23 import java.util.EnumSet ; 24 import java.util.List ; 25 import java.util.Set ; 26 import java.util.regex.Matcher ; 27 import java.util.regex.Pattern ; 28 import java.util.regex.PatternSyntaxException ; 29 30 import javax.lang.model.element.Element; 31 import javax.swing.JEditorPane ; 32 import javax.swing.JTree ; 33 import javax.swing.SwingUtilities ; 34 import static javax.lang.model.element.ElementKind.*; 35 import javax.lang.model.element.ExecutableElement; 36 import javax.lang.model.element.Modifier; 37 import javax.lang.model.element.PackageElement; 38 import javax.lang.model.element.TypeElement; 39 import javax.lang.model.element.TypeParameterElement; 40 import javax.lang.model.element.VariableElement; 41 import javax.lang.model.type.ArrayType; 42 import javax.lang.model.type.DeclaredType; 43 import static javax.lang.model.type.TypeKind.*; 44 import javax.lang.model.type.TypeMirror; 45 import javax.lang.model.type.TypeVariable; 46 import javax.lang.model.type.WildcardType; 47 48 52 class Utils { 53 static String format(Element element) { 54 return format(element, false); 55 } 56 57 static String format(Element element, boolean forSignature) { 58 StringBuilder stringBuilder = new StringBuilder (); 59 format(element, stringBuilder, forSignature); 60 61 return stringBuilder.toString(); 62 } 63 64 static void format(Element element, StringBuilder stringBuilder, boolean forSignature) { 65 if (element == null) { 66 return; 67 } 68 69 boolean first = true; 70 Set <Modifier> modifiers = element.getModifiers(); 71 72 switch (element.getKind()) { 73 case PACKAGE: 74 75 PackageElement packageElement = (PackageElement) element; 76 if (forSignature) { 77 stringBuilder.append("package "); } 79 stringBuilder.append(packageElement.getQualifiedName()); 80 break; 81 82 case CLASS: 83 case INTERFACE: 84 case ENUM: 85 if (forSignature) { 86 stringBuilder.append(toString(modifiers)); 87 if (modifiers.size() > 0) { 88 if (stringBuilder.length() > 0) { 89 stringBuilder.append(" "); 90 } 91 } 92 } 93 94 if (forSignature) { 95 switch (element.getKind()) { 96 case CLASS: 97 stringBuilder.append("class "); break; 99 case INTERFACE: 100 stringBuilder.append("interface "); break; 102 case ENUM: 103 stringBuilder.append("enum "); break; 105 } 106 } 107 108 TypeElement typeElement = (TypeElement) element; 109 stringBuilder.append(JavaMembersAndHierarchyOptions.isShowFQN() 110 ? typeElement.getQualifiedName().toString() 111 : typeElement.getSimpleName().toString()); 112 113 formatTypeParameters(typeElement.getTypeParameters(), stringBuilder); 114 115 if (!forSignature) { 116 if (modifiers.size() > 0) { 117 stringBuilder.append(" : "); 118 stringBuilder.append(toString(modifiers)); 119 } 120 } 121 122 break; 123 124 case CONSTRUCTOR: 125 if (forSignature) { 126 stringBuilder.append(toString(modifiers)); 127 if (modifiers.size() > 0) { 128 if (stringBuilder.length() > 0) { 129 stringBuilder.append(" "); 130 } 131 } 132 } 133 134 ExecutableElement constructorElement = (ExecutableElement) element; 135 stringBuilder.append(constructorElement.getEnclosingElement() 136 .getSimpleName().toString()); 137 stringBuilder.append("("); 138 formatVariableElements(constructorElement.getParameters(), 139 constructorElement.isVarArgs(), stringBuilder); 140 stringBuilder.append(")"); 141 142 List <? extends TypeMirror> thrownTypesMirrors = constructorElement.getThrownTypes(); 143 if (!thrownTypesMirrors.isEmpty()) { 144 stringBuilder.append(" throws "); formatTypeMirrors(thrownTypesMirrors, stringBuilder); 146 } 147 if (!forSignature) { 148 if (modifiers.size() > 0) { 149 stringBuilder.append(":"); 150 stringBuilder.append(toString(modifiers)); 151 } 152 } 153 154 break; 155 156 case METHOD: 157 ExecutableElement methodElement = (ExecutableElement) element; 158 TypeMirror returnTypeMirror = methodElement.getReturnType(); 159 List <?extends TypeParameterElement> typeParameters = methodElement.getTypeParameters(); 160 161 if (forSignature) { 162 stringBuilder.append(toString(modifiers)); 163 164 if (modifiers.size() > 0) { 165 if (stringBuilder.length() > 0) { 166 stringBuilder.append(" "); 167 } 168 } 169 170 if ((typeParameters != null) && (typeParameters.size() > 0)) { 171 formatTypeParameters(typeParameters, stringBuilder); 172 if (stringBuilder.length() > 0) { 173 stringBuilder.append(" "); 174 } 175 } 176 177 178 179 formatTypeMirror(returnTypeMirror, stringBuilder); 180 } 181 182 if (stringBuilder.length() > 0) { 183 stringBuilder.append(" "); 184 } 185 186 stringBuilder.append(methodElement.getSimpleName().toString()); 187 stringBuilder.append("("); 188 formatVariableElements(methodElement.getParameters(), 189 methodElement.isVarArgs(), stringBuilder); 190 stringBuilder.append(")"); 191 192 List <? extends TypeMirror> thrownTypesMirrorsByMethod = methodElement.getThrownTypes(); 193 if (!thrownTypesMirrorsByMethod.isEmpty()) { 194 stringBuilder.append(" throws "); formatTypeMirrors(thrownTypesMirrorsByMethod, stringBuilder); 196 } 197 198 if (!forSignature) { 199 stringBuilder.append(":"); 200 201 if (modifiers.size() > 0) { 202 stringBuilder.append(toString(modifiers)); 203 if (modifiers.size() > 0) { 204 stringBuilder.append(" "); 205 } 206 } 207 208 formatTypeMirror(returnTypeMirror, stringBuilder); 209 210 if ((typeParameters != null) && (typeParameters.size() > 0)) { 211 stringBuilder.append(":"); 212 formatTypeParameters(typeParameters, stringBuilder); 213 } 214 215 if (JavaMembersAndHierarchyOptions.isShowInherited()) { 216 stringBuilder.append(" ["); 217 stringBuilder.append(element.getEnclosingElement()); 218 stringBuilder.append("]"); 219 } 220 } 221 222 break; 223 224 case TYPE_PARAMETER: 225 TypeParameterElement typeParameterElement = (TypeParameterElement) element; 226 stringBuilder.append(typeParameterElement.getSimpleName()); 227 228 List <?extends TypeMirror> bounds = null; 229 try { 230 bounds = typeParameterElement.getBounds(); 231 if ((bounds != null) && (bounds.size() > 0)) { 232 if (bounds.size() == 1 && "java.lang.Object".equals( bounds.get(0).toString())) { } else { 234 stringBuilder.append(" extends "); first = true; 236 for (TypeMirror typeMirror : bounds) { 237 if (first) { 238 first = false; 239 } else { 240 stringBuilder.append(" & "); } 242 formatTypeMirror(typeMirror, stringBuilder); 243 } 244 } 245 } 246 } catch (NullPointerException npe) { 247 } 249 250 break; 251 252 case FIELD: 253 VariableElement fieldElement = (VariableElement) element; 254 if (forSignature) { 255 stringBuilder.append(toString(modifiers)); 256 257 if (stringBuilder.length() > 0) { 258 stringBuilder.append(" "); 259 } 260 261 formatTypeMirror(fieldElement.asType(), stringBuilder); 262 } 263 264 if (stringBuilder.length() > 0) { 265 stringBuilder.append(" "); 266 } 267 268 stringBuilder.append(fieldElement.getSimpleName().toString()); 269 270 if (!forSignature) { 271 stringBuilder.append(":"); 272 if (modifiers.size() > 0) { 273 stringBuilder.append(toString(modifiers)); 274 } 275 276 if (stringBuilder.length() > 0) { 277 stringBuilder.append(" "); 278 } 279 280 formatTypeMirror(fieldElement.asType(), stringBuilder); 281 282 if (JavaMembersAndHierarchyOptions.isShowInherited()) { 283 stringBuilder.append(" ["); 284 stringBuilder.append(element.getEnclosingElement()); 285 stringBuilder.append("]"); 286 } 287 } 288 289 break; 290 291 case ENUM_CONSTANT: 292 stringBuilder.append(element.toString()); 293 294 if (modifiers.size() > 0) { 295 stringBuilder.append(":"); 296 stringBuilder.append(toString(modifiers)); 297 } 298 299 if (JavaMembersAndHierarchyOptions.isShowInherited()) { 300 stringBuilder.append(" ["); 301 stringBuilder.append(element.getEnclosingElement()); 302 stringBuilder.append("]"); 303 } 304 305 break; 306 307 case PARAMETER: 308 VariableElement variableElement = (VariableElement) element; 309 formatTypeMirror(variableElement.asType(), stringBuilder); 310 stringBuilder.append(" "); 311 stringBuilder.append(element.getSimpleName().toString()); 312 313 break; 314 } 315 } 316 317 static void formatTypeMirror(TypeMirror typeMirror, 318 StringBuilder stringBuilder) { 319 if (typeMirror == null) { 320 return; 321 } 322 323 boolean first = true; 324 325 switch (typeMirror.getKind()) { 326 case BOOLEAN: 327 case BYTE: 328 case CHAR: 329 case DOUBLE: 330 case FLOAT: 331 case INT: 332 case LONG: 333 case NONE: 334 case NULL: 335 case SHORT: 336 case VOID: 337 stringBuilder.append(typeMirror); 338 339 break; 340 341 case TYPEVAR: 342 TypeVariable typeVariable = (TypeVariable)typeMirror; 343 stringBuilder.append(typeVariable.asElement().getSimpleName().toString()); 344 break; 345 346 case WILDCARD: 347 WildcardType wildcardType = (WildcardType)typeMirror; 348 stringBuilder.append("?"); 349 if ( wildcardType.getExtendsBound() != null ) { 350 stringBuilder.append(" extends "); formatTypeMirror(wildcardType.getExtendsBound(), stringBuilder); 352 } 353 if ( wildcardType.getSuperBound() != null ) { 354 stringBuilder.append(" super "); formatTypeMirror(wildcardType.getSuperBound(), stringBuilder); 356 } 357 358 break; 359 360 case DECLARED: 361 DeclaredType declaredType = (DeclaredType) typeMirror; 362 Element element = declaredType.asElement(); 363 if (element instanceof TypeElement) { 364 stringBuilder.append( 365 JavaMembersAndHierarchyOptions.isShowFQN() ? 366 ((TypeElement)element).getQualifiedName().toString() : 367 element.getSimpleName().toString()); 368 } else { 369 stringBuilder.append(element.getSimpleName().toString()); 370 } 371 List <? extends TypeMirror> typeArgs = declaredType.getTypeArguments(); 372 if ( !typeArgs.isEmpty() ) { 373 stringBuilder.append("<"); 374 formatTypeMirrors(typeArgs, stringBuilder); 375 stringBuilder.append(">"); 376 } 377 378 break; 379 380 case ARRAY: 381 382 int dims = 0; 383 384 while (typeMirror.getKind() == ARRAY) { 385 dims++; 386 typeMirror = ((ArrayType) typeMirror).getComponentType(); 387 } 388 389 formatTypeMirror(typeMirror, stringBuilder); 390 391 for (int i = 0; i < dims; i++) { 392 stringBuilder.append("[]"); 393 } 394 395 break; 396 } 397 } 398 399 static void formatTypeParameters( 400 List <? extends TypeParameterElement> typeParameters, 401 StringBuilder stringBuilder) { 402 if ((typeParameters == null) || (typeParameters.size() == 0)) { 403 return; 404 } 405 406 boolean first = true; 407 408 if (typeParameters.size() > 0) { 409 stringBuilder.append("<"); 410 first = true; 411 412 for (TypeParameterElement typeParameterElement : typeParameters) { 413 if (first) { 414 first = false; 415 } else { 416 stringBuilder.append(", "); 417 } 418 419 format(typeParameterElement, stringBuilder, false); 420 } 421 422 stringBuilder.append(">"); 423 } 424 } 425 426 static void formatVariableElements( 427 List <? extends VariableElement> variableElements, boolean varArgs, 428 StringBuilder stringBuilder) { 429 if ((variableElements == null) || (variableElements.size() == 0)) { 430 return; 431 } 432 433 boolean first = true; 434 435 for (VariableElement variableElement : variableElements) { 436 if (first) { 437 first = false; 438 } else { 439 stringBuilder.append(", "); 440 } 441 442 format(variableElement, stringBuilder, false); 443 } 444 445 if (varArgs) { 446 stringBuilder.append("..."); 447 } 448 } 449 450 static void formatTypeMirrors(List <?extends TypeMirror> thrownTypeMirros, 451 StringBuilder stringBuilder) { 452 if ((thrownTypeMirros == null) || (thrownTypeMirros.size() == 0)) { 453 return; 454 } 455 456 boolean first = true; 457 458 for (TypeMirror typeMirror : thrownTypeMirros) { 459 if (first) { 460 first = false; 461 } else { 462 stringBuilder.append(", "); 463 } 464 465 formatTypeMirror(typeMirror, stringBuilder); 466 } 467 } 468 469 static int getIntModifiers(Set <Modifier> modifiers) { 470 int intModifiers = 0; 471 472 if (modifiers.contains(Modifier.ABSTRACT)) { 473 intModifiers |= java.lang.reflect.Modifier.ABSTRACT; 474 } 475 476 if (modifiers.contains(Modifier.FINAL)) { 477 intModifiers |= java.lang.reflect.Modifier.FINAL; 478 } 479 480 if (modifiers.contains(Modifier.NATIVE)) { 481 intModifiers |= java.lang.reflect.Modifier.NATIVE; 482 } 483 484 if (modifiers.contains(Modifier.PRIVATE)) { 485 intModifiers |= java.lang.reflect.Modifier.PRIVATE; 486 } 487 488 if (modifiers.contains(Modifier.PROTECTED)) { 489 intModifiers |= java.lang.reflect.Modifier.PROTECTED; 490 } 491 492 if (modifiers.contains(Modifier.PUBLIC)) { 493 intModifiers |= java.lang.reflect.Modifier.PUBLIC; 494 } 495 496 if (modifiers.contains(Modifier.STATIC)) { 497 intModifiers |= java.lang.reflect.Modifier.STATIC; 498 } 499 500 if (modifiers.contains(Modifier.STRICTFP)) { 501 intModifiers |= java.lang.reflect.Modifier.STRICT; 502 } 503 504 if (modifiers.contains(Modifier.SYNCHRONIZED)) { 505 intModifiers |= java.lang.reflect.Modifier.SYNCHRONIZED; 506 } 507 508 if (modifiers.contains(Modifier.TRANSIENT)) { 509 intModifiers |= java.lang.reflect.Modifier.TRANSIENT; 510 } 511 512 if (modifiers.contains(Modifier.VOLATILE)) { 513 intModifiers |= java.lang.reflect.Modifier.VOLATILE; 514 } 515 516 return intModifiers; 517 } 518 519 static String toString(Set <Modifier> modifiers) { 520 return java.lang.reflect.Modifier.toString(getIntModifiers(modifiers)); 521 } 522 523 static Set <Modifier> getModifiers(int intModifiers) { 524 EnumSet <Modifier> modifiers = EnumSet.noneOf(Modifier.class); 525 526 if ((intModifiers & java.lang.reflect.Modifier.ABSTRACT) != 0) { 527 modifiers.add(Modifier.ABSTRACT); 528 } 529 530 if ((intModifiers & java.lang.reflect.Modifier.FINAL) != 0) { 531 modifiers.add(Modifier.FINAL); 532 } 533 534 if ((intModifiers & java.lang.reflect.Modifier.NATIVE) != 0) { 535 modifiers.add(Modifier.NATIVE); 536 } 537 538 if ((intModifiers & java.lang.reflect.Modifier.PRIVATE) != 0) { 539 modifiers.add(Modifier.PRIVATE); 540 } 541 542 if ((intModifiers & java.lang.reflect.Modifier.PROTECTED) != 0) { 543 modifiers.add(Modifier.PROTECTED); 544 } 545 546 if ((intModifiers & java.lang.reflect.Modifier.PUBLIC) != 0) { 547 modifiers.add(Modifier.PUBLIC); 548 } 549 550 if ((intModifiers & java.lang.reflect.Modifier.STATIC) != 0) { 551 modifiers.add(Modifier.STATIC); 552 } 553 554 if ((intModifiers & java.lang.reflect.Modifier.STRICT) != 0) { 555 modifiers.add(Modifier.STRICTFP); 556 } 557 558 if ((intModifiers & java.lang.reflect.Modifier.SYNCHRONIZED) != 0) { 559 modifiers.add(Modifier.SYNCHRONIZED); 560 } 561 562 if ((intModifiers & java.lang.reflect.Modifier.TRANSIENT) != 0) { 563 modifiers.add(Modifier.TRANSIENT); 564 } 565 566 if ((intModifiers & java.lang.reflect.Modifier.VOLATILE) != 0) { 567 modifiers.add(Modifier.VOLATILE); 568 } 569 570 return modifiers; 571 } 572 573 static boolean patternMatch(JavaElement javaToolsJavaElement, String pattern, String patternLowerCase) { 574 575 if (pattern == null) { 576 return true; 577 } 578 579 String patternRegexpString = pattern; 580 581 if (pattern.trim().length() == 0) { 582 patternRegexpString = pattern + ".*"; 583 } else { 584 patternRegexpString = pattern. 586 replaceAll(Pattern.quote("*"), Matcher.quoteReplacement(".*")). 587 replaceAll(Pattern.quote("?"), Matcher.quoteReplacement(".")) + 588 (pattern.endsWith("$") ? "" : ".*"); 589 } 590 591 String name = javaToolsJavaElement.getName(); 592 593 try { 594 Pattern compiledPattern = Pattern.compile(patternRegexpString, 595 JavaMembersAndHierarchyOptions.isCaseSensitive() ? 0 596 : Pattern.CASE_INSENSITIVE); 597 Matcher m = compiledPattern.matcher(name); 598 599 return m.matches(); 600 } catch (PatternSyntaxException pse) { 601 if (JavaMembersAndHierarchyOptions.isCaseSensitive()) { 602 return name.startsWith(pattern); 603 } 604 605 return name.toLowerCase().startsWith(patternLowerCase); 606 } 607 } 608 609 static String getClassName(String className) { 610 int firstLessThan = className.indexOf('<'); 612 613 if (firstLessThan != -1) { 614 className = className.substring(0, firstLessThan); 615 } 616 617 if (!JavaMembersAndHierarchyOptions.isShowFQN()) { 618 int lastDot = className.lastIndexOf('.'); 619 620 if (lastDot != -1) { 621 className = className.substring(lastDot + 1); 622 } 623 } 624 625 return className; 626 } 627 628 static String getClassNameSansPackage(String className) { 629 int firstLessThan = className.indexOf('<'); 631 632 if (firstLessThan != -1) { 633 className = className.substring(0, firstLessThan); 634 } 635 636 int lastDot = className.lastIndexOf('.'); 637 638 if (lastDot != -1) { 639 className = className.substring(lastDot + 1); 640 } 641 642 return className; 643 } 644 645 static void firstRow(JTree tree) { 647 int rowCount = tree.getRowCount(); 648 if (rowCount > 0) { 649 tree.setSelectionRow(0); 650 scrollTreeToSelectedRow(tree); 651 } 652 } 653 654 static void previousRow(JTree tree) { 655 int rowCount = tree.getRowCount(); 656 if (rowCount > 0) { 657 int selectedRow = tree.getSelectionModel().getMinSelectionRow(); 658 if (selectedRow == -1) { 659 selectedRow = (rowCount -1); 660 } else { 661 selectedRow--; 662 if (selectedRow < 0) { 663 selectedRow = (rowCount -1); 664 } 665 } 666 tree.setSelectionRow(selectedRow); 667 scrollTreeToSelectedRow(tree); 668 } 669 } 670 671 static void nextRow(JTree tree) { 672 int rowCount = tree.getRowCount(); 673 if (rowCount > 0) { 674 int selectedRow = tree.getSelectionModel().getMinSelectionRow(); 675 if (selectedRow == -1) { 676 selectedRow = 0; 677 tree.setSelectionRow(selectedRow); 678 } else { 679 selectedRow++; 680 } 681 tree.setSelectionRow(selectedRow % rowCount); 682 scrollTreeToSelectedRow(tree); 683 } 684 } 685 686 static void lastRow(JTree tree) { 687 int rowCount = tree.getRowCount(); 688 if (rowCount > 0) { 689 tree.setSelectionRow(rowCount - 1); 690 scrollTreeToSelectedRow(tree); 691 } 692 } 693 694 static void scrollTreeToSelectedRow(final JTree tree) { 695 final int selectedRow = tree.getLeadSelectionRow(); 696 if (selectedRow >=0) { 697 SwingUtilities.invokeLater( 698 new Runnable () { 699 public void run() { 700 tree.scrollRectToVisible(tree.getRowBounds(selectedRow)); 701 } 702 } 703 ); 704 } 705 } 706 707 static void showJavaDoc(JavaElement node, final JEditorPane javaDocPane) { 709 javaDocPane.setText(""); 710 String javaDoc = ((JavaElement) node).getJavaDoc(); 711 if (javaDoc != null) { 712 javaDoc = javaDoc 714 .replaceAll("@author ", "<b>Author:</b> ") .replaceAll("@deprecated ", "<b>Deprecated:</b> ") .replaceAll("@exception ", "<b>Exception:</b> ") .replaceAll("@param ", "<b>Parameter:</b> ") .replaceAll("@return ", "<b>Return:</b> ") .replaceAll("@see ", "<b>See:</b> ") .replaceAll("@since ", "<b>Since:</b> ") .replaceAll("@throws ", "<b>Throws:</b> ") .replaceAll("@version ", "<b>Version:</b> ") ; 724 javaDocPane.setText( 725 "<html>" + "<head>" + "</head>" + "<body>" + javaDoc.replaceAll("\n", "<br>") + "</body>" + "</html>" ); 733 } 734 SwingUtilities.invokeLater(new Runnable () { 735 public void run() { 736 javaDocPane.scrollRectToVisible(new Rectangle (0,0,1,1)); 737 }}); 738 } 739 } 740 | Popular Tags |