Eclipse PDE:模拟IResourceChangeEvents,用于PDE和开发人员工作区之间的IJavaProject创建? [英] Eclipse PDE: Mimicking IResourceChangeEvents for IJavaProject creation between PDE and developer's workspace?

查看:116
本文介绍了Eclipse PDE:模拟IResourceChangeEvents,用于PDE和开发人员工作区之间的IJavaProject创建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(注 - 最后解决方案如下)

在我的插件中,我正在尝试创建一个 IJavaProject ,它可以正常工作,但是我需要模仿 IResourceChangeEvents 来自我的PDE中的项目创建,以匹配开发人员工作区中Java项目创建产生的 IResourceChangeEvents

In my plug-in, I am trying to create an IJavaProject (using Eclipse JDT, code at the end) that creates a Java Project almost EXACTLY as if the IJavaProject were created by the developer (or whoever is using the plug-in). I am able to create the IJavaProject from my PDE, and it works fine, but I need to mimic the IResourceChangeEvents that arise from the project creation in my PDE to match the IResourceChangeEvents that arise from Java project creation in the developer's workspace.

我使用我的 IResourceChangeListener 来衡量'IResourceChangeEvents'(它使用访问者,应该是正确的 - 查看代码 here )。在开发人员工作区中创建Java项目时,我正在测量以下 IResourceChangeEvents

I am measuring the 'IResourceChangeEvents' using my IResourceChangeListener (it uses a visitor, and should be correct - view the code here). When a Java Project is created in the developer's workspace, I am measuring the following 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

And when I create an IJavaProject using Eclipse JDT in my PDE (code at the end), I measure these 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"

其中 CR CHANGED-ROOT CP CHANGED-PROJECT CF 更改文件

有另一种方式创建一个 IJavaProject 的建议?

Any suggestions on another way to create an 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!)。

As mentioned in the answer below, I batched the resource change events which causes Eclipse to build the IJavaProject much differently - and more efficiently - than without batching. As a result, my IJavaProject creation now matches Eclipse's internal resource tree representation for IJavaProject creation (WOOHOO!).

这是我的最终解决方案:

Here is my final solution:

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 文件夹 - 只是手动创建的工件)。

Here is the new resource tree, which matches the resource tree that I needed above (excluding the .settings folder - just an artifact from manual creation).

CHANGE-ROOT (1 child)
    ADD-PROJECT (4 children)
        ADD-FILE ".classpath"
        ADD-FILE ".project"
        ADD-FOLDER ".bin"
        ADD-FOLDER ".src"


推荐答案

尝试这两件事:


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

  • Use an implementation of IWorkspaceRunnable to batch all of the resource changes into a single transaction. That should make the changes look much more like the create project resource delta.

在运行代码之前,请确保项目已从磁盘中删除。看起来你从工作空间中删除它,但不是文件系统。

Make sure that the project is deleted from disk before running your code. It looks like you deleted it from the workspace but not the file system.

这篇关于Eclipse PDE:模拟IResourceChangeEvents,用于PDE和开发人员工作区之间的IJavaProject创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