在Eclipse RCP应用中利用扩展点机制解藕插件的依赖关系

原创 2007年10月10日 15:00:00
Eclipse RCP应用中利用扩展点机制解藕插件的依赖关系
在开发Eclipse RCP应用程序时,我们按照Eclipse插件的思路来组织和划分我们的程序模块,会使系统结构得到很大改善:比如,系统功能的灵活装配,系统的增量开发等。为了达到这种效果,我们要尽量减少插件之间的依赖关系。Eclipse平台中提供的扩展点机制可以用来实现这种目标。
一、业务场景
下面以一个具体的业务场景来说明:
比如,在我们的某个应用中,有WorkspaceDocumentJob三种业务功能,我们用三个Eclipse插件工程(WorkspacePluginDocumentPluginJobPlugin)分别来实现这些功能。
在三个插件中,WorkspaceView管理所有的Workspace业务对象,DocumentView管理所有的Document业务对象,JobView管理所有的Job业务对象。
同时,这三种业务不是孤立的,它们之间是有交互的:打开WorkspaceView中的某个WorkspaceDocumentView会作相应改变:显示该Workspace下的所有Document。同样,JobView也会根据Workspace的变化作相应的改变。
针对以上的业务场景,一种自然的做法是,在WorkspacePlugin中添加对另外两个插件的引用,直接在WorkspaceView中调用DocumentViewJobView的相关方法。
但是这种做法导致了三个插件之间比较强的依赖关系,和我们的系统功能的灵活装配的目标有所差距。下面我们利用Eclipse扩展点机制来解决这种问题。
二、定义扩展点
不难看出,上述场景是一个典型的Observer模式的应用:WorkspaceView是交互的发起者,而DocumentViewJobView是交互的监听者。
为了简便起见,在这里不再创建新的插件来容纳我们的接口和扩展点,我们在WorkspacePlugin定义一个Workspace监听器接口:IWorkspaceListener
publicinterface IWorkspaceListener {
   void workspaceOpened(Workspace ws);
   void workspaceClosed(Workspace ws);
}
接下来,我们针对IWorkspaceListener接口定义Workspace监听器扩展点:workspacelisteners
//注:我的开发环境是Eclipse3.2+中文语言包,如果是其他版本和语言,界面文字可能和下面的描述有所出入。
Eclipse IDE中,打开WorkspacePlugin下的plugin.xml(用插件清单编辑器的方式打开),切换到“扩展点”Tab页,新建一个扩展点:
在“扩展点标识”一栏输入我们上面确定的扩展点名称:workspacelisteners,在“扩展点名称”一栏输入一个友好的用于显示的名称,比如:workspace listeners。确定后,将会在工程的schema目录下生成一个workspacelisteners.exsdXML文件,同时会打开扩展点模式编辑器。
在扩展点模式编辑器中,我们输入一些该扩展点的其他信息,然后切换到“定义”Tab页:
新建一个名称为“listener”的元素,然后在“listener”下新建一个名为“class”的属性节点。
选中“class”节点,在右边的面板上编辑它的详细信息,在第三栏“使用”,默认是“optional”,我们这里改为“required”。这表明其他插件在使用本扩展点时,“class”属性必须指定。
然后,我们在默认的“extension”元素上,新建一个“序列”(sequence)。在“序列”点击右键,新建“引用”,将上面建立的“listener”元素加入序列。
至此,一个简单的扩展点定义完毕。
下图是在扩展点模式编辑器中看到的扩展点的定义结构的截图:
 
三、使用扩展点
上面的扩展点定义完毕,WorkspacePlugin更新后,我们分别在DocumentPluginJobPlugin的插件依赖项中加上WorkspacePlugin,这样在这两个插件中就可以使用workspacelisteners了。
使用workspacelisteners扩展点和使用Eclipse RCP中提供的其他扩展点没有任何区别。下面以DocumentPlugin为例简单说明。
根据业务场景的描述,DocumentView应该实现IWorkspaceListener接口:
publicclass DocumentView extends ViewPart implements IWorkspaceListener{
   publicvoid workspaceOpened(Workspace ws){
    //todo...
    //实现workspace打开后的相关更新
   }
   void workspaceClosed(Workspace ws){
    //todo...
    //实现workspace关闭后的相关更新
   }
}
接下来,我们在plugin.xml中声明使用workspacelisteners扩展点:
打开plugin.xml文件,切换到“扩展”Tab页,添加扩展点,找到workspacelisteners,确定。在“所有扩展”列表中就会看到“workspacelisteners”节点,右键点击“workspacelisteners”节点,新建一个扩展元素,选择我们前面定义的“listener”。
然后设置listener的“class”属性为DocumentView类的完整类名(包括package),这里是“document.DocumentView”。
至此,DocumentPlugin中使用workspacelisteners的相关工作已经完毕。在JobPlugin使用和上述基本类似,这里不再赘述。
四、加载扩展点
在前面的描述中,我们在WorkspacePlugin中定义了workspacelisteners扩展点,在DocumentPluginJobPlugin中使用了workspacelisteners扩展。下面我们需要在WorkspacePlugin加载所有的扩展,以便WorkspaceView变化时向这些扩展发出通知。
我们在WorkspaceView定义一个方法来加载扩展。
publicclass WorkspaceView extends ViewPart {
      
private List<IWorkspaceListener> listeners=new ArrayList<IWorkspaceListener>();
    private Workspace ws;//打开的Workspace
    publicvoid loadWorkspaceListeners(){
        IExtensionRegistry registry = Platform.getExtensionRegistry();
        //注:这里传入的扩展点的名称必须是全名,包括plugin的名称。
              IExtensionPoint point = registry.getExtensionPoint("workspace.workspacelisteners");
              IExtension[] extensions = point.getExtensions();
              for(int i=0;i<extensions.length;i++){
                     IConfigurationElement[] elements = extensions[i].getConfigurationElements();
                     for(int j=0;j<elements.length;j++){
                            try{
                                   Object listener=elements[j].createExecutableExtension("class");
                                   if(listener instanceof IWorkspaceListener)
                                          listeners.add((IWorkspaceListener)listener);
                            }
                            catch(CoreException e){
                                   //....todo
                            }
                     }
              }
    }
   
    //当界面操作打开Workspace,调用此方法通知所有IWorkspaceListener
    publicvoid notifyWorkspaceOpened(){
        Iterator<IWorkspaceListener> it=listeners.iterator();
        while(it.hasNext())
            it.next().workspaceOpened(ws);
    }
   
    //当界面操作关闭Workspace,调用此方法通知所有IWorkspaceListener
    publicvoid notifyWorkspaceClosed(){
        Iterator<IWorkspaceListener> it=listeners.iterator();
        while(it.hasNext())
            it.next().workspaceClosed(ws);
    }
}
参考资料:
Contributing to Eclipse 中文版》
 

