(注 - 最终解决方案如下)
在我的插件中,我正在尝试创建一个IJavaProject
(使用Eclipse JDT,最后的代码),几乎完全创建一个Java项目,好像IJavaProject是由开发人员创建的(或者是谁使用插件)。我可以从我的PDE创建IJavaProject
,它工作正常,但我需要模仿我的PDE中项目创建所产生的IResourceChangeEvents
以匹配出现的IResourceChangeEvents
来自开发人员工作区中的Java项目创建。
我正在衡量' IResourceChangeEvents'使用我的IResourceChangeListener
(它使用访问者,并且应该是正确的 - 查看代码here)。在开发人员工作区中创建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"
答案 0 :(得分:1)
尝试以下两件事:
使用IWorkspaceRunnable的实现将所有资源更改批处理到单个事务中。这应该使更改看起来更像创建项目资源增量。
确保在运行代码之前从磁盘中删除项目。它看起来像是从工作区中删除了它而不是文件系统。