Active development of JAMWiki has ceased, and bug fixes and support will be limited at best. If you are interested in taking over management of JAMWiki please send an email to the jamwiki-devel mailing list.

Tech:JAMWiki Design

ktip.png Please contribute to the JAMWiki project by helping to improve this article. Add to or expand some of the existing information, fix an error, or share your own knowledge to improve this subject! Don't worry about making mistakes - there will always be someone who can correct any errors later.

Disclaimer: The moment documentation is written it usually becomes outdated. This document attempts to provide an overview of some aspects of the design, but it may not be a 100% accurate description of the current code. Any and all contributors are encouraged to fix errors and make additions to this guideline - don't worry about making mistakes, as there will always be someone else who can correct inaccuracies.



The JAMWiki design philosophy follows that of many other open-source projects: keep it as simple as possible, but no simpler. Wherever possible standards and open-source libraries are utilized, including the following:

  • JDK 1.4 (and higher).
  • J2EE servlet 2.4 (and higher).
  • JSTL.
  • The Spring Framework. Used as a framework for handling servlet flow.
  • Acegi Security. Provides the infrastructure for user authentication and management.
  • The HSQL database. For users who choose not to utilize a third-party database, an internal version of HSQL is used.
  • Apache Lucene Search engine. Provides the wiki search functionality.
  • Apache Commons Libraries. Utilized for file upload processing, IO handling, database connection pooling, and other functionality.
  • ehcache. Provides a mechanism for caching data structures to improve performance.
  • java-diff. An implementation of the diff algorithm in Java.
  • JFlex Parser. Used to generate the default wiki parser.
  • JUnit. A unit-testing framework.
  • Maven. A framework for organizing and building projects.

Request Processing

The activity flow for requests is handled as follows:

  1. A request is received by the application server and is passed to the application.
  2. Within the web.xml file, filters have been defined indicating that requests for each virtual wiki should be passed to the Spring DispatcherServlet.
  3. The DispatcherServlet configuration is defined in jamwiki-servlet.xml. This file contains patterns and their handlers. For example, the pattern "Special:RecentChanges" is handled by the RecentChangesServlet.
  4. Each servlet extends JAMWikiServlet, which itself extends the Spring AbstractController servlet. The handleJAMWikiRequest() method of each servlet will be called (indirectly) from the Spring DispatcherServlet to handle each servlet request.
  5. After processing the request, the servlet will return and will eventually redirect to wiki.jsp for display. That JSP file acts as a gatekeeper to all JAMWiki JSP files, and loads the appropriate JSP for display based on configuration values passed in a PageInfo object that is initialized from the parent servlet. The PageInfo.contentJsp field will contain the name of the JSP file that is to be loaded.
  6. The appropriate JSP file is loaded, and the generated HTML is sent back to the requesting browser for display.

In addition to the steps above, the Acegi framework implements filters that may intercept requests based on security settings (defined in the applicationContext-acegi-security.xml file), and the JAMWikiFilter may also intercept requests to set content-type values or if an upgrade is detected.

Data Model

Here is a first relation diagram. It's not an ERD, it shows dependencies.

  --------- Environment -----     <------- Utilities
  ^            ^            ^                  ^
  |            |            |                  |
UserHandler  DataHandler  SearchEngine        /
      ^        ^              ^              /
       \       |              |             /
----------    ----------------------
|Category |   | VirtualWiki        |
| |-id    |   |  |-name            |
| |-name  |   |  |-defaulTopicName |
----------|   ----------------------
  |m            |1
  |             |
  |m            |m
--Topic-------------        -- TopicVersion ----
| |-id             |        |  |-id            |
| |-name           |        |  |-editDate      |
| |-type           |        |  |-author        |
| |-redirectTo     |        |  |-ipAddress     |
| |-content        | 1---m  |  |-editComment   |
| |-currentVersion |        |  |-editType      |
| |-adminOnly      |        |  |-versionContent|
| |-readOnly       |        --------------------
| |-deleteDate     |
| |-topicContent   |
| |-id                 |
| |-username           |
| |-displayName        |
| |-lastLoginDate      |
| |-lastLoginIpAddress |
| |-defaultLocale      |
| |-createIpAddress    |
| |-createDate         |
| |-description |


Topics can be categorized in categories and these categories can have one parent category.
RecentChange contains aggregated info from Topic and 2 TopicVersion.
A role is a permission that is granted to a user or group, such as ROLE_EDIT or ROLE_DELETE.
A role map is a link between a role object and either a user or a group.
General topic information like name.
Version of one topic.
VirtualWikis allow for the creation of separate wiki instances running within the same web application. Virtual wikis share users, but recent changes, topics, and other key wiki objects are unique within a virtual wiki.
A watchlist provides a mapping between a user and topics that the user wants to track changes to.
A WikiDiff is the internal representation of a single difference between two versions of a topic. If multiple sections of a topic have changed then multiple WikiDiff objects would be used to represent the full difference.
WikiFile has reference to uploaded file.
WikiFileVersion represents a version of an uploaded file. Uploading multiple copies of a file with the same name will produce multiple WikiFileVersions.
A WikiGroup is an internal data structure currently used only to represent logged-in or anonymous users.
WikiImage has reference to uploaded image.
Connection between 2 Topics where one topic citate another one.
WikiUser contains wiki-specific user details.
WikiUserInfo contains user information that might also be stored in an external directory system such as user name or email.


Class Diagrams


  • The following diagram highlights the singletons in the class hierarchy as of Revision: 1521.

jamwiki ingletons.PNG

  • There are six different types of nodes in the diagram above:
Red Singleton A class for which there should only be one instance in the entire system at any given time. This program detects singletons which enforce their own singularity, which means they keep one static instance of themselves and pass it around through a static getter method.
Orange Hingleton Derived from "helper singleton," a class which turns another class into a singleton by enforcing that class's singularity.
Yellow Mingleton Derived from "method singleton" a class which has any static method that returns some state without taking any parameters.
Green Fingleton Derived from "field singleton," a class which contains a public static field.
Lt Blue Other Any class which is directly dependent on a _ingleton.
Blue - Displays statistics about the current codebase. Is only drawn if the banner option (-b) is passed as a command line argument.