سؤال

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
  2. Contribute an extension to the extension point org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer
  3. Add an IIncludePathEntry, pointing to the JsGlobalScopeContainer using its id, to the Project that you want to use the library in

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.

Finally a library!

I hope that prevents someone else from spending hours of frustration on a topic that really could be simpler than it is.

نصائح أخرى

To set project include path you should use one of IJavaScriptProject::setRawIncludepath methods. IIncludePathEntries are created by calling JavaScriptCore::new*Entry method corresponding to entry kind.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top