Posted on 2008-01-16 08:42
笑看人生 閱讀(1558)
評論(3) 編輯 收藏 所屬分類:
Java插件開發
到目前為止,一個完整的流程設計器已基本完成,為了增加系統的可擴展性,比如目前活動的類型有三種,假如以后我們要增加活動的類型,怎么辦?按照目前的做法,我們只能修改代碼,為了使系統的擴展性更好,即我們如果要增加活動類型,只需要修改配置文件,而無須修改現有系統的代碼,為此,我們把活動類型定義一個擴展點,用戶以后要增加活動類型,只需擴展這個擴展點就可以了。(代碼)
在plugin.xml文件中,增加擴展點,Id為activity,Name為Activity,Schema為schema/activity.exsd
activity.exsd具體內容如下:

<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="com.example.workflow">
<annotation>
<appInfo>
<meta.schema plugin="com.example.workflow" id="activity" name="Activity"/>
</appInfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>

<element name="extension">
<complexType>
<sequence>
<element ref="activity" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appInfo>
<meta.attribute translatable="true"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="activity">
<complexType>
<attribute name="name" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="description" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="icon" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="type" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="figure" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.draw2d.IFigure"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>

<annotation>
<appInfo>
<meta.section type="since"/>
</appInfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>

<annotation>
<appInfo>
<meta.section type="examples"/>
</appInfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>

<annotation>
<appInfo>
<meta.section type="apiInfo"/>
</appInfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>

<annotation>
<appInfo>
<meta.section type="implementation"/>
</appInfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>

<annotation>
<appInfo>
<meta.section type="copyright"/>
</appInfo>
<documentation>
</documentation>
</annotation>

</schema>

定義這個擴展點有若干個活動節點組成,每個活動節點具有name,description,type,figure,icon屬性,其中icon屬性代表活動在編輯器托盤中顯示的圖標,有大小兩種圖標,而figure是活動要在編輯器區域顯示圖形對應的類,這個類必須實現IFigure接口,type代表活動類型。
定義完這個擴展點后,我們再在plugin.xml中自己擴展這個擴展點,代碼如下:
<extension
point="com.example.workflow.activity">
<activity
description="Create a StartActivity"
figure="org.eclipse.draw2d.Ellipse"
icon="start16.gif,start24.gif"
name="Start"
type="1">
</activity>
<activity
description="Create a Activity"
figure="org.eclipse.draw2d.RectangleFigure"
icon="activity16.gif,activity24.gif"
name="Activity"
type="2"></activity>
<activity
description="Create a EndActivity"
figure="org.eclipse.draw2d.Triangle"
icon="end16.gif,end24.gif"
name="End"
type="3">
</activity>
</extension>

如果以后要增加活動類型的話,直接在這里擴展就可以了,要實現不修改原來的代碼,就增加活動類型的話,還必須修改一些地方。
首先新建一個模型,來對應擴展點中對應的各個活動,代碼如下:
package com.example.workflow.model;


public class CreationEntry
{
private String name;//活動名稱
private String description;//活動描述
private String icon;//編輯器托盤上活動的圖標
private String type;//活動類型
private String figure;//活動在編輯器中顯示的圖形

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public String getDescription()
{
return description;
}

public void setDescription(String description)
{
this.description = description;
}

public String getIcon()
{
return icon;
}

public void setIcon(String icon)
{
this.icon = icon;
}

public String getType()
{
return type;
}

public void setType(String type)
{
this.type = type;
}

public String getFigure()
{
return figure;
}

public void setFigure(String figure)
{
this.figure = figure;
}
}

同時我們要新建一個模型工廠類,功能類似于原來的SimpleFactory,代碼如下:
package com.example.workflow.ui;

import org.eclipse.gef.requests.CreationFactory;

import com.example.workflow.model.CreationEntry;


public class CreationEntryFactory implements CreationFactory
{
private CreationEntry entry;

public CreationEntryFactory(CreationEntry entry)
{
this.entry = entry;
}


public Object getNewObject()
{
AbstractActivity activity = new AbstractActivity();
activity.setName(entry.getName());
activity.setFigure(entry.getFigure());
return activity;
}


public Object getObjectType()
{
return entry.getType();
}

}

同時修改一下WorkflowProcessXYLayoutEditPolicy類中的方法getCreateCommand,如下:

protected Command getCreateCommand(CreateRequest request)
{

return new AbstractActivityCreateCommand((AbstractActivity) request
.getNewObject(), (WorkflowProcess) getHost().getModel(),
(Rectangle) getConstraintFor(request));

}

另外還要修改一下類AbstractActivityEditPart中的方法createFigureForModel()

private IFigure createFigureForModel()
{

try
{
return (IFigure)Class.forName(getCastedModel().getFigure()).newInstance();

} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();

} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();

} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

還有給模型AbstractActivity增加屬性figure,以及該屬性的get/set方法。
修改原來WorkflowProcessEditorPaletteFactory中方法createActivitiesDrawer,同時增加一個方法getCreationEntry(),這個方法的目的就是取得所用擴展我們定義活動擴展點地方。

private static List<CreationEntry> getCreationEntry()
{
IExtensionPoint point = Platform.getExtensionRegistry()
.getExtensionPoint(Activator.PLUGIN_ID + ".activity");
List<CreationEntry> entry = new ArrayList<CreationEntry>();
CreationEntry model = null;

if(point != null)
{

for (IExtension extension : point.getExtensions())
{
for (IConfigurationElement config : extension

.getConfigurationElements())
{
model = new CreationEntry();
model.setName(config.getAttribute("name"));
model.setDescription(config.getAttribute("description"));
model.setIcon(config.getAttribute("icon"));
model.setType(config.getAttribute("type"));
model.setFigure(config.getAttribute("figure"));
entry.add(model);
}
}
return entry;
}
return null;
}


/** *//** */

/** *//** Create the "Activities" drawer. */

private static PaletteContainer createActivitiesDrawer()
{
PaletteDrawer componentsDrawer = new PaletteDrawer("Process");


for(CreationEntry entry : getCreationEntry())
{
componentsDrawer.add(new CombinedTemplateCreationEntry(
entry.getName(), entry.getDescription(), entry.getType(),
new CreationEntryFactory(entry),
ImageDescriptor
.createFromFile(Activator.class, "icons/" +
entry.getIcon().substring(0, entry.getIcon().indexOf(","))),
ImageDescriptor.createFromFile(Activator.class,
"icons/" + entry.getIcon().substring(entry.getIcon().indexOf(",")+1))));
}
return componentsDrawer;
}

至此,擴展點定義完成,以后要增加活動類型,我們只需擴展這個擴展點,指定一下活動的類型,名稱,活動在托盤和編輯器中顯示的圖標就可以了,再也不需要去修改原來的代碼了。