All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.ajde.ui.internal.TreeStructureViewBuilder Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * Copyright (c) 1999-2001 Xerox Corporation,
 *               2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved.
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v 2.0
 * which accompanies this distribution and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 *
 * Contributors:
 *     Xerox/PARC     initial implementation
 * ******************************************************************/


package org.aspectj.ajde.ui.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.aspectj.ajde.ui.FileStructureView;
import org.aspectj.ajde.ui.GlobalStructureView;
import org.aspectj.ajde.ui.IStructureViewNode;
import org.aspectj.ajde.ui.StructureView;
import org.aspectj.ajde.ui.StructureViewNodeFactory;
import org.aspectj.ajde.ui.StructureViewProperties;
//import org.aspectj.asm.internal.*;
//import org.aspectj.asm.internal.ProgramElement;
import org.aspectj.asm.IHierarchy;
import org.aspectj.asm.IProgramElement;

/**
 * @author Mik Kersten
 */
public class TreeStructureViewBuilder {

	private StructureViewNodeFactory nodeFactory;

	public TreeStructureViewBuilder(StructureViewNodeFactory nodeFactory) {
		this.nodeFactory = nodeFactory;
	}

	/**
	 * TODO:	get rid of instanceof tests
	 */
	public void buildView(StructureView view, IHierarchy model) {
		//		StructureViewProperties properties = view.getViewProperties();
		IProgramElement modelRoot = null;
		//		boolean noStructure = false;
		if (isFileView(view)) {
			FileStructureView fileView = (FileStructureView)view;
			if (fileView.getSourceFile() == null) {
				modelRoot = IHierarchy.NO_STRUCTURE;
				//				noStructure = true;
			} else {
				modelRoot = model.findElementForSourceFile(fileView.getSourceFile());
			}
		} else {
			modelRoot = model.getRoot();
		}

		IStructureViewNode viewRoot = null;
		if (!isFileView(view)) {
			StructureViewProperties.Hierarchy hierarchy
			= ((GlobalStructureView)view).getGlobalViewProperties().getHierarchy();
			if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)
					|| hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
				viewRoot = buildCustomTree((GlobalStructureView)view, model);
			}
		}
		if (viewRoot == null) {
			viewRoot = createViewNode(modelRoot, view.getViewProperties());//modelRoot;
		}

		if (view.getViewProperties().getSorting() == StructureViewProperties.Sorting.ALPHABETICAL
				|| (!isFileView(view) &&
						((GlobalStructureView)view).getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.DECLARATION))) {
			sortView(viewRoot, ALPHABETICAL_COMPARATOR);
		} else {
			sortView(viewRoot, DECLARATIONAL_COMPARATOR);
		}

		addPackageNode(view, viewRoot);
		view.setRootNode(viewRoot);
	}

	private void addPackageNode(StructureView view, IStructureViewNode viewRoot) {
		if (isFileView(view)) {
			//			IProgramElement fileNode = viewRoot.getStructureNode();
			//			IProgramElement parentNode = fileNode.getParent();
			//
			//			if (parentNode.getKind() == IProgramElement.Kind.PACKAGE) {
			//				String name = parentNode.getName();
			//				IProgramElement packageNode = new ProgramElement(name, IProgramElement.Kind.PACKAGE, null);
			//				packageNode.setSourceLocation(fileNode.getSourceLocation());
			//				StructureViewNode packageViewNode = createViewNode(
			//					packageNode,
			//					view.getViewProperties()
			//				);
			//				viewRoot.getChildren().add(0, packageViewNode);
			//			};
		}
	}

	private IStructureViewNode createViewNode(IProgramElement node, StructureViewProperties properties) {
		if (node == null) return null;
		List children = new ArrayList();
		//		IProgramElement pNode = node;
		//		if (node.getRelations() != null) {
		//			for (Iterator it = node.getRelations().iterator(); it.hasNext(); ) {
		//				IProgramElement IProgramElement = (IProgramElement)it.next();
		//				if (acceptNode(IProgramElement, properties)) {
		//					children.add(createViewNode(IProgramElement, properties));
		//				}
		//			}
		//		}
		if (node.isRunnable() && node.getParent() != null) {
			IProgramElement parent = node.getParent();
			if (parent.getKind().equals(IProgramElement.Kind.CLASS)
					|| parent.getKind().equals(IProgramElement.Kind.ASPECT)) {
				parent.setRunnable(true);
				node.setRunnable(false);
			}
		}
		if (node.getChildren() != null) {
			for (IProgramElement child : node.getChildren()) {
				if (acceptNode(child, properties)) {
					children.add(createViewNode(child, properties));
				}
			}
		}

		IStructureViewNode viewNode = nodeFactory.createNode(node, children);//new TreeViewNode(root, null, children);
		return viewNode;
	}

	/**
	 * @todo	get rid of this test, fix polymorphism
	 */
	private boolean isFileView(StructureView view) {
		return view instanceof FileStructureView
				&& !(view instanceof GlobalStructureView);
	}

	private boolean acceptGranularity(IProgramElement.Kind kind, StructureViewProperties.Granularity granularity) {

		if (granularity == StructureViewProperties.Granularity.DECLARED_ELEMENTS) {
			return true;
		} else if (granularity == StructureViewProperties.Granularity.MEMBER &&
				(kind != IProgramElement.Kind.CODE)) {
			return true;
		} else if (granularity == StructureViewProperties.Granularity.TYPE
				&& (kind == IProgramElement.Kind.PROJECT
				|| kind == IProgramElement.Kind.PACKAGE
				|| kind.isSourceFile()
				|| kind.isType())) {
			return true;
		} else if (granularity == StructureViewProperties.Granularity.FILE
				&& (kind == IProgramElement.Kind.PROJECT
				|| kind == IProgramElement.Kind.PACKAGE
				|| kind.isSourceFile())) {
			return true;
		} else if (granularity == StructureViewProperties.Granularity.PACKAGE
				&& (kind == IProgramElement.Kind.PROJECT
				|| kind == IProgramElement.Kind.PACKAGE)) {
			return true;
		} else {
			return false;
		}
	}

	private boolean acceptNode(IProgramElement node, StructureViewProperties properties) {
		if (node!=null) {
			IProgramElement pNode = node;
			if (!acceptGranularity(pNode.getKind(), properties.getGranularity())) {
				return false;
			} else if (pNode.getKind().isMember()) {
				if (properties.getFilteredMemberAccessibility().contains(pNode.getAccessibility())) {
					return false;
				}
				if (properties.getFilteredMemberKinds().contains(pNode.getKind())) {
					return false;
				}
				for (IProgramElement.Modifiers element : pNode.getModifiers()) {
					if (properties.getFilteredMemberModifiers().contains(element)) {
						return false;
					}
				}
			}
		}
		return true;
	}

	private void sortView(IStructureViewNode node, Comparator comparator) {
		if (node == null || node.getChildren() == null) return;
		node.getChildren().sort(comparator);
		for (Object o : node.getChildren()) {
			IStructureViewNode nextNode = (IStructureViewNode) o;
			if (nextNode != null) sortView(nextNode, comparator);
		}
	}

	private IStructureViewNode buildCustomTree(GlobalStructureView view, IHierarchy model) {
		IProgramElement rootNode = model.getRoot();
		IStructureViewNode treeNode = nodeFactory.createNode(rootNode);

		List rootNodes = new ArrayList();
		getRoots(rootNode, rootNodes, view.getGlobalViewProperties().getHierarchy());

		for (Iterator it = rootNodes.iterator(); it.hasNext(); ) {
			if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
				treeNode.add(getCrosscuttingChildren((IProgramElement)it.next()));
			} else if (view.getGlobalViewProperties().getHierarchy().equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
				treeNode.add(getInheritanceChildren(
						(IProgramElement)it.next(),
						view.getViewProperties().getRelations())
						);
			}
		}
		return treeNode;
	}

	private void getRoots(IProgramElement rootNode, List roots, StructureViewProperties.Hierarchy hierarchy) {
		//        if (rootNode != null && rootNode.getChildren() != null) {
		//            for (Iterator it = rootNode.getChildren().iterator(); it.hasNext(); ) {
		//                IProgramElement node = (IProgramElement)it.next();
		//                if (node instanceof IProgramElement) {
		//                    if (acceptNodeAsRoot((IProgramElement)node, hierarchy)) {
		//                        IProgramElement pNode = (IProgramElement)node;
		//                        List relations = pNode.getRelations();
		//                        String delimiter = "";
		//                        if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
		//                            delimiter = "uses pointcut";
		//                        } else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
		//                            delimiter = "inherits";
		//                        }
		//                        if (relations != null && relations.toString().indexOf(delimiter) == -1) {
		//                            boolean found = false;
		//                            for (Iterator it2 = roots.iterator(); it2.hasNext(); ) {
		//                                if (((IProgramElement)it2.next()).equals(pNode)) found = true;
		//                            }
		//                            if (!found) roots.add(pNode);
		//                        }
		//                    }
		//                }
		//                getRoots(node, roots, hierarchy);
		//            }
		//        }
	}

	public boolean acceptNodeAsRoot(IProgramElement node, StructureViewProperties.Hierarchy hierarchy) {
		if (hierarchy.equals(StructureViewProperties.Hierarchy.CROSSCUTTING)) {
			return node.getKind().equals(IProgramElement.Kind.ADVICE)
					|| node.getKind().equals(IProgramElement.Kind.POINTCUT);
		} else if (hierarchy.equals(StructureViewProperties.Hierarchy.INHERITANCE)) {
			return node.getKind().equals(IProgramElement.Kind.CLASS);
		} else {
			return false;
		}
	}

	private IStructureViewNode getInheritanceChildren(IProgramElement node, List associations) {
		//    	IStructureViewNode treeNode = nodeFactory.createNode(node);
		//        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
		//        List relations = ((IProgramElement)node).getRelations();
		throw new RuntimeException("unimplemented");
		//        if (relations != null) {
		//            for (Iterator it = relations.iterator(); it.hasNext(); ) {
		//				IRelationship relation = (IRelationship)it.next();
		//                if (relation.getName().equals("is inherited by")) {
		//                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
		////                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
		////                        StructureViewNode newNode = getInheritanceChildren(pNode, associations);
		//                        StructureViewNode typeChildren = buildTree(newNode.getStructureNode(), associations);
		//                        for (int i = 0; i < typeChildren.getChildren().size(); i++) {
		//                            newNode.add((StructureViewNode)typeChildren.getChildren().get(i));
		//                        }
		//						treeNode.add(newNode);
		//                    }
		//                }
		//            }
		//        }
		//        return treeNode;
	}

	private IStructureViewNode getCrosscuttingChildren(IProgramElement node) {
		//StructureViewNodeAdapter treeNode = new StructureViewNodeAdapter(node);
		//        IStructureViewNode treeNode = nodeFactory.createNode(node);
		//        List relations = ((IProgramElement)node).getRelations();
		throw new RuntimeException("unimplemented");
		//        if (relations != null) {
		//            for (Iterator it = relations.iterator(); it.hasNext(); ) {
		//				IRelationship relation = (IRelationship)it.next();
		//                if (relation.getName().equals("pointcut used by")) {
		//                    for (Iterator it2 = relation.getTargets().iterator(); it2.hasNext(); ) {
		//                        IProgramElement pNode = ((LinkNode)it2.next()).getProgramElementNode();
		//                        StructureViewNode newNode = getCrosscuttingChildren(pNode);
		//                        for (Iterator it3 = pNode.getRelations().iterator(); it3.hasNext(); ) {
		//							IRelationship relationNode = (IRelation)it3.next();
		//                            if (relationNode.getName().indexOf("pointcut") == -1) {
		//                                newNode.add(getRelations(relationNode));
		//                            }
		//                        }
		//                        treeNode.add(newNode);
		//                    }
		//                } else if (relations.toString().indexOf("uses pointcut") == -1) {
		//                    for (Iterator it4 = relations.iterator(); it4.hasNext(); ) {
		//                        IRelation relationNode = (IRelationship)it4.next();
		//                        if (relationNode.getName().indexOf("pointcut") == -1) {
		//                            treeNode.add(getRelations(relationNode));
		//                        }
		//                    }
		//                }
		//            }
		//        }
		//        return treeNode;
	}

	//    private IStructureViewNode buildTree(IProgramElement node, List associations) {
	//        //StructureViewNode treeNode = new StructureViewNodeAdapter(node);
	//        IStructureViewNode treeNode = nodeFactory.createNode(node);
	////        if (node instanceof IProgramElement) {
	//            List relations = ((IProgramElement)node).getRelations();
	//            if (relations != null) {
	//                for (Iterator it = relations.iterator(); it.hasNext(); ) {
	//					IRelationship relationNode = (IRelationship)it.next();
	//                    if (associations.contains(relationNode.toString())) {
	//                        treeNode.add(buildTree(relationNode, associations));
	//                    }
	//                }
	//            }
	//        }
	//        if (node != null) {
	//            List children = null;
	//            children = node.getChildren();
	//            if (children != null) {
	//                List childList = new ArrayList();
	//                for (Iterator itt = children.iterator(); itt.hasNext(); ) {
	//                    IProgramElement child = (IProgramElement)itt.next();
	//                    if (child instanceof IProgramElement) {
	//                        IProgramElement progNode = (IProgramElement)child;
	////                        if (progNode.getKind() != IProgramElement.Kind.CODE) {
	//                            childList.add(buildTree(child, associations));
	////                        }
	//                    } else {
	//                        childList.add(buildTree(child, associations));
	//                    }
	//                }
	//                //sortNodes(childList);
	//                for (Iterator it = childList.iterator(); it.hasNext(); ) {
	//                    treeNode.add((IStructureViewNode)it.next());
	//                }
	//            }
	//
	//        }
	//        return treeNode;
	//    }

	//    private IStructureViewNode getRelations(IRelationship node) {
	//    	return null;
	//        //StructureViewNode treeNode = new StructureViewNode(node);
	////        IStructureViewNode treeNode = nodeFactory.c(node);
	////        for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
	////            treeNode.add(
	////            	nodeFactory.createNode((IProgramElement)it.next())
	////            );
	////        }
	////        return treeNode;
	//    }
	//
	//	/**
	//	 * For debugging only.
	//	 */
	//	private void dumpView(IStructureViewNode root, int level) {
	//		System.out.println(root.getStructureNode());
	//		for (Iterator it = root.getChildren().iterator(); it.hasNext(); ) {
	//			dumpView((IStructureViewNode)it.next(), level++);
	//		}
	//		for (int i = 0; i < level; i++) {
	//			System.out.print(' ');
	//		}
	//	}

	/**
	 * Does not sort imports alphabetically.
	 */
	private static final Comparator ALPHABETICAL_COMPARATOR = new Comparator() {
		@Override
		public int compare(IStructureViewNode o1, IStructureViewNode o2) {
			IProgramElement sv1 = o1.getStructureNode();
			IProgramElement sv2 = o2.getStructureNode();
			if (sv1!=null && sv2!=null) {
				if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
				if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
				return sv1.getName().compareTo(sv2.getName());
			} else {
				return 0;
			}
		}
	};

	private static final Comparator DECLARATIONAL_COMPARATOR = new Comparator() {
		@Override
		public int compare(IStructureViewNode o1, IStructureViewNode o2) {
			IProgramElement sv1 = o1.getStructureNode();
			IProgramElement sv2 = o2.getStructureNode();
			if (sv1!=null && sv2!=null) {
				if (sv2.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return 1;
				if (sv1.getKind() == IProgramElement.Kind.IMPORT_REFERENCE) return -1;
				if (sv1.getSourceLocation() == null || sv2.getSourceLocation() == null) {
					return 0;
				} else if (sv1.getSourceLocation().getLine() < sv2.getSourceLocation().getLine()) {
					return -1;
				} else {
					return 1;
				}
			} else {
				return 0;
			}
		}
	};
}

