Добавить IncludePathEntry в JavaScriptProject программным способом

У меня есть плагин eclipse, который вносит свой вклад в характер проекта, требующий jsdt javaScriptNature. Теперь я хотел бы добавить библиотеку JavaScript, содержащуюся в моем плагине, в includepath проекта программно. Есть ли способ, которым я могу сделать это?

Я прочитал кое-что о JsGlobalScopeContainer и JsGlobalScopeContainerInitializer и попробовал их, но это кажется очень запутанным. Я просто хочу добавить библиотеку, содержащую некоторые файлы.js из моего плагина. Я просто не могу разобраться с этой концепцией.

Это то, что я придумал до сих пор:

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

2 ответа

Решение

Я наконец нашел способ добавить свою библиотеку прямо из моего плагина. Несмотря на то, что ответ Евгения не был неправильным, ему не хватало объяснений. Я постараюсь показать, как это сделать.

Если вы хотите добавить библиотеку, содержащую несколько файлов, вы можете сделать это следующим образом:

  1. Создайте класс, расширяющий JsGlobalScopeContainerInitializer
  2. Добавьте расширение в точку расширения org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer
  3. Добавьте IIncludePathEntry, указывающий на JsGlobalScopeContainer, используя его идентификатор, в проект, в котором вы хотите использовать библиотеку в

1. Создайте класс, расширяющий JsGlobalScopeContainerInitializer.

Есть несколько очень запутанных учебных пособий (в том числе на вики-сайте eclipse), которые поначалу усложняли понимание этого. Я придумал что-то вроде следующего:

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

Наиболее интересной частью является метод getIncludepathEntries(), где фактические записи будут извлечены из контейнера. Так как IIncludePathEntry не будет работать с URL-адресом псевдопротокола "file://", метод, предложенный Евгением "toFileURL", здесь не будет работать.

2. Добавьте расширение в точку расширения JSGlobalScope...

Чтобы сообщить Проектам, содержащим запись контейнера с идентификатором com.testvendor.testplugin.library, самый простой способ - добавить точку расширения *org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer** следующим образом:

<extension point="org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer">            
  <JsGlobalScopeContainerInitializer                                          
     id="com.testvendor.testplugin.library"                                                        
     class="com.testvendor.testplugin.library.LibInitializer"/>                           
</extension>

Где класс, конечно, ссылается на JsGlobalScopeContainerInitializer с шага 1.

3. добавление IIncludePathEntry в проект

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

Если вам повезет, у вас в библиотеке ресурсов JavaScript будет запись библиотеки, содержащая все объекты и классы JavaScript, которые содержатся в папке библиотеки, которую вы добавили с помощью ContainerIntitializer. И все эти объекты и классы будут доступны в предложениях по завершению кода.

Наконец-то библиотека

Я надеюсь, что это мешает кому-то еще тратить часы разочарования на тему, которая действительно может быть проще, чем она есть.

Чтобы установить путь включения проекта, вы должны использовать один из методов IJavaScriptProject::setRawIncludepath. IIncludePathEntries создаются путем вызова метода JavaScriptCore::new*Entry, соответствующего виду записи.

Другие вопросы по тегам