Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Eclipse PDE, Navigator View, TreeSelection - Получение типа и имени файла

Автор вопроса: JonОтветов: 4

Я пытаюсь получить сведения о структурированном выборе пользователя 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.

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

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

  • Возможно ли это сделать без зависимости от JDT? Есть ли обновления по состоянию на январь 2014? Paul Verest 26.01.2014

javaeclipseeclipse-rcpeclipse-plugineclipse-pde

Ответы

Ответ 1 · рейтинг 9 · Scott Stanchfield

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

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

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

Заводской подход к адаптерам

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

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

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

Зависимости

Плагин, который будет размещать адаптер, нуждается в следующих зависимостях.

  • 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, и ваш код выбора не будет иметь значения.


Прямой подход ICompilationUnit

[EDIT: я изменил ответ, но оставил следующую информацию в качестве справочной информации, потому что это стандартный способ изучения содержимого единицы компиляции, которая была выбрана в проводнике пакетов]

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

Вместо использования 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-файл для вас. Я загляну и посмотрю, существует ли он.

Ответ 2 · рейтинг 4 · VonC

Это (отделение Resource от 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 · рейтинг 3 · Eugene

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

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

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

Ответ 4 · рейтинг 3 · greg-449

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

Object firstElement = treeSelection.getFirstElement();

IResource resource = (IResource)Platform.getAdapterManager().getAdapter(firstElement, IResource.class);

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы