Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eclipse Plugin: how to get the path to the currently selected project

I am writing an Eclipse plugin that will display a menu item in the context menu for a Java Project. I have written the plugin.xml as follows:

<plugin>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="popup:org.eclipse.jdt.ui.PackageExplorer">
         <dynamic
               class="uk.co.dajohnston.plugin.classpathswitcher.menu.MenuContribution"
               id="uk.co.dajohnston.plugin.classpathSwitcher.switchMenuContribution">
            <visibleWhen>
               <with
                     variable="activeMenuSelection">
                  <iterate>
                     <adapt
                           type="org.eclipse.jdt.core.IJavaProject">
                     </adapt>
                  </iterate>
                  <count
                        value="1">
                  </count>
               </with>
            </visibleWhen>
         </dynamic>
      </menuContribution>
   </extension>

</plugin>

So I am now trying to write the MenuContribution class which extends CompoundContributionItem so that I can create a dynamic menu and the contents of this menu are going to be based on a set of files that exist in the Java Project's root directory. But I am stuck trying to get the path to the root directory from within the getContributionItems method.

Based on the plugin.xml file I can be guarenteed that the method will only be called if a single Java Project is selected, so all I need to do is get the current selection and then get its absolute path. Any ideas? Or is there a better way to do this?

like image 871
DaveJohnston Avatar asked Jul 31 '11 21:07

DaveJohnston


People also ask

How do I find the path of a project in Eclipse?

Use Alt+Enter on the project Name in Eclipse to see the complete path of the project directory where it resides.

How do I get to root directory in Eclipse?

You should be able to find that out by opening the properties dialog for the project, and looking under the Resource entry. Also, you can add resources to a project by using the Import menu option. Show activity on this post. The default root folder for any Eclipse project is also a relative path of that application.

How do I change the path of a resource in Eclipse?

On the Project, Right click and select option "Refactor" and then choose the option "Move". This will pop up a dialog box. Specify the folder where you want your project to be.

How do I run a specific project in Eclipse?

Step 1: Open Eclipse and click File > New > Java Project. Step 2: Provide the Project Name and click on the Finish button. Step 3: In the Package Explorer (left-hand side of the window) select the project which you have created.


1 Answers

Since I wrote the previous answer I have written another couple of utility plugins and now have a generic starter for Eclipse Navigator Popups. The files are as follows:

Basic manifest file

MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NavigatorPopup
Bundle-SymbolicName: com.nsd.NavigatorPopup;singleton:=true
Bundle-Version: 1.0.0.1
Bundle-Vendor: NSD
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.resources,
 org.eclipse.core.runtime
Bundle-RequiredExecutionEnvironment: JavaSE-1.6

Basic properties file

build.properties

source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
               META-INF/,\
               .

Plugin file

In particular note how <command commandId=...> of the <menuContribution...> <menu..> in the <extension point="org.eclipse.ui.menus"> extension point links to the <handler commandId=...> in the <extension point="org.eclipse.ui.handlers"> extension point this permits us to link multiple menu contributions to a single handler.

Also of note is the fact that there are multiple locationURI's as these can change from one perspective to another.

plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
    <extension point="org.eclipse.ui.commands">
        <category name="NSD Category" id="com.nsd.NavigatorPopup.commands.category"/>
        <command name="Navigator Popup" categoryId="com.nsd.NavigatorPopup.commands.category" id="com.nsd.NavigatorPopup.commands.navigatorPopupCommand"/>
    </extension>
    <extension point="org.eclipse.ui.handlers">
        <handler commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" class="com.nsd.navigatorpopup.NavigatorPopupHandler"/>
    </extension>
    <extension point="org.eclipse.ui.menus">
        <menuContribution locationURI="popup:org.eclipse.jdt.ui.PackageExplorer?after=additions">
            <menu label="Popup Utilities">
                <command commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" id="com.nsd.NavigatorPopup.menus.navigatorPopupCommand"/>
            </menu>
        </menuContribution>
        <menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
            <menu label="Popup Utilities">
                <command commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" id="com.nsd.NavigatorPopup.menus.navigatorPopupCommand"/>
            </menu>
        </menuContribution>
    </extension>
</plugin>

To find out more about the plugin for the current selection click on a file and use ALT-SHIFT-F1 for the Plug-in Selection Spy

Plug-in Selection Spy

Use ALT-SHIFT-F2 for the Plug-in Menu Spy. Note press the ALT-SHIFT-F2 combination before right clicking and selecting the popup menu item of interest. Plug-in Menu Spy

