[EDIT: I added the following alternative - the original answer is father down]
First: if you select something in the Package Explorer, the selected items are all Java Model objects - you have to deal with them at some level. There are two ways you can handle this:
- Use the ICompilationUnit directly (see farther down)
- Create an Eclipe adapter factory to automate the conversion
Adapter Factory Approach
You can create an adapter factory (which can live in your main plugin or a different one) that eclipse can use to automatically convert from an ICompilationUnit to an IFile.
Note: if you create the adapter factory in a different plugin, you'll probably need to set up an early-startup for it to get the adapter factory loaded. Otherwise, you'll need to have your plugin that will work with the selection depend on the plugin that provides the adapter.
There's some great details on adapters at http://www.eclipse.org/resources/resource.php?id=407, but I'll go over an implementation for this problem here.
Dependencies
The plugin that will host the adapter needs the following dependencies
- org.eclispe.core.resources
- org.eclipse.jdt.core
The adapter factory class
Define the following class in your 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};
}
}
The extension
In the plugin that will host the adapter factory, add the following to your 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>
Using the Adapter
With the above in place, 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 doesn't care.
Direct ICompilationUnit Approach
[EDIT: I've changing the answer, but leaving the following as reference information b/c it's the standard way to explore the content of a compilation unit that was selected in the package explorer]
This is actually the preferred way to get the contents of a file in the package explorer...
Rather than use CompilationUnit, you should use ICompilationUnit. Most of the 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'll be in good shape.
To see details of examining/modifying the Java Model and source code:
(In Eclipse)
Help->
Help Contents->
JDT Plug-in Developer's Guide->
Programmer's Guide->
JDT Core
That shows how to work with the Java Model appropriately
To isolate where you reference the java model, you can create an (eclipse) adapter that will convert Java Model objects into files. Assuming such an adapter exists, you can then ask the AdapterManager to convert it to a java file for you. I'll take a peek and see if one exists.