1 2 25 26 package org.aspectj.ajde.ui.internal; 27 28 import java.io.File ; 29 import java.util.*; 30 import org.aspectj.asm.*; 31 import org.aspectj.ajde.ui.*; 32 33 36 public class TreeStructureViewBuilder implements StructureBuilder { 37 38 private StructureViewNodeFactory nodeFactory; 39 40 public TreeStructureViewBuilder(StructureViewNodeFactory nodeFactory) { 41 this.nodeFactory = nodeFactory; 42 } 43 44 47 public void buildView(StructureView view, StructureModel model) { 48 StructureViewProperties properties = view.getViewProperties(); 49 StructureNode modelRoot = null; 50 boolean noStructure = false; 51 if (isFileView(view)) { 52 FileStructureView fileView = (FileStructureView)view; 53 if (fileView.getSourceFile() == null) { 54 modelRoot = model.NO_STRUCTURE; 55 noStructure = true; 56 } else { 57 modelRoot = model.findRootNodeForSourceFile(fileView.getSourceFile()); 58 } 59 } else { 60 modelRoot = model.getRoot(); 61 } 62 63 StructureViewNode viewRoot = null; 64 if (!isFileView(view)) { 65 StructureViewProperties.Hierarchy hierarchy 66 = ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy(); 67 if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING) 68 || hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) { 69 viewRoot = buildCustomTree((GlobalStructureView)view, model); 70 } 71 } 72 if (viewRoot == null) { 73 viewRoot = createViewNode(modelRoot, view.getViewProperties()); } 75 76 if (view.getViewProperties().getSorting() == StructureViewProperties.Sorting.ALPHABETICAL 77 || (!isFileView(view) && 78 ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.DECLARATION))) { 79 sortView(viewRoot, ALPHABETICAL_COMPARATOR); 80 } else { 81 sortView(viewRoot, DECLARATIONAL_COMPARATOR); 82 } 83 84 addPackageNode(view, viewRoot); 85 view.setRootNode(viewRoot); 86 } 87 88 private void addPackageNode(StructureView view, StructureViewNode viewRoot) { 89 if (isFileView(view)) { 90 ProgramElementNode fileNode = (ProgramElementNode)viewRoot.getStructureNode(); 91 if (fileNode.getPackageName() != null) { 92 ProgramElementNode packageNode = new ProgramElementNode(fileNode.getPackageName(), ProgramElementNode.Kind.PACKAGE, null); 93 packageNode.setSourceLocation(fileNode.getSourceLocation()); 94 StructureViewNode packageViewNode = createViewNode( 95 packageNode, 96 view.getViewProperties() 97 ); 98 viewRoot.getChildren().add(0, packageViewNode); 99 } 100 } 101 } 102 103 private StructureViewNode createViewNode(StructureNode node, StructureViewProperties properties) { 104 List children = new ArrayList(); 105 if (node instanceof ProgramElementNode) { 106 ProgramElementNode pNode = (ProgramElementNode)node; 107 if (pNode.getRelations() != null) { 108 for (Iterator it = pNode.getRelations().iterator(); it.hasNext(); ) { 109 StructureNode structureNode = (StructureNode)it.next(); 110 if (acceptNode(structureNode, properties)) { 111 children.add(createViewNode(structureNode, properties)); 112 } 113 } 114 } 115 if (pNode.isRunnable() && pNode.getParent() != null) { 116 ProgramElementNode parent = (ProgramElementNode)pNode.getParent(); 117 if (parent.getProgramElementKind().equals(ProgramElementNode.Kind.CLASS) 118 || parent.getProgramElementKind().equals(ProgramElementNode.Kind.ASPECT)) { 119 parent.setRunnable(true); 120 pNode.setRunnable(false); 121 } 122 } 123 } 124 if (node.getChildren() != null) { 125 for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { 126 StructureNode structureNode = (StructureNode)it.next(); 127 if (acceptNode(structureNode, properties)) { 128 children.add(createViewNode(structureNode, properties)); 129 } 130 } 131 } 132 StructureViewNode viewNode = nodeFactory.createNode(node, children); return viewNode; 134 } 135 136 139 private boolean isFileView(StructureView view) { 140 return view instanceof FileStructureView 141 && !(view instanceof GlobalStructureView); 142 } 143 144 private boolean acceptGranularity(ProgramElementNode.Kind kind, StructureViewProperties.Granularity granularity) { 145 if (kind == ProgramElementNode.Kind.CODE) return false; 146 147 if (granularity == StructureViewProperties.Granularity.MEMBER) { 148 return true; 149 } else if (granularity == StructureViewProperties.Granularity.TYPE 150 && (kind == ProgramElementNode.Kind.PROJECT 151 || kind == ProgramElementNode.Kind.PACKAGE 152 || kind.isSourceFileKind() 153 || kind.isTypeKind())) { 154 return true; 155 } else if (granularity == StructureViewProperties.Granularity.FILE 156 && (kind == ProgramElementNode.Kind.PROJECT 157 || kind == ProgramElementNode.Kind.PACKAGE 158 || kind.isSourceFileKind())) { 159 return true; 160 } else if (granularity == StructureViewProperties.Granularity.PACKAGE 161 && (kind == ProgramElementNode.Kind.PROJECT 162 || kind == ProgramElementNode.Kind.PACKAGE)) { 163 return true; 164 } else { 165 return false; 166 } 167 } 168 169 private boolean acceptNode(StructureNode node, StructureViewProperties properties) { 170 if (node instanceof ProgramElementNode) { 171 ProgramElementNode pNode = (ProgramElementNode)node; 172 if (!acceptGranularity(pNode.getProgramElementKind(), properties.getGranularity())) { 173 return false; 174 } else if (pNode.isMemberKind()) { 175 if (properties.getFilteredMemberAccessibility().contains(pNode.getAccessibility())) { 176 return false; 177 } 178 if (properties.getFilteredMemberKinds().contains(pNode.getProgramElementKind())) { 179 return false; 180 } 181 for (Iterator it = pNode.getModifiers().iterator(); it.hasNext(); ) { 182 if (properties.getFilteredMemberModifiers().contains(it.next())) { 183 return false; 184 } 185 } 186 } 187 } else if (node instanceof RelationNode) { 188 Relation relation = ((RelationNode)node).getRelation(); 189 return properties.getRelations().contains(relation); 190 } else { 191 return true; 192 } 193 return true; 194 } 195 196 private void sortView(StructureViewNode node, Comparator comparator) { 197 if (node == null || node.getChildren() == null) return; 198 Collections.sort(node.getChildren(), comparator); 199 for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { 200 StructureViewNode nextNode = (StructureViewNode)it.next(); 201 if (nextNode != null) sortView(nextNode, comparator); 202 } 203 } 204 205 private StructureViewNode buildCustomTree(GlobalStructureView view, StructureModel model) { 206 StructureNode rootNode = model.getRoot(); 207 StructureViewNode treeNode = nodeFactory.createNode(rootNode); 208 209 List rootNodes = new ArrayList(); 210 getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy()); 211 212 for (Iterator it = rootNodes.iterator(); it.hasNext(); ) { 213 if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) { 214 treeNode.add(getCrosscuttingChildren((StructureNode)it.next())); 215 } else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) { 216 treeNode.add(getInheritanceChildren( 217 (StructureNode)it.next(), 218 view.getViewProperties().getRelations()) 219 ); 220 } 221 } 222 return treeNode; 223 } 224 225 private void getRoots(StructureNode rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) { 226 if (rootNode.getChildren() != null) { 227 for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) { 228 StructureNode node = (StructureNode)it.next(); 229 if (node instanceof ProgramElementNode) { 230 if (acceptNodeAsRoot((ProgramElementNode)node, hierarchy)) { 231 ProgramElementNode pNode = (ProgramElementNode)node; 232 List relations = pNode.getRelations(); 233 String delimiter = ""; 234 if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) { 235 delimiter = "uses pointcut"; 236 } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) { 237 delimiter = "inherits"; 238 } 239 if (relations != null && relations.toString().indexOf(delimiter) == -1) { 240 boolean found = false; 241 for (Iterator it2 = roots.iterator(); it2.hasNext(); ) { 242 if (((ProgramElementNode)it2.next()).equals(pNode)) found = true; 243 } 244 if (!found) roots.add(pNode); 245 } 246 } 247 } 248 getRoots(node, roots, hierarchy); 249 } 250 } 251 } 252 253 public boolean acceptNodeAsRoot(ProgramElementNode node, StructureViewProperties.Hierarchy hierarchy) { 254 if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) { 255 return node.getProgramElementKind().equals(ProgramElementNode.Kind.ADVICE) 256 || node.getProgramElementKind().equals(ProgramElementNode.Kind.POINTCUT); 257 } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) { 258 return node.getProgramElementKind().equals(ProgramElementNode.Kind.CLASS); 259 } else { 260 return false; 261 } 262 } 263 264 private StructureViewNode getInheritanceChildren(StructureNode node, List associations) { 265 StructureViewNode treeNode = nodeFactory.createNode(node); 266 List relations = ((ProgramElementNode)node).getRelations(); 268 if (relations != null) { 269 for (Iterator it = relations.iterator(); it.hasNext(); ) { 270 RelationNode relation = (RelationNode)it.next(); 271 if (relation.getName().equals("is inherited by")) { 272 for (Iterator it2 = relation.getChildren().iterator(); it2.hasNext(); ) { 273 ProgramElementNode pNode = ((LinkNode)it2.next()).getProgramElementNode(); 274 StructureViewNode newNode = getInheritanceChildren(pNode, associations); 275 StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations); 276 for (int i = 0; i < typeChildren.getChildren().size(); i++) { 277 newNode.add((StructureViewNode)typeChildren.getChildren().get(i)); 278 } 279 treeNode.add(newNode); 280 } 281 } 282 } 283 } 284 return treeNode; 285 } 286 287 private StructureViewNode getCrosscuttingChildren(StructureNode node) { 288 StructureViewNode treeNode = nodeFactory.createNode(node); 290 List relations = ((ProgramElementNode)node).getRelations(); 291 if (relations != null) { 292 for (Iterator it = relations.iterator(); it.hasNext(); ) { 293 RelationNode relation = (RelationNode)it.next(); 294 if (relation.getName().equals("pointcut used by")) { 295 for (Iterator it2 = relation.getChildren().iterator(); it2.hasNext(); ) { 296 ProgramElementNode pNode = ((LinkNode)it2.next()).getProgramElementNode(); 297 StructureViewNode newNode = getCrosscuttingChildren(pNode); 298 for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) { 299 RelationNode relationNode = (RelationNode)it3.next(); 300 if (relationNode.getName().indexOf("pointcut") == -1) { 301 newNode.add(getRelations(relationNode)); 302 } 303 } 304 treeNode.add(newNode); 305 } 306 } else if (relations.toString().indexOf("uses pointcut") == -1) { 307 for (Iterator it4 = relations.iterator(); it4.hasNext(); ) { 308 RelationNode relationNode = (RelationNode)it4.next(); 309 if (relationNode.getName().indexOf("pointcut") == -1) { 310 treeNode.add(getRelations(relationNode)); 311 } 312 } 313 } 314 } 315 } 316 return treeNode; 317 } 318 319 private StructureViewNode buildTree(StructureNode node, List associations) { 320 StructureViewNode treeNode = nodeFactory.createNode(node); 322 if (node instanceof ProgramElementNode) { 323 List relations = ((ProgramElementNode)node).getRelations(); 324 if (relations != null) { 325 for (Iterator it = relations.iterator(); it.hasNext(); ) { 326 RelationNode relationNode = (RelationNode)it.next(); 327 if (associations.contains(relationNode.getRelation().toString())) { 328 treeNode.add(buildTree(relationNode, associations)); 329 } 330 } 331 } 332 } 333 if (node != null) { 334 List children = null; 335 children = node.getChildren(); 336 if (children != null) { 337 List childList = new ArrayList(); 338 for (Iterator itt = children.iterator(); itt.hasNext(); ) { 339 StructureNode child = (StructureNode)itt.next(); 340 if (child instanceof ProgramElementNode) { 341 ProgramElementNode progNode = (ProgramElementNode)child; 342 if (!progNode.isCode()) { 343 childList.add(buildTree(child, associations)); 344 } 345 } else { 346 childList.add(buildTree(child, associations)); 347 } 348 } 349 for (Iterator it = childList.iterator(); it.hasNext(); ) { 351 treeNode.add((StructureViewNode)it.next()); 352 } 353 } 354 355 } 356 return treeNode; 357 } 358 359 private StructureViewNode getRelations(RelationNode node) { 360 StructureViewNode treeNode = nodeFactory.createNode(node); 362 for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { 363 treeNode.add( 364 nodeFactory.createNode((StructureNode)it.next()) 365 ); 366 } 367 return treeNode; 368 } 369 370 373 private void dumpView(StructureViewNode root, int level) { 374 System.out.println(root.getStructureNode()); 375 for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) { 376 dumpView((StructureViewNode)it.next(), level++); 377 } 378 for (int i = 0; i < level; i++) { 379 System.out.print(' '); 380 } 381 } 382 383 private static final Comparator ALPHABETICAL_COMPARATOR = new Comparator() { 384 public int compare(Object o1, Object o2) { 385 StructureNode sv1 = ((StructureViewNode)o1).getStructureNode(); 386 StructureNode sv2 = ((StructureViewNode)o2).getStructureNode(); 387 if (sv1 instanceof ProgramElementNode && sv2 instanceof ProgramElementNode) { 388 ProgramElementNode p1 = (ProgramElementNode)sv1; 389 ProgramElementNode p2 = (ProgramElementNode)sv2; 390 return p1.getName().compareTo(p2.getName()); 391 } else { 392 return 0; 393 } 394 } 395 }; 396 397 private static final Comparator DECLARATIONAL_COMPARATOR = new Comparator() { 398 public int compare(Object o1, Object o2) { 399 StructureNode sv1 = ((StructureViewNode)o1).getStructureNode(); 400 StructureNode sv2 = ((StructureViewNode)o2).getStructureNode(); 401 if (sv1 instanceof ProgramElementNode && sv2 instanceof ProgramElementNode) { 402 ProgramElementNode p1 = (ProgramElementNode)sv1; 403 ProgramElementNode p2 = (ProgramElementNode)sv2; 404 if (p1.getSourceLocation() == null) { 405 return 0; 406 } else if (p1.getSourceLocation().getLineNumber() < p2.getSourceLocation().getLineNumber()) { 407 return -1; 408 } else { 409 return 1; 410 } 411 } else { 412 return 0; 413 } 414 } 415 }; 416 } 417 418 461 | Popular Tags |