Finally the code for the plug-in.

NavigatorPopupHandler.java

package com.nsd.navigatorpopup;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;

// ====================================================================================================================
// This handler will obtain the core information about a file from a navigator popup menu
// ====================================================================================================================
public class NavigatorPopupHandler extends AbstractHandler {
    private IWorkbenchWindow window;
    private IWorkbenchPage activePage;

    private IProject theProject;
    private IResource theResource;
    private IFile theFile;

    private String workspaceName;
    private String projectName;
    private String fileName;

    public NavigatorPopupHandler() {
        // Empty constructor
    }

    public Object execute(ExecutionEvent event) throws ExecutionException {
        // Get the project and file name from the initiating event if at all possible
        if(!extractProjectAndFileFromInitiatingEvent(event)) {
            return null;
        }

        // CODE THAT USES THE FILE GOES HERE
        MessageDialog.openInformation(this.window.getShell(), "NavigatorPopup", String.format("File Details.\n\nWorkspace=%s\nProject=%s\nFile=%s", workspaceName, projectName, fileName));

        return null;
    }

    private boolean extractProjectAndFileFromInitiatingEvent(ExecutionEvent event) {
        // ============================================================================================================
        // The execute method of the handler is invoked to handle the event. As we only contribute to Explorer
        // Navigator views we expect to get a selection tree event
        // ============================================================================================================
        this.window = HandlerUtil.getActiveWorkbenchWindow(event);
        // Get the active WorkbenchPage
        this.activePage = this.window.getActivePage();

        // Get the Selection from the active WorkbenchPage page
        ISelection selection = this.activePage.getSelection();
        if(selection instanceof ITreeSelection) {
            TreeSelection treeSelection = (TreeSelection) selection;
            TreePath[] treePaths = treeSelection.getPaths();
            TreePath treePath = treePaths[0];

            // The TreePath contains a series of segments in our usage:
            // o The first segment is usually a project
            // o The last segment generally refers to the file

            // The first segment should be a IProject
            Object firstSegmentObj = treePath.getFirstSegment();
            this.theProject = (IProject) ((IAdaptable) firstSegmentObj).getAdapter(IProject.class);
            if(this.theProject == null) {
                MessageDialog.openError(this.window.getShell(), "Navigator Popup", getClassHierarchyAsMsg(
                                "Expected the first segment to be IAdapatable to an IProject.\nBut got the following class hierarchy instead.", "Make sure to directly select a file.",
                                firstSegmentObj));
                return false;
            }

            // The last segment should be an IResource
            Object lastSegmentObj = treePath.getLastSegment();
            this.theResource = (IResource) ((IAdaptable) lastSegmentObj).getAdapter(IResource.class);
            if(this.theResource == null) {
                MessageDialog.openError(this.window.getShell(), "Navigator Popup", getClassHierarchyAsMsg(
                                "Expected the last segment to be IAdapatable to an IResource.\nBut got the following class hierarchy instead.", "Make sure to directly select a file.",
                                firstSegmentObj));
                return false;
            }

            // As the last segment is an IResource we should be able to get an IFile reference from it
            this.theFile = (IFile) ((IAdaptable) lastSegmentObj).getAdapter(IFile.class);

            // Extract additional information from the IResource and IProject
            this.workspaceName = this.theResource.getWorkspace().getRoot().getLocation().toOSString();
            this.projectName = this.theProject.getName();
            this.fileName = this.theResource.getName();

            return true;
        } else {
            String selectionClass = selection.getClass().getSimpleName();
            MessageDialog.openError(this.window.getShell(), "Unexpected Selection Class", String.format("Expected a TreeSelection but got a %s instead.\nProcessing Terminated.", selectionClass));
        }

        return false;
    }

    @SuppressWarnings("rawtypes")
    private static String getClassHierarchyAsMsg(String msgHeader, String msgTrailer, Object theObj) {
        String msg = msgHeader + "\n\n";

        Class theClass = theObj.getClass();
        while(theClass != null) {
            msg = msg + String.format("Class=%s\n", theClass.getName());
            Class[] interfaces = theClass.getInterfaces();
            for(Class theInterface : interfaces) {
                msg = msg + String.format("    Interface=%s\n", theInterface.getName());
            }
            theClass = theClass.getSuperclass();
        }

        msg = msg + "\n" + msgTrailer;

        return msg;
    }
}

And the result of running the plug-in on its own java file.

Plugin Result

like image 88
TJA Avatar answered Sep 23 '22 17:09

TJA