這個文章基本是"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引用,該擴展點包羅萬象,這里我們遵循循序漸進的原則,從最最簡單的內容開始:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet id="{string}"> (0 or more)
- <label>{string}label>
- <description>{string}description> (optional)
- project-facet>
- <project-facet-version facet="{string}" version="{string}"/> (0 or more)
- extension>
這里加入了兩個節點:project-facet是我們要加入的facet, project-facet-version用來制定我們的facet版本, 每一個facet至少需要給它指定一個版本,否則不可用, 后面大家就會知道,實際上我們大部分工作都集中在project-facet-version中配置, 配置后的代碼如下:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet id="formgen.core">
- <label>FormGen Corelabel>
- <description>
- Enables generation of HTML forms based on XML definition files.
- description>
- project-facet>
- <project-facet-version facet="formgen.core" version="1.0"/>
- <project-facet id="formgen.ext">
- <label>FormGen Extensionslabel>
- <description>
- Enables additional FormGen widgets.
- description>
- project-facet>
- <project-facet-version facet="formgen.ext" version="1.0"/>
- extension>
設置好后運行我們的插件項目,創建一個Dynamic Web Project, 在向導中第一個頁面的Target Runtime設置為none,繼續進入到下一個頁面,這時在下面的列表中就會出現我們添加的兩個facet
接下來的工作就是給facet指定約束
由于我們的FormGen是基于Servlet的,因此它應該適用于所有的Java EE項目.下面我們通過增加約束讓FormGen facet也能在EJB項目向導中使用.
下面是我們將要用到的擴展節點的相關說明:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet-version>
- <constraint> (optional)
- [expr]
- constraint>
- project-facet-version>
- extension>
- [expr] =
- <requires facet="{string}" version="{version.expr}" soft="{boolean}"/> or
- <conflicts facet="{string}" version="{version.expr}"/> or
- <conflicts group="{string}"/> or
- <and>
- [expr] (1 or more)
- and> or
- <or>
- [expr] (1 or more)
- 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屬于某個組,需要這樣定義擴展點:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet-version>
- <group-member id="{string}"/> (0 or more)
- project-facet-version>
- extension>
and & or 是用來做邏輯判斷的,寫程序的都知道,這里不做介紹
下面是我們的FormGen的facet定義,為了讓我們創建的項目是一個Java EE項目,這里我們設置FormGen Core依賴jst.web facet. FormGen Ext facet需要建立在 FormGen Core的基礎上
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet-version id="formgen.core" version="1.0">
- <constraint>
- <requires facet="jst.web" version="2.2,2.3,2.4"/>
- constraint>
- project-facet>
- <project-facet-version id="formgen.ext" version="1.0">
- <constraint>
- <requires facet="formgen.core" version="1.0"/>
- constraint>
- project-facet>
- extension>
實現Action
經過了上面的設置之后,運行插件,在新建工程向導里面選擇FormGen Core會出現錯誤提示信息,這是因為我們還沒有實現對應的Action,這里所說的Action是指facet所要執行的操作,這里有三種類型的action:INSTALL, UNINSTALL, and VERSION_CHANGE,下面的工作就是實現FormGen Core的action
下面是action對應的擴展點設置格式:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <action id="{string}" facet="{string}" version="{version.expr}" type="INSTALL|UNINSTALL|VERSION_CHANGE">
- <delegate class="{class:org.eclipse.wst.common.project.facet.core.IDelegate}"/>
- <property name="{string}" value="{string}"/> (0 or more)
- action>
- 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 目錄下
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <project-facet-version facet="formgen.core" version="1.0">
- <action type="INSTALL">
- <delegate class="com.formgen.eclipse.FormGenCoreFacetInstallDelegate"/>
- action>
- project-facet-version>
- <project-facet-version facet="formgen.ext" version="1.0">
- <action type="INSTALL">
- <delegate class="com.formgen.eclipse.FormGenExtFacetInstallDelegate"/>
- action>
- project-facet-version>
- extension>
- package com.formgen.eclipse;
- import org.eclipse.core.resources.IFolder;
- import org.eclipse.core.resources.IProject;
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.core.runtime.IProgressMonitor;
- import org.eclipse.core.runtime.Path;
- import org.eclipse.wst.common.project.facet.core.IDelegate;
- import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
- public final class FormGenCoreFacetInstallDelegate implements IDelegate
- {
- public void execute( final IProject pj,
- final IProjectFacetVersion fv,
- final Object config,
- final IProgressMonitor monitor )
- throws CoreException
- {
- monitor.beginTask( "", 2 );
- try
- {
- final IFolder webInfLib = Utils.getWebInfLibDir( pj );
- Utils.copyFromPlugin( new Path( "libs/formgen-core.jar" ),
- webInfLib.getFile( "formgen-core.jar" ) );
- monitor.worked( 1 );
- Utils.registerFormGenServlet( pj );
- monitor.worked( 1 );
- }
- finally
- {
- monitor.done();
- }
- }
- }
java 代碼
- package com.formgen.eclipse;
- import org.eclipse.core.resources.IFolder;
- import org.eclipse.core.resources.IProject;
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.core.runtime.IProgressMonitor;
- import org.eclipse.core.runtime.Path;
- import org.eclipse.wst.common.project.facet.core.IDelegate;
- import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
- public final class FormGenExtFacetInstallDelegate implements IDelegate
- {
- public void execute( final IProject pj,
- final IProjectFacetVersion fv,
- final Object config,
- final IProgressMonitor monitor )
- throws CoreException
- {
- monitor.beginTask( "", 1 );
- try
- {
- final IFolder webInfLib = Utils.getWebInfLibDir( pj );
- Utils.copyFromPlugin( new Path( "libs/formgen-ext.jar" ),
- webInfLib.getFile( "formgen-ext.jar" ) );
- monitor.worked( 1 );
- }
- finally
- {
- monitor.done();
- }
- }
- }
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <category id="{string}">
- <label>{string}label>
- <description>{string}description> (optional)
- category>
- <project-facet>
- <category>{string}category> (optional)
- project-facet>
- extension>
設置如下:
- <extension point="org.eclipse.wst.common.project.facet.core.facets">
- <category id="formgen.category">
- <label>FormGenlabel>
- <description>Enables generation of HTML forms based on XML definition files.description>
- category>
- <project-facet id="formgen.core">
- <category>formgen.categorycategory>
- project-facet>
- <project-facet id="formgen.ext">
- <category>formgen.categorycategory>
- project-facet>
- extension>
效果如圖
安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢】