You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TreeStructureViewBuilder.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v 2.0
  7. * which accompanies this distribution and is available at
  8. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.ajde.ui.internal;
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.Comparator;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. import org.aspectj.ajde.ui.FileStructureView;
  20. import org.aspectj.ajde.ui.GlobalStructureView;
  21. import org.aspectj.ajde.ui.IStructureViewNode;
  22. import org.aspectj.ajde.ui.StructureView;
  23. import org.aspectj.ajde.ui.StructureViewNodeFactory;
  24. import org.aspectj.ajde.ui.StructureViewProperties;
  25. //import org.aspectj.asm.internal.*;
  26. //import org.aspectj.asm.internal.ProgramElement;
  27. import org.aspectj.asm.IHierarchy;
  28. import org.aspectj.asm.IProgramElement;
  29. /**
  30. * @author Mik Kersten
  31. */
  32. public class TreeStructureViewBuilder {
  33. private StructureViewNodeFactory nodeFactory;
  34. public TreeStructureViewBuilder(StructureViewNodeFactory nodeFactory) {
  35. this.nodeFactory = nodeFactory;
  36. }
  37. /**
  38. * <b>TODO</b>: get rid of instanceof tests
  39. */
  40. public void buildView(StructureView view, IHierarchy model) {
  41. // StructureViewProperties properties = view.getViewProperties();
  42. IProgramElement modelRoot = null;
  43. // boolean noStructure = false;
  44. if (isFileView(view)) {
  45. FileStructureView fileView = (FileStructureView)view;
  46. if (fileView.getSourceFile() == null) {
  47. modelRoot = IHierarchy.NO_STRUCTURE;
  48. // noStructure = true;
  49. } else {
  50. modelRoot = model.findElementForSourceFile(fileView.getSourceFile());
  51. }
  52. } else {
  53. modelRoot = model.getRoot();
  54. }
  55. IStructureViewNode viewRoot = null;
  56. if (!isFileView(view)) {
  57. StructureViewProperties.Hierarchy hierarchy
  58. = ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy();
  59. if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)
  60. || hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  61. viewRoot = buildCustomTree((GlobalStructureView)view, model);
  62. }
  63. }
  64. if (viewRoot == null) {
  65. viewRoot = createViewNode(modelRoot, view.getViewProperties());//modelRoot;
  66. }
  67. if (view.getViewProperties().getSorting() == StructureViewProperties.Sorting.ALPHABETICAL
  68. || (!isFileView(view) &&
  69. ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.DECLARATION))) {
  70. sortView(viewRoot, ALPHABETICAL_COMPARATOR);
  71. } else {
  72. sortView(viewRoot, DECLARATIONAL_COMPARATOR);
  73. }
  74. addPackageNode(view, viewRoot);
  75. view.setRootNode(viewRoot);
  76. }
  77. private void addPackageNode(StructureView view, IStructureViewNode viewRoot) {
  78. if (isFileView(view)) {
  79. // IProgramElement fileNode = viewRoot.getStructureNode();
  80. // IProgramElement parentNode = fileNode.getParent();
  81. //
  82. // if (parentNode.getKind() == IProgramElement.Kind.PACKAGE) {
  83. // String name = parentNode.getName();
  84. // IProgramElement packageNode = new ProgramElement(name, IProgramElement.Kind.PACKAGE, null);
  85. // packageNode.setSourceLocation(fileNode.getSourceLocation());
  86. // StructureViewNode packageViewNode = createViewNode(
  87. // packageNode,
  88. // view.getViewProperties()
  89. // );
  90. // viewRoot.getChildren().add(0, packageViewNode);
  91. // };
  92. }
  93. }
  94. private IStructureViewNode createViewNode(IProgramElement node, StructureViewProperties properties) {
  95. if (node == null) return null;
  96. List children = new ArrayList();
  97. // IProgramElement pNode = node;
  98. // if (node.getRelations() != null) {
  99. // for (Iterator it = node.getRelations().iterator(); it.hasNext(); ) {
  100. // IProgramElement IProgramElement = (IProgramElement)it.next();
  101. // if (acceptNode(IProgramElement, properties)) {
  102. // children.add(createViewNode(IProgramElement, properties));
  103. // }
  104. // }
  105. // }
  106. if (node.isRunnable() && node.getParent() != null) {
  107. IProgramElement parent = node.getParent();
  108. if (parent.getKind().equals(IProgramElement.Kind.CLASS)
  109. || parent.getKind().equals(IProgramElement.Kind.ASPECT)) {
  110. parent.setRunnable(true);
  111. node.setRunnable(false);
  112. }
  113. }
  114. if (node.getChildren() != null) {
  115. for (IProgramElement child : node.getChildren()) {
  116. if (acceptNode(child, properties)) {
  117. children.add(createViewNode(child, properties));
  118. }
  119. }
  120. }
  121. IStructureViewNode viewNode = nodeFactory.createNode(node, children);//new TreeViewNode(root, null, children);
  122. return viewNode;
  123. }
  124. /**
  125. * @todo get rid of this test, fix polymorphism
  126. */
  127. private boolean isFileView(StructureView view) {
  128. return view instanceof FileStructureView
  129. && !(view instanceof GlobalStructureView);
  130. }
  131. private boolean acceptGranularity(IProgramElement.Kind kind, StructureViewProperties.Granularity granularity) {
  132. if (granularity == StructureViewProperties.Granularity.DECLARED_ELEMENTS) {
  133. return true;
  134. } else if (granularity == StructureViewProperties.Granularity.MEMBER &&
  135. (kind != IProgramElement.Kind.CODE)) {
  136. return true;
  137. } else if (granularity == StructureViewProperties.Granularity.TYPE
  138. && (kind == IProgramElement.Kind.PROJECT
  139. || kind == IProgramElement.Kind.PACKAGE
  140. || kind.isSourceFile()
  141. || kind.isType())) {
  142. return true;
  143. } else if (granularity == StructureViewProperties.Granularity.FILE
  144. && (kind == IProgramElement.Kind.PROJECT
  145. || kind == IProgramElement.Kind.PACKAGE
  146. || kind.isSourceFile())) {
  147. return true;
  148. } else if (granularity == StructureViewProperties.Granularity.PACKAGE
  149. && (kind == IProgramElement.Kind.PROJECT
  150. || kind == IProgramElement.Kind.PACKAGE)) {
  151. return true;
  152. } else {
  153. return false;
  154. }
  155. }
  156. private boolean acceptNode(IProgramElement node, StructureViewProperties properties) {
  157. if (node!=null) {
  158. IProgramElement pNode = node;
  159. if (!acceptGranularity(pNode.getKind(), properties.getGranularity())) {
  160. return false;
  161. } else if (pNode.getKind().isMember()) {
  162. if (properties.getFilteredMemberAccessibility().contains(pNode.getAccessibility())) {
  163. return false;
  164. }
  165. if (properties.getFilteredMemberKinds().contains(pNode.getKind())) {
  166. return false;
  167. }
  168. for (IProgramElement.Modifiers element : pNode.getModifiers()) {
  169. if (properties.getFilteredMemberModifiers().contains(element)) {
  170. return false;
  171. }
  172. }
  173. }
  174. }
  175. return true;
  176. }
  177. private void sortView(IStructureViewNode node, Comparator<IStructureViewNode> comparator) {
  178. if (node == null || node.getChildren() == null) return;
  179. node.getChildren().sort(comparator);
  180. for (Object o : node.getChildren()) {
  181. IStructureViewNode nextNode = (IStructureViewNode) o;
  182. if (nextNode != null) sortView(nextNode, comparator);
  183. }
  184. }
  185. private IStructureViewNode buildCustomTree(GlobalStructureView view, IHierarchy model) {
  186. IProgramElement rootNode = model.getRoot();
  187. IStructureViewNode treeNode = nodeFactory.createNode(rootNode);
  188. List rootNodes = new ArrayList();
  189. getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy());
  190. for (Iterator it = rootNodes.iterator(); it.hasNext(); ) {
  191. if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  192. treeNode.add(getCrosscuttingChildren((IProgramElement)it.next()));
  193. } else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  194. treeNode.add(getInheritanceChildren(
  195. (IProgramElement)it.next(),
  196. view.getViewProperties().getRelations())
  197. );
  198. }
  199. }
  200. return treeNode;
  201. }
  202. private void getRoots(IProgramElement rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) {
  203. // if (rootNode != null && rootNode.getChildren() != null) {
  204. // for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) {
  205. // IProgramElement node = (IProgramElement)it.next();
  206. // if (node instanceof IProgramElement) {
  207. // if (acceptNodeAsRoot((IProgramElement)node, hierarchy)) {
  208. // IProgramElement pNode = (IProgramElement)node;
  209. // List relations = pNode.getRelations();
  210. // String delimiter = "";
  211. // if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  212. // delimiter = "uses pointcut";
  213. // } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  214. // delimiter = "inherits";
  215. // }
  216. // if (relations != null && relations.toString().indexOf(delimiter) == -1) {
  217. // boolean found = false;
  218. // for (Iterator it2 = roots.iterator(); it2.hasNext(); ) {
  219. // if (((IProgramElement)it2.next()).equals(pNode)) found = true;
  220. // }
  221. // if (!found) roots.add(pNode);
  222. // }
  223. // }
  224. // }
  225. // getRoots(node, roots, hierarchy);
  226. // }
  227. // }
  228. }
  229. public boolean acceptNodeAsRoot(IProgramElement node, StructureViewProperties.Hierarchy hierarchy) {
  230. if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  231. return node.getKind().equals(IProgramElement.Kind.ADVICE)
  232. || node.getKind().equals(IProgramElement.Kind.POINTCUT);
  233. } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  234. return node.getKind().equals(IProgramElement.Kind.CLASS);
  235. } else {
  236. return false;
  237. }
  238. }
  239. private IStructureViewNode getInheritanceChildren(IProgramElement node, List associations) {
  240. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  241. // //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
  242. // List relations = ((IProgramElement)node).getRelations();
  243. throw new RuntimeException("unimplemented");
  244. // if (relations != null) {
  245. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  246. // IRelationship relation = (IRelationship)it.next();
  247. // if (relation.getName().equals("is inherited by")) {
  248. // for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
  249. //// IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
  250. //// StructureViewNode newNode = getInheritanceChildren(pNode, associations);
  251. // StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations);
  252. // for (int i = 0; i < typeChildren.getChildren().size(); i++) {
  253. // newNode.add((StructureViewNode)typeChildren.getChildren().get(i));
  254. // }
  255. // treeNode.add(newNode);
  256. // }
  257. // }
  258. // }
  259. // }
  260. // return treeNode;
  261. }
  262. private IStructureViewNode getCrosscuttingChildren(IProgramElement node) {
  263. //StructureViewNodeAdapter treeNode = new StructureViewNodeAdapter(node);
  264. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  265. // List relations = ((IProgramElement)node).getRelations();
  266. throw new RuntimeException("unimplemented");
  267. // if (relations != null) {
  268. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  269. // IRelationship relation = (IRelationship)it.next();
  270. // if (relation.getName().equals("pointcut used by")) {
  271. // for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
  272. // IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
  273. // StructureViewNode newNode = getCrosscuttingChildren(pNode);
  274. // for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) {
  275. // IRelationship relationNode = (IRelation)it3.next();
  276. // if (relationNode.getName().indexOf("pointcut") == -1) {
  277. // newNode.add(getRelations(relationNode));
  278. // }
  279. // }
  280. // treeNode.add(newNode);
  281. // }
  282. // } else if (relations.toString().indexOf("uses pointcut") == -1) {
  283. // for (Iterator it4 = relations.iterator(); it4.hasNext(); ) {
  284. // IRelation relationNode = (IRelationship)it4.next();
  285. // if (relationNode.getName().indexOf("pointcut") == -1) {
  286. // treeNode.add(getRelations(relationNode));
  287. // }
  288. // }
  289. // }
  290. // }
  291. // }
  292. // return treeNode;
  293. }
  294. // private IStructureViewNode buildTree(IProgramElement node, List associations) {
  295. // //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
  296. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  297. //// if (node instanceof IProgramElement) {
  298. // List relations = ((IProgramElement)node).getRelations();
  299. // if (relations != null) {
  300. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  301. // IRelationship relationNode = (IRelationship)it.next();
  302. // if (associations.contains(relationNode.toString())) {
  303. // treeNode.add(buildTree(relationNode, associations));
  304. // }
  305. // }
  306. // }
  307. // }
  308. // if (node != null) {
  309. // List children = null;
  310. // children = node.getChildren();
  311. // if (children != null) {
  312. // List childList = new ArrayList();
  313. // for (Iterator itt = children.iterator(); itt.hasNext(); ) {
  314. // IProgramElement child = (IProgramElement)itt.next();
  315. // if (child instanceof IProgramElement) {
  316. // IProgramElement progNode = (IProgramElement)child;
  317. //// if (progNode.getKind() != IProgramElement.Kind.CODE) {
  318. // childList.add(buildTree(child, associations));
  319. //// }
  320. // } else {
  321. // childList.add(buildTree(child, associations));
  322. // }
  323. // }
  324. // //sortNodes(childList);
  325. // for (Iterator it = childList.iterator(); it.hasNext(); ) {
  326. // treeNode.add((IStructureViewNode)it.next());
  327. // }
  328. // }
  329. //
  330. // }
  331. // return treeNode;
  332. // }
  333. // private IStructureViewNode getRelations(IRelationship node) {
  334. // return null;
  335. // //StructureViewNode treeNode = new StructureViewNode(node);
  336. //// IStructureViewNode treeNode = nodeFactory.c(node);
  337. //// for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
  338. //// treeNode.add(
  339. //// nodeFactory.createNode((IProgramElement)it.next())
  340. //// );
  341. //// }
  342. //// return treeNode;
  343. // }
  344. //
  345. // /**
  346. // * For debugging only.
  347. // */
  348. // private void dumpView(IStructureViewNode root, int level) {
  349. // System.out.println(root.getStructureNode());
  350. // for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) {
  351. // dumpView((IStructureViewNode)it.next(), level++);
  352. // }
  353. // for (int i = 0; i < level; i++) {
  354. // System.out.print(' ');
  355. // }
  356. // }
  357. /**
  358. * Does not sort imports alphabetically.
  359. */
  360. private static final Comparator<IStructureViewNode> ALPHABETICAL_COMPARATOR = new Comparator<IStructureViewNode>() {
  361. @Override
  362. public int compare(IStructureViewNode o1, IStructureViewNode o2) {
  363. IProgramElement sv1 = o1.getStructureNode();
  364. IProgramElement sv2 = o2.getStructureNode();
  365. if (sv1!=null && sv2!=null) {
  366. if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
  367. if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
  368. return sv1.getName().compareTo(sv2.getName());
  369. } else {
  370. return 0;
  371. }
  372. }
  373. };
  374. private static final Comparator<IStructureViewNode> DECLARATIONAL_COMPARATOR = new Comparator<IStructureViewNode>() {
  375. @Override
  376. public int compare(IStructureViewNode o1, IStructureViewNode o2) {
  377. IProgramElement sv1 = o1.getStructureNode();
  378. IProgramElement sv2 = o2.getStructureNode();
  379. if (sv1!=null && sv2!=null) {
  380. if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
  381. if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
  382. if (sv1.getSourceLocation() == null || sv2.getSourceLocation() == null) {
  383. return 0;
  384. } else if (sv1.getSourceLocation().getLine() < sv2.getSourceLocation().getLine()) {
  385. return -1;
  386. } else {
  387. return 1;
  388. }
  389. } else {
  390. return 0;
  391. }
  392. }
  393. };
  394. }
  395. // private boolean acceptNode(ProgramElementNode node) {
  396. // return true;
  397. // if (node.getKind().equals("package")) return true;
  398. //
  399. // if (node.getKind().equals("file")) {
  400. // if (granularity == ViewProperties.Granularity.PACKAGE) {
  401. // return false;
  402. // } else {
  403. // return true;
  404. // }
  405. // }
  406. //
  407. // if (node.getKind().equals("class") || node.getKind().equals("aspect") || node.getKind().equals("interface")) {
  408. // if (granularity == ViewProperties.Granularity.FILE || granularity == ViewProperties.Granularity.PACKAGE) {
  409. // return false;
  410. // } else {
  411. // return true;
  412. // }
  413. // }
  414. //
  415. // if (node.isMemberKind()) {
  416. // if (granularity == ViewProperties.Granularity.MEMBER) {
  417. // for (Iterator it = modifiers.iterator(); it.hasNext(); ) {
  418. // if (node.getModifiers().contains((String)it.next())) return false;
  419. // }
  420. // for (Iterator it2 = visibility.iterator(); it2.hasNext(); ) {
  421. // if (node.getAccessibility().equals((String)it2.next())) return false;
  422. // }
  423. // if (filteredMemberKinds.contains(node.getKind())) {
  424. // return false;
  425. // } else {
  426. // return true;
  427. // }
  428. // } else {
  429. // return false;
  430. // }
  431. // }
  432. //
  433. // if (node.isCode()) return false;
  434. //
  435. // return false;
  436. // }