plugin-dev-guide.html 15.4 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2

Matt Tucker's avatar
Matt Tucker committed
3 4
<html>
<head>
5 6
    <title>Jive Messenger Plugin Guide</title>
    <link href="style.css" rel="stylesheet" type="text/css">
Matt Tucker's avatar
Matt Tucker committed
7
</head>
8

Matt Tucker's avatar
Matt Tucker committed
9 10 11 12
<body>

<h1>Jive Messenger Plugin Developer Guide</h1>

13 14
<a name="top"></a>

Matt Tucker's avatar
Matt Tucker committed
15 16 17 18
<h2>Introduction</h2>

<p>
Plugins enhance the functionality of Jive Messenger. This document is a
19 20
developer's guide for creating plugins.
</p>
Matt Tucker's avatar
Matt Tucker committed
21 22 23

<h2>Structure of a Plugin</h2>

24
<p>
25
Plugins live in the <tt>plugins</tt> directory of <tt>messengerHome</tt>. When a plugin
Matt Tucker's avatar
Matt Tucker committed
26
is deployed as a JAR or WAR file, it is automatically expanded into a directory. The files in a
27
plugin directory are as follows:
28 29 30 31 32
</p>

<fieldset>
    <legend>Plugin Structure</legend>
<pre>myplugin/
33 34 35
 |- plugin.xml      &lt;- Plugin definition file
 |- readme.html     &lt;- Optional readme file for plugin, which will be displayed to end users
 |- changelog.html  &lt;- Optional changelog file for plugin, which will be displayed to end users
36 37
 |- icon_small.gif  &lt;- Optional small (16x16) icon associated with the plugin (can also be a .png file)
 |- icon_large.gif  &lt;- Optional large (32x32) icon associated with the plugin (can also be a .png file)
38 39 40
 |- classes/        &lt;- Resources your plugin needs (i.e., a properties file)
 |- lib/            &lt;- Libraries (JAR files) your plugin needs
 |- web             &lt;- Resources for Admin Console integration, if any
Matt Tucker's avatar
Matt Tucker committed
41
     |- WEB-INF/
42 43
         |- web.xml           &lt;- Generated web.xml containing compiled JSP entries
         |- web-custom.xml    &lt;- Optional user-defined web.xml for custom servlets
Matt Tucker's avatar
Matt Tucker committed
44
     |- images/
45 46 47
</pre>
</fieldset>

Matt Tucker's avatar
Matt Tucker committed
48 49
<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>
Matt Tucker's avatar
Matt Tucker committed
50

51
<p>
Matt Tucker's avatar
Matt Tucker committed
52 53
The <tt>plugin.xml</tt> file specifies the main Plugin class. A sample
file might look like the following:
54
</p>
Matt Tucker's avatar
Matt Tucker committed
55

56 57 58
<fieldset>
    <legend>Sample plugin.xml</legend>
<pre class="xml">
Matt Tucker's avatar
Matt Tucker committed
59 60
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plugin&gt;
61
    <span class="comment">&lt;!-- Main plugin class --&gt;</span>
Matt Tucker's avatar
Matt Tucker committed
62
    &lt;class&gt;org.example.ExamplePlugin&lt;/class&gt;
Matt Tucker's avatar
Matt Tucker committed
63

64 65 66 67 68
    <span class="comment">&lt;!-- Plugin meta-data --&gt;</span>
    &lt;name&gt;Example Plugin&lt;/name&gt;
    &lt;description&gt;This is an example plugin.&lt;/description&gt;
    &lt;author&gt;Jive Software&lt;/author&gt;
    &lt;version&gt;1.0&lt;/version&gt;
69 70 71
    &lt;date&gt;07/15/2005&lt;/date&gt;
    &lt;url&gt;http://www.jivesoftware.org/pluginX&lt;/url&gt;
    &lt;minServerVersion&gt;2.2.0&lt;/minServerVersion&gt;
