Project Natures

来源:互联网 发布:淘宝分享是什么 编辑:程序博客网 时间:2024/06/06 08:50
 
在Eclipse平台中使用nature来描述工程的类型,查看工程根目录下的.project文件,会发现是用于标记工程类型的标签<nature>,比如java工程的标记为:
 
……
<nature>org.eclipse.jdt.core.javanature</nature>
……
 
一个project往往拥有多个nature,例如一个Plug-in开发工程同时拥有Java Nature(JDT)和Plugin Nature(PDE)等。
所有的nature都是一个实现了扩展点org.eclipse.core.resources.natures的插件,在插件中可以自定义工程增加或者删除该nature所需要执行的动作。下面我们用一个简单的例子来说明上面的问题。
 
案例说明:
       假设现在需要开发一个实体维护的插件。所有实体的定义保存在若干个分散的XML文件中,实体之间往往会有关联关系,比如我们在编辑实体A时,需要查看A关联的实体B的一些信息,如果此刻去扫描工程目录下的XML文件来查找实体B的信息是不可取的,因为无论性能还是效率上都很难满足要求,所以需要在工程打开的时候就能预先缓存所有的实体信息。这样就引入了两个问题:
  • Workspace下有多个工程,如何知道哪个工程是需要缓存实体信息的?
  • 何时执行缓存动作?何时销毁缓存?
Natures能够很好的解决上面的问题。
 
实现Nature
1.         首先增加一个新的org.eclipse.core.resources.natures扩展点:
<extension
   point="org.eclipse.core.resources.natures"
   id="entityNature"
   name="Entity Nature">
   <runtime>
      <run class="com.company.natures.EntityNature">
      </run>
   </runtime>
</extension>
 
2.         Run class实现
编写实现类com.company.natures.EntityNature,注意类EntityNature必须实现接口org.eclipse.core.resources.IProjectNature
 
 
configure()和deconfigure()方法分别为工程被设置和删除该nature时会执行的动作,对应我们的实现分别为对实体的缓存和删除实体缓存操作。
 
给工程设置Nature
上面我们已经定义好了entityNature,但如何给工程设置此nature呢?请看如下方法:
 
publicvoid setEntityNature(IProject project){
        try {
              IProjectDescription description = project.getDescription();
              String[] natures = description.getNatureIds();
              String[] newNatures = new String[natures.length + 1];
              System.arraycopy(natures, 0, newNatures, 0, natures.length);
              newNatures[natures.length] = "com.company.natures.entityNature";
              description.setNatureIds(newNatures);
              project.setDescription(description, null);
           } catch (CoreException e) {
              e.printStackTrace();
           }
    }
 
如果判断这个工程是否是一个实体工程,这里给出一种实现:
 
publicboolean hasEntityNature(IProject project){
        try {
            return project.hasNature(“com.company.natures.entityNature”);
        } catch (CoreException e) {
            e.printStackTrace();
        }
        returnfalse;
    }
 
注意:
nature的全局唯一ID是由“插件的ID”加上“natures扩展中定义的ID”组合而成的。 例如上面的”com.company.natures.entityNature”= “com.company.natures “(Plug-in id) + ”.” + ”entityNature”(nature id)。
 
Nature的依赖
       先前已经说过了一个project可能拥有多个nature,现实中这些nature之间可能会有依赖关系,例如一个project如果包含Entity Nature的话,同时也需要包含Java Nature:即如果一个工程如果是一个实体工程的话,那么它也一定是一个java工程。
修改我们的Plug-in描述文件如下:
 
<extension
   point="org.eclipse.core.resources.natures"
   id="entityNature"
   name="Entity Nature">
   <runtime>
      <run class="com.company.natures.EntityNature">
      </run>
   </runtime>
   <requires-nature id="org.eclipse.jdt.core.javanature"/>
</extension>
 
可以看到增加requires-nature标签表明该nature需要依赖哪些其他的nature,这时需要修改先前的setEntityNature()方法以支持对多个nature组合的合法性验证:
 
publicvoid setEntityNatureWithValidate(IProject project,Workspace workspace){
        try {
              IProjectDescription description = project.getDescription();
              String[] natures = description.getNatureIds();
              String[] newNatures = new String[natures.length + 1];
              System.arraycopy(natures, 0, newNatures, 0, natures.length);
              newNatures[natures.length] = "com.company.natures.entityNature";
             
              IStatus status = workspace.validateNatureSet(natures);
              if (status.getCode() == IStatus.OK) {//check
                 description.setNatureIds(newNatures);
                 project.setDescription(description, null);
              } else {
                 // TODO提醒用户
              }
              description.setNatureIds(newNatures);
              project.setDescription(description, null);
           } catch (CoreException e) {
              e.printStackTrace();
           }
    }
 
Workspace.validateNatureSet(String[] natureIds)方法主要做如下几项验证工作:
  • natureIds所有的nature已经被注册
  • natureIds中所有nature依赖的nature已经包含在natureIds
  • natureIds中所有nature之间没有循环依赖关系
  • natureIds中没有重复的nature
 
Nature 描述信息
在运行时如何根据nature id得到该nature相关的信息呢?
通过IWorkspace.getNatureDescriptor(String natureId)方法可以获得指定nature的描述信息,接口IProjectNatureDescriptor正是对natrue描述信息的抽象。
 
IProjectNatureDescriptor descriptor = workspace.getNatureDescriptor( "com.example.natures.myOtherNature" );
 
当然,也可以取得当前workspace所有nature的描述信息:
 
IProjectNatureDescriptor[] descriptors = workspace.getNatureDescriptors();
 
 
原创粉丝点击