Using And Embedding JSPWiki

An Excellent Wiki Engine

Zed Builds and Bugs Manager is proud to incorporate our Wiki engine from JSPWiki, an open source Wiki that is built on Java Server Pages technology. As such, it fits right in with the rest of Zed Builds and Bugs, as it is written in Java and is hosted perfectly by our Jetty embedded HTTP Server.

JSPWiki brings a lot to the table that we think has been overlooked by some of the reviews of available Open Source Wiki's. It is fully UTF-8 enabled right out of the box, has support for a wide variety of markup features, and one of the best features (in our opinion) is the easy way that you can create custom plugins for JSPWiki.

Creating Custom Plugins

JSPWiki makes creating custom plugins a breeze by providing the com.ecyrd.jspwiki.plugin.WikiPlugin interface. There's only one method to implement in the interface and that's the execute(WikiContext, Map) method.

The Map parameter gives you a name/value map of each of the arguments that were supplied to the plugin invocation so that you can tailor the output of your plugin to user customization. There are some handy access methods that you'll want to create to help you to pick out the parameters with appropriate data type conversions. For example:

boolean getBooleanParam(Map params, String name, boolean default_value){
  String value = (String)params.get(name);
  if(value == null || value.length() == 0){
    return default_value;
  }
  if(value.compareToIgnoreCase("true") == 0){
    return true;
  } else {
    return false;
}
That makes it easy to deal with pulling boolean values out of the parameter Map, and supplying a default value so that the user doesn't have to specify the parameter if they just want to go with the default values.

The WikiContext parameter also has some nice little gems that are of great use. One of them that we take significant advantage of is the access to the RenderingManager that is provided by the WikiContext. Simply do this:

context.getEngine().getRenderingManager();
to get the RenderingManager object. Why? Well, specifically in our case we allow users to display task and bug information inside their wiki pages. Since we don't want the user's entering or editing the information in two separate places, we've provided a JSPWiki plugin that does this. By having access to the RenderingManager we can allow the users to write their task description using Wiki Markup and when displayed in the wiki it will be appropriately formatted.

We give the user's 2 options for displaying task descriptions in the wiki. They can have the task contents formatted as Wiki Markup, or as a code block. Here's the snippet that does this and shows how easy it is to utilize the RenderingManager to handle the Wiki Markup processing:

if(description_included){ // has the user asked for a task description to be included?
  if(style.compareToIgnoreCase("wiki") == 0){ // user wants to use wiki markup for their task display
    sb.append( context.getEngine().getRenderingManager().getHTML( context, t.description );
  } else if(style.compareToIgnoreCase("code") == 0){ // user wants the task displayed as code
    sb.append("<pre>\n").append( t.description ).append( "</pre>\n");
  } else {
    ...
  }
}

Embedding JSPWiki

Embedding JSPWiki was a little tricky to get right, but worked out very well for our setup. We provide a minimum of 2 wiki's for each installation. The first is the Zed documentation wiki (a version of which you can see live on our web site) which is always a single instance. The second and beyond correspond to the setup of Zed itself. Zed can support multiple teams, with each team having its own build/task/discussion database, and separate wiki. Depending on how many separate teams the administrator wants to support via a single Zed server, they'll also get the same number of wiki instances.

Each JSPWiki instance points to the same set of libraries, so that functionality is always consistent, but each gets its own configuration file that is copied dynamically from a standard template that we ship. We do simple replacement on the standard template before bringing it live, and we supply a standard set of content to get each team started with their own Wiki.

Going Beyond JSPWiki

Since the Zed server is the core application, which launches the Jetty HTTP listener, and the JSPWiki web application contexts it is also possible to do centralized user management, password authentication, and to tie JSPWiki back into the containing Zed application in the user's web browser.

The Zed server handles users, groups, authentication, etc. To tie JSPWiki into this central administration, it was enough to extend the com.ecyrd.jspwiki.auth.login.AbstractLoginModule class as such:

public boolean login() throws LoginException {
  // The user has already been authenticated on the thread currently serving this HTTP request
  // Look up their information, and set the JSPWiki principal information properly
  long tid = Thread.currentThread().getId();
  String session = ThreadSessions.getInstance().getThreadSession(tid);
  if(session == null){
    return false;
  }
  SessionInfo si = SessionList.getInstance().getSession( session );

  Principal principal = new WikiPrincipal( si.fullname, WikiPrincipal.FULL_NAME);

  m_principals.add( new PrincipalWrapper( principal ) );

  // Now indicate that this new principal is authenticated
  m_principals.add( Role.AUTHENTICATED );
  m_principals.add( Role.ALL );
 
  // If login succeeds, commit these roles
  m_principalsToOverwrite.add( WikiPrincipal.GUEST );
  m_principalsToOverwrite.add( Role.ANONYMOUS );
  m_principalsToOverwrite.add( Role.ASSERTED );

  // If login fails, remove these roles
  m_principalsToRemove.add( Role.AUTHENTICATED );

  return true;
}

With Zed, you also don't have to worry about installing Tomcat, Jetty, or another application server yourself and handling the configuration required. It's all centralized and contained within a single installation process. Once Zed is up and running, JSPWiki is available right inside the box.

We're very happy to include JSPWiki in the Zed installation, as it is a key part of our overall offering and provides a professional, enterprise wiki that can be used by your entire software team. It is very well put together, and very functional. We'll be contributing as much back to the JSPWiki community as we can to help it to stay at the top of its game.