Posted on 2008-01-16 08:42
笑看人生 阅读(1555)
评论(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;
}

至此,扩展点定义完成,以后要增加活动类型,我们只需扩展这个扩展点,指定一下活动的类型,名称,活动在托盘和编辑器中显示的图标就可以了,再也不需要去修改原来的代码了。