Matt Tucker's avatar
Matt Tucker committed
72

73 74 75 76
    <span class="comment">&lt;!-- Admin console entries --&gt;</span>
    &lt;adminconsole&gt;
        <span class="comment">&lt;!-- More on this below --&gt;</span>
    &lt;/adminconsole&gt;
Matt Tucker's avatar
Matt Tucker committed
77 78
&lt;/plugin&gt;
</pre>
79 80
</fieldset>

81 82
<p>The meta-data fields that can be set in the plugin.xml file:

Matt Tucker's avatar
Matt Tucker committed
83
<ul>
84 85 86
    <li>name -- the name of the plugin.</li>
    <li>description -- the description of the plugin.</li>
    <li>author -- the author of the plugin.</li>
87
    <li>version -- the version of the plugin.</li>
88
    <li>date -- the date the plugin was released. The date must be in the form MM/dd/yyyy, such
89 90
          as 07/15/2005.</li>
    <li>url -- a URL where additional information about the plugin is available.</li>
91 92 93
    <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>
94
    <li>parentPlugin -- the name of the parent plugin (given as "foo" for the "foo.jar" plugin).
Matt Tucker's avatar
Matt Tucker committed
95 96
            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
97
            child plugin will not function without its parent present.</li>
Matt Tucker's avatar
Matt Tucker committed
98 99
</ul></p>

100 101 102 103 104
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>
105 106
    <li><tt>icon_small.png</tt> -- Optional small (16x16) icon associated with the plugin. It can also be a .gif file.</li>
    <li><tt>icon_large.png</tt> -- Optional large (32x32) icon associated with the plugin. It can also be a .gif file.</li>
107 108
</ul>

109 110
<p>Your plugin class must be implement the
<tt><a href="javadoc/org/jivesoftware/messenger/container/Plugin.html">Plugin</a></tt>
Matt Tucker's avatar
Matt Tucker committed
111
interface from the <a href="javadoc/index.html">Jive Messenger API</a> as
Matt Tucker's avatar
Matt Tucker committed
112
well as have a default (no argument) contructor. The Plugin interface has
113
methods for initializing and destroying the plugin.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
</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 {

131
    public void initializePlugin(PluginManager manager, File pluginDirectory) {
132 133 134
        <span class="comment">// Your code goes here</span>
    }

135
    public void destroyPlugin() {
136 137 138 139 140
        <span class="comment">// Your code goes here</span>
    }
}
</pre>
</fieldset>
Matt Tucker's avatar
Matt Tucker committed
141 142 143 144

<h2>Modifying the Admin Console</h2>

<p>Plugins can add tabs, sections, and pages to the admin console. There
Matt Tucker's avatar
Matt Tucker committed
145
are a several steps to accomplishing this:
Matt Tucker's avatar
Matt Tucker committed
146 147

<ul>
148 149 150 151 152 153 154 155 156 157 158 159 160
    <li>An &lt;adminconsole/&gt; 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>
Matt Tucker's avatar
Matt Tucker committed
161
</ul>
Matt Tucker's avatar
Matt Tucker committed
162

163
<p>The <tt>&lt;adminconsole /&gt;</tt> section of <tt>plugin.xml</tt> defines additional
Matt Tucker's avatar
Matt Tucker committed
164 165
tabs, sections and entries in the Admin Console framework. A sample
<tt>plugin.xml</tt> file might look like the following:</p>
Matt Tucker's avatar
Matt Tucker committed
166

167 168 169
<fieldset>
    <legend>Sample plugin.xml</legend>
<pre class="xml">
Matt Tucker's avatar
Matt Tucker committed
170 171
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plugin&gt;
172
    <span class="comment">&lt;!-- Main plugin class --&gt;</span>
Matt Tucker's avatar
Matt Tucker committed
173
    &lt;class&gt;org.example.ExamplePlugin&lt;/class&gt;
