Eclipse WTP Projects Facets实战指南(2)

修饰工作
给facet在选择列表中添加图标
格式如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.ui.images">  
  2.   <image facet="{string}" path="{string}"/> (0 or more)   
  3.   <image category="{string}" path="{string}"/> (0 or more)   
  4. extension>  


设置如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.ui.images">  
  2.   <image facet="formgen.core" path="icons/formgen-core.gif"/>  
  3.   <image facet="formgen.ext" path="icons/formgen-ext.gif"/>  
  4.   <image category="formgen.category" path="icons/formgen-cat.gif"/>  
  5. extension>  

效果如图

 Eclipse WTP Projects Facets实战指南(2)

添加向导页
有时候我们可能需要根据用户的输入来执行facet, 通过添加wizard page来接收用户的输入, 用户在facet选择列表页做出选择之后,将出现我们添加的wizard Page
下面通过给我们的servlet指定url pattern的例子来进行说明
plugin.xml设置格式如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <action>  
  3.     <config-factory class="class:org.eclipse.wst.common.project.facet.core.IActionConfigFactory"/>  
  4.   action>  
  5. extension>  
  6.   
  7. <extension point="org.eclipse.wst.common.project.facet.ui.wizardPages">  
  8.   <wizard-pages action="{string}"> (0 or more)   
  9.     <page class="{class:org.eclipse.wst.common.project.facet.ui.IFacetWizardPage}"/> (1 or more)   
  10.   wizard-pages>  
  11. extension>    

 
这里需要说明的是为了让我们定制的wizard page和action delegate之间进行通信, 需要使用一个javabean或者是map来封装wizard page中输入的数据, 而且必须在action配置中提供一个action factory,该对象将由factory创建, wizard page填充数据, action delegate负责从该对象读取数据

除外,wizard page将通过指定的action id来引用action, 这也是我们前面推荐指定action id而不是系统生成的原因

配置如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <project-facet-version facet="formgen.core" version="1.0">  
  3.     <action type="INSTALL" id="formgen.core.install">  
  4.       <config-factory class="com.formgen.eclipse.FormGenCoreFacetInstallConfig$Factory"/>  
  5.     action>  
  6.   project-facet-version>  
  7. extension>  
  8.   
  9. <extension point="org.eclipse.wst.common.project.facet.ui.wizardPages">  
  10.   <wizard-pages action="formgen.core.install">  
  11.     <page class="com.formgen.eclipse.FormGenCoreFacetInstallPage"/>  
  12.   wizard-pages>  
  13. extension>  

 

代码如下:

java 代码
  1. package com.formgen.eclipse;   
  2.   
  3. import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;   
  4.   
  5. public final class FormGenCoreFacetInstallConfig   
  6. {   
  7.     private String urlPattern = "*.form";   
  8.   
  9.     public String getUrlPattern()   
  10.     {   
  11.         return this.urlPattern;   
  12.     }   
  13.   
  14.     public void setUrlPattern( final String urlPattern )   
  15.     {   
  16.         this.urlPattern = urlPattern;   
  17.     }   
  18.   
  19.     public static final class Factory implements IActionConfigFactory   
  20.     {   
  21.         public Object create()   
  22.         {   
  23.             return new FormGenCoreFacetInstallConfig();   
  24.         }   
  25.     }   
  26. }   
  27.   


 