关于插件开发扩展和扩展点的理解和思考

背景: 一个大的产品是由很多的插件构成。插件间的相互协作是必不可少的。 相互协作的典型方式是依赖,A依赖B,A就可以使用B中开放的包中的类了。(这种方式的优缺暂不讨论) 通过扩展扩展点的方式...
  • weiweiwei256
  • weiweiwei256
  • 2016年01月05日 14:14
  • 1255

RCP添加帮助插件

开发基于Eclipse开的RCP软件可以直接加入Eclipse的帮助系统,使您的产品更加完善。Eclipse帮助系统提供的良好组织模式以及基于lucene的全文搜索功能。在Eclipse的网站上有一篇...
  • sidihuo
  • sidihuo
  • 2015年05月08日 11:41
  • 593

屏蔽Eclipse自带快捷键 消除Eclipse RCP快捷键定义冲突之终极法

快捷键的数量是有限的,何况Eclipse预定义了为数不少的快捷键,所以你开发的RCP程序自定义的快捷键与Eclipse默认定义出现冲突是寻常情况,这时候如何让我们自定义的快捷键优先被接受?方法有几种,...
  • dreajay
  • dreajay
  • 2014年10月08日 11:26
  • 1332

eclipse自定义扩展点

一、组成 一个扩展点(Extension Point)包括ID、Name及Schema文件,shema文件以ID命名,后缀为.exsd,存放在插件schema目录下。   使用eclipse的向导...
  • Yangyan518
  • Yangyan518
  • 2016年01月26日 16:46
  • 1102

让RCP程序自动加载新插件

http://blog.csdn.net/xiaofenguser/article/details/727454 用eclipse开发的RCP应用程序默认是不能自动加载新插件的,加一个插件到RCP系...
  • likunwen_001
  • likunwen_001
  • 2014年03月04日 11:03
  • 969

(转)一篇很不错的介绍Eclipse插件Menu及其扩展点的文章

原文在:http://tech.ddvip.com/2010-04/1271054623150507.html                   菜单是各种软件及开发平台会提供的必备功能,Ecl...
  • wjy320
  • wjy320
  • 2014年01月06日 16:38
  • 1560

使用Eclipse RCP进行桌面程序开发

所谓RCP,就是Rich Client Platform的缩写,即富客户平台,是Eclipse进化的产物(自3.0版以后出现),是Eclipse组织向用户提供的强大的开放性开发平台,能够使用户方便地创...
  • xxyy888
  • xxyy888
  • 2013年07月10日 11:50
  • 994

Eclipse RCP(Java 富客户端开发插件)

Eclipse RCP是一项位于Eclipse平台核心的功能。大多数人想到Eclipse时,会想到Java集成开发环境(IDE)。如果将Eclipse中关于 IDE的内容剥去,剩下的就是一个提供基...
  • qinpanke
  • qinpanke
  • 2014年06月24日 14:43
  • 1284

Eclipse RCP 中创建自定义首选项,并能读取首选项中的值

Eclipse RCP 中创建自定义首选项,并能读取首选项中的值
  • luoww1
  • luoww1
  • 2014年06月25日 12:36
  • 3654

eclipse_RCP添加视图

源文件:http://blog.csdn.net/lyq19870515/article/details/9346921 想要在RCP里添加视图 那就必须先建立视图: [j...
  • luoww1
  • luoww1
  • 2015年11月16日 14:54
  • 1209
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在Eclipse RCP应用中利用扩展点机制解藕插件的依赖关系
举报原因:
原因补充:

(最多只允许输入30个字)