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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  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 v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  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. * @todo 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 (Object element : node.getChildren()) {
  116. IProgramElement IProgramElement = (IProgramElement)element;
  117. if (acceptNode(IProgramElement, properties)) {
  118. children.add(createViewNode(IProgramElement, properties));
  119. }
  120. }
  121. }
  122. IStructureViewNode viewNode = nodeFactory.createNode(node, children);//new TreeViewNode(root, null, children);
  123. return viewNode;
  124. }
  125. /**
  126. * @todo get rid of this test, fix polymorphism
  127. */
  128. private boolean isFileView(StructureView view) {
  129. return view instanceof FileStructureView
  130. && !(view instanceof GlobalStructureView);
  131. }
  132. private boolean acceptGranularity(IProgramElement.Kind kind, StructureViewProperties.Granularity granularity) {
  133. if (granularity == StructureViewProperties.Granularity.DECLARED_ELEMENTS) {
  134. return true;
  135. } else if (granularity == StructureViewProperties.Granularity.MEMBER &&
  136. (kind != IProgramElement.Kind.CODE)) {
  137. return true;
  138. } else if (granularity == StructureViewProperties.Granularity.TYPE
  139. && (kind == IProgramElement.Kind.PROJECT
  140. || kind == IProgramElement.Kind.PACKAGE
  141. || kind.isSourceFile()
  142. || kind.isType())) {
  143. return true;
  144. } else if (granularity == StructureViewProperties.Granularity.FILE
  145. && (kind == IProgramElement.Kind.PROJECT
  146. || kind == IProgramElement.Kind.PACKAGE
  147. || kind.isSourceFile())) {
  148. return true;
  149. } else if (granularity == StructureViewProperties.Granularity.PACKAGE
  150. && (kind == IProgramElement.Kind.PROJECT
  151. || kind == IProgramElement.Kind.PACKAGE)) {
  152. return true;
  153. } else {
  154. return false;
  155. }
  156. }
  157. private boolean acceptNode(IProgramElement node, StructureViewProperties properties) {
  158. if (node!=null) {
  159. IProgramElement pNode = node;
  160. if (!acceptGranularity(pNode.getKind(), properties.getGranularity())) {
  161. return false;
  162. } else if (pNode.getKind().isMember()) {
  163. if (properties.getFilteredMemberAccessibility().contains(pNode.getAccessibility())) {
  164. return false;
  165. }
  166. if (properties.getFilteredMemberKinds().contains(pNode.getKind())) {
  167. return false;
  168. }
  169. for (Object element : pNode.getModifiers()) {
  170. if (properties.getFilteredMemberModifiers().contains(element)) {
  171. return false;
  172. }
  173. }
  174. }
  175. }
  176. return true;
  177. }
  178. private void sortView(IStructureViewNode node, Comparator<IStructureViewNode> comparator) {
  179. if (node == null || node.getChildren() == null) return;
  180. Collections.sort(node.getChildren(), comparator);
  181. for (Object o : node.getChildren()) {
  182. IStructureViewNode nextNode = (IStructureViewNode) o;
  183. if (nextNode != null) sortView(nextNode, comparator);
  184. }
  185. }
  186. private IStructureViewNode buildCustomTree(GlobalStructureView view, IHierarchy model) {
  187. IProgramElement rootNode = model.getRoot();
  188. IStructureViewNode treeNode = nodeFactory.createNode(rootNode);
  189. List rootNodes = new ArrayList();
  190. getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy());
  191. for (Iterator it = rootNodes.iterator(); it.hasNext(); ) {
  192. if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  193. treeNode.add(getCrosscuttingChildren((IProgramElement)it.next()));
  194. } else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  195. treeNode.add(getInheritanceChildren(
  196. (IProgramElement)it.next(),
  197. view.getViewProperties().getRelations())
  198. );
  199. }
  200. }
  201. return treeNode;
  202. }
  203. private void getRoots(IProgramElement rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) {
  204. // if (rootNode != null && rootNode.getChildren() != null) {
  205. // for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) {
  206. // IProgramElement node = (IProgramElement)it.next();
  207. // if (node instanceof IProgramElement) {
  208. // if (acceptNodeAsRoot((IProgramElement)node, hierarchy)) {
  209. // IProgramElement pNode = (IProgramElement)node;
  210. // List relations = pNode.getRelations();
  211. // String delimiter = "";
  212. // if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  213. // delimiter = "uses pointcut";
  214. // } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  215. // delimiter = "inherits";
  216. // }
  217. // if (relations != null && relations.toString().indexOf(delimiter) == -1) {
  218. // boolean found = false;
  219. // for (Iterator it2 = roots.iterator(); it2.hasNext(); ) {
  220. // if (((IProgramElement)it2.next()).equals(pNode)) found = true;
  221. // }
  222. // if (!found) roots.add(pNode);
  223. // }
  224. // }
  225. // }
  226. // getRoots(node, roots, hierarchy);
  227. // }
  228. // }
  229. }
  230. public boolean acceptNodeAsRoot(IProgramElement node, StructureViewProperties.Hierarchy hierarchy) {
  231. if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
  232. return node.getKind().equals(IProgramElement.Kind.ADVICE)
  233. || node.getKind().equals(IProgramElement.Kind.POINTCUT);
  234. } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
  235. return node.getKind().equals(IProgramElement.Kind.CLASS);
  236. } else {
  237. return false;
  238. }
  239. }
  240. private IStructureViewNode getInheritanceChildren(IProgramElement node, List associations) {
  241. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  242. // //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
  243. // List relations = ((IProgramElement)node).getRelations();
  244. throw new RuntimeException("unimplemented");
  245. // if (relations != null) {
  246. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  247. // IRelationship relation = (IRelationship)it.next();
  248. // if (relation.getName().equals("is inherited by")) {
  249. // for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
  250. //// IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
  251. //// StructureViewNode newNode = getInheritanceChildren(pNode, associations);
  252. // StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations);
  253. // for (int i = 0; i < typeChildren.getChildren().size(); i++) {
  254. // newNode.add((StructureViewNode)typeChildren.getChildren().get(i));
  255. // }
  256. // treeNode.add(newNode);
  257. // }
  258. // }
  259. // }
  260. // }
  261. // return treeNode;
  262. }
  263. private IStructureViewNode getCrosscuttingChildren(IProgramElement node) {
  264. //StructureViewNodeAdapter treeNode = new StructureViewNodeAdapter(node);
  265. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  266. // List relations = ((IProgramElement)node).getRelations();
  267. throw new RuntimeException("unimplemented");
  268. // if (relations != null) {
  269. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  270. // IRelationship relation = (IRelationship)it.next();
  271. // if (relation.getName().equals("pointcut used by")) {
  272. // for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
  273. // IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
  274. // StructureViewNode newNode = getCrosscuttingChildren(pNode);
  275. // for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) {
  276. // IRelationship relationNode = (IRelation)it3.next();
  277. // if (relationNode.getName().indexOf("pointcut") == -1) {
  278. // newNode.add(getRelations(relationNode));
  279. // }
  280. // }
  281. // treeNode.add(newNode);
  282. // }
  283. // } else if (relations.toString().indexOf("uses pointcut") == -1) {
  284. // for (Iterator it4 = relations.iterator(); it4.hasNext(); ) {
  285. // IRelation relationNode = (IRelationship)it4.next();
  286. // if (relationNode.getName().indexOf("pointcut") == -1) {
  287. // treeNode.add(getRelations(relationNode));
  288. // }
  289. // }
  290. // }
  291. // }
  292. // }
  293. // return treeNode;
  294. }
  295. // private IStructureViewNode buildTree(IProgramElement node, List associations) {
  296. // //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
  297. // IStructureViewNode treeNode = nodeFactory.createNode(node);
  298. //// if (node instanceof IProgramElement) {
  299. // List relations = ((IProgramElement)node).getRelations();
  300. // if (relations != null) {
  301. // for (Iterator it = relations.iterator(); it.hasNext(); ) {
  302. // IRelationship relationNode = (IRelationship)it.next();
  303. // if (associations.contains(relationNode.toString())) {
  304. // treeNode.add(buildTree(relationNode, associations));
  305. // }
  306. // }
  307. // }
  308. // }
  309. // if (node != null) {
  310. // List children = null;
  311. // children = node.getChildren();
  312. // if (children != null) {
  313. // List childList = new ArrayList();
  314. // for (Iterator itt = children.iterator(); itt.hasNext(); ) {
  315. // IProgramElement child = (IProgramElement)itt.next();
  316. // if (child instanceof IProgramElement) {
  317. // IProgramElement progNode = (IProgramElement)child;
  318. //// if (progNode.getKind() != IProgramElement.Kind.CODE) {
  319. // childList.add(buildTree(child, associations));
  320. //// }
  321. // } else {
  322. // childList.add(buildTree(child, associations));
  323. // }
  324. // }
  325. // //sortNodes(childList);
  326. // for (Iterator it = childList.iterator(); it.hasNext(); ) {
  327. // treeNode.add((IStructureViewNode)it.next());
  328. // }
  329. // }
  330. //
  331. // }
  332. // return treeNode;
  333. // }
  334. // private IStructureViewNode getRelations(IRelationship node) {
  335. // return null;
  336. // //StructureViewNode treeNode = new StructureViewNode(node);
  337. //// IStructureViewNode treeNode = nodeFactory.c(node);
  338. //// for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
  339. //// treeNode.add(
  340. //// nodeFactory.createNode((IProgramElement)it.next())
  341. //// );
  342. //// }
  343. //// return treeNode;
  344. // }
  345. //
  346. // /**
  347. // * For debugging only.
  348. // */
  349. // private void dumpView(IStructureViewNode root, int level) {
  350. // System.out.println(root.getStructureNode());
  351. // for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) {
  352. // dumpView((IStructureViewNode)it.next(), level++);
  353. // }
  354. // for (int i = 0; i < level; i++) {
  355. // System.out.print(' ');
  356. // }
  357. // }
  358. /**
  359. * Does not sort imports alphabetically.
  360. */
  361. private static final Comparator<IStructureViewNode> ALPHABETICAL_COMPARATOR = new Comparator<IStructureViewNode>() {
  362. @Override
  363. public int compare(IStructureViewNode o1, IStructureViewNode o2) {
  364. IProgramElement sv1 = o1.getStructureNode();
  365. IProgramElement sv2 = o2.getStructureNode();
  366. if (sv1!=null && sv2!=null) {
  367. if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
  368. if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
  369. return sv1.getName().compareTo(sv2.getName());
  370. } else {
  371. return 0;
  372. }
  373. }
  374. };
  375. private static final Comparator<IStructureViewNode> DECLARATIONAL_COMPARATOR = new Comparator<IStructureViewNode>() {
  376. @Override
  377. public int compare(IStructureViewNode o1, IStructureViewNode o2) {
  378. IProgramElement sv1 = o1.getStructureNode();
  379. IProgramElement sv2 = o2.getStructureNode();
  380. if (sv1!=null && sv2!=null) {
  381. if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
  382. if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
  383. if (sv1.getSourceLocation() == null || sv2.getSourceLocation() == null) {
  384. return 0;
  385. } else if (sv1.getSourceLocation().getLine() < sv2.getSourceLocation().getLine()) {
  386. return -1;
  387. } else {
  388. return 1;
  389. }
  390. } else {
  391. return 0;
  392. }
  393. }
  394. };
  395. }
  396. // private boolean acceptNode(ProgramElementNode node) {
  397. // return true;
  398. // if (node.getKind().equals("package")) return true;
  399. //
  400. // if (node.getKind().equals("file")) {
  401. // if (granularity == ViewProperties.Granularity.PACKAGE) {
  402. // return false;
  403. // } else {
  404. // return true;
  405. // }
  406. // }
  407. //
  408. // if (node.getKind().equals("class") || node.getKind().equals("aspect") || node.getKind().equals("interface")) {
  409. // if (granularity == ViewProperties.Granularity.FILE || granularity == ViewProperties.Granularity.PACKAGE) {
  410. // return false;
  411. // } else {
  412. // return true;
  413. // }
  414. // }
  415. //
  416. // if (node.isMemberKind()) {
  417. // if (granularity == ViewProperties.Granularity.MEMBER) {
  418. // for (Iterator it = modifiers.iterator(); it.hasNext(); ) {
  419. // if (node.getModifiers().contains((String)it.next())) return false;
  420. // }
  421. // for (Iterator it2 = visibility.iterator(); it2.hasNext(); ) {
  422. // if (node.getAccessibility().equals((String)it2.next())) return false;
  423. // }
  424. // if (filteredMemberKinds.contains(node.getKind())) {
  425. // return false;
  426. // } else {
  427. // return true;
  428. // }
  429. // } else {
  430. // return false;
  431. // }
  432. // }
  433. //
  434. // if (node.isCode()) return false;
  435. //
  436. // return false;
  437. // }