java 代码
  1. package com.formgen.eclipse;   
  2.   
  3. import org.eclipse.swt.SWT;   
  4. import org.eclipse.swt.layout.GridData;   
  5. import org.eclipse.swt.layout.GridLayout;   
  6. import org.eclipse.swt.widgets.Composite;   
  7. import org.eclipse.swt.widgets.Label;   
  8. import org.eclipse.swt.widgets.Text;   
  9. import org.eclipse.wst.common.project.facet.ui.AbstractFacetWizardPage;   
  10.   
  11. public final class FormGenCoreFacetInstallPage extends AbstractFacetWizardPage   
  12. {   
  13.     private FormGenCoreFacetInstallConfig config;   
  14.     private Text urlPatternTextField;   
  15.   
  16.     public FormGenCoreFacetInstallPage()   
  17.     {   
  18.         super"formgen.core.facet.install.page" );   
  19.   
  20.         setTitle( "FormGen Core" );   
  21.         setDescription( "Configure the FormGen servlet." );   
  22.     }   
  23.   
  24.     public void createControl( final Composite parent )   
  25.     {   
  26.         final Composite composite = new Composite( parent, SWT.NONE );   
  27.         composite.setLayout( new GridLayout( 1false ) );   
  28.   
  29.         final Label label = new Label( composite, SWT.NONE );   
  30.         label.setLayoutData( gdhfill() );   
  31.         label.setText( "URL Pattern:" );   
  32.   
  33.         this.urlPatternTextField = new Text( composite, SWT.BORDER );   
  34.         this.urlPatternTextField.setLayoutData( gdhfill() );   
  35.         this.urlPatternTextField.setText( this.config.getUrlPattern() );   
  36.   
  37.         setControl( composite );   
  38.     }   
  39.   
  40.     public void setConfig( final Object config )   
  41.     {   
  42.         this.config = (FormGenCoreFacetInstallConfig) config;   
  43.     }   
  44.   
  45.     public void transferStateToConfig()   
  46.     {   
  47.         this.config.setUrlPattern( this.urlPatternTextField.getText() );   
  48.     }   
  49.   
  50.     private static GridData gdhfill()   
  51.     {   
  52.         return new GridData( GridData.FILL_HORIZONTAL );   
  53.     }   
  54. }   
  55.   


 

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 FormGenCoreFacetInstallConfig cfg   
  26.                 = (FormGenCoreFacetInstallConfig) config;   
  27.   
  28.             final IFolder webInfLib = Utils.getWebInfLibDir( pj );   
  29.   
  30.             Utils.copyFromPlugin( new Path( "libs/formgen-core.jar" ),   
  31.                                   webInfLib.getFile( "formgen-core.jar" ) );   
  32.   
  33.             monitor.worked( 1 );   
  34.   
  35.             Utils.registerFormGenServlet( pj, cfg.getUrlPattern() );   
  36.   
  37.             monitor.worked( 1 );   
  38.         }   
  39.         finally  
  40.         {   
  41.             monitor.done();   
  42.         }   
  43.     }   
  44. }   
  45.   

效果如图

Eclipse WTP Projects Facets实战指南(2)

定义Preset
为了将创建某个工程所需要的facet集中在一个用一个名字代替,这就需要使用preset(或称configuration),其扩展点格式如下:

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

为了让preset能应用于指定的facet project, preset必须包含所有的fixed facet, 所谓的fixed facet指的是那些要创建的工程所必须的而不能删除的facet.
设置如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <preset id="formgen.preset">  
  3.     <label>FormGen Web Project</label>  
  4.     <description>Creates a web project with FormGen functionality.</description>  
  5.     <facet id="jst.java" version="5.0"/>  
  6.     <facet id="jst.web" version="2.2"/>  
  7.     <facet id="formgen.core" version="1.0"/>  
  8.     <facet id="formgen.ext" version="1.0"/>  
  9.   </preset>  
  10. </extension>  

效果如图

Eclipse WTP Projects Facets实战指南(2)

指定runtime映射
在创建project的时候,有时候需要指定项目依赖的runtime,我们也可以通过扩展点来检查当前的facet所需要的runtime是否指定.
配置格式如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.runtimes">  
  2.   <supported> (0 or more)   
  3.     <runtime-component any="{boolean}"/> (optional)   
  4.     <runtime-component id="{string}"version="{version.expr}"/> (0 or more)   
  5.     <facet id="{string}"version="{version.expr}"/> (1 or more)   
  6.   </supported>  
  7. </extension>  


