選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

TreeStructureViewBuilder.java 19KB

4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
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. // }