Eclipse WTP Projects Facets实战指南(1)

阅读更多

这个文章基本是"Building Project Facets"的中文版

在WTP中创建Dynamic Web Project工程的时候提供了Project Facets的功能,它让用户在创建web项目的时候,可以像搭积木一下给我们创建的project添加各种功能模块,下面我们通过一个例子来讲解一下WTP中的Project Facets的用法

通常我们给创建的工程可能添加以下元素:资源文件, Builder, Nature标识等, 我们知道Eclipse本身提供了一个Nature的功能,但是Facets跟Nature是有区别的, 给工程添加Nature是用来给Eclipse底层的工具使用的,而Facets是用来给最终用户使用的, 通常Facets提供的模块都是自描述的,这样可以保证用户在使用的时候,避免添加不必要的Facet模块, 而且对于我们开发者而言也避免了在新建向导中插入新的wizard page以及避免通过右键菜单来给工程添加或者去掉某模块,从而大大简化了开发人员的工作量, 因此Facets对用户和开发者来说都是一个不错的选择

下面我们结合一个名为FormGen的实例来介绍, FormGen用来在我们创建的web工程中,加入一些我们自己的jar包以及修改web.xml文件

废话少说,先在插件工程中添加org.eclipse.wst.common.project.facet.core.facets 扩展点, 当然这里需要在依赖中加入org.eclipse.wst.common.project.facet.core引用,该扩展点包罗万象,这里我们遵循循序渐进的原则,从最最简单的内容开始:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">    
  2.   
  3.   <project-facet id="{string}"> (0 or more)   
  4.     <label>{string}label>  
  5.     <description>{string}description> (optional)   
  6.   project-facet>  
  7.   
  8.   <project-facet-version facet="{string}" version="{string}"/> (0 or more)   
  9.      
  10. extension>  

这里加入了两个节点:project-facet是我们要加入的facet, project-facet-version用来制定我们的facet版本, 每一个facet至少需要给它指定一个版本,否则不可用, 后面大家就会知道,实际上我们大部分工作都集中在project-facet-version中配置, 配置后的代码如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   
  3.   <project-facet id="formgen.core">  
  4.     <label>FormGen Corelabel>  
  5.     <description>  
  6.       Enables generation of HTML forms based on XML definition files.   
  7.     description>  
  8.   project-facet>  
  9.   
  10.   <project-facet-version facet="formgen.core" version="1.0"/>  
  11.   
  12.   <project-facet id="formgen.ext">  
  13.     <label>FormGen Extensionslabel>  
  14.     <description>  
  15.       Enables additional FormGen widgets.   
  16.     description>  
  17.   project-facet>  
  18.   
  19.   <project-facet-version facet="formgen.ext" version="1.0"/>  
  20.      
  21. extension>  

设置好后运行我们的插件项目,创建一个Dynamic Web Project, 在向导中第一个页面的Target Runtime设置为none,继续进入到下一个页面,这时在下面的列表中就会出现我们添加的两个facet

Eclipse WTP Projects Facets实战指南(1)_第1张图片

接下来的工作就是给facet指定约束
由于我们的FormGen是基于Servlet的,因此它应该适用于所有的Java EE项目.下面我们通过增加约束让FormGen facet也能在EJB项目向导中使用.
下面是我们将要用到的扩展节点的相关说明:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <project-facet-version>  
  3.     <constraint> (optional)   
  4.       [expr]   
  5.     constraint>  
  6.   project-facet-version>  
  7. extension>  
  8.   
  9. [expr] =   
  10.   <requires facet="{string}" version="{version.expr}" soft="{boolean}"/> or   
  11.   <conflicts facet="{string}" version="{version.expr}"/> or   
  12.   <conflicts group="{string}"/> or   
  13.   <and>  
  14.     [expr] (1 or more)   
  15.   and> or   
  16.   <or>  
  17.     [expr] (1 or more)   
  18.   or>  

约束由树状结构的表达式组成, 它包括4个部分,这里我们分别来加以说明:

