自定义插件的实现
把自己的一些粗糙想法写出来,即是对自己的一个总结,也能对其他人有些帮助。简单随笔,若在实现中遇到问题,具体再聊。
插件清单
Eclipse中的插件都是XML文件来进行描述,比如:
这段XML描述了插件的绝大多数信息,包括插件的ID,name,版本,启动类,同时所有的扩展节点也都在这里定义,该插件对外提供的库以及资源也都要定义在这个文件中。
文件的名称为“plugin.xml”Eclipse启动的时候会扫描“plugins”目录下的所有 “plugin.xml”文件,进而装载所有的插件,因此,需要用XML Parser 将这些信息Parser出来,形成插件的基本信息,具体选用DOM、SAX、还是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
了解Eclipse的Plugin 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方法就可以了。
Plugin与PluginClassLoader
简单demo准备,实现过程。
我们模拟几个重要的类是:
Plugin:插件类,描述每个具体的插件。
PluginDesciptor: 插件描述符,记录了插件的ID,Name,Version,依赖,扩展点等。
PluginManager:插件管理器,负责所有插件资源的管理,包括插件的启动,停止等。
PluginRegistry:插件注册表,提供了一个由插件ID到plugin的映射。
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>
<!-- 定义两个扩展点PopupMenu和MainMenu-->
<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.
/*
* 得到插件描述符,描述符中记录了插件的ID,Name,Version,依赖,扩展点等。
* 通过Plugin.xml文件得知,关于core的扩展点有两个:PopupMenu和MainMenu。这两个扩展点都声
* 明了自己扩展的类和名称.Name 只是定义该扩展点的名称,Class则为了加载真正的功能。
*/
core = pluginManager.getRegistry().getPluginDescriptor(
"com.bjrongzhi.nms.client.plugins.core");
} catch (JpfException e) {
text-align: justify; margin: 0cm
分享到:
Global site tag (gtag.js) - Google Analytics
|
相关推荐
在"自定义plugin插件实现phonegap与Android交互"这个主题中,我们主要关注的是如何通过编写自定义插件来打通JavaScript和Android之间的通信壁垒。在PhoneGap中,Plugin是连接Web层和Native层的桥梁,它们是用Java...
标题:“Office 自定义插件 Vsto” 在Microsoft Office的应用中,VSTO(Visual Studio Tools for Office)是一种强大的开发工具,它允许程序员利用.NET Framework和Visual Studio来创建自定义的解决方案,以扩展...
1. **设置项目结构**:首先,你需要创建一个Java或Kotlin项目,用于存放你的Gradle插件代码。例如,项目名为`HCPlugin`,它应该包含一个`src/main/groovy`目录,用来存放Groovy编写的Gradle插件代码,或者`src/main/...
安装"DefinePageGenerator.exe"文件是获取这些功能的第一步。这通常是一个可执行程序,用于在你的Zencart店铺中安装插件。在安装之前,请确保你的Zencart系统已更新至最新版本,并备份数据库,以防万一出现问题时能...
总结来说,通过Cordova开发自定义插件,可以扩展其核心功能,调用第三方JAR包,实现更丰富的原生功能。同时,通过精心设计的回调机制,可以有效地在Android和JavaScript之间进行信息交换,使得Web开发者也能构建出...
实现自定义注解的第一步是定义注解类。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface BindView { int value(); } ``` 这里,`@Retention(RetentionPolicy....
自定义插件不仅能够增强 Cordova 应用的功能,还能让开发者更灵活地结合原生平台的能力,提高用户体验。继续深入学习 Cordova 插件开发,你可以创建更复杂的功能,如访问设备硬件、集成第三方库等。
7. **第三方插件冲突**:某些第三方插件可能会影响到自定义插件的行为。检查并排除可能的冲突。 DivShow可能是项目的名称或者是某个子文件夹,这并没有提供足够的信息来进一步解释其在插件构建过程中的角色。如果...
创建自定义登录界面的第一步是确定要修改的部分。WordPress的默认登录界面位于`wp-login.php`文件中,但直接修改这个核心文件是不推荐的,因为更新WordPress时可能会覆盖我们的改动。因此,我们需要通过插件来实现...
"JQ第三方分享插件+可自定义链接、标题"这个标题揭示了一个基于jQuery的第三方分享工具,它允许开发者方便地在他们的H5页面上实现社交分享功能,并且可以定制分享的链接和标题,以满足不同场景的需求。 jQuery是一...
在这种情况下,通常会选取命令中文名的第一个字母,例如"TR"代表"修剪"(TRIM),"EX"代表"延长"(EXTEND)。这种做法既保留了快捷键的易记性,又避免了快捷键之间的冲突。 在CASS中,快捷键的自定义对于提升工作...
1. 如何在`plugin.xml`中配置自定义插件。 2. 创建Java插件类以处理JavaScript调用。 3. 引入并使用第三方jar包进行功能扩展。 4. 编写JavaScript接口以调用Java插件方法。 5. 实现原生与JavaScript之间的信息回调。...
在Cordova中,自定义插件是扩展其功能的关键机制,它们提供了JavaScript和原生平台代码之间的桥梁,使得Web应用程序能够访问设备的硬件特性和原生API。 ### 1. Cordova插件的基本结构 一个Cordova插件通常包含以下...
// 初始化第一个滚动条 $('.scrollbar1').customScrollbar(); // 初始化第二个滚动条 $('.scrollbar2').customScrollbar({ thumbHoverColor: '#ff0000' // 设置滑块悬停时的颜色 }); ``` ### 四、插件使用方法 1...
8. **与“致远”系统的整合**:"致远"是一个协同办公软件,可能提供了API或插件机制来支持Groovy脚本的执行。理解“致远”的架构和接口,是成功实现这个功能的关键。 通过观看"通过groovy自定义函数实现提取明细表...
通过以上步骤,我们可以构建一个自定义的高德地图定位插件,使得在Cordova应用中能灵活控制和使用高德的定位服务。这种插件化的开发方式既保留了Web开发的便捷性,又充分利用了原生平台的能力,提高了应用的性能和...
通过以上步骤,我们可以成功实现FCKEditor中的自定义插件功能。这种自定义方式不仅增强了编辑器的功能性,还能够更好地满足项目需求。对于需要高度定制化界面和功能的开发场景而言,这种方法非常实用且灵活。
在本文中,我们将深入探讨如何在Eclipse IDE中创建自定义插件样式,特别是通过使用`net.sf.eclipsespresentation.metal_1.0.0.jar`库来实现一个电子邮件功能的例子。这个库主要用于增强Eclipse的界面展示,使得...