1 19 20 package org.netbeans.modules.java.navigation; 21 22 import com.sun.javadoc.Doc; 23 import org.netbeans.api.java.source.CancellableTask; 24 import org.netbeans.api.java.source.CompilationController; 25 import org.netbeans.api.java.source.CompilationInfo; 26 import org.netbeans.api.java.source.ElementHandle; 27 import org.netbeans.api.java.source.JavaSource; 28 import org.netbeans.api.java.source.JavaSource.Phase; 29 import org.netbeans.api.java.source.SourceUtils; 30 import org.netbeans.api.java.source.UiUtils; 31 import org.openide.ErrorManager; 32 import org.openide.filesystems.FileObject; 33 import java.io.IOException ; 34 import java.util.ArrayList ; 35 import java.util.List ; 36 import java.util.Set ; 37 import javax.lang.model.element.Element; 38 import javax.lang.model.element.ElementKind; 39 import javax.lang.model.element.ExecutableElement; 40 import javax.lang.model.element.Modifier; 41 import javax.lang.model.element.PackageElement; 42 import javax.lang.model.element.TypeElement; 43 import javax.lang.model.element.VariableElement; 44 import javax.lang.model.type.DeclaredType; 45 import javax.lang.model.type.TypeKind; 46 import javax.lang.model.type.TypeMirror; 47 import javax.swing.Icon ; 48 import javax.swing.tree.DefaultMutableTreeNode ; 49 import javax.swing.tree.DefaultTreeModel ; 50 51 56 public final class JavaMembersModel extends DefaultTreeModel { 57 static Element[] EMPTY_ELEMENTS_ARRAY = new Element[0]; 58 static ElementHandle[] EMPTY_ELEMENTHANDLES_ARRAY = new ElementHandle[0]; 59 60 private String pattern = ""; private String patternLowerCase = ""; private FileObject fileObject; 63 private ElementHandle[] elementHandles; 64 65 71 public JavaMembersModel(FileObject fileObject, Element[] elements, CompilationInfo compilationInfo) { 72 super(null); 73 this.fileObject = fileObject; 74 75 if ((elements == null) || (elements.length == 0)) { 76 elementHandles = EMPTY_ELEMENTHANDLES_ARRAY; 77 } else { 78 List <ElementHandle> elementHandlesList = new ArrayList <ElementHandle>(elements.length); 79 80 for (Element element : elements) { 81 elementHandlesList.add(ElementHandle.create(element)); 82 } 83 84 elementHandles = elementHandlesList.toArray(EMPTY_ELEMENTHANDLES_ARRAY); 85 } 86 87 update(elements, compilationInfo); 88 } 89 90 94 public String getPattern() { 95 return this.pattern; 96 } 97 98 102 public void setPattern(String pattern) { 103 this.pattern = pattern; 104 105 if (pattern == null) { 106 patternLowerCase = null; 107 } else { 108 patternLowerCase = pattern.toLowerCase(); 109 } 110 } 111 112 115 public void update() { 116 update(elementHandles); 117 } 118 119 private void update(final ElementHandle[] elementHandles) { 120 if ((elementHandles == null) && (elementHandles.length == 0)) { 121 return; 122 } 123 124 JavaSource javaSource = JavaSource.forFileObject(fileObject); 125 126 if (javaSource != null) { 127 try { 128 javaSource.runUserActionTask(new CancellableTask<CompilationController>() { 129 public void cancel() { 130 } 131 132 public void run( 133 CompilationController compilationController) 134 throws Exception { 135 compilationController.toPhase(Phase.ELEMENTS_RESOLVED); 136 137 List <Element> elementsList = new ArrayList <Element>(elementHandles.length); 138 139 for (ElementHandle elementHandle : elementHandles) { 140 elementsList.add(elementHandle.resolve( 141 compilationController)); 142 } 143 144 Element[] elements = elementsList.toArray(EMPTY_ELEMENTS_ARRAY); 145 update(elements, compilationController); 146 } 147 }, false); 148 149 return; 150 } catch (IOException ioe) { 151 ErrorManager.getDefault().notify(ioe); 152 } 153 } 154 } 155 156 private void update(final Element[] elements, 157 CompilationInfo compilationInfo) { 158 if ((elements == null) && (elements.length == 0)) { 159 return; 160 } 161 162 DefaultMutableTreeNode root = new DefaultMutableTreeNode (); 163 164 for (Element element : elements) { 165 if (element.getKind() == ElementKind.PACKAGE) { 166 root.add(new PackageTreeNode(fileObject, 167 ((PackageElement) element), compilationInfo)); 168 } else if ((element.getKind() == ElementKind.CLASS) || 169 (element.getKind() == ElementKind.INTERFACE) || 170 (element.getKind() == ElementKind.ENUM)) { 171 root.add(new TypeTreeNode(fileObject, ((TypeElement) element), 172 compilationInfo)); 173 } else if (element.getKind() == ElementKind.CONSTRUCTOR) { 174 root.add(new ConstructorTreeNode(fileObject, 175 ((ExecutableElement) element), compilationInfo)); 176 } else if (element.getKind() == ElementKind.METHOD) { 177 root.add(new MethodTreeNode(fileObject, 178 ((ExecutableElement) element), compilationInfo)); 179 } else if (element.getKind() == ElementKind.FIELD) { 180 root.add(new FieldTreeNode(fileObject, 181 ((VariableElement) element), compilationInfo)); 182 } else if (element.getKind() == ElementKind.ENUM_CONSTANT) { 183 root.add(new EnumConstantTreeNode(fileObject, 184 ((VariableElement) element), compilationInfo)); 185 } 186 } 187 188 setRoot(root); 189 } 190 191 boolean patternMatch(JavaElement javaToolsJavaElement) { 192 return Utils.patternMatch(javaToolsJavaElement, pattern, patternLowerCase); 193 } 194 195 private abstract class AbstractMembersTreeNode 196 extends DefaultMutableTreeNode implements JavaElement { 197 private FileObject fileObject; 198 private ElementHandle<?extends Element> elementHandle; 199 private ElementKind elementKind; 200 private Set <Modifier> modifiers; 201 private String name = ""; 202 private String label = ""; 203 private String tooltip = null; 204 private Icon icon = null; 205 private String javaDoc = ""; 206 207 AbstractMembersTreeNode(FileObject fileObject, 208 Element element, CompilationInfo compilationInfo) { 209 this.fileObject = fileObject; 210 this.elementHandle = ElementHandle.create(element); 211 this.elementKind = element.getKind(); 212 this.modifiers = element.getModifiers(); 213 214 setName(element.getSimpleName().toString()); 215 setIcon(UiUtils.getElementIcon(element.getKind(), 216 element.getModifiers())); 217 setLabel(Utils.format(element)); 218 setToolTip(Utils.format(element, true)); 219 Doc doc = compilationInfo.getElementUtilities().javaDocFor(element); 220 if (doc != null) { 221 StringBuilder stringBuilder = new StringBuilder (); 222 setJavaDoc(doc.getRawCommentText()); 223 } 224 loadChildren(element, compilationInfo); 225 } 226 227 public FileObject getFileObject() { 228 return fileObject; 229 } 230 231 public String getName() { 232 return name; 233 } 234 235 protected void setName(String name) { 236 this.name = name; 237 } 238 239 public String getLabel() { 240 return label; 241 } 242 243 protected void setLabel(String label) { 244 this.label = label; 245 } 246 247 public String getTooltip() { 248 return tooltip; 249 } 250 251 protected void setToolTip(String tooltip) { 252 this.tooltip = tooltip; 253 } 254 255 public Icon getIcon() { 256 return icon; 257 } 258 259 protected void setIcon(Icon icon) { 260 this.icon = icon; 261 } 262 263 protected void setElementHandle( 264 ElementHandle<?extends Element> elementHandle) { 265 this.elementHandle = elementHandle; 266 } 267 268 public String getJavaDoc() { 269 return javaDoc; 270 } 271 272 public void setJavaDoc(String javaDoc) { 273 this.javaDoc = javaDoc; 274 } 275 276 public Set <Modifier> getModifiers() { 277 return modifiers; 278 } 279 280 public ElementHandle getElementHandle() { 281 return elementHandle; 282 } 283 284 public void gotoElement() { 285 openElementHandle(); 286 } 287 288 protected abstract void loadChildren(Element element, 289 CompilationInfo compilationInfo); 290 291 public String toString() { 292 return getLabel(); 293 } 294 295 protected void openElementHandle() { 296 if (elementHandle == null) { 297 return; 298 } 299 300 UiUtils.open(fileObject, elementHandle); 301 } 302 } 303 304 private class PackageTreeNode extends AbstractMembersTreeNode { 305 PackageTreeNode(FileObject fileObject, PackageElement packageElement, 306 CompilationInfo compilationInfo) { 307 super(fileObject, packageElement, compilationInfo); 308 } 309 310 public boolean isLeaf() { 311 return true; 312 } 313 314 protected void loadChildren(Element element, 315 CompilationInfo compilationInfo) { 316 } 317 } 318 319 private class TypeTreeNode extends AbstractMembersTreeNode { 320 private boolean inSuperClassRole; 321 322 TypeTreeNode(FileObject fileObject, TypeElement typeElement, 323 CompilationInfo compilationInfo) { 324 this(fileObject, typeElement, compilationInfo, false); 325 } 326 327 TypeTreeNode(FileObject fileObject, TypeElement typeElement, 328 CompilationInfo compilationInfo, boolean inSuperClassRole) { 329 super(fileObject, typeElement, compilationInfo); 330 this.inSuperClassRole = inSuperClassRole; 331 } 332 333 public boolean isLeaf() { 334 return false; 335 } 336 337 protected void loadChildren(Element element, 338 CompilationInfo compilationInfo) { 339 loadChildren(element, compilationInfo, 0); 340 } 341 342 protected int loadChildren(Element element, 343 CompilationInfo compilationInfo, int index) { 344 TypeElement typeElement = (TypeElement) element; 345 346 List <?extends Element> enclosedElements = typeElement.getEnclosedElements(); 347 348 for (Element enclosedElement : enclosedElements) { 349 AbstractMembersTreeNode node = null; 350 351 if (enclosedElement.getKind() == ElementKind.CLASS || 352 enclosedElement.getKind() == ElementKind.INTERFACE|| 353 enclosedElement.getKind() == ElementKind.ENUM) { 354 if (!JavaMembersAndHierarchyOptions.isShowInner()) { 355 continue; 356 } 357 358 if (JavaMembersAndHierarchyOptions.isShowInherited()) { 359 continue; 360 } 361 362 node = new TypeTreeNode(getFileObject(), 363 (TypeElement) enclosedElement, compilationInfo); 364 } else { 365 Set <Modifier> modifiers = enclosedElement.getModifiers(); 366 367 if (enclosedElement.getKind() == ElementKind.CONSTRUCTOR) { 368 if (!JavaMembersAndHierarchyOptions.isShowConstructors()) { 369 continue; 370 } 371 372 ExecutableElement constructor = (ExecutableElement) enclosedElement; 373 374 if ((!modifiers.contains(Modifier.PUBLIC) && 375 !modifiers.contains(Modifier.PROTECTED) && 376 !modifiers.contains(Modifier.PRIVATE)) && 377 !JavaMembersAndHierarchyOptions.isShowPackage()) { 378 continue; 379 } else if (modifiers.contains(Modifier.PROTECTED) && 380 !JavaMembersAndHierarchyOptions.isShowProtected()) { 381 continue; 382 } else if (modifiers.contains(Modifier.PRIVATE) && 383 !JavaMembersAndHierarchyOptions.isShowPrivate()) { 384 continue; 385 } 386 387 node = new ConstructorTreeNode(getFileObject(), 388 constructor, compilationInfo); 389 } else if (enclosedElement.getKind() == ElementKind.METHOD) { 390 if (!JavaMembersAndHierarchyOptions.isShowMethods()) { 391 continue; 392 } 393 394 ExecutableElement method = (ExecutableElement) enclosedElement; 395 396 if ((!modifiers.contains(Modifier.PUBLIC) && 397 !modifiers.contains(Modifier.PROTECTED) && 398 !modifiers.contains(Modifier.PRIVATE)) && 399 !JavaMembersAndHierarchyOptions.isShowPackage()) { 400 continue; 401 } else if (modifiers.contains(Modifier.PROTECTED) && 402 !JavaMembersAndHierarchyOptions.isShowProtected()) { 403 continue; 404 } else if (modifiers.contains(Modifier.PRIVATE) && 405 !JavaMembersAndHierarchyOptions.isShowPrivate()) { 406 continue; 407 } 408 409 if (modifiers.contains(Modifier.STATIC) && 410 !JavaMembersAndHierarchyOptions.isShowStatic()) { 411 continue; 412 } 413 414 node = new MethodTreeNode(getFileObject(), method, 415 compilationInfo); 416 } else if (enclosedElement.getKind() == ElementKind.FIELD) { 417 if (!JavaMembersAndHierarchyOptions.isShowFields()) { 418 continue; 419 } 420 421 VariableElement field = (VariableElement) enclosedElement; 422 423 if ((!modifiers.contains(Modifier.PUBLIC) && 424 !modifiers.contains(Modifier.PROTECTED) && 425 !modifiers.contains(Modifier.PRIVATE)) && 426 !JavaMembersAndHierarchyOptions.isShowPackage()) { 427 continue; 428 } else if (modifiers.contains(Modifier.PROTECTED) && 429 !JavaMembersAndHierarchyOptions.isShowProtected()) { 430 continue; 431 } else if (modifiers.contains(Modifier.PRIVATE) && 432 !JavaMembersAndHierarchyOptions.isShowPrivate()) { 433 continue; 434 } 435 436 if (modifiers.contains(Modifier.STATIC) && 437 !JavaMembersAndHierarchyOptions.isShowStatic()) { 438 continue; 439 } 440 441 node = new FieldTreeNode(getFileObject(), field, 442 compilationInfo); 443 } else if (enclosedElement.getKind() == ElementKind.ENUM_CONSTANT) { 444 if (!JavaMembersAndHierarchyOptions.isShowEnumConstants()) { 445 continue; 446 } 447 448 VariableElement enumConstant = (VariableElement) enclosedElement; 449 450 if ((!modifiers.contains(Modifier.PUBLIC) && 451 !modifiers.contains(Modifier.PROTECTED) && 452 !modifiers.contains(Modifier.PRIVATE)) && 453 !JavaMembersAndHierarchyOptions.isShowPackage()) { 454 continue; 455 } else if (modifiers.contains(Modifier.PROTECTED) && 456 !JavaMembersAndHierarchyOptions.isShowProtected()) { 457 continue; 458 } else if (modifiers.contains(Modifier.PRIVATE) && 459 !JavaMembersAndHierarchyOptions.isShowPrivate()) { 460 continue; 461 } 462 463 if (modifiers.contains(Modifier.STATIC) && 464 !JavaMembersAndHierarchyOptions.isShowStatic()) { 465 continue; 466 } 467 468 node = new EnumConstantTreeNode(getFileObject(), 469 enumConstant, compilationInfo); 470 } 471 472 if ((node == null) || !patternMatch(node)) { 473 continue; 474 } 475 } 476 477 if (node == null) { 478 continue; 479 } 480 481 insert(node, index++); 482 } 483 484 if (JavaMembersAndHierarchyOptions.isShowInherited()) { 485 TypeMirror superClassTypeMirror = typeElement.getSuperclass(); 486 487 if (superClassTypeMirror.getKind() == TypeKind.NONE) { 488 } else { 490 TypeElement superClass = (TypeElement) ((DeclaredType) typeElement.getSuperclass()).asElement(); 491 492 if ((superClass != null) && 493 !superClass.getQualifiedName().toString() 494 .equals(Object .class.getName())) { 495 FileObject fileObject = SourceUtils.getFile(superClass, 496 compilationInfo.getClasspathInfo()); 497 insert(new TypeTreeNode(fileObject, superClass, 498 compilationInfo, true), index++); 499 } 500 } 501 502 List <?extends TypeMirror> interfaces = typeElement.getInterfaces(); 503 504 for (TypeMirror interfaceTypeMirror : interfaces) { 505 TypeElement anInterface = (TypeElement) ((DeclaredType) interfaceTypeMirror).asElement(); 506 FileObject fileObject = SourceUtils.getFile(anInterface, 507 compilationInfo.getClasspathInfo()); 508 insert(new TypeTreeNode(fileObject, anInterface, 509 compilationInfo, true), index++); 510 } 511 } 512 513 if (JavaMembersAndHierarchyOptions.isShowInner()) { 514 if (!inSuperClassRole && 515 JavaMembersAndHierarchyOptions.isShowInherited()) { 516 for (Element enclosedElement : enclosedElements) { 517 if (enclosedElement.getKind() == ElementKind.CLASS || 518 enclosedElement.getKind() == ElementKind.INTERFACE || 519 enclosedElement.getKind() == ElementKind.ENUM 520 ) { 521 AbstractMembersTreeNode node = new TypeTreeNode(getFileObject(), 522 (TypeElement) enclosedElement, 523 compilationInfo); 524 insert(node, index++); 525 } 526 } 527 } 528 } 529 530 return index; 531 } 532 } 533 534 private class ConstructorTreeNode extends AbstractMembersTreeNode { 535 ConstructorTreeNode(FileObject fileObject, 536 ExecutableElement contructorElement, CompilationInfo compilationInfo) { 537 super(fileObject, contructorElement, compilationInfo); 538 } 539 540 public boolean isLeaf() { 541 return true; 542 } 543 544 protected void loadChildren(Element element, 545 CompilationInfo compilationInfo) { 546 } 547 } 548 549 private class MethodTreeNode extends AbstractMembersTreeNode { 550 MethodTreeNode(FileObject fileObject, ExecutableElement methodElement, 551 CompilationInfo compilationInfo) { 552 super(fileObject, methodElement, compilationInfo); 553 } 554 555 public boolean isLeaf() { 556 return true; 557 } 558 559 protected void loadChildren(Element element, 560 CompilationInfo compilationInfo) { 561 } 562 } 563 564 private class FieldTreeNode extends AbstractMembersTreeNode { 565 FieldTreeNode(FileObject fileObject, VariableElement variableElement, 566 CompilationInfo compilationInfo) { 567 super(fileObject, variableElement, compilationInfo); 568 } 569 570 public boolean isLeaf() { 571 return true; 572 } 573 574 protected void loadChildren(Element element, 575 CompilationInfo compilationInfo) { 576 } 577 } 578 579 private class EnumConstantTreeNode extends AbstractMembersTreeNode { 580 EnumConstantTreeNode(FileObject fileObject, 581 VariableElement variableElement, CompilationInfo compilationInfo) { 582 super(fileObject, variableElement, compilationInfo); 583 } 584 585 public boolean isLeaf() { 586 return true; 587 } 588 589 protected void loadChildren(Element element, 590 CompilationInfo compilationInfo) { 591 } 592 } 593 } 594 | Popular Tags |