requires:是用的最多的部分,它表示当前的facet还需要依赖的其他facet, 如果对所依赖的facet没有版本要求,那么不用设置version属性, version可以设置为表达式, soft属性用来创建一种特定类型的依赖,即如果依赖facet不存在,那么当前facet将不会在选项列表中出现,其本facet必须在引用facet之后被安装

conflicts:冲突约束用来制定如果在同一个工程中已经存在了这里指定的facet,那么当前声明的facet将不可用,它用两种形式:可以指定单个冲突或组(group)冲突的facet.对于组冲突,这里需要解释一下, 组冲突用来指定当前的facet与没有在facet列表中列出的某一类facet有冲突,比如说, WTP自己的moudule facet都属于moudules组, 而这些facet在定义的时候,都将组冲突设置为modules, 这样就可以保证两个module不会同时安装在同一个工程中

要让一个facet属于某个组,需要这样定义扩展点:

  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">      
  2.   <project-facet-version>      
  3.     <group-member id="{string}"/> (0 or more)      
  4.   project-facet-version>      
  5. extension>  

and & or 是用来做逻辑判断的,写程序的都知道,这里不做介绍

下面是我们的FormGen的facet定义,为了让我们创建的项目是一个Java EE项目,这里我们设置FormGen Core依赖jst.web facet. FormGen Ext facet需要建立在 FormGen Core的基础上

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   
  3.   <project-facet-version id="formgen.core" version="1.0">  
  4.     <constraint>  
  5.       <requires facet="jst.web" version="2.2,2.3,2.4"/>  
  6.     constraint>  
  7.   project-facet>  
  8.   
  9.   <project-facet-version id="formgen.ext" version="1.0">  
  10.     <constraint>  
  11.       <requires facet="formgen.core" version="1.0"/>  
  12.     constraint>  
  13.   project-facet>  
  14.      
  15. extension>  


实现Action
经过了上面的设置之后,运行插件,在新建工程向导里面选择FormGen Core会出现错误提示信息,这是因为我们还没有实现对应的Action,这里所说的Action是指facet所要执行的操作,这里有三种类型的action:INSTALL, UNINSTALL, and VERSION_CHANGE,下面的工作就是实现FormGen Core的action

Eclipse WTP Projects Facets实战指南(1)_第2张图片

下面是action对应的扩展点设置格式:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <action id="{string}" facet="{string}" version="{version.expr}" type="INSTALL|UNINSTALL|VERSION_CHANGE">  
  3.     <delegate class="{class:org.eclipse.wst.common.project.facet.core.IDelegate}"/>  
  4.     <property name="{string}" value="{string}"/> (0 or more)   
  5.   action>  
  6. extension>  


下面我们对上述设置进行一下说明:
version属性可以是单个值也可以是表达式,如果action使用所有的facet,那么不设置

id属性可选,如果不制定,系统将以"[facet-id]#[version-expression]#[action-type](#[prop-name]=[prop-value])*"格式创建一个, 为了可读性,最好自己制定id

在action内部还可以在project-facet-version元素内部中使用,如果是这样的话,那么facet和version属性将被忽略,如果同一个action delegate实现被多个facet 版本使用,那么最好在外面单独设置一个action节点,这样系统会进行优化

对于VERSION_CHANGE类型的Action而言, 那么制定了version信息之后,其行为将会收到一些限制, 我们只需要在action下的property中制定from.versions属性即可,其值可以是单个,也可以是表达式

我们的FormGen Core的action要做两件事:(1)copy formgen-core.jar 到项目的WEB-INF/lib 目录下;(2)将FormGen servlet添加到web.xml中.而FormGen Ext会将copy formgen-ext.jar 到WEB-INF/lib 目录下

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   
  3.   <project-facet-version facet="formgen.core" version="1.0">  
  4.     <action type="INSTALL">  
  5.       <delegate class="com.formgen.eclipse.FormGenCoreFacetInstallDelegate"/>  
  6.     action>  
  7.   project-facet-version>  
  8.   
  9.   <project-facet-version facet="formgen.ext" version="1.0">  
  10.     <action type="INSTALL">  
  11.       <delegate class="com.formgen.eclipse.FormGenExtFacetInstallDelegate"/>  
  12.     action>  
  13.   project-facet-version>  
  14.      
  15. extension>  

 

