转:http://blog.csdn.net/huwenfeng_2011/article/details/43418493

Plugin接口规范

插件是openfire功能的增强表现,它的主要任务:

l  在XMPP协议中作为附加功能实现

l  动态修改控制管理台

l  使用openfire api作为新功能添加到服务器

Openfire里面的插件都会存放在plugins(工程目录为:src/plugins)的住目录下。使用ant工具编译后插件会打成jar包生成在target/openfire/plugins目录下。一个完整的插件应该包含以下的结构:

Yourplugin/

| -plugin.xml                            插件定义文件
        | -readme.html                          任择自述文件的插件,它会显示给最终用户

| -changelog.html                      任择修改文件的插件,它会显示给最终用户

| -icon_small.gif                       可选小( 16x16 )图标与插件(也可以是 PNG文件)

| -icon_large.gif                       可选大( 32x32 )图标与插件(也可以是 PNG文件) 
        |classes/                                    资源的插件需要(即属性文件) 
        |-database/                               可选数据库架构文件,你需要插件
        | -i18n/                                      插件国际化的语言配置。 
        |-lib/                                        您的插件的jar包

|-web                                      资源的管理控制台集成,如果有的话
            | - WEB-INF

|-web-custom.xml              可选用户自定义的web.xml中的自定义servlets
            |-images/                         图片文件存放的目录

|-test-plugin.jsp         jsp文件

其中类和lib目录是可选的,类目录下的所有文件和以及在lib目录的所有JAR文件中都会被添加到classpath路径下。 plugin.xml 这个文件也必须要添加到您的插件当中,这个文件描述了改插件的的基本信息和一些需要在控制台上生成目录的信息。Plugin.xml文件中的内容应如下所示:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <plugin>
  3. <!—需要的插件类 -->
  4. <class>org.example.ExamplePlugin</class>
  5. <!-- 插件元数据 -->
  6. <name>Example Plugin</name>
  7. <description>This is an example plugin.</description>
  8. <author>Jive Software</author>
  9. <version>1.0</version>
  10. <date>07/01/2006</date>
  11. <url>http://www.igniterealtime.org/projects/openfire/plugins.jsp</url>
  12. <!-- 要求openfire服务器的最低版本 -->
  13. <minServerVersion>3.0.0</minServerVersion>
  14. <licenseType>gpl</licenseType>
  15. <!-- 管理控制台的条目 -->
  16. <adminconsole>
  17. <!-- More on this below -->
  18. </adminconsole>
  19. </plugin>

该元素的领域设置介绍:

l   Name                        该插件的名称

l   Description                    该插件说明

l   Author                       该插件作者

l   Version                      该插件的版本标识

l   Date                         该插件的发布日期

l   Url                          该插件说明网址

l   minServerVersion              该插件需要最低版本Opfenfire的支持

l   licenseType                   显示许可协议,常用的显示值如下:

“commercial”:commercial “商业” :插件是下发布的商业许可协议。

“gpl”: 通用公共许可证,插件发布使用GNU公共授权

“apache”:Apache许可证internal

“internal”:插件是提供内部组织使用

“other”: 如果许可未设置就会假定为其他

l  databaseKey                   如果插件需要它自己的数据表,该databaseKey内容应设立一个架构                    主要名称(通常是相同名称的插件)。数据库架构文件为每个支持的数据库,然后放置在数据库目录下的插件。例如, “foo”,架构文件将被称为“ foo_mysql.sql ” , “ foo_oracle.sql ”等等,我们建议您,您的表前缀of ,以避免可能的冲突与其他应用程序安装在同一数据库。脚本应该进入ofVersion表使用的关键,这样的架构版本信息可跟踪,例如: 
INSERT INTO ofVersion (name, version) VALUES ('foo', 0); databaseVersion -数据库版本号(如果数据库模式的定义)。新的插件与数据库架构应该开始在版本。如果将来插件版本的需要更新,这些更新可以定义创建子目录中的升级数据库目录为每个版本。例如,目录database/upgrade/1database/upgrade/2将包含脚本,如“ foo_mysql.sql ”和“ foo_oracle.sql ”中包含相关的数据库,为每一个版本的变化。每个脚本应该更新版本中的信息ofVersion表,例如: 
UPDATE ofVersion set version=1 where name='foo';

l     parentPlugin                 父层插件(作为“foo”的“ foo.jar ”插件)。当一个插件有一个父插件,插件的类加载器将被使用来而不是建立一个新的类加载器。这可让插件更加紧密地协同工作。子插件将不会影响其父插件。

l   Adminconsole                  该插件在管理控制台的条目

一个完整plugin.xml文件内容应该如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <plugin>
  3. <class>org.jivesoftware.openfire.plugin.RegistrationPlugin</class>
  4. <name>Registration</name>
  5. <description>Performs various actions whenever a new user account is created.</description>
  6. <author>Ryan Graham</author>
  7. <version>1.5.0</version>
  8. <date>12/2/2009</date>
  9. <minServerVersion>3.7.0</minServerVersion>
  10. <adminconsole>
  11. <tab id="tab-users">
  12. <sidebar id="sidebar-users">
  13. <item id="registration-props-form" name="Registration Properties"
  14. url="registration-props-form.jsp"
  15. description="User Registration" />
  16. </sidebar>
  17. </tab>
  18. </adminconsole>
  19. </plugin>

