Web Tools Platform (WTP) 是 Eclipse 上構建 J2EE Web 應用的核心插件集,提供豐富的項目創建、Web Service、Servlet 等標準向導。但實際業務往往需要定制化功能——如創建 Portlet 應用需生成特定部署描述文件、自定義語法編輯器等。當 WTP 通用功能無法滿足業務需求時,必須進行擴展開發。
數據分散在各頁面,無統一數據模型,適合簡單頁面跳轉。
內嵌 Data Model(屬性集合,支持監聽器、驗證、自定義訪問規則),通過 Synchronize Helper 實現頁面控件與模型數據雙向同步。採用 DataModel-View-Operation 模式:Model 封裝狀態,View 負責交互,Operation 執行業務動作。
在 Data Model Wizard 基礎上引入 DataModelProvider,形成 DataModel-DataModelProvider-View-Operation 四層架構:
dataModel.getProperty(provider.PROPERTY_NAME)。synchHelper.synchText(widget, provider.PROPERTY, null) 綁定控件與模型屬性。優勢:Model 純粹存儲,存取職責分離,便於擴展存取邏輯;Provider 集中管理屬性語義。
基於 Dynamic Web Application Project Wizard,新增「Main Class Group Panel」輸入包名與主類名,並生成 Portlet 部署描述文件。
<extension point="org.eclipse.ui.newWizards">
<wizard class="com.sample.tools.app.wizard.SampleProjectWizard"
icon="icons/newapp_wiz.gif"
id="com.sample.tools.app.wizard.SampleProjectWizard"
name="Sample Project" project="true">
<description>Create a WTP Sample Project</description>
</wizard>
</extension>
Wizard 類:繼承 DataModelWizard,實現 INewWizard:
public class SampleProjectWizard extends DataModelWizard implements INewWizard {
protected void doAddPages() {
addPage(new SampleProjectFirstPage(getDataModel(), "first.page"));
}
protected IDataModelProvider getDefaultProvider() {
return new SampleProjectCreationDataModelProvider();
}
public void init(IWorkbench wb, IStructuredSelection sel) { }
}
WizardPage 類:繼承 WTP 頁面基類,重寫 createPresetPanel 隱藏不需字段,新增自定義面板:
protected void createPresetPanel(Composite top) {
Group group = new Group(top, SWT.NONE);
group.setText("Sample Main Class");
// Package 輸入框
synchHelper.synchText(tp, SampleProjectCreationDataModelProvider.PACKAGE, null);
// Main Class Name 輸入框
synchHelper.synchText(tc, SampleProjectCreationDataModelProvider.MAIN_CLASS_NAME, null);
}
DataModelProvider 類:繼承 WebFacetProjectCreationDataModelProvider,定義新屬性與默認值:
public class SampleProjectCreationDataModelProvider extends WebFacetProjectCreationDataModelProvider {
public static final String PACKAGE = "MAIN_CLASS_PACKAGE";
public static final String MAIN_CLASS_NAME = "MAIN_CLASS_NAME";
public Object getDefaultProperty(String propertyName) {
if (PACKAGE.equals(propertyName)) return "com.sample.app";
if (MAIN_CLASS_NAME.equals(propertyName)) return "NewsListSample";
return super.getDefaultProperty(propertyName);
}
public Set getPropertyNames() {
Set names = super.getPropertyNames();
names.add(PACKAGE); names.add(MAIN_CLASS_NAME);
return names;
}
public IDataModelOperation getDefaultOperation() {
return new SampleCreationOperation(getDataModel());
}
}
Operation 類:繼承父操作,執行額外創建邏輯:
public IStatus execute(IProgressMonitor monitor, IAdaptable info) {
IStatus status = super.execute(monitor, info);
if (status.isOK()) {
String pkg = getDataModel().getStringProperty(PACKAGE);
String cls = getDataModel().getStringProperty(MAIN_CLASS_NAME);
// 創建主類、複製資源文件、生成 Portlet 描述符等
}
return status;
}
本文採用面向對象繼承擴展方式:子類化現有 Wizard 組件,通過重寫/覆蓋修改行為。另一種方案是擴展點擴展,影響所有現有實例,僅能增強不能減弱功能,讀者可自行查閱相關文檔。