下面是不依赖其他组件的配置:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.runtimes">  
  2.   <supported>  
  3.     <runtime-component any="true"/>  
  4.     <facet id="formgen.core"/>  
  5.     <facet id="formgen.ext"/>  
  6.   </supported>  
  7. </extension>  


下面是依赖tomcat的配置

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.runtimes">  
  2.   <supported>  
  3.     <runtime-component id="org.eclipse.jst.server.tomcat" version="[5.0"/>  
  4.     <facet id="formgen.core"/>  
  5.     <facet id="formgen.ext"/>  
  6.   </supported>  
  7. </extension>  

总结

通过上面的步骤, 我们创建了一个完整的project facet, 这里面包括指定约束, 实现action, 对facet分组, 创建wizard page. 更多的信息可看下面的参考附录
附录A 定制Version Comparetor
就是对版本进行比较的策略进行定制, 如果要使用自己的版本比较方式, 那么可以通过扩展点来处理,格式如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <project-facet>  
  3.     <version-comparator class="{class:java.util.Comparator<String>}"/>  
  4.   </project-facet>  
  5. </extension>  


可以直接从接口从头实现,也可以继承org.eclipse.wst.common.project.facet.core.DefaultVersionComparator来进行定制
代码如下:

java 代码
  1. /**  
  2.  * Returns the string containing the separator characters that should be  
  3.  * used when breaking the version string into segments. The default  
  4.  * implementation returns ".". Subclasses can override this method.  
  5.  *   
  6.  * @return the separator characters  
  7.  */  
  8.        
  9. protected String getSeparators();   
  10.        
  11. /**  
  12.  * Parses a segment of the version string. The default implementation parses  
  13.  * the first segment as an integer (leading zeroes are ignored) and the  
  14.  * rest of the segments as decimals (leading zeroes are kept). Subclasses   
  15.  * can override this method to provide custom parsing for any number of   
  16.  * segments.  
  17.  *   
  18.  * @param version the full version string  
  19.  * @param segment the version segment  
  20.  * @param position the position of the segment in the version string  
  21.  * @return the parsed representation of the segment as a {@see Comparable}  
  22.  * @throws VersionFormatException if encountered an error while parsing  
  23.  */  
  24.        
  25. protected Comparable parse( final String version,   
  26.                             final String segment,   
  27.                             final int position )   
  28.        
  29.     throws VersionFormatException;   

