`
liubingjun
  • 浏览: 21127 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

第一个自定义插件的实现

阅读更多

自定义插件的实现

把自己的一些粗糙想法写出来,即是对自己的一个总结,也能对其他人有些帮助。简单随笔,若在实现中遇到问题,具体再聊。

插件清单

Eclipse中的插件都是XML文件来进行描述,比如:

这段XML描述了插件的绝大多数信息,包括插件的IDname,版本,启动类,同时所有的扩展节点也都在这里定义,该插件对外提供的库以及资源也都要定义在这个文件中。

 

文件的名称为“plugin.xmlEclipse启动的时候会扫描“plugins”目录下的所有 plugin.xml”文件,进而装载所有的插件,因此,需要用XML Parser 将这些信息Parser出来,形成插件的基本信息,具体选用DOMSAX、还是Pull Parser 都无所谓。

 Eclipse采用微内核+插件的模式构架,也就是说,除了一个微小的核儿之外,所有的东西都是插件(All are plugins)

扩展点概述

Eclipse Plugin Framework 最核心的概念就要算“Extension Point(扩展点)”了。打个比方,“Extension Point”就像我们日常生活中的插销板,而Extension 就是能够插入到这个插销板上面的插销。

系统的开放性很大程度上取决于系统究竟给你多少Extension Point

对于Eclipse来说,因为采用微内核+插件的方式,因此,定义扩展点是很重要的步骤,在扩展功能的同时,你可以在任何你觉得可能被扩展的地方定义扩展点,来方便其他人扩展系统的功能。

举个例子,Eclipse UI中,工具栏、视图都留有扩展点,这样可以方便的进行扩展。

Eclipse的插件扩展点都定义在plugin.xml,每个插件要扩展那些扩展点也定义在这个文件中。你可以搜索eclipse的安装目录,会发现数以百计的plugin.xml文件

ClassLoader

了解EclipsePlugin Framework 需要对ClassLoader(类装载器)有比较深的理解。

ClassLoader——顾名思义,就是Java中用来装载类的部分,要将一个类的名字装载为JVM中实际的二进制类数据。在JVM中,任何一个类被加载,都是通过ClassLoader来实现的,同时,每个Class对象都有一个引用指向装载他的ClassLoader,你可以通过getClassLoader()方法得到它。

 

ClassLoader是一个抽象类,你可以定义自己的ClassLoader来实现特定的Load功能。Eclipse Plugin Framework就实现了自己的ClassLoader

 

ClassLoader使用的是“Delegation Model(双亲委托模型)”来查找,定位类资源。每一个ClassLoader都有一个父ClassLoader实例(在构造的时候传入),当这个ClassLoader被要求加载一个类时,他首先会询问自己的父ClassLoader,看看他能否加载,如果不能,则自己加载。

最后来看一下代码:

可见,ClassLoader首先会查找该类是否已经被装载,如果没有,就询问自己的父ClassLoader,如果还不能装载,就调用findClass()方法来装载类。所以,一般简单的自定义ClassLoader只需要重写findClass方法就可以了。

PluginPluginClassLoader

简单demo准备,实现过程。

我们模拟几个重要的类是:

Plugin:插件类,描述每个具体的插件。

PluginDesciptor 插件描述符,记录了插件的IDNameVersion,依赖,扩展点等。

PluginManager:插件管理器,负责所有插件资源的管理,包括插件的启动,停止等。

PluginRegistry:插件注册表,提供了一个由插件IDplugin的映射。

Demo示例:

 

自定义插件类,派生于Plugin

package com.bjrongzhi.nms.client.plugins.core;

 

import org.java.plugin.Plugin;

 

public class PluginCore extends Plugin {

 

    protected void doStart() throws Exception {

    }

 

    protected void doStop() throws Exception {

    }

 

}

 

 

定义扩展点

<?xml version="1.0" ?>

<!DOCTYPE plugin PUBLIC "-//JPF//Java Plug-in Manifest 1.0" "http://jpf.sourceforge.net/plugin_1_0.dtd">

<plugin id="com.bjrongzhi.nms.client.plugins.core" version="1.0.0" >

   <runtime>

      <library id="core" path="/" type="code">

        <export prefix="*" />

      </library>

   </runtime>

 

<!--  定义两个扩展点PopupMenuMainMenu-->

   <extension-point id="PopupMenu">

      <parameter-def id="class"/>

      <parameter-def id="name"/>

   </extension-point>

   <extension-point id="MainMenu">

      <parameter-def id="class"/>

      <parameter-def id="name"/>

   </extension-point>

</plugin>

 

定义扩展类

package com.bjrongzhi.nms.client.plugins.popupmenu;

 

/**

 * 仿真管理系统右键菜单

 *

 * @author zhangdy

 *

 */

public class ResMgrPopupMenu extends AbstractPopupMenu {

       //省略……..

       JMenuItem mi_deleteSubnet = new JMenuItem("删除子网");

       JMenuItem mi_createLable = new JMenuItem("创建标签");

       public ResMgrPopupMenu() {

      

              mi_createPerfSnmp.addActionListener(new DoCreatePerfSnmp());/

/省略……..

             

              // 站点界面的右键菜单

              table_menu.put(ClientMainPane.class.getName(), new JMenuItem[] {

                            mi_createSdhNe,

                            // mi_createShelf,

                            // mi_createIPNe,

                            mi_createPerfmonitortask, mi_createPerfSnmp, // mi_createPerfTest

              // // 测试

                            });

      

 

}

 

扩展插件的配置

<?xml version="1.0" ?>

<!DOCTYPE plugin PUBLIC "-//JPF//Java Plug-in Manifest 1.0" "http://jpf.sourceforge.net/plugin_1_0.dtd">

<plugin id="com.bjrongzhi.nms.client.plugins.popupmenu" version="1.0.0">

   <!--

        该插件依赖的插件在这里定义   

   -->

   <requires>

      <import plugin-id="com.bjrongzhi.nms.client.plugins.core"/>

   </requires>

   <runtime>

  

   <!-- PluginClassLoader会将根目录都加入到URLClassLoader的类搜索路径中去,

          这样,就可以用这个类加载器来加载相应的插件类和资源了。-->

      <library id="popupmenu" path="/" type="code">

         <export prefix="*" />

      </library>

   </runtime>

  

   <!-- 这是core关于PopupMenu的扩展点,这是"ResMgrPopupMenu"插件中对此扩展点的一个扩展声明,声明了自己扩展的类和名称。Name

            只是定义该扩展点的名称,而其中的"class"则是为了加载真正的功能。

   -->

    <extension plugin-id="com.bjrongzhi.nms.client.plugins.core" point-id="PopupMenu" id="resmgrpopupmenu">

      <parameter id="class" value="com.bjrongzhi.nms.client.plugins.popupmenu.ResMgrPopupMenu"/>

      <parameter id="name" value="ResMgrPopupMenu"/>

   </extension>

</plugin>

 

获取插件描述符

package com.bjrongzhi.nms.client.topo.menu;

 

import com.bjrongzhi.nms.client.topo.ClientMainPane;

 

public class PluginTools {

 

       public static PluginTools instance = new PluginTools();

       public static PluginManager pluginManager;

       public static PluginDescriptor core;

       // TODO

       private TNetwork network = ClientMainPane.network;

 

       static {

              try {

                     ExtendedProperties config = new ExtendedProperties(System

                                   .getProperties());

                     PluginsCollector collector = new DefaultPluginsCollector();

                     collector.configure(config);

 

                     pluginManager = ObjectFactory.newInstance(config).createManager();

                     Collection<PluginLocation> pluginLocations = collector

                                   .collectPluginLocations();

 

                     pluginManager.publishPlugins((PluginLocation[]) pluginLocations

                                   .toArray(new PluginLocation[pluginLocations.size()]));

                     // Create instance of plug-in manager.

 

                     /*

                      * 得到插件描述符,描述符中记录了插件的IDNameVersion,依赖,扩展点等。

                      * 通过Plugin.xml文件得知,关于core的扩展点有两个:PopupMenuMainMenu。这两个扩展点都声

                      * 明了自己扩展的类和名称.Name 只是定义该扩展点的名称,Class则为了加载真正的功能。

                      */

                     core = pluginManager.getRegistry().getPluginDescriptor(

                                   "com.bjrongzhi.nms.client.plugins.core");

              } catch (JpfException e) {

text-align: justify; margin: 0cm

0
0
分享到:
评论

相关推荐

    CASS常用命令自定义快捷键插件

    针对CASS选择命令复杂问题,开了了快捷键LISP (1)尽可能采用单数字或字母快捷键 (2)部分使用两个及以上字母快捷键,均提取中文命令第一个字母,有些尽可能采用同一个字母

    400个DreamWeaver插件

    这个插件也可以实现这个功能。更妙的是,他提供许多网络上的字体资源供大家选择 mxp/插入类似国际象棋棋盘形状及颜色的一组层 mxp/插入一个很COOL的可以改变大小的层,IE4以上支持。不过我没有试验成功 :( mxp/...

    齐博cms微信自定义回复插件

    齐博cms微信自定义回复插件 数据库版。安装说明包含在内,因为腾讯把Hello2BizUser变更为subscribe事件,自己下载后更换下...不更换则会出现关注微信后第一条自动回复的微信错误,其他没有问题。如果不会更换就联系我吧

    PCS7 WINCC报表1.不需要第三方任何插件实现 2.采用数据库方式实现快速生成WINCC报表 3.提供脚本源码程序

    1.不需要第三方任何插件实现。 2.采用数据库方式实现快速生成WINCC报表。 3.提供脚本源码程序。 4.可移植,也可以导出来生成EXCEL文件。 实现PCS7 WINCC报表时无需依赖任何第三方插件。 采用数据库方式实现,能够...

    九宫格抽奖转盘--支持自定义转盘大小

    作者本人闲来无事,正好朋友需要做抽奖转盘特效,因缘际会之下,打算自己动手写一个插件玩玩,素材都是用的网络上面的,看见相同的... 这个插件是作者独立完成的第一个插件,仅作练手,还有诸多瑕疵;欢迎大家拍砖!

    redevtools:直接从本地主机使用自定义插件扩展浏览器devtools

    直接从本地主机使用自定义插件扩展浏览器devtools: 一些例子: 从控制台浏览和编辑请求 钩住方法并轻松调试它们 将JSON对象转换为TypeScript接口 在页面中显示Web组件及其状态 每个插件都可以在此仓库的plugins...

    Msbox(基于Jquery的弹窗提示插件)

    /** ... * 这是我的第一个jquery插件,如果对本插件有更好的改进意见请发邮件lonely_net@163.com ,感谢使用。 * * @by the way: 由于时间关系,没有提供插件的min版本,各位如果需要请自己压缩。 */

    [原创]基于FLASH机制实现的不同域窗口相互调用js的插件-虫洞

    4)本插件在JS中的实现是依靠一个静态类Wormhole来实现的,使用时在页面中相当于单实例模式,不用构造一个对象,只用初始化即可 5)由于AS3之间的LocalConncetion还可以传递支持序列化的自定义对象,使用此插件传输的数据...

    2018最新Office插件开发之使用ExcelDNA开发XLL插件免费教学视频

    Lesson5-第一个完整的ExcelDna自定义函数及参数说明 Lesson6-第一个完整的ExcelDna加载项命令 Lesson7-第一个完整的VS2017插件项目 Lesson8-项目调试和自定义函数参数传递 Lesson9-XLL插件与VBA的交互 Lesson10-...

    VS2022 扩展插件 打包安装 插件

    VS2022 扩展插件 打包安装 插件。原始链接 :https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects 下载老是网络失败。 好不容易下到,共享出来!

    embed标签的使用(在网页中播放各种音频视频的插件的使用)

    starttime:“分:秒”,设置歌曲开始播放的时间,如,starttime=“00:10”,从第10开始播放 endtime: “分:秒”,设置歌曲结束播放的时间 width:控制面板的宽 height:控制面板的高 controls:控制面板的外观 ...

    华表插件5.3.8.exe

    是第一个国产ActiveX商业组件,有300多个编程接口;Cell组件适用于Windows环境下各种开发工具(如VB,VC,Visual Foxpro,Delphi,C+Builder,PowerBuilder,.net)等。实现自定义报表、图表、公式、自定义函数、数据库...

    AUTOIT生成自动安装的工具

    3.如果需要修改安装路径或输入注册码,请在第1步前将路径复制好,然后单击文本框,会弹出一个提示框,输入需要修改的路径即可 4.检测到点击其他控件(标准树形treeviw、列表listview控件)会自动转换成相对位置点击 ...

    jQuery带缩略图焦点图插件 自定义滑块内容

    今天我们要来分享一款基于jQuery的焦点图插件,这款jQuery焦点图功能十分强大,有以下两个特点:第一是焦点图带有缩略图预览,当鼠标滑过对应图片的按钮时,即可弹出缩略图;第二是焦点图的滑块内容可以自定义,可以...

    广告经理插件for pw7 pw7.3 pw7.3.2适用于需要自定义广告赚更多M的站长

    1、在后台自定义广告中增加一个变量名为:” text5”(变量名可以自己随意取建意以adv_为前缀,后台取什么名字前台也要引用这个名字),类型为”文字”,排列数为“2“的广告类型,然后可以在前台的插件区或后台的...

    gaze:轻量级的跨平台网络包监听工具,支持自定义插件

    gaze是一个命令行下的轻量级网络包监听工具, 有颜色显示, 跨平台(linux & windows), 支持TCP协议, 支持自定义插件. 为什么是gaze 能做网络抓包的工具很多, 例如tcpdump和wireshark, 为什么还要自己写一个? gaze具的...

    yl_linkage_帝国CMS无限联动插件_

    多级联动本插件理论上支持帝国cms任何版本。本插件在帝国CMS7.0正式版{UTF-8}下制作完成,GBK自行转换文件...第一个条目作为提示项,自动选择唯一选项的菜单,设置回调函数在onChange事件触发时获取下拉菜单相关信息。

    自定义提示JQ验证

    验证一般会用第三方插件验证。发现太麻烦,就自己写了一个。三个参数,第一个参数为input的id,第二个是:验证的function名字,第三个是自定义提示语. 大牛轻喷,谢谢

    小程序插件 新闻模板 vue + nvue

    · h5和小程序采用使用了swiper+自定义顶部tabbar实现,并封装下拉刷新和上滑加载组件 · app端由于swiper在安卓下的糟糕表现在这种场景下是...· nvue里面加了详细注释,即使第一次用也可以很快学会并自己实现。

    泛微OA前端开发接口方法和自定义方方法总结注释

    方式1:模板上代码块,针对单个节点,在显示/打印/移动模板单独配置 方式2:【路径管理】-打开具体路径-【基础设置】-【自定义页面】,针对此路径下所有节点所有模板生效 方式3:【路径管理】-【应用设置】-【流程...

Global site tag (gtag.js) - Google Analytics