/* *******************************************************************
* 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 v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* Helen Hawkins Converted to new interface (bug 148190)
* ******************************************************************/
package org.aspectj.ajde.ui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.ui.internal.NavigationHistoryModel;
import org.aspectj.ajde.ui.internal.TreeStructureViewBuilder;
import org.aspectj.asm.IHierarchy;
import org.aspectj.asm.IHierarchyListener;
import org.aspectj.asm.IProgramElement;
import org.aspectj.asm.IRelationship;
import org.aspectj.asm.internal.AspectJElementHierarchy;
/**
* @author Mik Kersten
*/
public class StructureViewManager {
private final TreeStructureViewBuilder treeViewBuilder;
// private String buildConfigFilePath = null;
private final NavigationHistoryModel historyModel = new NavigationHistoryModel();
private final ArrayList structureViews = new ArrayList();
private FileStructureView defaultFileView = null;
private static final StructureViewProperties DEFAULT_VIEW_PROPERTIES;
private static final List AVAILABLE_RELATIONS;
public final IHierarchyListener VIEW_LISTENER = new IHierarchyListener() {
public void elementsUpdated(IHierarchy model) {
// updating structure views:
for (Iterator it = structureViews.iterator(); it.hasNext();) {
treeViewBuilder.buildView((StructureView) it.next(), (AspectJElementHierarchy) model);
}
}
};
/**
* @param nodeFactory concrete factory for creating view nodes
*/
public StructureViewManager(StructureViewNodeFactory nodeFactory) {
treeViewBuilder = new TreeStructureViewBuilder(nodeFactory);
Ajde.getDefault().getModel().addListener(VIEW_LISTENER);
}
public void fireNavigateBackAction(StructureView view) {
IProgramElement backNode = historyModel.navigateBack();
if (backNode == null) {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation("No node to navigate back to in history");
} else {
navigationAction(backNode, false);
}
}
public void fireNavigateForwardAction(StructureView view) {
IProgramElement forwardNode = historyModel.navigateForward();
if (forwardNode == null) {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation("No node to navigate forward to in history");
} else {
navigationAction(forwardNode, false);
}
}
/**
* Only navigations of the default view are registered with the history.
*
* @param newFilePath the canonicalized path to the new file
*/
public void fireNavigationAction(String newFilePath, int lineNumber) {
IProgramElement currNode = Ajde.getDefault().getModel().getHierarchy().findElementForSourceLine(newFilePath, lineNumber);
if (currNode != null) {
navigationAction(currNode, true);
}
}
/**
* History is recorded for {@link LinkNode} navigations.
*/
public void fireNavigationAction(IProgramElement pe, boolean isLink) {
navigationAction(pe, isLink);
}
/**
* Highlights the given node in all structure views. If the node represents code and as such is below the granularity visible in
* the view the parent is highlighted, along with the corresponding sourceline.
*/
private void navigationAction(IProgramElement node, boolean recordHistory) {
if (node == null)
return;
// navigating to node: " + node + ", recordHistory: " + recordHistory
if (recordHistory)
historyModel.navigateToNode(node);
if (defaultFileView != null && node.getSourceLocation() != null) {
String newFilePath = node.getSourceLocation().getSourceFile().getAbsolutePath();
if (defaultFileView.getSourceFile() != null && !defaultFileView.getSourceFile().equals(newFilePath)) {
defaultFileView.setSourceFile(newFilePath);
treeViewBuilder.buildView(defaultFileView, Ajde.getDefault().getModel().getHierarchy());
}
}
for (Iterator it = structureViews.iterator(); it.hasNext();) {
StructureView view = (StructureView) it.next();
if (!(view instanceof GlobalStructureView) || !recordHistory || defaultFileView == null) {
if (node.getKind().equals(IProgramElement.Kind.CODE)) {
IProgramElement parentNode = node.getParent();
if (parentNode != null) {
IStructureViewNode currNode = view.findCorrespondingViewNode(parentNode);
int lineOffset = node.getSourceLocation().getLine() - parentNode.getSourceLocation().getLine();
if (currNode != null)
view.setActiveNode(currNode, lineOffset);
}
} else {
IStructureViewNode currNode = view.findCorrespondingViewNode(node);
if (currNode != null)
view.setActiveNode(currNode);
}
}
}
}
public void refreshView(StructureView view) {
IStructureViewNode activeNode = view.getActiveNode();
treeViewBuilder.buildView(view, Ajde.getDefault().getModel().getHierarchy());
view.setActiveNode(activeNode);
}
public StructureViewProperties getDefaultViewProperties() {
return DEFAULT_VIEW_PROPERTIES;
}
/**
* Returns the list of all available relations.
*/
public List getAvailableRelations() {
return AVAILABLE_RELATIONS;
}
/**
* @param properties can not be null
*/
public GlobalStructureView createGlobalView(GlobalViewProperties properties) {
GlobalStructureView view = new GlobalStructureView(properties);
structureViews.add(view);
return view;
}
/**
* @param sourceFilePath full path to corresponding source file
* @param properties if null default properties will be used
* @return always returns a view intance
*/
public FileStructureView createViewForSourceFile(String sourceFilePath, StructureViewProperties properties) {
// creating view for file:
if (properties == null)
properties = DEFAULT_VIEW_PROPERTIES;
FileStructureView view = new FileStructureView(properties);
view.setSourceFile(sourceFilePath);
treeViewBuilder.buildView(view, Ajde.getDefault().getModel().getHierarchy());
structureViews.add(view);
return view;
}
/**
* @return true if the view was found and removed, false otherwise
*/
public boolean deleteView(StructureView view) {
return structureViews.remove(view);
}
public void setDefaultFileView(FileStructureView defaultFileView) {
this.defaultFileView = defaultFileView;
}
public FileStructureView getDefaultFileView() {
return defaultFileView;
}
static {
AVAILABLE_RELATIONS = new ArrayList();
AVAILABLE_RELATIONS.add(IRelationship.Kind.ADVICE);
AVAILABLE_RELATIONS.add(IRelationship.Kind.DECLARE);
DEFAULT_VIEW_PROPERTIES = new StructureViewProperties();
DEFAULT_VIEW_PROPERTIES.setRelations(AVAILABLE_RELATIONS);
}
}
// this.multiFileViewMode = multiFileViewMode;
// if (!multiFileViewMode) {
// structureViews.add(DEFAULT_FILE_VIEW);
// structureViews.add(DECLARATION_VIEW);
// structureViews.add(CROSSCUTTING_VIEW);
// structureViews.add(INHERITANCE_VIEW);
// }
// public GlobalStructureView getGlobalStructureView(StructureViewProperties.Hierarchy hierarchy) {
// if (hierarchy == StructureViewProperties.Hierarchy.CROSSCUTTING) {
// return CROSSCUTTING_VIEW;
// } else if (hierarchy == StructureViewProperties.Hierarchy.INHERITANCE) {
// return INHERITANCE_VIEW;
// } else {
// return DECLARATION_VIEW;
// }
// }
// public FileStructureView getDefaultFileStructureView() {
// return DEFAULT_FILE_VIEW;
// }