我的RCP之旅(四)-- Extension
Eclipse基于Extension Point的扩展机制果然不同凡响.不用改变源码,通过扩展点添加插件即可实现功能的增强.
先看看如何通过扩展实现功能增强:
我们就看看用户是如何编写一个自己的view,然后扩展org.eclipse.ui.Views来将自己的view在RCP框架中运行起来.
- 首先要自己实现一个view:
public class View extends ViewPart {
public static final String ID = "com.rcp.test.view.View"; //$NON-NLS-1$
/**
- Create contents of the view part
- @param parent
*/
@Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
//
createActions();
initializeToolBar();
initializeMenu();
}/**
- Create the actions
*/
private void createActions() {
// Create the actions
}/**
- Initialize the toolbar
*/
private void initializeToolBar() {
IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
}/**
- Initialize the menu
*/
private void initializeMenu() {
IMenuManager menuManager = getViewSite().getActionBars().getMenuManager();
}@Override
public void setFocus() {
// Set the focus
}}
可以看到只要继承了ViewPart 的类就可以进行扩展(因为在Views这个扩展点定义了扩展这个扩展点的时候必须继承ViewPart )
- 在pulgin.xml中配置扩展信息:
<extension
point="org.eclipse.ui.views">
<view
class="com.rcp.test.view.View"
id="com.rcp.test.view.View"
name="New ViewPart">
</view>
</extension>很简单在org.eclipse.ui.views下添加这个类就可以了..
大家看到了实现一个扩展,那接下来看看如果定义一个扩展点:
通过Eclipse的图形话工具是很容易就可以定义一个扩展点的.不过我还是说说直接配xml吧(嘿嘿!)
- 首先在plugin.xml配置一个扩展点:
<extension-point id="ChatListener" name="Chat Listener" schema="schema/ChatListener.exsd"/>
这里只要定义扩展点的id,名字和schema文件,schema就是真正约束扩展点的定义.
- 定义schema
如上一般schema都是放在schema文件夹下的.来看看schema都包含些什么:
<?xml version='1.0' encoding='UTF-8'?>
<!– Schema file written by PDE –>
<schema targetNamespace="com.kevin.im">
<annotation>
<appInfo>
<meta.schema plugin="com.kevin.im" id="ChatListener" name="Chat Listener"/>
</appInfo>
<documentation>
[文档信息]</documentation>
</annotation><element name="extension">
<complexType>
<sequence minOccurs="2" maxOccurs="2">
<element ref="rosterListener"/>
<element ref="receiver"/>
</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="rosterListener">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation></documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.ecf.presence.roster.IRosterListener"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element><element name="receiver">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation></documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":com.kevin.im.client.IMessageReceiver"/>
</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>
如上 <meta.schema plugin="com.kevin.im" id="ChatListener" name="Chat Listener"/>
这句定义了扩展点的plugin id和扩展点的id,在代码中寻找这个扩展点的时候要用 #plugin#.#id#的形式来取..注意:id不能包含".",不然程序会解析不出来<element name="extension">
<complexType>
<sequence minOccurs="2" maxOccurs="2">
<element ref="rosterListener"/>
<element ref="receiver"/>
</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="rosterListener">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation></documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.ecf.presence.roster.IRosterListener"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element><element name="receiver">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation></documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":com.kevin.im.client.IMessageReceiver"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>这一段实际上就是XML schema 的定义….这个我这里就不介绍了..直接用可视化编辑很很容易的定义
- 最后看看然后在代码中直接访问这些扩展点:
IExtensionRegistry reg = Platform.getExtensionRegistry(); //从系统中获得扩展点信息
IExtensionPoint extPointForChat = reg.getExtensionPoint("com.test.View"); //根据扩展点id获得整个扩展点for (IConfigurationElement config : extPointForChat.getConfigurationElements()) {//遍历扩展点的配置
View view=(View) config.createExecutableExtension("class"); //通过class这个attribute来创建这个类
}//接下去的,就看你用取到的属性干吗了..hoho
如果自定义扩展点的信息较多较复杂,则可以模仿*.ui.views读取扩展点信息的方式,分成3种不同的类:
● ViewDescriptor——这是一个和自定义扩展点某一项信息相对应的数据类,它实际上为外界封闭了对IConfigurationElement类的访问。
● ViewRegistry——如果说ViewDescriptor是扩展点某一项的信息封装,那么ViewRegistry就是对自定义扩展点所有信息的封装。如果把ViewDescriptor比作某个省份,那么ViewRegistry就是整个国家。
● ViewRegistryReader——这个类负责向ViewRegistry输送数据,如果说ViewRegistry是盲人,那么ViewRegistryReader就是读报人。