174 175 176 177 178 179 180 181 182 183 184

    <span class="comment">&lt;!-- Admin console entries --&gt;</span>
    &lt;adminconsole&gt;
        &lt;tab id="mytab" name="Example" url="my-plugin-admin.jsp" description="Click to manage..."&gt;
            &lt;sidebar id="mysidebar" name="My Plugin"&gt;
               &lt;item id="my-plugin" name="My Plugin Admin"
                   url="my-plugin-admin.jsp"
                   description="Click to administer settings for my plugin" /&gt;
            &lt;/sidebar&gt;
        &lt;/tab&gt;
    &lt;/adminconsole&gt;
Matt Tucker's avatar
Matt Tucker committed
185
&lt;/plugin&gt;
186 187
</pre>
</fieldset>
Matt Tucker's avatar
Matt Tucker committed
188

189 190 191
<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>
Matt Tucker's avatar
Matt Tucker committed
192 193
as the page. You can override existing tabs, sections, and items by using
the existing id attribute values in your own <tt>&lt;adminconsole&gt;</tt> defintion.
194 195
</p>

Matt Tucker's avatar
Matt Tucker committed
196 197 198 199 200 201 202 203
<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
204 205
            instead of creating your own. Only create new tabs for very
            significant new functionality.
Matt Tucker's avatar
Matt Tucker committed
206
		<li>Don't use the word "plugin" in names of tabs, sidebars and items.
207 208
            For example, instead of having an item called "Gateway Plugin", it
            could be called "Gateway Settings".
Matt Tucker's avatar
Matt Tucker committed
209 210 211
		<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
212 213
	        meta-data. Instead, let Jive Messenger inform the user about which
            plugins are installed and provide plugin management.
Matt Tucker's avatar
Matt Tucker committed
214
</ul>
Matt Tucker's avatar
Matt Tucker committed
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
<h3>Writing Pages for the Admin Console</h3>

<p>
Jive Messenger uses the <a href="http://www.opensymphony.com/sitemesh/" target="_blank">Sitemesh</a>
framework to decorate pages in the admin console. A globally-defined decorator is applied to
each page in order to render the final output, as in the following diagram:</p>
<br>
<div align="center"><img src="images/sitemesh.png" width="484" height="372" alt="Sitemesh"></div>
<br><br>
<p>
Creating pages that work with Sitemesh is easy. Simply create valid HTML pages and then
use meta tags to send instructions to Sitemesh. When rendering the output, Sitemesh will
use the instructions you provide to render the decorator along with any content in the
body of your HTML page. The following meta tags can be used:
<ul>
    <li><b>pageID</b> -- the ID of the page, which must match an entry in the admin console
    XML described above. Either a pageID or subPageID <b>must</b> be specified.</li>
    <li><b>subPageID</b> -- the ID of the sub-page, which must match an entry in the
    admin console XML described above. Sub-pages are used for administrative actions
    related to a parent page ID. For example, editing or deleting a particular group.
    Either a pageID or subPageID <b>must</b> be specified.</li>
    <li><b>extraParams</b> (Optional) -- extra parameters that should be passed in to the page.
    For example, on a page to delete a group it might be the ID of the group. Parameters
    must be URL encoded.</li>
    <li><b>decorator</b> (Optional) -- overrides the Sitemesh decorator to use for the page.
    A decorator named <tt>none</tt> is available that will simply render the page
    without a decorator.</li>
</ul>

The following HTML snippet demonstrates a valid page:
</p>

<fieldset>
    <legend>Sample HTML</legend>
<pre>
   &lt;html&gt;
   &lt;head&gt;
       &lt;title&gt;My Plugin Page&lt;/title&gt;
       &lt;meta name="pageID" content="myPluginPage"/&gt;
   &lt;/head&gt;
   &lt;body&gt;
        Body here!
   &lt;/body&gt;
   &lt;/html&gt;