java 代码
  1. package com.formgen.eclipse;   
  2.   
  3. import org.eclipse.core.resources.IFolder;   
  4. import org.eclipse.core.resources.IProject;   
  5. import org.eclipse.core.runtime.CoreException;   
  6. import org.eclipse.core.runtime.IProgressMonitor;   
  7. import org.eclipse.core.runtime.Path;   
  8. import org.eclipse.wst.common.project.facet.core.IDelegate;   
  9. import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;   
  10.   
  11. public final class FormGenCoreFacetInstallDelegate implements IDelegate   
  12. {   
  13.     public void execute( final IProject pj,   
  14.                          final IProjectFacetVersion fv,   
  15.                          final Object config,   
  16.                          final IProgressMonitor monitor )   
  17.   
  18.         throws CoreException   
  19.   
  20.     {   
  21.         monitor.beginTask( ""2 );   
  22.   
  23.         try  
  24.         {   
  25.             final IFolder webInfLib = Utils.getWebInfLibDir( pj );   
  26.   
  27.             Utils.copyFromPlugin( new Path( "libs/formgen-core.jar" ),   
  28.                                   webInfLib.getFile( "formgen-core.jar" ) );   
  29.   
  30.             monitor.worked( 1 );   
  31.   
  32.             Utils.registerFormGenServlet( pj );   
  33.   
  34.             monitor.worked( 1 );   
  35.         }   
  36.         finally  
  37.         {   
  38.             monitor.done();   
  39.         }   
  40.     }   
  41. }   
  42.   

java 代码

  1. package com.formgen.eclipse;   
  2.   
  3. import org.eclipse.core.resources.IFolder;   
  4. import org.eclipse.core.resources.IProject;   
  5. import org.eclipse.core.runtime.CoreException;   
  6. import org.eclipse.core.runtime.IProgressMonitor;   
  7. import org.eclipse.core.runtime.Path;   
  8. import org.eclipse.wst.common.project.facet.core.IDelegate;   
  9. import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;   
  10.   
  11. public final class FormGenExtFacetInstallDelegate implements IDelegate   
  12. {   
  13.     public void execute( final IProject pj,   
  14.                          final IProjectFacetVersion fv,   
  15.                          final Object config,   
  16.                          final IProgressMonitor monitor )   
  17.   
  18.         throws CoreException   
  19.   
  20.     {   
  21.         monitor.beginTask( ""1 );   
  22.   
  23.         try  
  24.         {   
  25.             final IFolder webInfLib = Utils.getWebInfLibDir( pj );   
  26.   
  27.             Utils.copyFromPlugin( new Path( "libs/formgen-ext.jar" ),   
  28.                                   webInfLib.getFile( "formgen-ext.jar" ) );   
  29.   
  30.             monitor.worked( 1 );   
  31.         }   
  32.         finally  
  33.         {   
  34.             monitor.done();   
  35.         }   
  36.   
  37.     }   
  38. }   
  39.   

 


xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <category id="{string}">  
  3.     <label>{string}label>  
  4.     <description>{string}description> (optional)   
  5.   category>  
  6.   <project-facet>  
  7.     <category>{string}category> (optional)   
  8.   project-facet>  
  9. extension>  


设置如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   
  3.   <category id="formgen.category">  
  4.     <label>FormGenlabel>  
  5.     <description>Enables generation of HTML forms based on XML definition files.description>  
  6.   category>  
  7.   
  8.   <project-facet id="formgen.core">  
  9.     <category>formgen.categorycategory>  
  10.   project-facet>  
  11.   
  12.   <project-facet id="formgen.ext">  
  13.     <category>formgen.categorycategory>  
  14.   project-facet>  
  15.   
  16. extension>  


效果如图

 Eclipse WTP Projects Facets实战指南(1)_第3张图片

你可能感兴趣的:(Eclipse,EXT,Web,XML,Servlet)