Плагин Eclipse: как получить путь к выбранному в данный момент проекту
Я пишу плагин Eclipse, в котором будет отображаться элемент меню в контекстном меню для Java Project. Я написал файл plugin.xml следующим образом:
<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>
Итак, теперь я пытаюсь написать класс MenuContribution
, который расширяет CompoundContributionItem
, чтобы я мог создать динамическое меню, и содержимое этого меню будет основываться на наборе файлов, существующих в Java-проекте корневая директория. Но я застреваю, пытаясь получить путь к корневому каталогу из метода getContributionItems
.
На основе файла plugin.xml я могу гарантировать, что метод будет вызываться только при выборе одного Java-проекта, поэтому все, что мне нужно сделать, это получить текущий выбор, а затем получить его абсолютный путь. Есть идеи? Или есть лучший способ сделать это?
Ответы
Ответ 1
Это должно помочь вам ближе (если вы не решите его полностью для вас;))
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null)
{
IStructuredSelection selection = (IStructuredSelection) window.getSelectionService().getSelection();
Object firstElement = selection.getFirstElement();
if (firstElement instanceof IAdaptable)
{
IProject project = (IProject)((IAdaptable)firstElement).getAdapter(IProject.class);
IPath path = project.getFullPath();
System.out.println(path);
}
}
Ответ 2
Если бы у меня был очень долгий день, пройдя через ответы и множество других ответов, я нашел бит, который, наконец, заставил меня сделать цикл Java Reflection, чтобы изучить структуру класса и интерфейса выбора из Дерево в навигаторе. Цикл интроспекции класса находится в конечном месте покоя, но первоначально намного ближе к вершине метода execute.
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.runtime.IAdaptable;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
public class MyHandler extends AbstractHandler {
/**
* The constructor.
*/
public MyHandler() {
}
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage activePage = window.getActivePage();
ISelection selection = activePage.getSelection();
if (selection != null) {
System.out.println("Got selection");
if (selection instanceof IStructuredSelection) {
System.out.println("Got a structured selection");
if (selection instanceof ITreeSelection) {
TreeSelection treeSelection = (TreeSelection) selection;
TreePath[] treePaths = treeSelection.getPaths();
TreePath treePath = treePaths[0];
System.out.println("Last");
Object lastSegmentObj = treePath.getLastSegment();
Class currClass = lastSegmentObj.getClass();
while(currClass != null) {
System.out.println(" Class=" + currClass.getName());
Class[] interfaces = currClass.getInterfaces();
for(Class interfacey : interfaces) {
System.out.println(" I=" + interfacey.getName());
}
currClass = currClass.getSuperclass();
}
if(lastSegmentObj instanceof IAdaptable) {
IFile file = (IFile) ((IAdaptable) lastSegmentObj).getAdapter(IFile.class);
if(file != null) {
System.out.println("File=" + file.getName());
String path = file.getRawLocation().toOSString();
System.out.println("path: " + path);
}
}
}
}
}
return null;
}
}
Ответ 3
Поскольку я написал предыдущий ответ, я написал еще пару плагинов утилиты и теперь имею общий стартер для всплывающих окон Eclipse Navigator. Файлы выглядят следующим образом:
Основной файл манифеста
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
Файл основных свойств
build.properties
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.
Файл плагина
В частности, обратите внимание, как < command commandId =... > < menuContribution... > < menu. > в ссылках < extension point = "org.eclipse.ui.menus" > ссылки на команду < обработчик commandId =. <& strong > в < extension point = "org.eclipse.ui.handlers" > , это позволяет нам связывать несколько вкладов меню с одним обработчиком. p >
Также следует отметить тот факт, что существует несколько locationURI, поскольку они могут меняться с одной точки зрения на другую.
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>
Чтобы узнать больше о плагине для текущего выбора, нажмите на файл и используйте ALT-SHIFT-F1 для выбора шпионского модуля
![Plug-in Selection Spy]()
Используйте ALT-SHIFT-F2 для шпионского меню Plug-in Menu. Обратите внимание на комбинацию ALT-SHIFT-F2 перед щелчком правой кнопкой мыши и выбрав интересующий пункт всплывающего меню.
![Plug-in Menu Spy]()
Наконец, код для плагина.
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;
}
}
И результат запуска плагина в собственном java файле.
![Plugin Result]()