/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package org.absmodels.abs.plugin.navigator; import java.util.ArrayList; import static org.absmodels.abs.plugin.util.UtilityFunctions.getAbsNature; import org.absmodels.abs.plugin.builder.AbsNature; import org.absmodels.abs.plugin.util.InternalASTNode; import org.absmodels.abs.plugin.util.UtilityFunctions; import org.absmodels.abs.plugin.util.UtilityFunctions.EditorPosition; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.navigator.ILinkHelper; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.ITextEditor; import abs.frontend.ast.CompilationUnit; import abs.frontend.ast.ModuleDecl; /** * Class for providing 'link with editor support' for the ABSNavigator * @author cseise * */ public class LinkHelper implements ILinkHelper { /** * {@inheritDoc} */ @Override public IStructuredSelection findSelection(IEditorInput anInput) { if (anInput instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) anInput; IProject project = getProject(fileInput); AbsNature nature = getAbsNature(project); //If we did not get back an ABS nature, do nothing. if (nature == null) { return null; } ITextEditor editor = UtilityFunctions.openABSEditorForFile(fileInput.getPath(), project); IFile file = fileInput.getFile(); ModuleDecl md = getModuleDeclAtCurrentCursor(file, nature, editor); return buildTreeSelection(nature, project, new InternalASTNode<ModuleDecl>(md,nature)); } return null; } private ModuleDecl getModuleDeclAtCurrentCursor(IFile file, AbsNature nature, ITextEditor editor) { ModuleDecl md = null; synchronized (nature.modelLock) { if (nature.getCompilationUnit(file).getNumModuleDecl() > 0){ //get start line of editor selection ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection(); int startLine = selection.getStartLine(); CompilationUnit cu = nature.getCompilationUnit(file); //find the module which the selection is located in... for (ModuleDecl m : cu.getModuleDecls()){ EditorPosition position = UtilityFunctions.getPosition(m); int moduleStartLine = position.getLinestart(); int moduleEndLine = position.getLineend(); if (startLine >= moduleStartLine && startLine <= moduleEndLine){ md = m; break; } } //if no module was found or no selection was made, take the first one in the compilation unit as fallback if (md == null){ md = cu.getModuleDecl(0); } } } return md; } /** * Build up a {@link TreeSelection} suitable for the ABSNavigator from the * given component * * @param project * IProject The according project of the ModuleDecl. * @param md * ModuleDecl The target ModuleDecl to highlight. * @return A TreeSelection including a {@link TreePath} from project to md * or null if md or project is null, or if no ABSnature can be * retrieved from project */ private static TreeSelection buildTreeSelection(AbsNature nature, IProject project, InternalASTNode<ModuleDecl> md) { assert nature != null; assert nature == md.getNature(); // TODO: if this holds (as it should), remove argument if (project != null && md != null) { // Split the module's name and return the module hierarchy ArrayList<ModulePath> paths = md.getParentHierarchyForModuleDecl(); ArrayList<Object> arli = new ArrayList<Object>(); arli.add(project); if (paths.size() > 0){ ModulePath lastElement = paths.get(paths.size()-1); arli.addAll(paths); if (!(lastElement.hasModule() && lastElement.getModulePath().equals(md.getASTNode().getName()))){ arli.add(md); } }else{ if (NavigatorUtils.hasSubModules(md)){ arli.add(new ModulePath(nature, md.getASTNode().getName())); }else{ arli.add(md); } } TreePath path = new TreePath(arli.toArray()); TreeSelection ts = new TreeSelection(new TreePath[] { path }); return ts; } return null; } private IProject getProject(FileEditorInput anInput){ return anInput.getFile().getProject(); } @Override public void activateEditor(IWorkbenchPage aPage, IStructuredSelection aSelection) { if (aSelection instanceof TreeSelection) { TreeSelection ts = (TreeSelection) aSelection; try { NavigatorUtils.openEditor(ts); } catch (PartInitException e) { UtilityFunctions.showErrorMessage("Fatal error in ABS Navigator View:\n Could not open the editor connected to the selected tree element."); } } } }