This guide serves as a tool to help developers customize and extend Jive Forums. Topics covered include creating custom UI's (skins), and integrating Jive Forums with your existing authentication and user systems.

Table of Contents


Overview and Architecture

Jive Forums ArchitectureJive Forums has a complete and rich API for manipulating forum content. The following is a broad overview of the major components in the system:

Skin: The skin is the front-end to the system, usually written in JSP (the default skin uses Webwork). The skin is responsible for calling the Jive Forums API and displaying the results to users in HTML (or in another format). The default skin includes many features that can be configured through the admin tool, so most developers find that making small changes to the default skin will suffice. If larger UI or feature changes are required, a totally new skin can be created.

Filters: Filters dynamically reformat the contents of messages to provide additional functionality. For example, the URL filter turns any URL that a user types in a message into a clickable link. Another filter syntax highlights Java source code. Filters are applied dynamically, and any number of custom filters can be created and installed.

Core API: The core API provides all the business logic for creating, manipulating, and displaying forum content. It is discussed further below.

Backend: A database is used to store all data. Authentication and user and group storage is pluggable so that alternate backends can be used for that functionality such as LDAP or custom database tables.

Using the API

The Javadocs provide the best reference for programming with the core API. As a start, almost all programming with Jive Forums will look like the following:

// Use the AuthFactory to attempt to login the user. If login
// works, an Auth token is returned. In this case, we use the
// AuthToken method that takes a username and password as arguments.
// Another method takes servlet request and response objects instead, which
// can be used for single sign-on support.
AuthToken auth = null;
try {
    auth = AuthFactory.getAuthToken(username, password);
}
catch (UnauthorizedException) {
    // Logging in the user with the given username and password failed. In this
    // case, we'll use the anonymous login method instead. Instead, you
    // might display a dialog to the end user saying that login failed.
    auth = AuthFactory.getAnonymousAuthToken();
} 
// Now, use the AuthToken token to get a ForumFactory instance. The
// ForumFactory class is the main gateway into the rest of the Jive Forums
// API. The auth token we pass in will determine which methods
// we're allowed to call.
ForumFactory factory = ForumFactory.getInstance(auth);
 // ... all other logic goes here.

Security

Security through permissions checking is implemented in Jive Forums at the method-level via methods that throw an UnauthorizedException. In this case, users that call the method without proper permissions will generate the exception.

Protection Proxy For example, a user can only set the name of a forum if they've been granted "forum administrator" or higher permission on it. In the image at right, two users are shown trying to call the "getName" and "setName" methods. The "Bob" user is not a forum administrator, so calling the Forum.setName(String) method fails and throws an UnauthorizedException.

This functionality is implemented using the protection proxy pattern (see the GOF pattern book). Proxy objects are transparently created when needed using the Authorization token that is passed in when getting an AuthorizationFactory instance. This design allows for powerful permission checking while still being an easy system for developers to use.

Permission checking is also implemented in all Iterators in the system. For example, a user is only allowed to get a handle on a Forum object if they have read permission on it. So, the ForumFactory.forums() method will only return an Iterator for the forums that a user has read permission for. This means you'll seldom need to do explicit permission checking in your custom code.

Extended Properties

Extended properties are used to store additional data about objects. Almost all major objects in Jive Forums can have extended properties, including categories, forums, threads, messages, attachments, users, and groups. Each object type with extended property support includes the following methods:

As an example, a feature in the default skin allows you to track the IP addresses of users that make posts. A code snippet to do this might look like the following:

    // Use the JSP "request" object to get the IP.
    String IPAddress = request.getRemoteAddr();
    // Assume we've created a message object already. 
    message.setProperty("IP", IPAddress);

Extended properties are also useful for storing extra information about users such as their homepage, favorite color, etc.

You can use a ResultFilter to get lists of objects with particular values for extended properties. For example, using the "IP" extended property of messages, you could show all messages in a forum posted from a certain IP address. Methods in the ResultFilter class related to extended properties are:

A list of extended properties used internally by Jive Forums can be seen here.

Internationalization (i18n)

This section describes how to localize your Jive Forums installation. Internationalization is the process of changing the format of dates and numbers to obey rules unique to your region and translating user-interface text to your language. For example the number 1,234.00 is an English locale would be formatted as 1.234,00 in the locale for France. Similarily, user-interface text like "Your Name" in English would be translated to "Ihr Name" for German locales.

Character Encoding

