`
liubingjun
  • 浏览: 21681 次
  • 性别: 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
分享到:
评论

相关推荐

    自定义plugin插件实现phonegap与Android交互

    在"自定义plugin插件实现phonegap与Android交互"这个主题中,我们主要关注的是如何通过编写自定义插件来打通JavaScript和Android之间的通信壁垒。在PhoneGap中,Plugin是连接Web层和Native层的桥梁,它们是用Java...

    Office 自定义插件 Vsto

    标题:“Office 自定义插件 Vsto” 在Microsoft Office的应用中,VSTO(Visual Studio Tools for Office)是一种强大的开发工具,它允许程序员利用.NET Framework和Visual Studio来创建自定义的解决方案,以扩展...

    AndroidStudio自定义Gradle插件

    1. **设置项目结构**:首先,你需要创建一个Java或Kotlin项目,用于存放你的Gradle插件代码。例如,项目名为`HCPlugin`,它应该包含一个`src/main/groovy`目录,用来存放Groovy编写的Gradle插件代码,或者`src/main/...

    zencart 自定义页面插件 机会难得 大家把握

    安装"DefinePageGenerator.exe"文件是获取这些功能的第一步。这通常是一个可执行程序,用于在你的Zencart店铺中安装插件。在安装之前,请确保你的Zencart系统已更新至最新版本,并备份数据库,以防万一出现问题时能...

    cordova开发自定义插件(详细篇含jar包调用示例)

    总结来说,通过Cordova开发自定义插件,可以扩展其核心功能,调用第三方JAR包,实现更丰富的原生功能。同时,通过精心设计的回调机制,可以有效地在Android和JavaScript之间进行信息交换,使得Web开发者也能构建出...

    Android自定义注解实现View绑定Demo

    实现自定义注解的第一步是定义注解类。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface BindView { int value(); } ``` 这里,`@Retention(RetentionPolicy....

    cordvoa android 自定义插件 toast

    自定义插件不仅能够增强 Cordova 应用的功能,还能让开发者更灵活地结合原生平台的能力,提高用户体验。继续深入学习 Cordova 插件开发,你可以创建更复杂的功能,如访问设备硬件、集成第三方库等。

    phonegap/Cordova和android自定义插件模块,cordova build后插件不会消失

    7. **第三方插件冲突**:某些第三方插件可能会影响到自定义插件的行为。检查并排除可能的冲突。 DivShow可能是项目的名称或者是某个子文件夹,这并没有提供足够的信息来进一步解释其在插件构建过程中的角色。如果...

    自定义wordpress登陆界面插件

    创建自定义登录界面的第一步是确定要修改的部分。WordPress的默认登录界面位于`wp-login.php`文件中,但直接修改这个核心文件是不推荐的,因为更新WordPress时可能会覆盖我们的改动。因此,我们需要通过插件来实现...

    JQ第三方分享插件+可自定义链接、标题

    "JQ第三方分享插件+可自定义链接、标题"这个标题揭示了一个基于jQuery的第三方分享工具,它允许开发者方便地在他们的H5页面上实现社交分享功能,并且可以定制分享的链接和标题,以满足不同场景的需求。 jQuery是一...

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

    在这种情况下,通常会选取命令中文名的第一个字母,例如"TR"代表"修剪"(TRIM),"EX"代表"延长"(EXTEND)。这种做法既保留了快捷键的易记性,又避免了快捷键之间的冲突。 在CASS中,快捷键的自定义对于提升工作...

    cordova 自定义插件demo(含jar包调用示例)

    1. 如何在`plugin.xml`中配置自定义插件。 2. 创建Java插件类以处理JavaScript调用。 3. 引入并使用第三方jar包进行功能扩展。 4. 编写JavaScript接口以调用Java插件方法。 5. 实现原生与JavaScript之间的信息回调。...

    cordova自定义插件

    在Cordova中,自定义插件是扩展其功能的关键机制,它们提供了JavaScript和原生平台代码之间的桥梁,使得Web应用程序能够访问设备的硬件特性和原生API。 ### 1. Cordova插件的基本结构 一个Cordova插件通常包含以下...

    jquery自定义滚动条插件

    // 初始化第一个滚动条 $('.scrollbar1').customScrollbar(); // 初始化第二个滚动条 $('.scrollbar2').customScrollbar({ thumbHoverColor: '#ff0000' // 设置滑块悬停时的颜色 }); ``` ### 四、插件使用方法 1...

    通过groovy自定义函数实现提取明细表字段至主表字段.rar

    8. **与“致远”系统的整合**:"致远"是一个协同办公软件,可能提供了API或插件机制来支持Groovy脚本的执行。理解“致远”的架构和接口,是成功实现这个功能的关键。 通过观看"通过groovy自定义函数实现提取明细表...

    Android-自定义使用高德SDK进行定位的插件

    通过以上步骤,我们可以构建一个自定义的高德地图定位插件,使得在Cordova应用中能灵活控制和使用高德的定位服务。这种插件化的开发方式既保留了Web开发的便捷性,又充分利用了原生平台的能力,提高了应用的性能和...

    FCKEditort自定义插件

    通过以上步骤,我们可以成功实现FCKEditor中的自定义插件功能。这种自定义方式不仅增强了编辑器的功能性,还能够更好地满足项目需求。对于需要高度定制化界面和功能的开发场景而言,这种方法非常实用且灵活。

    自定义eclipse 插件样式的例子

    在本文中,我们将深入探讨如何在Eclipse IDE中创建自定义插件样式,特别是通过使用`net.sf.eclipsespresentation.metal_1.0.0.jar`库来实现一个电子邮件功能的例子。这个库主要用于增强Eclipse的界面展示,使得...

Global site tag (gtag.js) - Google Analytics