2014-03-19 44 views
1

(注 - 最終的解決方案如下)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-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" 

回答

1

嘗試這兩個東西:

  • 使用IWorkspaceRunnable的實現批量所有的資源變成一個單一的交易。這應該使更改看起來更像創建項目資源增量。

  • 確保項目在運行代碼之前從磁盤中刪除。它看起來像你從工作區中刪除它,但不是文件系統。

+0

謝謝你的提示。當批量更改資源時,您是否建議異步運行它?由於我試圖返回我的'javaProject',我想我應該等到作業完全完成後再使用我的'javaProject'。我正在考慮在'runInWorkspace'中使用'WorkspaceJob'並創建一個擴展'Job'的內部類,然後使用'IJobManager'來加入作業直到完成。 – modulitos

+0

@Lucas同步工作正常。雖然它的運行速度比沒有IWorkspaceRunnable的速度要快很多,因爲每次添加資源時都沒有運行構建器 - 最後只有一次。 –

相關問題