</pre>
</fieldset>

263
<h2>Using the Jive Messenger Build Script</h2>
Matt Tucker's avatar
Matt Tucker committed
264

265
<p>
Matt Tucker's avatar
Matt Tucker committed
266 267
The Jive Messenger build script will help you build and develop plugins. It
looks for plugin development directories in the following format:
268 269
</p>

Matt Tucker's avatar
Matt Tucker committed
270 271 272
<fieldset>
    <legend>Plugin Structure</legend>
<pre>myplugin/
273 274 275
 |- plugin.xml      &lt;- Plugin definition file
 |- readme.html     &lt;- Optional readme file for plugin
 |- changelog.html  &lt;- Optional changelog file for plugin
276 277
 |- icon_small.gif  &lt;- Optional small (16x16) icon associated with the plugin (can also be a .png file)
 |- icon_large.gif  &lt;- Optional large (32x32) icon associated with the plugin (can also be a .png file)
278 279
 |- classes/        &lt;- Resources your plugin needs (i.e., a properties file)
 |- lib/            &lt;- Libraries your plugin needs
Matt Tucker's avatar
Matt Tucker committed
280
 |- src/
281
     |- java        &lt;- Java source code for your plugin
Matt Tucker's avatar
Matt Tucker committed
282 283 284 285 286 287
     |   |- com
     |       |- mycompany
     |           |- *.java
     |- web
         |- *.jsp      &lt;- JSPs your plugin uses for the admin console
         |- images/    &lt;- Any images your JSP pages need (optional)
288
         |- WEB-INF
Matt Tucker's avatar
Matt Tucker committed
289
             |- web.xml    &lt;- Optional file where custom servlets can be registered
Matt Tucker's avatar
Matt Tucker committed
290 291 292
</pre>
</fieldset>

Matt Tucker's avatar
Matt Tucker committed
293
<p>The build script will compile source files and JSPs and create a valid
Matt Tucker's avatar
Matt Tucker committed
294 295 296 297
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>

298 299
<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
300 301 302 303 304 305 306
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>
307

Matt Tucker's avatar
Matt Tucker committed
308 309
<h2>Implementing Your Plugin</h2>

Matt Tucker's avatar
Matt Tucker committed
310
<p>Plugins have full access to the Jive Messenger API. This provides a tremendous
Matt Tucker's avatar
Matt Tucker committed
311 312 313 314
amount of flexibility for what plugins can accomplish. However, there are several integration
points that are the most common:

<ol>
Matt Tucker's avatar
Matt Tucker committed
315 316 317 318 319
    <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
Matt Tucker's avatar
Matt Tucker committed
320
 example above); sub-domains are only used for routing within the XMPP server.
Matt Tucker's avatar
Matt Tucker committed
321

322
    <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
323
  namespace. The following code snippet demonstrates how to register an IQHandler:
Matt Tucker's avatar
Matt Tucker committed
324

325 326 327 328 329
  <pre>
  IQHandler myHandler = new MyIQHander();
  IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
  iqRouter.addHandler(myHandler);
  </pre>
Matt Tucker's avatar
Matt Tucker committed
330

331 332 333 334 335
    <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
336 337 338 339 340 341
    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.

Matt Tucker's avatar
Matt Tucker committed
342 343 344
</ol>

</p>
Matt Tucker's avatar
Matt Tucker committed
345

Matt Tucker's avatar
Matt Tucker committed
346 347 348 349 350 351 352 353
<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>
Matt Tucker's avatar
Matt Tucker committed
354
<p>Because Jive Messenger is released under the Open Source GPL license, any plugins developed
Matt Tucker's avatar
Matt Tucker committed
355 356 357 358
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>
Matt Tucker's avatar
Matt Tucker committed
359

360 361
<br><br>

Matt Tucker's avatar
Matt Tucker committed
362 363
</body>
</html>