(注 - 最終的解決方案如下)Eclipse PDE:模仿IResourceChangeEvents在PDE和開發人員工作區之間創建IJavaProject?
在我的插件,我想創建一個IJavaProject
(使用Eclipse JDT,在結束代碼)創建一個Java項目幾乎完全一樣,如果在IJavaProject是由開發人員(或使用該插件的人員)創建的。我能夠從我的PDE創建IJavaProject
,並且它工作正常,但我需要模仿在我的PDE中創建項目時產生的IResourceChangeEvents
,以匹配在開發人員的工作空間中創建Java項目時產生的IResourceChangeEvents
。
我正在使用我的IResourceChangeListener
(它使用訪問者,應該是正確的 - 查看代碼here)來測量'IResourceChangeEvents'。當開發人員的工作區中創建一個Java項目,我測量了以下IResourceChangeEvents
:
CHANGE-ROOT (1 child)
ADD-PROJECT (5 children)
ADD-FILE ".classpath"
ADD-FILE ".project"
ADD-FOLDER ".settings" ADD-FILE ".prefs"
ADD-FOLDER ".bin"
ADD-FOLDER ".src"
當我創造我的PDE(末碼)使用Eclipse JDT的IJavaProject
,我衡量這些IResourceChangeEvents
:
C-R
C-P
ADD-FILE ".project"
C-R
C-P "JavaProject"
C-R
C-P
CHANGE-FILE ".project"
C-R
C-P
ADD-FOLDER "bin"
C-R
C-P
C-F
ADD-FILE ".project"
C-R
C-P
ADD-FILE ".classpath"
C-R
C-P
ADD-FOLDER "src"
C-R
C-P
CHANGED-FILE ".classpath"
哪裏C-R
爲CHANGED-ROOT
,C-P
是CHANGED-PROJECT
和C-F
是CHANGED-FILE
。
對另一種創建IJavaProject
的方式有何建議?
這裏是我IJavaProject
創建代碼:
public static IJavaProject getJavaProject(IProject project) throws CoreException
{
return getJavaProject(project, "src", "bin");
}
public static IJavaProject getJavaProject(IProject project, String sourceFolderPath,
String binFolderPath) throws CoreException
{
if (!project.exists())
// This creates ADDED (.project)
ResourceUtility.createProject(project);
System.out.println("setting description nature id's.");
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] {JavaCore.NATURE_ID});
System.out.println("setting project description.");
// Creates CHANGED (JavaProject/.project)
project.setDescription(description, null);
System.out.println("Creating project.");
// Does not do anything.
IJavaProject javaProject = JavaCore.create(project);
IFolder binFolder = project.getFolder(binFolderPath);
// Creates ADDED (JavaProject/bin)
binFolder.create(false, true, null);
javaProject.setOutputLocation(binFolder.getFullPath(), null);
System.out.println("Installing VM.");
List<IClasspathEntry> entries = new ArrayList<>();
IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall();
System.out.println("JDTUtil: vmInstall: " + vmInstall);
LibraryLocation[] locations = JavaRuntime.getLibraryLocations(vmInstall);
System.out.println("JDTUtil: lib locations: " + locations);
// Creates ADDED (JavaProject/bin/.project) - ignored by RCL
for (LibraryLocation element: locations)
{
entries.add(JavaCore.newLibraryEntry(element.getSystemLibraryPath(), null, null));
}
// add libs to project class path
// Creates ADDED (JavaProject/.classpath)
javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), null);
//
IFolder sourceFolder = project.getFolder(sourceFolderPath);
// Creates ADDED (JavaProject/src)
sourceFolder.create(false, true, null);
IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(sourceFolder);
IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath());
// Creates CHANGED (JavaProject/.classpath)
javaProject.setRawClasspath(newEntries, null);
return javaProject;
}
最終解決
正如下面的答覆中提到,我成批導致的Eclipse構建IJavaProject很多不同的資源變化的事件 - 和比沒有配料更有效率。因此,我的IJavaProject創建現在與Eclipse的內部資源樹表示(用於創建IJavaProject(WOOHOO!))相匹配。
這是我最終的解決方案:
public static IJavaProject getJavaProjectBatched(final IProject project, final String sourceFolderPath,
final String binFolderPath) throws CoreException
{
IWorkspaceRunnable r = new IWorkspaceRunnable()
{
@Override public void run(@Nullable IProgressMonitor monitor) throws CoreException
{
if (!project.exists())
ResourceUtility.createProject(project);
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] {JavaCore.NATURE_ID});
project.setDescription(description, null);
IFolder binFolder = project.getFolder(binFolderPath);
binFolder.create(false, true, null);
final IFolder sourceFolder = project.getFolder(sourceFolderPath);
sourceFolder.create(false, true, null);
final IJavaProject javaProject = JavaCore.create(project);
javaProject.setOutputLocation(binFolder.getFullPath(), null);
IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(sourceFolder);
IClasspathEntry[] newEntries = new IClasspathEntry[1];
newEntries[0] = JavaCore.newSourceEntry(root.getPath());
javaProject.setRawClasspath(newEntries, null);
}
};
project.getWorkspace().run(r, null,IWorkspace.AVOID_UPDATE, null);
@SuppressWarnings("null") @NonNull IJavaProject javaProject = JavaCore.create(project);
return javaProject;
}
這裏是新的資源樹,我需要以上(不包括.settings
文件夾 - 剛剛從手工創建一個神器)資源樹相匹配。
CHANGE-ROOT (1 child)
ADD-PROJECT (4 children)
ADD-FILE ".classpath"
ADD-FILE ".project"
ADD-FOLDER ".bin"
ADD-FOLDER ".src"
謝謝你的提示。當批量更改資源時,您是否建議異步運行它?由於我試圖返回我的'javaProject',我想我應該等到作業完全完成後再使用我的'javaProject'。我正在考慮在'runInWorkspace'中使用'WorkspaceJob'並創建一個擴展'Job'的內部類,然後使用'IJobManager'來加入作業直到完成。 – modulitos
@Lucas同步工作正常。雖然它的運行速度比沒有IWorkspaceRunnable的速度要快很多,因爲每次添加資源時都沒有運行構建器 - 最後只有一次。 –