1 19 20 package org.netbeans.modules.java.navigation; 21 22 import com.sun.javadoc.Doc; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import java.util.List ; 27 import java.util.Set ; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.Element; 30 import javax.lang.model.element.ElementKind; 31 import javax.lang.model.element.Modifier; 32 import javax.lang.model.element.TypeElement; 33 import javax.lang.model.element.TypeElement; 34 import javax.lang.model.type.TypeMirror; 35 import javax.lang.model.util.Types; 36 import javax.swing.Icon ; 37 import javax.swing.tree.DefaultMutableTreeNode ; 38 import javax.swing.tree.DefaultTreeModel ; 39 import org.netbeans.api.java.source.CancellableTask; 40 import org.netbeans.api.java.source.CompilationController; 41 import org.netbeans.api.java.source.CompilationInfo; 42 import org.netbeans.api.java.source.ElementHandle; 43 import org.netbeans.api.java.source.JavaSource; 44 import org.netbeans.api.java.source.JavaSource.Phase; 45 import org.netbeans.api.java.source.SourceUtils; 46 import org.netbeans.api.java.source.UiUtils; 47 import org.openide.ErrorManager; 48 import org.openide.filesystems.FileObject; 49 50 55 public final class JavaHierarchyModel extends DefaultTreeModel { 56 static Element[] EMPTY_ELEMENTS_ARRAY = new Element[0]; 57 static ElementHandle[] EMPTY_ELEMENTHANDLES_ARRAY = new ElementHandle[0]; 58 59 62 private String pattern = ""; private String patternLowerCase = ""; private FileObject fileObject; 65 private ElementHandle[] elementHandles; 66 67 69 public JavaHierarchyModel(FileObject fileObject, Element[] elements, CompilationInfo compilationInfo) { 70 super(null); 71 this.fileObject = fileObject; 72 73 if ((elements == null) || (elements.length == 0)) { 74 elementHandles = EMPTY_ELEMENTHANDLES_ARRAY; 75 } else { 76 List <ElementHandle> elementHandlesList = new ArrayList <ElementHandle>(elements.length); 77 78 for (Element element : elements) { 79 elementHandlesList.add(ElementHandle.create(element)); 80 } 81 82 elementHandles = elementHandlesList.toArray(EMPTY_ELEMENTHANDLES_ARRAY); 83 } 84 85 update(elements, compilationInfo); 86 } 87 88 92 public String getPattern() { 93 return this.pattern; 94 } 95 96 100 public void setPattern(String pattern) { 101 this.pattern = pattern; 102 if (pattern == null) { 103 patternLowerCase = null; 104 } else { 105 patternLowerCase = pattern.toLowerCase(); 106 } 107 } 108 109 110 public void update() { 111 update(elementHandles); 112 } 113 114 private void update(final ElementHandle[] elementHandles) { 115 if ((elementHandles == null) && (elementHandles.length == 0)) { 116 return; 117 } 118 119 JavaSource javaSource = JavaSource.forFileObject(fileObject); 120 121 if (javaSource != null) { 122 try { 123 javaSource.runUserActionTask(new CancellableTask<CompilationController>() { 124 public void cancel() { 125 } 126 127 public void run( 128 CompilationController compilationController) 129 throws Exception { 130 compilationController.toPhase(Phase.ELEMENTS_RESOLVED); 131 132 List <Element> elementsList = new ArrayList <Element>(elementHandles.length); 133 134 for (ElementHandle elementHandle : elementHandles) { 135 elementsList.add(elementHandle.resolve( 136 compilationController)); 137 } 138 139 Element[] elements = elementsList.toArray(EMPTY_ELEMENTS_ARRAY); 140 update(elements, compilationController); 141 } 142 }, false); 143 144 return; 145 } catch (IOException ioe) { 146 ErrorManager.getDefault().notify(ioe); 147 } 148 } 149 } 150 151 private void update(final Element[] elements, 152 CompilationInfo compilationInfo) { 153 if ((elements == null) && (elements.length == 0)) { 154 return; 155 } 156 157 DefaultMutableTreeNode root = new DefaultMutableTreeNode (); 158 159 for (Element element : elements) { 160 if ((element.getKind() == ElementKind.CLASS) || 161 (element.getKind() == ElementKind.INTERFACE) || 162 (element.getKind() == ElementKind.ENUM)) { 163 if (JavaMembersAndHierarchyOptions.isShowSuperTypeHierarchy()) { 164 root.add(new TypeTreeNode(fileObject, 165 ((TypeElement) element), compilationInfo)); 166 } else { 167 Types types = compilationInfo.getTypes(); 168 TypeElement typeElement = ((TypeElement) element); 169 List <TypeElement> superClasses = new ArrayList <TypeElement>(); 170 superClasses.add(typeElement); 171 172 TypeElement superClass = (TypeElement) types.asElement(typeElement.getSuperclass()); 173 while (superClass != null) { 174 superClasses.add(0, superClass); 175 superClass = (TypeElement) types.asElement(superClass.getSuperclass());; 176 } 177 DefaultMutableTreeNode parent = root; 178 for(TypeElement superTypeElement:superClasses) { 179 FileObject fileObject = SourceUtils.getFile(superTypeElement, compilationInfo.getClasspathInfo()); 180 DefaultMutableTreeNode child = new SimpleTypeTreeNode(fileObject, superTypeElement, compilationInfo, typeElement != superTypeElement); 181 parent.insert(child, 0); 182 parent = child; 183 } 184 } 185 } 186 } 187 188 setRoot(root); 189 } 190 191 public boolean patternMatch(JavaElement javaToolsJavaElement) { 192 return Utils.patternMatch(javaToolsJavaElement, pattern, patternLowerCase); 193 } 194 195 private abstract class AbstractHierarchyTreeNode 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 AbstractHierarchyTreeNode(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 TypeTreeNode extends AbstractHierarchyTreeNode { 305 private boolean inSuperClassRole; 306 307 TypeTreeNode(FileObject fileObject, TypeElement typeElement, 308 CompilationInfo compilationInfo) { 309 this(fileObject, typeElement, compilationInfo, false); 310 } 311 312 TypeTreeNode(FileObject fileObject, TypeElement typeElement, 313 CompilationInfo compilationInfo, boolean inSuperClassRole) { 314 super(fileObject, typeElement, compilationInfo); 315 this.inSuperClassRole = inSuperClassRole; 316 } 317 318 public boolean isLeaf() { 319 return false; 320 } 321 322 protected void loadChildren(Element element, 323 CompilationInfo compilationInfo) { 324 loadChildren(element, compilationInfo, 0); 325 } 326 327 protected int loadChildren(Element element, 328 CompilationInfo compilationInfo, int index) { 329 Types types = compilationInfo.getTypes(); 330 331 TypeElement typeElement = (TypeElement) element; 332 333 TypeElement superClass = (TypeElement) types.asElement(typeElement.getSuperclass()); 334 if (superClass != null && !superClass.getQualifiedName().toString().equals(Object .class.getName())) { 335 FileObject fileObject = SourceUtils.getFile(superClass, compilationInfo.getClasspathInfo()); 336 insert(new TypeTreeNode(fileObject, superClass, compilationInfo, true), index++); 337 } 338 List <? extends TypeMirror> interfaces = typeElement.getInterfaces(); 339 for (TypeMirror interfaceMirror:interfaces) { 340 TypeElement interfaceElement = (TypeElement) types.asElement(interfaceMirror); 341 if (interfaceElement != null) { 342 FileObject fileObject = SourceUtils.getFile(interfaceElement, compilationInfo.getClasspathInfo()); 343 insert(new TypeTreeNode(fileObject, (TypeElement)interfaceElement, compilationInfo, true), index++); 344 } 345 } 346 347 if (JavaMembersAndHierarchyOptions.isShowInner()) { 348 if (!inSuperClassRole) { 349 for (Element childElement:typeElement.getEnclosedElements()) { 350 AbstractHierarchyTreeNode node = null; 351 if ((childElement.getKind() == ElementKind.CLASS) || 352 (childElement.getKind() == ElementKind.INTERFACE) || 353 (childElement.getKind() == ElementKind.ENUM)) { 354 node = new TypeTreeNode(fileObject, (TypeElement)childElement, compilationInfo, true); 355 insert(node, index++); 356 } 357 } 358 } 359 } 360 return index; 361 } 362 } 363 364 private class SimpleTypeTreeNode extends AbstractHierarchyTreeNode { 365 private boolean inSuperClassRole; 366 367 SimpleTypeTreeNode(FileObject fileObject, TypeElement typeElement, 368 CompilationInfo compilationInfo) { 369 this(fileObject, typeElement, compilationInfo, false); 370 } 371 372 SimpleTypeTreeNode(FileObject fileObject, TypeElement typeElement, 373 CompilationInfo compilationInfo, boolean inSuperClassRole) { 374 super(fileObject, typeElement, compilationInfo); 375 this.inSuperClassRole = inSuperClassRole; 376 } 377 378 public boolean isLeaf() { 379 return false; 380 } 381 382 protected void loadChildren(Element element, 383 CompilationInfo compilationInfo) { 384 TypeElement typeElement = (TypeElement) element; 385 if (inSuperClassRole) { 386 return; 387 } 388 } 401 } 402 403 } 404 | Popular Tags |