Eclipse PDE, Navigator View, TreeSelection - получение типа и имени файла - PullRequest
7 голосов
/ 22 апреля 2009

Я пытаюсь получить подробную информацию о структурированном выделении пользователя Eclipse в представлении дерева навигатора. В настоящее время у меня есть следующее, основанное на точке расширения org.eclipse.ui.popMenus:

public void run(IAction action) {

Shell shell = new Shell();

ISelection selection = workbenchPart.getSite().getSelectionProvider().getSelection();

if (structuredSelection instanceof org.eclipse.jface.viewers.TreeSelection) {

   org.eclipse.jface.viewers.TreeSelection treeSelection = (org.eclipse.jface.viewers.TreeSelection) structuredSelection;
   IAdaptable firstElement = (IAdaptable) treeSelection.getFirstElement();

   // Relies on an internal API, bad juju
   if (firstElement instanceof org.eclipse.jdt.internal.core.CompilationUnit) {
    org.eclipse.jdt.internal.core.CompilationUnit compilationUnit = (org.eclipse.jdt.internal.core.CompilationUnit) firstElement;                                   
    String editorSelection = new String(compilationUnit.getContents());
   }            
}

Проблема в том, что он в настоящее время связан с API модуля компиляции JDT, который является внутренним и слишком специфичным для того, что я хочу.

В идеале я хочу иметь возможность получить основное имя файла, его тип и содержание, не полагаясь на:

  1. Внутренний API
  2. Код единицы компиляции JDT.

Это позволило бы мне получить свойства универсального файла, когда пользователь щелкнет правой кнопкой мыши по файлу в представлении навигатора.

Может, кто-нибудь подскажет, как мне поступить, пожалуйста?

Ответы [ 4 ]

9 голосов
/ 22 апреля 2009

[РЕДАКТИРОВАТЬ: я добавил следующую альтернативу - оригинальный ответ отцом вниз]

Во-первых: если вы выбираете что-то в Package Explorer, все выбранные элементы являются объектами Java Model - вам придется иметь дело с ними на каком-то уровне. Есть два способа справиться с этим:

  1. Используйте ICompilationUnit напрямую (см. Ниже)
  2. Создание фабрики адаптеров Eclipe для автоматизации преобразования

Адаптер заводского подхода

Вы можете создать фабрику адаптеров (которая может находиться в вашем основном плагине или в другом), которую eclipse может использовать для автоматического преобразования из ICompilationUnit в IFile.

Примечание: если вы создаете фабрику адаптеров в другом плагине, вам, вероятно, потребуется настроить ранний запуск, чтобы загрузить фабрику адаптеров. В противном случае вам потребуется, чтобы ваш плагин, который будет работать с выбором, зависит от плагина, который предоставляет адаптер.

На адаптерах http://www.eclipse.org/resources/resource.php?id=407, есть несколько замечательных деталей, но здесь я расскажу о реализации этой проблемы.

1021 * Зависимость * Плагину, в котором будет размещен адаптер, необходимы следующие зависимости org.eclispe.core.resources org.eclipse.jdt.core Адаптер заводского класса

Определите следующий класс в вашем новом плагине

package com.javadude.foo;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jdt.core.ICompilationUnit;

public class CompilationUnitToFileAdapter implements IAdapterFactory {
    @Override
    public Object getAdapter(Object adaptableObject, Class adapterType) {
        if (adaptableObject instanceof ICompilationUnit)
            // note: "adapting" it here just means returning the ref'd IFile
            return (IFile) ((ICompilationUnit)adaptableObject).getResource();
        return null;
    }
    @Override
    public Class[] getAdapterList() {
        return new Class[] {IFile.class};
    }
}

Расширение

В плагине, в котором будет размещена фабрика адаптеров, добавьте в свой файл plugin.xml следующее:

<extension point="org.eclipse.core.runtime.adapters">
    <factory
        adaptableType="org.eclipse.jdt.core.ICompilationUnit"
        class="com.javadude.foo.AdapterFactory1">
        <adapter type="org.eclipse.core.resources.IFile" />
    </factory>
</extension>

Использование адаптера

С учетом вышесказанного вы можете написать:

Object firstElement = ((ITreeSelection) selection).getFirstElement();
IFile file = (IFile) Platform.getAdapterManager().
                         getAdapter(firstElement, IFile.class);
if (file == null)
    // adapter not present; cannot use as IFile
else
    // adapter present - you can use it as an IFile

Используя этот подход, вы можете добавить дополнительные адаптеры для преобразования других типов в IFile, и ваш код выбора не имеет значения.


Подход Direct ICompilationUnit

[РЕДАКТИРОВАТЬ: я изменяю ответ, но оставляю следующее в качестве справочной информации, поскольку это стандартный способ изучения содержимого модуля компиляции, который был выбран в проводнике пакетов]

На самом деле это предпочтительный способ получения содержимого файла в проводнике пакетов ...

Вместо того, чтобы использовать CompilationUnit, вы должны использовать ICompilationUnit. Большинство API-интерфейсов eclipse используют интерфейсы для общего пользования и классы для внутренних деталей.

Если вы измените свой код на

if (firstElement instanceof ICompilationUnit) {
    ICompilationUnit unit = (ICompilationUnit firstElement;
    String contents = new String(unit.getContents());
}

Вы будете в хорошей форме.

Чтобы увидеть подробности изучения / изменения модели Java и исходного кода:

(In Eclipse)
Help->
  Help Contents->
    JDT Plug-in Developer's Guide->
      Programmer's Guide->
        JDT Core

Это показывает, как правильно работать с моделью Java

Чтобы определить, где вы ссылаетесь на модель Java, вы можете создать адаптер (eclipse), который будет преобразовывать объекты модели Java в файлы. Предполагая, что такой адаптер существует, вы можете попросить AdapterManager преобразовать его в файл Java для вас. Я посмотрю и посмотрю, существует ли он.

4 голосов
/ 26 января 2014

Это (отделение ресурса от JDT) было одной из целей E4 (Eclipse 4) .
Список плагинов для REsources больше не упоминает JDT (опять же, только Eclipse 4.x):

  • org.eclipse.core.filesystem - Абстрактный, общий API-интерфейс файловой системы, включая реализацию этого API-интерфейса для локальной файловой системы. Это API, через который плагин ресурсов обращается к базовой файловой системе.
  • org.eclipse.core.resources - Содержит API и реализацию модели ресурсов
  • org.eclipse.core.resources.compatibility - Плагин, обеспечивающий поддержку миграции для пользователей, открывающих старые рабочие пространства в Eclipse 3.1 или новее

Демонстрационный проект, такой как e4photo , не требует JDT для доступа к IResource из выбора IContainer .

void setSelection(@Named(IServiceConstants.ACTIVE_SELECTION)
        IResource selection) {
...
IResource[] members = input.members();
...
IResource resource = members[i];
if (resource.getType() == IResource.FILE) {
  InputStream contents = ((IFile) resource).getContents();
3 голосов
/ 29 января 2014

Похоже, JDT уже определяет IAdapterFactory для всех элементов Java, включая единицу компиляции (org.eclipse.jdt.internal.ui.JavaElementAdapterFactory). Адаптер определен для IResource, а не IFile, поэтому вы должны иметь возможность:

Object firstElement = treeSelection.getFirstElement();

IResource resource = (IResource)Platform.getAdapterManager().getAdapter(firstElement, IResource.class);
3 голосов
/ 22 апреля 2009

Чего ты пытаешься достичь? Вы хотите получить содержимое файла? Тогда вы можете попробовать:

IAdaptable firstElement = (IAdaptable) treeSelection.getFirstElement();

IFile file = (IFile) firstElement.getAdapter(IFile.class);
if (file != null && file.isAccessible()) {
    // Use getContents API
    ....
}
...