This page briefly describes the main components of the JCopist core module.
The template manager is responsible for the storage of the document templates used by the server. It is invoked when a new template is added, or when another component needs to use an existing template.
There is currently only one available implementation, which stores the unzipped content of the templates on the file system. However, new template managers can be developed by implementing the net.sf.jcopist.templates.ITemplateManager interface (for instance, templates could be stored in a relational database).
A builder merges a template with the dynamic data supplied by a client, in order to produce an OpenDocument.
More precisely, the builder requests the template's data from the template manager, copies it in a temporary directory, runs FreeMarker on some of the files, and re-zips the directory's content.
Builders are obtained through the builder manager , which manages an internal pool of builders.
A converter converts the OpenDocument created by the builder to the format requested by the user.
This is where OpenOffice.org comes into play, as we need a running instance to perform the conversion. Therefore, there is a one-one relationship between converters and OpenOffice.org instances : a converter launches an soffice.bin process when it is created, and monitors this process throughout its lifetime (try killing an soffice.bin process while JCopist is running, it will be re-spawned).
Converters are obtained through the converter manager , which manages two internal pools of converters: one for synchronous jobs, and one for asynchronous jobs. The reason to have to separate pools is to avoid contention between the two types of jobs.
A sender is used to send the generated document to its final destination (senders are only used in asynchronous mode). The client specifies which senders to use and how to configure them by adding transport instances to the submitted job.
Senders are obtained through the sender manager . As senders do not maintain an internal state, they need not be pooled. Therefore, the sender manager dynamically instantiates the sender(s) corresponding to the transport(s) requested by the client.
Whether in synchronous or asynchronous mode, the way to process a job is the same. It is implemented in the net.sf.jcopist.process.impl.DocumentManager class that dipatch jobs to the needed module :
There is not much more in the synchronous service than what's described above. Once the final document is generated, it is directly returned to the client. The synchronnous jobs are handled by net.sf.jcopist.service.impl.RealtimeServiceHelper .
The asynchronous mode uses a few more components, as submitted jobs need to be queued.
An embedded HSQL database is used to store waiting and failed Jobs. The net.sf.jcopist.process.impl.DocumentManager is used to queue the jobs. It uses an internal pool of threads to process the jobs from the queue; these threads dispatch jobs in the required server modules ( builder, converter, sender).
Note that, in order to provide fault-tolerance, each job is stored in the database when it enters the queue ; the persisted job is deleted only when it has been entirely processed or if the database has been re-initialized. Therefore, if the server crashes, all pending jobs can be recovered.