插件开发

注意:启动of的开发模式需要添加tools.jar包 添加到target/lib目录下

设置参数-DdevelopmentMode="true"

一、添加如下结构插件包

二、编写TestIQHandle类

  1. public class TestIQHandle extends IQHandler {
  2. private static final String MODULE_NAME = "test plugin";
  3. private static final String NAME_SPACE = "com:test:testplug";
  4. private IQHandlerInfo info;
  5. public TestIQHandle(){
  6. super(MODULE_NAME);
  7. info = new IQHandlerInfo("query", NAME_SPACE);
  8. }
  9. public TestIQHandle(String moduleName) {
  10. super(moduleName);
  11. info = new IQHandlerInfo("query", NAME_SPACE);
  12. }
  13. @Override
  14. public IQ handleIQ(IQ packet) throws UnauthorizedException {
  15. IQ reply = IQ.createResultIQ(packet);
  16. Element groups = packet.getChildElement();
  17. if(true){
  18. System.out.println("=======请求非法========");
  19. }
  20. if(!IQ.Type.get.equals(packet.getType())){
  21. reply.setChildElement(groups.createCopy());
  22. reply.setError(PacketError.Condition.bad_request);
  23. return reply;
  24. }
  25. //StringUtils.substringBefore(packet.getFrom().toString(), "@");
  26. return reply;
  27. }
  28. @Override
  29. public IQHandlerInfo getInfo() {
  30. // TODO Auto-generated method stub
  31. return info;
  32. }
  33. }

三、编写TestPlugin类

  1. public class TestPlugin implements Plugin ,PropertyEventListener{
  2. private XMPPServer server;
  3. @Override
  4. public void initializePlugin(PluginManager manager, File pluginDirectory) {
  5. server = XMPPServer.getInstance();
  6. server.getIQRouter().addHandler(new TestIQHandle());
  7. PropertyEventDispatcher.addListener(this);
  8. System.out.println("==========插件初始化=============");
  9. }
  10. @Override
  11. public void destroyPlugin() {
  12. PropertyEventDispatcher.removeListener(this);
  13. System.out.println("==========插件销毁动作=============");
  14. }
  15. @Override
  16. public void propertySet(String property, Map<String, Object> params) {
  17. // TODO Auto-generated method stub
  18. }
  19. @Override
  20. public void propertyDeleted(String property, Map<String, Object> params) {
  21. // TODO Auto-generated method stub
  22. }
  23. @Override
  24. public void xmlPropertySet(String property, Map<String, Object> params) {
  25. // TODO Auto-generated method stub
  26. }
  27. @Override
  28. public void xmlPropertyDeleted(String property, Map<String, Object> params) {
  29. // TODO Auto-generated method stub
  30. }
  31. }

四、编写TestServlet

  1. public class TestServlet extends HttpServlet{
  2. public TestServlet() {
  3. super();
  4. }
  5. public void doGet(HttpServletRequest request, HttpServletResponse response)
  6. throws ServletException, IOException {
  7. System.out.println("============调用servlet=============");
  8. }
  9. public void doPost(HttpServletRequest request, HttpServletResponse response)
  10. throws ServletException, IOException {
  11. this.doGet(request, response);
  12. }
  13. public void init() throws ServletException {
  14. AuthCheckFilter.addExclude("test/testservlet");
  15. System.out.println("==========init()============");
  16. }
  17. public void destroy() {
  18. System.out.println("==========destroy()=========");
  19. AuthCheckFilter.addExclude("test/testservlet");
  20. }
  21. }

五、配置web-custom.xml

  1. <?xml version='1.0' encoding='ISO-8859-1'?>
  2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
  3. <web-app>
  4. <servlet>
  5. <servlet-name>TestServlet</servlet-name>
  6. <servlet-class>com.test.plugin.test.TestServlet</servlet-class>
  7. </servlet>
  8. <servlet-mapping>
  9. <servlet-name>TestServlet</servlet-name>
  10. <url-pattern>/servlet</url-pattern>
  11. </servlet-mapping>
  12. </web-app>