附录B Version Expression
为了一次指定多个版本,就需要使用版本表达式(version expression), 在很多地方我都用到了版本表达式, 版本表达式如果有多个,则使用逗号分隔,这里的逗号表示或的意思, 范围通过括号加破折号来制定,如[x-z), 中括号表示包含, 小括号表示不包含
下面是一些例子:
1.2
1.2,1.5,3.2
[1.2-3.2]
[3.7-5.0)
[3.7
5.0)
1.2,[3.0-4.5),[7.3
附录C Event Handler
project fact可以为某些事件注册listener, 这些时间包括:
PRE_INSTALL
POST_INSTALL
PRE_UNINSTALL
POST_UNINSTALL
PRE_VERSION_CHANGE
POST_VERSION_CHANGE
RUNTIME_CHANGED
事件处理器的声明和action的声明非常类似,但是他们也有一些区别,主要体现在:
与action不同, 事件处理器无法由用户直接触发,因此无法将事件处理器与wizard page关联,也无法为其提供封装数据的配置对象
可以给一个事件设置多个事件处理器,但是他们的调用顺序是不确定的
事件处理器的配置格式如下:

xml 代码
  1. <extension point="org.eclipse.wst.common.project.facet.core.facets">  
  2.   <event-handler facet="{string}" version="{version.expr}" type="{event.type}">  
  3.     <delegate class="{class:org.eclipse.wst.common.project.facet.core.IDelegate}"/>  
  4.   </action>  
  5. </extension>  


与action的配置很类似,也实现了IDelegate接口, 而且event-handler也可以嵌入到project-facet-version元素内部,此时的facet和version属性将被忽略.

PRE_* and POST_* 事件处理器用来取得配置对象,然后传递给IDelegate的execute方法使用, RUNTIME_CHANGED 事件处理器是用来取得IRuntimeChangedEvent实例

java 代码
  1. package org.eclipse.wst.common.project.facet.core;   
  2.   
  3. import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;   
  4.   
  5. /**  
  6.  * Describes the runtime changed event to the RUNTIME_CHANGED event handlers.  
  7.  */  
  8.   
  9. public interface IRuntimeChangedEvent   
  10. {   
  11.     /**  
  12.      * Returns the runtime previously associated with the project.  
  13.      *   
  14.      * @return the runtime previously associated with the project, or null  
  15.      */  
  16.        
  17.     IRuntime getOldRuntime();   
  18.        
  19.     /**  
  20.      * Returns the runtime that's now associated with the project.  
  21.      *   
  22.      * @return the runtime that's now associated with the project, or null  
  23.      */  
  24.        
  25.     IRuntime getNewRuntime();   
  26. }   
  27.   

附录D Property Tester
Property Tester是用来被org.eclipse.core.expressions 包中的扩展点测试使用的,它常用来决定某些菜单或者属性页选项是否可用.属性名为org.eclipse.wst.common.project.facet.core.projectFacet,值为facet id或者facet id 加冒号再加版本表达式的组合
下面的这个例子用来控制project的属性页是否可用

xml 代码
  1. <extension point="org.eclipse.ui.propertyPages">  
  2.   <page    
  3.     adaptable="true"  
  4.     objectClass="org.eclipse.core.resources.IProject"  
  5.     name="FormGen Properties"  
  6.     class="com.formgen.eclipse.FormGenPropertiesPage"  
  7.     id="org.eclipse.jst.j2ee.internal.J2EEDependenciesPage">  
  8.     <enabledWhen>  
  9.       <test    
  10.         forcePluginActivation="true"  
  11.         property="org.eclipse.wst.common.project.facet.core.projectFacet"  
  12.         value="formgen.core"/>  
  13.     </enabledWhen>             
  14.   </page>  
  15. </extension>  


附录E Wizard Content
有时候我们可能根据其他facet所对应的wizard page的用户输入来调整action的行为, 而IWizardContet接口就是为该目的而设计的, wizard page的setWizardContext方法被调用的时候会取得该接口的handler, 如果你的代码对IWziardContenxt造成依赖,可能需要注意以下事项:
1.fact需要的内容可能在执行前已经被install了, 此时在wizard context中将无法找到要install的配置,所以在需要做一些判断
2.如果某些情况下wizard page不被调用的话,要给配置对象设置默认值
下面是IWizardContext接口的代码:

java 代码
  1. package org.eclipse.wst.common.project.facet.ui;   
  2.   
  3. import java.util.Set;   
  4.   
  5. import org.eclipse.core.runtime.CoreException;   
  6. import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;   
  7. import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;   
  8. import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action.Type;   
  9.   
  10. /**  
  11.  * The interface exposed to the facet action wizard pages that allows them  
  12.  * to gather information about the wizard state.  
  13.  */  
  14.   
  15. public interface IWizardContext    
  16. {   
  17.     /**  
  18.      * Returns the name of the project that the wizard is operating on. If the  
  19.      * wizard is in the project creation mode, the project will not yet exist  
  20.      * in the workspace.  
  21.      *   
  22.      * @return the name of the project that the wizard is operating on  
  23.      */  
  24.        
  25.     String getProjectName();   
  26.        
  27.     /**  
  28.      * Returns the set of facets currently selected in the wizard. If the wizard  
  29.      * is in the add/remove facets mode (vs. project creation), this method will   
  30.      * return the set of facets currently installed in a project after being   
  31.      * modified by the current set of actions.   
  32.      *   
  33.      * @return the set of facets currently selected in the wizard (element type:  
  34.      *   {@see IProjectFacetVersion})  
  35.      */  
  36.        

你可能感兴趣的:(eclipse,tomcat,UI,xml,ext)