到目前為止,一個(gè)完整的流程設(shè)計(jì)器已基本完成,為了增加系統(tǒng)的可擴(kuò)展性,比如目前活動的類型有三種,假如以后我們要增加活動的類型,怎么辦?按照目前的做法,我們只能修改代碼,為了使系統(tǒng)的擴(kuò)展性更好,即我們?nèi)绻黾踊顒宇愋停恍枰薷呐渲梦募鵁o須修改現(xiàn)有系統(tǒng)的代碼,為此,我們把活動類型定義一個(gè)擴(kuò)展點(diǎn),用戶以后要增加活動類型,只需擴(kuò)展這個(gè)擴(kuò)展點(diǎn)就可以了。(代碼)
在plugin.xml文件中,增加擴(kuò)展點(diǎn),Id為activity,Name為Activity,Schema為schema/activity.exsd
activity.exsd具體內(nèi)容如下:

<?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>

定義這個(gè)擴(kuò)展點(diǎn)有若干個(gè)活動節(jié)點(diǎn)組成,每個(gè)活動節(jié)點(diǎn)具有name,description,type,figure,icon屬性,其中icon屬性代表活動在編輯器托盤中顯示的圖標(biāo),有大小兩種圖標(biāo),而figure是活動要在編輯器區(qū)域顯示圖形對應(yīng)的類,這個(gè)類必須實(shí)現(xiàn)IFigure接口,type代表活動類型。
定義完這個(gè)擴(kuò)展點(diǎn)后,我們再在plugin.xml中自己擴(kuò)展這個(gè)擴(kuò)展點(diǎn),代碼如下:
<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>

如果以后要增加活動類型的話,直接在這里擴(kuò)展就可以了,要實(shí)現(xiàn)不修改原來的代碼,就增加活動類型的話,還必須修改一些地方。
首先新建一個(gè)模型,來對應(yīng)擴(kuò)展點(diǎn)中對應(yīng)的各個(gè)活動,代碼如下:
package com.example.workflow.model;


public class CreationEntry
{
private String name;//活動名稱
private String description;//活動描述
private String icon;//編輯器托盤上活動的圖標(biāo)
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;
}
}

同時(shí)我們要新建一個(gè)模型工廠類,功能類似于原來的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();
}

}

同時(shí)修改一下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,同時(shí)增加一個(gè)方法getCreationEntry(),這個(gè)方法的目的就是取得所用擴(kuò)展我們定義活動擴(kuò)展點(diǎn)地方。

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;
}

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