六、test-plugin.jsp

  1. <%@ page import="java.util.*,
  2. org.jivesoftware.openfire.XMPPServer,
  3. org.jivesoftware.util.*,
  4. com.test.plugin.TestPlugin"
  5. errorPage="error.jsp"
  6. %>
  7. <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
  8. <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
  9. <%-- Define Administration Bean --%>
  10. <jsp:useBean id="admin" class="org.jivesoftware.util.WebManager"  />
  11. <c:set var="admin" value="${admin.manager}" />
  12. <% admin.init(request, response, session, application, out ); %>
  13. <%String path = request.getContextPath();
  14. System.out.println("path= "+path);
  15. %>
  16. <html>
  17. <head>
  18. <title>User Service Properties</title>
  19. <meta name="pageID" content="test_plugin"/>
  20. </head>
  21. <body>
  22. <p>==============================================</p>
  23. <form action="<%=path %>/plugins/testplug/servlet" method="post">               //testplug是插件的名称
  24. <fieldset>
  25. <legend>test plugin</legend>
  26. <div>
  27. <input type="text" size="15" /><br>
  28. <input type="text" size="15" /><br>
  29. </div>
  30. </fieldset>
  31. <br><br>
  32. <input type="submit" value="Save Settings">
  33. </form>
  34. </body>
  35. </html>

七、Plugin.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <plugin>
  3. <class>com.test.plugin.server.TestPlugin</class>
  4. <name>TestPlugin</name>
  5. <description>test plugin For myTestPlugin</description>
  6. <author>huwf</author>
  7. <version>1.0.0</version>
  8. <date>5/10/2013</date>
  9. <url>http://www.baidu.com</url>
  10. <minServerVersion>3.5.1</minServerVersion>
  11. <licenseType>gpl</licenseType>
  12. <adminconsole>
  13. <tab id="tab-server">
  14. <sidebar id="sidebar-server-settings">
  15. <item id="test_plugin"
  16. name="testPlugin"
  17. url="test-plugin.jsp"
  18. description="Edit subscription plugin properties" />
  19. </sidebar>
  20. </tab>
  21. </adminconsole>
  22. </plugin>

八、发布/编译插件

 

(转)OpenFire源码学习之十五:插件开发的更多相关文章

  1. (转)OpenFire源码学习之十:连接管理(上)

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43415827 关于连接管理分为上下两部分 连接管理 在大并发环境下,连接资源 需要随着用 ...

  2. (转)OpenFire源码学习之十八:IOS离线推送

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43458213 IOS离线推送 场景: 如果您有iOS端的APP,在会话聊天的时候,用户登 ...

  3. (转)OpenFire源码学习之十四:插件管理

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43418433 Plugin管理 Openfire把插件模块加入到容器分为以下步骤: l  ...

  4. (转)OpenFire源码学习之十二:HttpBind&Script Syntax

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43417343 HttpSessionManager 该类管理所有通过httpbing连接 ...

  5. yii2源码学习笔记(十五)

    这几天有点忙今天好些了,继续上次的module来吧 /** * Returns the directory that contains the controller classes according ...

  6. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  7. async-validator 源码学习笔记(五):Schema

    系列文章: 1.async-validator 源码学习(一):文档翻译 2.async-validator 源码学习笔记(二):目录结构 3.async-validator 源码学习笔记(三):ru ...

  8. (转)OpenFire源码学习之七:组(用户群)与花名册(用户好友)

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43413651 Group 在openfire中的gorop——组,也可以理解为共享组.什 ...

  9. Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路

    写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 ...

随机推荐

  1. i.js

    i.js 动态更新 <script type="text/javascript"> function isCardNo(idCard) { // 15位和18位身份证号 ...

  2. Excel表格 函数

    1.四则运算(加.减.乘.除).求和.平均.计数.最值. 2. 逻辑函数 (IF函数.NOT函数.等) 3.时间和日期 ( NOW 返回当前日期和时间.等) 4.数学与三角函数 5.文本 ( LOWE ...

  3. [CSP-S模拟测试]:时间机器(贪心+set)

    题目描述 作为一名天才科学家,$Kurisu$已经设计出了时间机器的构造. 根据$Kurisu$的构想,时间机器中有$n$种需要放置电阻的节点,第$i$种节点有$s_i$个,其电压$U$的变动范围是$ ...

  4. python中匿名函数lambda如何用

    python中经常用到的一个函数:匿名函数lambda ,什么是匿名函数?匿名函数的意义是什么?匿名函数怎么样用?(疑问三连,what,why,how) 一,什么是匿名函数? python中没有名字的 ...

  5. (转)使用OpenGL显示图像(四)运用投影与相机视角

    运用投影与相机视角 编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/projection.html 在OpenG ...

  6. Name your feature branches by convention

    https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=azure-devops Nam ...

  7. 修改 DbVisualizer 自动完成快捷键

    1.找到 DbVisualizer 安装目录 lib目录 下的 dbvis.jar 包. 2.使用 WinRaR 打开dbvis.jar包,编辑 dbvis-actions.xml 文件(解压或直接修 ...

  8. JS 常用字符串,数组操作

    JavaScript String/Array对象 JS String对象   String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 pro ...

  9. (54) C# 调用 kernel32.dll

    https://www.cnblogs.com/cwy173/archive/2010/10/02/1841321.html Kernel32 API AddAtom 向本地原子表添加一个字符串 Al ...

  10. Codeforces Round #499 (Div. 2) Problem-A-Stages(水题纠错)

    CF链接  http://codeforces.com/contest/1011/problem/A Natasha is going to fly to Mars. She needs to bui ...