The character encoding affects what languages users will be able to post messages in. The default of "ISO-8859-1" is suitable for Western languages, but won't work for Eastern languages such as Chinese or Japanese. For sites that want to support a broad variety of languages, we recommend using "UTF-8" (Unicode) as your character encoding. You can change the encoding used by Jive Forums inside the admin tool.

Your database must support the character encoding that you choose. Specifically, many database must be specially configured to support Unicode. Although MySQL doesn't normally support Unicode, you can use a JDBC driver workaround by adding the following to the <database> section of jive_startup.xml:

<mysql>
    <useUnicode>true</useUnicode>
</mysql>

If you're not a MySQL user, consult your database documentation for information about enabling Unicode support in your database.

Translating the Jive Forums Interface

All text in the Jive Forums default skin is stored in resource bundles. A resource bundle is a file containing key/value pairs. The default skin loads text using keys and the correct values are retrieved based on locale settings (English values are used for English locales, French values for French locales, etc). Key/value pairs in the English resource bundle might look like the following:

    skin.yes=Yes
    skin.no=No
    skin.topic=Topic
    skin.message=Message

The German resource bundle would contain the same keys, but different values:

    skin.yes=Ja
    skin.no=Nein
    skin.topic=Thema
    skin.message=Beitrag

Making your own translation involves copying the English resource bundle, renaming the file, then translating its contents.

To start, extract the "jive_forums_i18n.properties" file from the jiveforums.jar file, which is part of the Jive Forums distribution. To extract the file, use the "jar" tool (part of the standard Java distribution):

    jar -xf jiveforums.jar jive_forums_i18n.properties

Next, you'll need to rename the file to be specific to your locale. For example, the German resource bundle is named "jive_forums_i18n_de.properties" because "de" is the language code for German. For French, the file would be called "jive_forums_i18n_fr.properties". A list of language codes can be found at: http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt.

International Characters

When translating from English, you may need to use special characters for you language (for example, Germans use characters like ä, ü, or ß). Unfortunately, all resource bundle files must be saved in ASCII format which doesn't allow for many international characters. It's recommended you work on your translation in a text editor that supports all characters in your language. After finishing your translation, use the "native2ascii" tool (built in to Java) to convert international characters to the ASCII format. Here's how you use the native2ascii tool:

    native2ascii -encoding XXX my_translation.properties jive_forums_i18n_YY.properties
                               ^                         ^
                               input file                output file

The "-encoding XXX" parameter is optional. If you don't specify it, Java will use the default encoding value, taken from System property "file.encoding". If you do specify an encoding (XXX), it must be taken from the first column of the table of supported encodings in the Supported Encodings document.

Testing Your Translation

