Eclipse PDE, Navigator View, TreeSelection - getting type and file name

I am trying to get the details of a custom structured Eclipse selection in the Tree Navigator view. Currently, I have the following which is based on the extension point 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()); } } 

The problem is that it is currently linked to the JDT compilation API module, which is internal and too specific for what I want.

Ideally, I want to get the base name, type and contents of a file without having to rely on:

  • Internal API
  • JDT compilation module code.

This will allow me to get the properties of the shared file when the user right-clicks the file as a navigator.

Can someone provide me with any pointers to how I do this?

+7
java eclipse eclipse-plugin eclipse-rcp eclipse-pde
source share
4 answers

[EDIT: I added the following alternative - original answer - fathers down]

Firstly: if you select something in the Package Explorer, the selected elements will be Java Model objects - you will have to deal with them at some level. There are two ways to deal with this:

  • Use ICompilationUnit directly (see below)
  • Create an Eclipe factory adapter to automate conversion

Adapter factory approach

You can create a factory adapter (which can live in your main plugin or another) that eclipse can use to automatically convert from ICompilationUnit to IFile.

Note. If you are creating a factory adapter in another plugin, you probably need to configure an early launch to load the factory adapter. Otherwise, you need your plug-in, which will work with the choice, to depend on the plug-in that the adapter provides.

There is some detailed information about adapters at http://www.eclipse.org/resources/resource.php?id=407 , but I will discuss the implementation of this problem here.

Dependencies

The plug-in on which the adapter will be placed needs the following dependencies

  • org.eclispe.core.resources
  • org.eclipse.jdt.core

Factory class adapter

Define the next class in a new plugin

 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}; } } 

Expansion

In the plugin that will host the factory adapter, add the following to your plugin.xml file:

 <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> 

Using adapter

With the above, you can now write:

 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 

Using this approach, you can add additional adapters to convert other types to IFile, and your selection code does not care.


Direct approach ICompilationUnit

[EDIT: I change the answer, but leave the b / c reference as the standard way to examine the contents of the compilation unit that was selected in the package explorer]

This is really the preferred way to get the contents of a file in the package explorer ...

Instead of using CompilationUnit, you should use ICompilationUnit. Most eclipse APIs use interfaces for public consumption and classes for internal details.

If you change your code to

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

You will be in good shape.

Learn more about viewing / modifying a Java model and source code:

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

This shows how to work with the Java model.

To isolate a reference to a Java model, you can create an (eclipse) adapter that converts Java Model objects to files. Assuming such an adapter exists, you can ask AdapterManager to convert it to a java file for you. I will stop by and see if it exists.

+8
source share

What are you trying to achieve? Do you want to get the contents of the file? Then you can try:

 IAdaptable firstElement = (IAdaptable) treeSelection.getFirstElement(); IFile file = (IFile) firstElement.getAdapter(IFile.class); if (file != null && file.isAccessible()) { // Use getContents API .... } 
+3
source share

This (resource decoupling from JDT) was one of the goals of E4 (Eclipse 4) .
The list of plugins for REsources no longer mentions JDT (again, only Eclipse 4.x):

  • org.eclipse.core.filesystem is an abstract, common file system API, including an implementation of this API for the local file system. This is the API through which the resource plugin accesses the underlying file system.
  • org.eclipse.core.resources - contains the API and resource model implementation
  • org.eclipse.core.resources.compatibility is a plugin that provides migration support for users opening old workspaces in Eclipse version 3.1 or higher

A demo project, such as e4photo , does not require a JDT to access IResource from 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
source share

It seems that the JDT already defines an IAdapterFactory for all Java elements, including the compilation unit ( org.eclipse.jdt.internal.ui.JavaElementAdapterFactory ). The adapter is defined for IResource , not IFile , so you can:

 Object firstElement = treeSelection.getFirstElement(); IResource resource = (IResource)Platform.getAdapterManager().getAdapter(firstElement, IResource.class); 
+3
source share

All Articles