介绍
插件加强了Openfire的功能,这篇文档指导开发者如何创建一个插件。
插件的结构
插件位于openfireHome目录下的plugins目录中,当一个插件以一个JAR或者WAR文件部署时,他会被自动的解压。一个插件的目录结构如下所示:
myplugin/ |- plugin.xml <- 插件的声明文件 |- readme.html <- 可选 插件的自述文件,可以展示给使用用户 |- changelog.html <- 可选 插件的更新日志,可以展示给使用用户 |- logo_small.gif <- 可选 插件的小图标(16x16) (也可以是png文件) |- logo_large.gif <- 可选 插件的大图标(32x32) (也可以是png文件) |- classes/ <- 插件的资源文件(即class文件或properties文件) |- database/ <- 可选 插件需要的数据库脚本 |- i18n/ <- 可选 插件国际化所需要的i18n文件 |- lib/ <- 插件所需要的lib文件 (JAR files) |- web <- Admin集成所需要的资源 |- WEB-INF/ |- web.xml <- 生成的web.xml文件,包括编译后的JSP实例 |- web-custom.xml <- 可选 用户定义的web.xml,包含定制的servlets |- images/
如果插件需要在Openfire的控制台添加页面,则需要创建web目录。下面将详细进行描述。
plugin.xml指定了插件的主类,示例如下:
<?xml version="1.0" encoding="UTF-8"?> <plugin> <!-- Main plugin class --> <class>org.example.ExamplePlugin</class> <!-- Plugin meta-data --> <name>Example Plugin</name> <description>This is an example plugin.</description> <author>Jive Software</author> <version>1.0</version> <date>07/01/2006</date> <url>http://www.igniterealtime.org/projects/openfire/plugins.jsp</url> <minServerVersion>3.0.0</minServerVersion> <licenseType>gpl</licenseType> <!-- Admin console entries --> <adminconsole> <!-- More on this below --> </adminconsole> </plugin>
plugin.xml文件中的元数据包括:
- name — 插件的名称
- description — 插件的描述
- author — 插件的作者
- version — 插件的版本
- date — 插件发布的日期,日期的格式必须是MM/dd/yyyy,比如07/01/2006
- url — 关于该插件更多信息的地址
- minServerVersion — 允许该插件最小的Openfire版本号(从Openfile 2.1.2版本开始支持),如果Openfire的版本号比需要的小,则插件不会被启动
-
databaseKey — 如果插件需要自己的数据库表,databaseKey将被用于数据库脚本的名称(通常与插件名称相同)。可被支持的数据库脚本文件需要放置在 database目录下。例如,给定的databaseKey为foo,脚本文件可以为“foo_mysql.sql”、 “foo_oracle.sql”等。我们建议表名增加前缀“of”,避免与其他应用使用的表名产生冲突。databaseKey可以作为 ofVersion表的一条记录的key,这样脚本的版本信息可以被跟踪,例如:
1
INSERT INTO ofVersion (name, version) VALUES ('foo', 0);
-
databaseVersion — 数据库脚本的版本(如果使用数据库脚本的话)。一个新插件的数据库脚本文本从0开始。如果将来该插件的数据库脚本需要更新,则这些更新可以在 database/upgrade子目录下定义。例如,目录database/upgrade/1和database/upgrade/2都可以包含脚本 foo_myslq.sql和foo_oracle.sql,这些脚本中包含每个版本相关联的数据库修改。每个脚本都会更新ofVersion表中的版本 信息。
1
UPDATE ofVersion set version=1 where name='foo';
- parentPlugin — 父插件的名称(对于foo.jar插件可以使用名称foo)。当一个插件有一个父插件,父插件的类加载器将被直接使用,而不需要创建一个新的类加载器。这将让插件能更紧密的合作。没有父插件的配合,子插件将不能正常使用。
-
licenseType — 指明该插件使用的许可协议,有效的值有:
- commercial:该插件是在商业许可协议下发布的
- gpl:该插件是在GNU公共许可协议下(GPL)发布的
- apache:该插件是在Apache协议下发布的
- internal:该插件只能用于组织内部,且不允许扩散
- other:该插件的发布许可协议不包含在上述列表中,详情可见插件中的自述文件
如果许可类型没有指定,则会被设置为other。
插件中的几个附加文件可为最终的使用用户提供额外的信息(这些文件都位于插件的根目录):
- readme.html — 可选 插件的自述文件,将展现给最终用户
- changelog.html — 可选 插件的更新李日,将展现给最终用户
- logo_small.png — 可选 插件的小图标(16×16),也可以是.gif文件
- logo_large.png — 可选 插件的大图标(32×32),也可以是.gif文件
插件类必须实现Plugin接口,他有一个默认的构造方法(无参数)。Plugin接口有方法用于初始化和销毁插件。
package org.example; import org.jivesoftware.openfire.container.Plugin; import org.jivesoftware.openfire.container.PluginManager; import java.io.File; /** * A sample plugin for Openfire. */ public class ExamplePlugin implements Plugin { public void initializePlugin(PluginManager manager, File pluginDirectory) { // Your code goes here } public void destroyPlugin() { // Your code goes here } }
插件开发的最优方法
当选择一个包名作为你的插件名称时,我们推荐你选择对你或者你的组织来说有特色的名称,这将尽可能的避免可能的冲突。例如,所有人都是用org.example.PluginName,即使PluginName不同,你可能会碰到类名冲突的问题,特别是在集群运行时。
配置管理后台
插件可以在管理后台添加Tab标签、片段和页面,通过下面的几个步骤可以完成配置:
- 在plugin.xml文件中添加<adminconsole/>
- JSP文件必须已被编译,且添加到插件的classpath中。web.xml文件中包含被编译的JSP servlet实体,且被放置在插件的web目录下。注意:Openfile的build脚本可以完成JSP文件的编译和web.xml文件的创建,下面 将会详细描述。
- JSP页面中所需要的图片都必须放置在web/images/目录下,且只允许为GIF何PNG文件。
plugin.xml文件中的<adminconsole/>片段用于在管理后台框架中添加一个Tab标签、片段和页面。示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<!-- Main plugin class -->
<class>org.example.ExamplePlugin</class>
<!-- Admin console entries -->
<adminconsole>
<tab id="mytab" name="Example" url="my-plugin-admin.jsp" description="Click to manage...">
<sidebar id="mysidebar" name="My Plugin">
<item id="my-plugin" name="My Plugin Admin"
url="my-plugin-admin.jsp"
description="Click to administer settings for my plugin" />
</sidebar>
</tab>
</adminconsole>
</plugin>
在示例中,我们定义了一个新Tab标签“Example”,一个工具条片段“My Plugin”和一个页面“My Plugin Admin”。我们同样注册了一个页面my-plugin-admin.jsp。你可以重写一个已经存在的Tab标签,片段和页面,通过在中使用已经存在的id。
管理后台最优方法
当通过插件对Openfile的管理后台有所调整时,这里有几条最优方法可供参考。通用主题可以使插件无缝的集成:
- 尽可能的集成到已经存在的Tab标签或者左侧导航,而不是创建自己的。只有在提供重大新功能时才创建新的Tab。
- 不要在Tab标签、左侧导航中中使用“plugin”字样,例如使用“Gateway Settings”,而不是“Gateway Plugin”。
- 在你定制的插件页面中,尽可能的匹配已经存在的管理后台的UI。
- 没有必要创建一个入口来展示插件的元数据信息,而是让用户直接使用Openfire提供的功能,了解哪些插件已被安装并对这些插件进行管理。
创建管理后台页面
Openfire使用Sitemesh框架来管理后台的页面。一个全局定义的状态被应用到各个页面中,用于渲染最终的输出,如下图:
使用Sitemesh创建创建一个页面很简单。先创建一个HTML页面,然后使用meta标签将指令传递给Sitemesh框架。在渲染输出时,Sitemesh将使用你提供的指令来渲染HTML页面中body标签中的所有内容。下面的meta标签可被使用:
- pageID — 页面的ID,他必须符合上述的管理后台的XML条目,pageID和subPageID必须被指定。
- subPageID — 子页面的ID,他必须符合上述的管理后台的XML条目。子页面用于具体的功能操作,他与父页面ID相关联。例如,编辑或删除一个组。pageID或者subPageID必须被指定。
- extraParams(可选)– 需要传递给页面的额外参数。例如,在一个页面中删除一个分组,那么分组的ID需要传递给该页面。所有的参数必须是做了URL encoded编码的。
- decorator(可选)– 为该页面重写Sitemesh装饰者。一个名为为none的装饰者将被用于渲染页面。
下面的HTML片段展示了一个有效的页面:
<html> <head> <title>My Plugin Page</title> <meta name="pageID" content="myPluginPage"/> </head> <body> Body here! </body> </html> |
在插件中使用i18n
如果想把你的插件翻译成多种语言,可以使用下面的步骤:
- 在插件的根目录下创建“i18n”目录
- 按照 %[plugin_name]%_i18n_language.properties 的命名规范来添加资源文件,[plugin_name]使用插件的目录名。
-
在JSP文件中使用国际化的key来代替确切的文本,例如:
1 2 3 4
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> ... <fmt:message key="some.key.name" />
-
在Java类中需要国际化的文本可以使用LocalUtils类:
1
org.jivesoftware.util.LocaleUtils.getLocalizedString("some.key.name", "[plugin_name]");
-
在plugin.xml中需要国际化的文本使用${var}格式:
1 2
<sidebar id="gateways" name="${plugin.sidebar.name}" description="${plugin.sidebar.description}"> <description>${plugin.description}</description>
使用Openfire的Build脚本
Openfire提供的build脚本可以帮助你编译和开发插件。脚本按照下面的目录结构寻找资源:
myplugin/
|- plugin.xml <- 插件描述文件 |- readme.html <- 插件自述文件 |- changelog.html <- 插件更新日志 |- logo_small.gif <- 插件小图标 |- logo_large.gif <- 插件大图标 |- classes/ <- 插件的类和properties文件 |- lib/ <- 插件需要的lib库 |- src/ |- database <- 插件的数据库脚本 |- java <- 插件的Java源码 | |- com | |- mycompany | |- *.java |- web |- *.jsp <- 插件用于管理后台的JSP页面 |- images/ <- JSP页面中需要的图片文件 |- WEB-INF |- web.xml <- 当JSP被编译成servlet后,将在该文件中注册
build脚本将编译源码和JSP文件,并且按照插件的结构创建一个JAR文件。将你的插件目录拷贝到src/plugins目录下,然后使用命令 ant plugins 就可以编译你的插件了,但是这种方式会编译你所有的插件,如果需要编译一个单独的插件可以这样做:
在bulid目录下添加文件:build.properties内容如下:
packaged.plugin.name=broadcast
然后build.xml文件中加入加入以下target:
<target name="build.one.plugin" description="build one plugin"> <mkdir dir="${plugin.dest.dir}"/> <delete dir="${plugin.dev.dest.dir}/${packaged.plugin.name}"/> <delete file="${plugin.dev.dest.dir}/${packaged.plugin.name}.jar"/> <delete file="${plugin.dest.dir}/${packaged.plugin.name}.jar"/> <echo>building plugin ${packaged.plugin.name} ..</echo> <buildplugin plugin="${packaged.plugin.name}" pluginsrc="${plugin.src.dir}"/> <delete dir="${target.openfireHome}/plugins/${packaged.plugin.name}"/> <delete file="${target.openfireHome}/plugins/${packaged.plugin.name}.jar"/> <copy file="${plugin.dest.dir}/${packaged.plugin.name}.jar" todir="${target.openfireHome}/plugins" overwrite="true"/> </target>
<target name="build.more.plugin" description="build more plugin"> <foreach target="build.one.plugin" param="packaged.plugin.name" list="${packaged.plugin.name}" delimiter=";"> </foreach> </target>
你的插件所需要的所有JAR文件需要放到lib目录下。在编译过程中,这些JAR文件同样会被复制到插件的lib目录下。
如果你创建了一个src/web/WEB-INF/web.xml文件,当插件启动时,注册其中的servlet将被初始化。只有web.xml中注册和 映射的servlet将被认可。注意:此功能是通过JSP编译过程中所生成的web.xml文件合并到自定义的web.xml文件实现的。
实现你自己的插件
插件可以使用所有的Openfire API,这为插件的功能提供了极大的灵活性。下面有几种最常用的集成方式:
- 注册一个插件作为一个组件。组件可以接收发送给特定子域的所有数据包。例如,test_component.example.com,发送给 joe@test_component.example.com的数据包将被分发到该组件。注意:组件中定义的子域与DNS的子域是无关的。所有的 XMPP路由在socket级别已经通过使用主服务器域名完成路由(如example.com),子域名只用于XMPP服务器内部路由。
-
注册一个插件作为IQHandler,IQ处理器在特定的命名空间内相应IQ数据包,下面的代码片段展示如何注册一个IQHandler:
1 2 3
IQHandler myHandler = new MyIQHander(); IQRouter iqRouter = XMPPServer.getInstance().getIQRouter(); iqRouter.addHandler(myHandler);
- 注册一个插件作为PacketInterceptor,用于接收所有的数据包,并且可以随意的抛弃他们。例如,一个拦截器可以抛弃所有包含禁词的消息,或者标记他们让管理员进行审核。
- 你可以持久化存储插件的设置,通过使用JiveGlobals.getProperty(String)和 JiveGlobals.setProperty(String,String)方法,作为Openfire的属性。通过实现 org.jivesoftware.util.PropertyEventListener的方法,使你的插件可以监听他的属性值的变化。你可以使用 PropertyEventDispatcher.addListener(PropertyEventListener)方法注册你的插件作为一个监听器。务必在插件的destroyPlugin方法中注销你的插件。
常见问题
我可以使用一个目录而不是JAR文件来部署插件吗?
不可以,所有的插件必须使用JAR或者WAR文件来部署。当plugin目录下的JAR或者WAR文件不存在时,Openfire会认为该文件已经被删除用户期望卸载该插件,然后会同步删除对应的目录。
相关推荐
以下是对Openfire插件开发核心概念的详细解释: 1. **插件结构**: 插件的基本结构包括一个包含所有必要组件的文件夹。其中,`plugin.xml`是定义插件的关键文件,`readme.html`和`changelog.html`是供用户查看的...
总结来说,Openfire 插件开发的关键在于理解 `plugin.xml` 文件的结构和内容,以及如何组织和编写 Java 类以实现所需功能。通过熟练掌握这些知识,开发者可以轻松地扩展 Openfire 的功能,满足特定的业务需求。从...
在"openfire_plugin"这个压缩包中,我们很可能会找到一系列与Openfire插件开发相关的源代码文件。这些文件通常包含以下几个部分: 1. **主类(Main Class)**:这是插件的核心部分,负责加载和初始化插件。它继承自...
#### 六、Openfire插件开发指南 ##### 6.1 插件开发目的 - 提升服务器功能。 - 支持定制化需求。 ##### 6.2 开发流程 - **目录结构**:定义插件文件夹及文件组织方式。 - **配置文件**:`plugin.xml`用于配置...
这些类的设计便于开发者理解和使用Openfire的插件系统来扩展功能,而无需修改源代码,降低了开发的复杂性和维护的难度。 Openfire的插件机制允许开发者在不改动核心代码的基础上为服务器添加新功能,这样可以在不...
对于开发者来说,OpenFire提供了API和插件开发框架,可以利用它们开发自定义的功能。通过API,可以实现与OpenFire的服务器端交互,如用户管理、消息发送等。OpenFire的插件开发允许你扩展服务器功能,例如集成其他...
在Openfire插件开发中,Servlet插件主要用于处理HTTP相关的请求,如提供Web服务接口、实现RESTful API等。 Openfire中的Servlet插件可以被配置成监听特定的URL路径,当接收到对应的HTTP请求时,插件将被调用执行...
- **插件开发**:了解如何编写和打包Openfire插件,以及如何通过`plugin.xml`文件定义插件行为。 - **分布式缓存**:通过Coherence的使用,可能涉及数据缓存策略和高可用性设计。 - **数据库集成**:与数据库的...
Openfire是一款开源、基于XMPP协议的实时协作服务器,它提供了强大的聊天、会议以及...通过深入研究这个源代码,开发者不仅可以学习到Openfire插件开发的技巧,还能了解到如何将实时通信技术应用于物联网设备的控制。
### OpenFire二次开发环境搭建详解 #### 一、概述 OpenFire是一款开源的企业级即时通讯服务器,基于XMPP协议标准,适用于多种应用场景。对于开发者来说,掌握如何搭建OpenFire的二次开发环境至关重要,这不仅有助...
"document"文件夹可能包含的是关于Spark、Smack和Openfire的开发指南、API文档、配置教程等。这些文档详细解释了如何安装、配置和使用这些工具,以及如何解决常见问题。对于初学者来说,这些文档是学习和掌握IM系统...
开发过程中,可以利用Eclipse的插件开发工具,如POM.xml配置,以及调试和测试功能。 3. **数据库迁移至MySQL** 默认情况下,Openfire使用HSQLDB作为内置数据库。如果需要使用MySQL,需要修改Openfire的数据库连接...
在提供的文件名"openfire_online"中,可能包含的是插件的源代码、配置文件或者安装指南等资源。根据具体的内容,你可以通过阅读文档、编译源码或按照指示进行安装,以实现Openfire的在线用户统计功能。如果你是...
**Openfire数据库架构指南** Openfire是一款开源的即时通讯服务器,它基于XMPP协议,用于构建实时通信系统。本文将深入探讨Openfire的数据库架构,包括其设计原理、表结构和字段含义,以便理解Openfire如何存储和...
- **插件开发**: 开发自定义插件以增加新功能或改进现有功能。 - **性能优化**: 根据实际应用场景对服务器进行调优,提高性能。 #### 八、常见问题及解决方法 在部署和开发过程中可能会遇到一些问题,例如编译...
《OpenFire深入浅出》这本书是关于开源即时通讯服务器OpenFire的权威指南,它涵盖了OpenFire的各个方面,从基础安装到高级配置,旨在帮助读者全面理解并熟练掌握OpenFire的使用和管理。OpenFire是一款基于Java开发的...
7. **spark+openfire插件开发(RTX类似的组织架构).mht**:这个文档可能涉及如何创建类似RTX(企业即时通讯工具)的组织架构功能的插件。 8. **install4j打包Spark详解.mht**:install4j是一个跨平台的应用程序打包...
- **内容**:包括Openfire的安装指南、配置指南以及最重要的Javadoc文档。 ##### 4. src目录 - **概述**:存放Openfire核心代码的目录,是开发者进行源代码研究的重点区域。 - **内容**:主要关注Java文件夹,其中...
API文档中可能包含插件开发指南,包括如何创建、部署和调用插件API,以及如何处理事件和集成其他服务。 5. **安全性**:Openfire API可能涵盖安全相关的接口,如加密通信、权限控制、安全设置等。开发者需要理解...
3. **可扩展性**:Openfire的插件架构使其易于扩展,开发者可以通过编写插件来增加新功能,如视频通话、会议、多语言支持等。 4. **管理员工具**:Openfire提供了一个Web界面,管理员可以通过浏览器轻松管理用户、...