To test your translation, the first step is to have a working Jive Forums installation. Save your translated file (example, jive_forums_i18n_de.properties) to your Jive Forums webapp WEB-INF/classes directory. (If you do not have Jive Forums installed as a webapp, your properties file must be in the appserver's classpath.) Next, restart your appserver then log-in to the Jive Forums admin tool. Click the tab "Global Settings" then choose "Locale Settings" from the sidebar. Under the "Change Locale Settings" section, scroll through the list of available locales until you see your language. For example, to test the German resource bundle, you should choose any of the locales starting with "German". Save your settings then load up the default skin. If you see all user interface buttons, column headers, etc, translated to your language then you've correctly loaded your resource bundle. If you still see English text you may have named your bundle incorrectly or your appserver wasn't able to load it.

Authentication and User Database Integration

By default, Jive Forums uses its own database to perform authentication and store user data. Jive Forums Silver also includes a module that can use LDAP for authentication and accessing user data. You can configure Jive Forums to perform authentication and load user data from any other external system by implementing a few of the Jive Forums interfaces.

Authentication

The Jive Forums interfaces com.jivesoftware.base.AuthFactory and com.jivesoftware.base.AuthToken must be implemented to provide custom authentication. AuthFactory has the following methods to override:

The default skin will attempt to authenticate by:

  1. Checking for an existing AuthToken object in the user's session. If one is not found, go to the next step.
  2. Authenticating via the createAuthToken(request, response) method. This check allows single sign-on to work. If this check fails, go to the next step.
  3. At this point, it's assumed the user is a guest so create an anonymous auth token.

Using the login form in the default skin will peform authentication using the createAuthToken(username, password) method and then store the resulting AuthToken in the user's session.

The following classes provide a sample implementation of AuthFactory and AuthToken that authenticate via an external user database, and leave the auto-login functionality as-is:

CustomAuthFactory.java
CustomAuthToken.java

Once you've created and compiled your custom authentication classes, you should put them in a JAR file and then add the JAR to the classpath of the Jive Forums web-application, for example by adding it to the WEB-INF/lib directory. Next, you must tell Jive Forums to use your custom AuthFactory class by adding a Jive Property in the Admin Tool > System > Jive Properties. The property name is "AuthFactory.className" and the value is the name of your custom AuthFactory class. For example, set "AuthFactory.className to "com.foo.CustomAuthFactory" (without the quotes).

User Database

The Jive Forums interfaces com.jivesoftware.base.UserManager and com.jivesoftware.base.User can be implemented to provide a way to integrate with existing user stores. Any user data store that can be accessed programmatically in Java can be integrated with Jive Forums. This includes relational databases via the JDBC API, directory services such as LDAP, or custom stores that are accessible via a Java API.

When integrating with an external user database, consider the following:

  1. Your implementation of User should also implement com.jivesoftware.util.Cacheable. This is because user data is cached within Jive Forums by default to improve performance. The Cacheable interface requires that you implement one method, getCachedSize(), which needs to return the size of the the object graph (the object and all member objects) in bytes. You can look at the SimpleUserAdapter class below for how to handle the cache size calculation. In fact if you use this and don't add any fields, you can use it as is.
  2. External databases generally have pre-existing access tools and patterns that define the business rules around the modification of the data. Jive Software considers it a best practice to configure external databases as read-only databases and to continue to use the existing rules create, delete, and modify user data in the external database. Generally the following methods of UserManager will remain unimplemented:
    • createUser(String username, String password, String email)
    • createUser(String username, String password, String name, String email, boolean nameVisible, boolean emailVisible, Map properties)
    • deleteUser(User user)
    This also should incldue any "set" methods in the User interface that corresponds to a field in the external database.
  3. If password information is maintained in the external database you should not implement any function that sets or gets password data. In such cases, you will also be implementing custom authentication.
  4. In addition, other utility functions such as int getUserCount() and Iterator users() need not be implemented if the external database does not provide this information. Instead, they can return 0 or empty iterators. This data will then not be viewable in the default administration skin.
  5. Jive Forums requires that all users can be identified by a unique numeric userID as well as a unique username. Your external user systems may not have both. In that case, you'll need to first identify the unique identifier in your database, or "primary key". For example, if your user database only has a unique username (and not ID), all lookups into your database will need to use that field. Because Jive Forums also needs to be able to do a user lookup based on ID, you'll need to create a mapping table between username and ID. We recommend using the standard jiveUser database table to store this mapping. The com.jivesoftware.base.database.sequence.SequenceManager class can be used to generate unique ID's that are suitable for this mapping table. If you do not have a String to use as a username, simply use the String representation of your numeric ID as the username.
  6. Always strive to minimize redundant data. For example, if the external database maintains first name and last name information, this should not also be maintained within Jive Forums.
  7. Any event which modifies internal Jive Forums data should also trigger a com.jivesoftware.base.event.UserEvent so that Jive Forums's event listener architecture is fully integrated.

Any unimplemented function should throw an UnsupportedOperationException.

The following classes provide a sample implementation of UserManager and User that returns id, username, name and email data from an external database table and accesses that table in a read-only manner:

CustomUserManager.java
CustomUser.java

The CustomUser class extends the com.jivesoftware.base.ext.SimpleUserAdapater class, which simplifies User integrations.

As in the custom authentication case, you should put them in a JAR file and then add the JAR to the classpath of the Jive Forums web-application after you've created and compiled your custom user classes. You must tell Jive Forums to use your custom UserManager class by adding a Jive Property in the Admin Tool > System > Jive Properties. The property name is "UserManager.className" and the value is the name of your custom UserManager class. For example, set "UserManager.className" to "com.foo.CustomUserManager" (without the quotes).

Custom Auth, User and Group Debugging

Sometimes it is necessary to turn on verbose debugging inside of the Jive Forums application. This is especially useful if you're using custom auth, user or group implementations. The Jive Forums LDAP module (Silver only) also has a fair amount of debug messages available. To enable this, turn on debug messages via the Log viewer in the admin tool (you'll need to restart the appserver for this to take effect). It is only recommended you run this in a debug or test environment because there can be quite a large amount of debug generated and might impact performance.

Once debug messages are enabled watch the jive.debug.log - it should detail steps its going through as well as any errors it may run into.

Finally, you may wish to additionally implement the IntrospectiveUser and IntrospectiveUserManager interfaces (which extend User and UserManager), as they allow for richer functionality by users of the interfaces.