gpt4 book ai didi

java - Eclipse PDE : Mimicking IResourceChangeEvents for IJavaProject creation between PDE and developer's workspace?

转载 作者:太空宇宙 更新时间:2023-11-04 06:57:45 24 4
gpt4 key购买 nike

(注意 - 最终解决方案如下)

在我的插件中,我试图创建一个 IJavaProject (使用 Eclipse JDT,代码在最后),它创建一个 Java 项目,几乎完全就像 IJavaProject 是由开发人员(或使用该插件的人)创建的一样。我能够从 PDE 创建 IJavaProject,并且工作正常,但我需要模仿 PDE 中创建项目时产生的 IResourceChangeEvents,以匹配在开发人员工作区中创建 Java 项目时产生的 IResourceChangeEvents

我正在使用我的 IResourceChangeListener 测量“IResourceChangeEvents”(它使用访问者,并且应该是正确的 - 查看代码 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-RCHANGED-ROOTC-PCHANGED-PROJECTC-FCHANGED-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"

最佳答案

尝试以下两件事:

  • 使用 IWorkspaceRunnable 的实现将所有资源更改批处理到单个事务中。这应该会使更改看起来更像创建项目资源增量。

  • 确保在运行代码之前已从磁盘中删除该项目。看起来您已从工作区中删除了它,但没有从文件系统中删除它。

关于java - Eclipse PDE : Mimicking IResourceChangeEvents for IJavaProject creation between PDE and developer's workspace?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22494353/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com