//    private boolean acceptNode(ProgramElementNode node) {
//    	return true;
//        if (node.getKind().equals("package")) return true;
//
//        if (node.getKind().equals("file")) {
//            if (granularity == ViewProperties.Granularity.PACKAGE) {
//                return false;
//            } else {
//                return true;
//            }
//        }
//
//        if (node.getKind().equals("class") || node.getKind().equals("aspect") || node.getKind().equals("interface")) {
//            if (granularity == ViewProperties.Granularity.FILE || granularity == ViewProperties.Granularity.PACKAGE) {
//                return false;
//            } else {
//                return true;
//            }
//        }
//
//        if (node.isMemberKind()) {
//            if (granularity == ViewProperties.Granularity.MEMBER) {
//                for (Iterator it = modifiers.iterator(); it.hasNext(); ) {
//                    if (node.getModifiers().contains((String)it.next())) return false;
//                }
//                for (Iterator it2 = visibility.iterator(); it2.hasNext(); ) {
//                    if (node.getAccessibility().equals((String)it2.next()))  return false;
//                }
//                if (filteredMemberKinds.contains(node.getKind())) {
//                    return false;
//                } else {
//                    return true;
//                }
//            } else {
//                return false;
//            }
//        }
//
//        if (node.isCode()) return false;
//
//        return false;
//    }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy