Добавить 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 ответа
Я наконец нашел способ добавить свою библиотеку прямо из моего плагина. Несмотря на то, что ответ Евгения не был неправильным, ему не хватало объяснений. Я постараюсь показать, как это сделать.
Если вы хотите добавить библиотеку, содержащую несколько файлов, вы можете сделать это следующим образом:
- Создайте класс, расширяющий JsGlobalScopeContainerInitializer
- Добавьте расширение в точку расширения org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer
- Добавьте 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, соответствующего виду записи.