1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Jive Messenger Plugin Guide</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Jive Messenger Plugin Developer Guide</h1>
<a name="top"></a>
<h2>Introduction</h2>
<p>
Plugins enhance the functionality of Jive Messenger. This document is a
developer's guide for creating plugins.
</p>
<h2>Structure of a Plugin</h2>
<p>
Plugins live in the <tt>plugins</tt> directory of <tt>messengerHome</tt>. When a plugin
is deployed as a JAR or WAR file, it is automatically expanded into a directory. The files in a
plugin directory are as follows:
</p>
<fieldset>
<legend>Plugin Structure</legend>
<pre>myplugin/
|- plugin.xml <- Plugin definition file
|- readme.html <- Optional readme file for plugin, which will be displayed to end users
|- changelog.html <- Optional changelog file for plugin, which will be displayed to end users
|- icon_small.gif <- Optional small (16x16) icon associated with the plugin
|- icon_large.gif <- Optional large (32x32) icon associated with the plugin
|- classes/ <- Resources your plugin needs (i.e., a properties file)
|- lib/ <- Libraries (JAR files) your plugin needs
|- web <- Resources for Admin Console integration, if any
|- WEB-INF/
|- web.xml <- Generated web.xml containing compiled JSP entries
|- web-custom.xml <- Optional user-defined web.xml for custom servlets
|- images/
</pre>
</fieldset>
<p>The <tt>web</tt> directory exists for plugins that need to add content
to the Jive Messenger Admin Console. Further details are below.</p>
<p>
The <tt>plugin.xml</tt> file specifies the main Plugin class. A sample
file might look like the following:
</p>
<fieldset>
<legend>Sample plugin.xml</legend>
<pre class="xml">
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<span class="comment"><!-- Main plugin class --></span>
<class>org.example.ExamplePlugin</class>
<span class="comment"><!-- Plugin meta-data --></span>
<name>Example Plugin</name>
<description>This is an example plugin.</description>
<author>Jive Software</author>
<version>1.0</version>
<date>07/15/2005</date>
<url>http://www.jivesoftware.org/pluginX</url>
<minServerVersion>2.2.0</minServerVersion>
<span class="comment"><!-- Admin console entries --></span>
<adminconsole>
<span class="comment"><!-- More on this below --></span>
</adminconsole>
</plugin>
</pre>
</fieldset>
<p>The meta-data fields that can be set in the plugin.xml file:
<ul>
<li>name -- the name of the plugin.</li>
<li>description -- the description of the plugin.</li>
<li>author -- the author of the plugin.</li>
<li>version -- the version of the plugin.</li>
<li>date -- the date the plugin was released. The date must be in the form MM/dd/yyyy, such
as 07/15/2005.</li>
<li>url -- a URL where additional information about the plugin is available.</li>
<li>minServerVersion -- the minimum version of Jive Messenger required
to run the plugin (supported by Jive Messenger 2.1.2 and later). If the
server version is less than the required value, the plugin will not be started.</li>
<li>parentPlugin -- the name of the parent plugin (given as "foo" for the "foo.jar" plugin).
When a plugin has a parent plugin, the parent plugin's class loader will be used instead
of creating a new class loader. This lets plugins work together more closely. A
child plugin will not function without its parent present.</li>
</ul></p>
Several additional files can be present in the plugin to provide additional information to
end-users (all placed in the main plugin directory):
<ul>
<li><tt>readme.html</tt> -- Optional readme file for plugin, which will be displayed to end users.</li>
<li><tt>changelog.html</tt> -- Optional changelog file for plugin, which will be displayed to end users.</li>
<li><tt>icon_small.gif</tt> -- Optional small (16x16) icon associated with the plugin.</li>
<li><tt>icon_large.gif</tt> -- Optional large (32x32) icon associated with the plugin.</li>
</ul>
<p>Your plugin class must be implement the
<tt><a href="javadoc/org/jivesoftware/messenger/container/Plugin.html">Plugin</a></tt>
interface from the <a href="javadoc/index.html">Jive Messenger API</a> as
well as have a default (no argument) contructor. The Plugin interface has
methods for initializing and destroying the plugin.
</p>
<fieldset>
<legend>Sample plugin implementation</legend>
<pre class="java">
package org.example;
import org.jivesoftware.messenger.container.Plugin;
import org.jivesoftware.messenger.container.PluginManager;
import java.io.File;
/**
* A sample plugin for Jive Messenger.
*/
public class ExamplePlugin implements Plugin {
public void initialize(PluginManager manager, File pluginDirectory) {
<span class="comment">// Your code goes here</span>
}
public void destroy() {
<span class="comment">// Your code goes here</span>
}
}
</pre>
</fieldset>
<h2>Modifying the Admin Console</h2>
<p>Plugins can add tabs, sections, and pages to the admin console. There
are a several steps to accomplishing this:
<ul>
<li>An <adminconsole/> section must be added to the
<tt>plugin.xml</tt> file.
</li>
<li>JSP files must be compiled and put into the classpath of the
plugin. A <tt>web.xml</tt> file containing the compiled JSP
servlet entries must be put into the <tt>web/</tt> directory
of the plugin. <i>Note:</i> the Jive Messenger build script
can assist with compiling JSPs and creating the web.xml. This
is detailed below.
</li>
<li>Any images required by your JSP pages must live in <tt>web/images/</tt>
directory. Only GIF and PNG images are supported.
</li>
</ul>
<p>The <tt><adminconsole /></tt> section of <tt>plugin.xml</tt> defines additional
tabs, sections and entries in the Admin Console framework. A sample
<tt>plugin.xml</tt> file might look like the following:</p>
<fieldset>
<legend>Sample plugin.xml</legend>
<pre class="xml">
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<span class="comment"><!-- Main plugin class --></span>
<class>org.example.ExamplePlugin</class>
<span class="comment"><!-- Admin console entries --></span>
<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>
</pre>
</fieldset>
<p>
In this example, we've defined a new tab "Example", a sidebar section
"My Plugin" and a page "My Plugin Admin". We've registered <tt>my-plugin-admin.jsp</tt>
as the page. You can override existing tabs, sections, and items by using
the existing id attribute values in your own <tt><adminconsole></tt> defintion.
</p>
<h3>Admin Console Best Practices</h3>
There are several best practices to consider when making changes to
the Jive Messenger admin console via a plugin. The general theme is
that plugins should integrate seamlessly:
<ul>
<li>Integrate into existing tabs and sidebar sections whenever possible
instead of creating your own. Only create new tabs for very
significant new functionality.
<li>Don't use the word "plugin" in names of tabs, sidebars and items.
For example, instead of having an item called "Gateway Plugin", it
could be called "Gateway Settings".
<li>Try to match the UI of the existing admin console in your custom
plugin pages.
<li>There is no need to create an admin console entry to show plugin
meta-data. Instead, let Jive Messenger inform the user about which
plugins are installed and provide plugin management.
</ul>
<h2>Using the Jive Messenger Build Script</h2>
<p>
The Jive Messenger build script will help you build and develop plugins. It
looks for plugin development directories in the following format:
</p>
<fieldset>
<legend>Plugin Structure</legend>
<pre>myplugin/
|- plugin.xml <- Plugin definition file
|- readme.html <- Optional readme file for plugin
|- changelog.html <- Optional changelog file for plugin
|- icon_small.gif <- Optional small (16x16) icon associated with the plugin
|- icon_large.gif <- Optional large (32x32) icon associated with the plugin
|- classes/ <- Resources your plugin needs (i.e., a properties file)
|- lib/ <- Libraries your plugin needs
|- src/
|- java <- Java source code for your plugin
| |- com
| |- mycompany
| |- *.java
|- web
|- *.jsp <- JSPs your plugin uses for the admin console
|- images/ <- Any images your JSP pages need (optional)
|- WEB-INF
|- web.xml <- Optional file where custom servlets can be registered
</pre>
</fieldset>
<p>The build script will compile source files and JSPs and create a valid
plugin structure and JAR file. Put your plugin directories in the <tt>src/plugins</tt>
directory of the source distribution and then use <tt>ant plugins</tt> to
build your plugins.</p>
<p>Any JAR files your plugin needs during compilation should be put
into the <tt>lib</tt> directory. These JAR files will also be copied into
the plugin's generated <tt>lib</tt> directory as part of the build process.</p>
<p>If you create a src/web/WEB-INF/web.xml file, any servlets registered there
will be initialized when the plugin starts up. Only servlet registrations and servlet
mappings will be honored from the web.xml file. Note: this feature is implemented by
merging your custom web.xml file into the web.xml file generated by the JSP compilation
process.</p>
<h2>Implementing Your Plugin</h2>
<p>Plugins have full access to the Jive Messenger API. This provides a tremendous
amount of flexibility for what plugins can accomplish. However, there are several integration
points that are the most common:
<ol>
<li>Register a plugin as a <a href="javadoc/org/jivesoftware/messenger/Component.html">Component</a>.
Components receive all packets addressed to a particular sub-domain. For example,
<tt>test_component.example.com</tt>. So, a packet sent to <tt>joe@test_component.example.com</tt> would
be delivered to the component. Note that the sub-domains defined as components are unrelated to DNS entries
for sub-domains. All XMPP routing at the socket level is done using the primary server domain (example.com in the
example above); sub-domains are only used for routing within the XMPP server.
<li>Register a plugin as an <a href="javadoc/org/jivesoftware/messenger/IQHandler.html">IQHandler</a>. IQ handlers respond to IQ packets with a particular element name and
namespace. The following code snippet demonstrates how to register an IQHandler:
<pre>
IQHandler myHandler = new MyIQHander();
IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
iqRouter.addHandler(myHandler);
</pre>
<li>Register a plugin as a <a href="javadoc/org/jivesoftware/messenger/interceptor/PacketInterceptor.html">
PacketInterceptor</a> to receive all packets being sent through the system and
optionally reject them. For example, an interceptor could reject all messages that contained
profanity or flag them for review by an administrator.</li>
<li>You can store persistent plugin settings as Jive Messenger properties using the
JiveGlobals.getProperty(String) and JiveGlobals.setProperty(String, String) methods. Make
your plugin a property listener to listen for changes to its properties by implementing the
<tt>org.jivesoftware.messenger.event.PropertyEventListener</tt> method.
You can register your plugin as a listener using the PropertyEventDispatcher.addListener(PropertyEventListener)
method. Be sure to unregister your plugin as a listener in your plugin's destroyPlugin() method.
</ol>
</p>
<h2>Plugin FAQ</h2>
<b>Can I deploy a plugin as a directory instead of a JAR?</b>
<p>No, all plugins must be deployed as JAR or WAR files. When a JAR or WAR is not present for the plugin,
Jive Messenger assumes that the file has been deleted and that the users wants to destroy the plugin,
so it also deletes the directory.</p>
<b>What license agreement are plugins subject to?</b>
<p>Because Jive Messenger is released under the Open Source GPL license, any plugins developed
must also be released under the GPL or a compatible Open Source license. It is a
violation of the license agreement to create plugins that are not Open Source. Please visit
<a href="http://www.jivesoftware.com/products/messenger/">Jive Software</a> if you need different
licensing terms for Jive Messenger, including the right to create commercial plugins.</p>
<br><br>
</body>
</html>