I have a eclipse plugin contributing a project nature requiring the jsdt javaScriptNature. I now like to add a javascript library contained in my plugin to the includepath of the project programatically. Is there a way i can do this?
I read something about JsGlobalScopeContainer and JsGlobalScopeContainerInitializer and tried them but that seems very confusing. I just want to add a library containing some .js files from my plugin. I just can't get my head around this concept.
This is what i came up with so far:
IJavaScriptProject jsProj = JavaScriptCore.create(p);
Path pa = new Path("/src/de/otris/eclipse/portalscripting/psLibrary/library.js");
IIncludePathEntry entry = JavaScriptCore.newProjectEntry(pa);
IIncludePathEntry[] ipaths = jsProj.getRawIncludepath();
IIncludePathEntry[] newpaths = new IIncludePathEntry[ipaths.length +1];
System.arraycopy(ipaths, 0, newpaths, 0, ipaths.length);
newpaths[ipaths.length] = entry;
jsProj.setRawIncludepath(newpaths, null);
I finally found a way to add my library directly from my plugin. Allthough the answer of Eugene wasn't to wrong, it lacked some explainations. I'll try to show how to do this.
If you want to add a library containing several files you can do it this way:
1. Create a Class extending JsGlobalScopeContainerInitializer
There are a few very confusing tutorials out there (including the one on the eclipse wiki) that at first made it harder to understand this. I came up with something like the following:
[... package and imports ommited ...]
public class LibInitializer extends JsGlobalScopeContainerInitializer {
private static final String LIBRARY_ID = "com.testvendor.testplugin.library";
public IPath getPath() {
return new Path(LIBRARY_ID);
}
@Override
public LibraryLocation getLibraryLocation() {
return null;
}
@Override
public String getDescription() {
return "Test Library";
}
@Override
public String getDescription(IPath containerPath, IJavaScriptProject project) {
return getDescription();
}
@Override
public IIncludePathEntry[] getIncludepathEntries() {
try {
//get the Bundle object of the plugin
Bundle bundle = Platform.getBundle("com.testvendor.testplugin");
//get the java.io.File object corresponding to the root of the bundles installation directory
File bundleFile = FileLocator.getBundleFile(bundle);
//add the location pointing to the library relative to that bundle root
File libraryLocation = new File(bundleFile, "bin/com/testvendor/testplugin/library/");
//create a Path object from it
IPath pa = new Path(libraryLocation.getAbsolutePath());
/* create an IIncludePathEntry of the type "library" from this path
my library only contains one folder (for now) so this is it */
IIncludePathEntry entry = JavaScriptCore.newLibraryEntry(pa, pa, pa);
//put the entry (or entries if you had more) into an array and return
IIncludePathEntry[] entries = {entry};
return entries;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
The most interesting part is the method getIncludepathEntries() where the actual entries will be retrieved from the container. Since an IIncludePathEntry will not work with an URL of the "file://" pseudo-protocol the method "toFileURL" suggested by Eugene will not work here.
2. Contribute an extension to the JSGlobalScope... extension Point
To tell Projects containing an container entry with the id com.testvendor.testplugin.library the easiest way is to contribute to the extension point *org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer** like this:
<extension point="org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer">
<JsGlobalScopeContainerInitializer
id="com.testvendor.testplugin.library"
class="com.testvendor.testplugin.library.LibInitializer"/>
</extension>
Where class of course refers to the JsGlobalScopeContainerInitializer from step 1.
3. adding the IIncludePathEntry to the Project
IJavaScriptProject jsProj = ... get your project object from somewhere ...
//create an instance of the container from step 1.
JsGlobalScopeContainerInitializer container = new LibInitializer();
//create an includepath entry refering to the container
IIncludePathEntry entry = JavaScriptCore.newContainerEntry(container.getPath());
IIncludePathEntry[] ipaths = jsProj.getRawIncludepath();
IIncludePathEntry[] newpaths = new IIncludePathEntry[ipaths.length +1];
System.arraycopy(ipaths, 0, newpaths, 0, ipaths.length);
//add the new entry
newPaths[ipaths.length] = enty;
// set the new includepath to the project
jsProj.setRawIncludepath(newpaths, null);
If you're lucky now you'll have a library entry in your JavaScript Resources containing all JavaScript objects and classes which are contained in the library folder you added with the ContainerIntitializer. And all this objects and classes will be available in the code completion suggestions.
I hope that prevents someone else from spending hours of frustration on a topic that really could be simpler than it is.