forrest-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ross Gardler <>
Subject Re: [RT] A new Forrest implementation?
Date Fri, 18 Aug 2006 01:17:07 GMT
Ross Gardler wrote:
> This is a Random Thought. The ideas contained within are not fully
> developed and are bound to have lots of holes. The idea is to promote
> healthy discussion, so please, everyone, dive in and discuss.

In order to better support my position in this RT I've been 
experimenting with alternative implementations.

I now have a working (although very hacky) version of a new Forrest 
Core. It is *very* basic right now so don't get too excited, I'm only 
trying to feed the flames of this discussion. The deployed webapp 
version is 960kb, this includes the test code and sample documents. Add 
the size of Xalan and Xerces for the CLI version.

Clearly this will grow as we add some of the missing features (see 
below). Spring, ehcache and an RE processor are probably the largest 
additional dependencies we need in core and they weighs in at a few 
hundred Kb each (I think).

In other words, it looks like I can deliver in just a few megabytes.

What is does have:

- XHTML2 as internal format

- Locationmap support

- plugin architecture

- XSLT transformations

- CLI interface (very basic no link following)

- Webapp interface

- File and HTTP readers

What it doesn't have:

- Container managed components

- pattern matching in the Locationmap or in the output plugin selection

- handling of aggregated documents - they work on the input side, but 
I'm still considering how best to handle them on the output side.

- external config files (i.e. the locationmap and available plugins are 
currently hard coded data structures)

- image (and other binary files) handling

- cacheing

- optimisation (i.e. no SAX stream between the individual components)

- adequate demos (a couple of Hello World input plugins and Gavs XHTML2 
sample document only)

- loads of stuff I haven't thought of yet


It's really simple (honest), the processing goes like this:

request URI (to controller)
   -> source documents(s)  (from readers)
     -> internal document(s)  (from input plugins)
       -> output document        (from output plugins)

The main componets are:

This is the interface point between the application (CLI,  webapp, or 
JUnit tests so far). To use it you do somethin like:

requestURI = new URI(TestController.TEST_REQUEST_URI);
Controller controller = new Controller();
AbstractOutputDocument doc = controller.getOutputDocument(requestURI);

A simple lookup table mapping the requestURI to the required source 
document(s) - it supports optional files and aggregation.

A locationmap is built as follows (remember this should be read from a 
config file):

URI requestURI = new URI(TestController.TEST_REQUEST_URI);
location = new Location(requestURI, this.getClass().getResource(
locationMap.put(requestURI, location);
location = new Location(requestURI, this.getClass().getResource(
         TestController.SOURCE_DOCUMENT_XHTML2_SIMPLE), true);
locationMap.put(requestURI, location);

Then you get the locations(s) with:

List<Location> locations = locationMap.get(requestURI);

Given the URL of a source document this factory returns the correct 
reader for the document. For example "" will return an 
HTTPReader whilst "file://bar" will return a file reader.

Reads a source document and infers the type of document it is (XML, 
image etc. although only XML is supported right now). This returns a 
typed document class representing the document by using a DocumentFactory.

This is perhaps the most complicated part of the system. It is roughly 
equivalent to the source resolver, that is, it infers the type of 
document we are working with. Once it knows the type of document it can 
provide a typed document object.

If we have a mime-type that gives us enough information it will use that 
(i.e. an OOo document). If not it will try looking ahead into the 
contents of the file until it has enough info. For example:

while ((numRead = != -1 && mimeType == null) {
   String readData = String.valueOf(buf, 0, numRead);
   buf = new char[1024];
   if (fileData.toString().contains("<?xml")) {
         String type = getXMLDocumentType(fileData.toString());
	doc = new XMLSourceDocument(fileData.toString(), reader);

Given a typed source document this factory provides an InputPlugin to 
convert from the source document to an internal XHTML2 document.

Given one or more internal documents and a request URI this factory 
provides an OutputPlugin for producing the final document as requested.

What Next?

- make the locationmap load from an XML file

- use a component manager and configure plugins from the containers 
config files (rather than building the config in code)

- handle aggregation on the output side (I'd like to discuss how to 
handle this if anyone is interested in helping out, but we must be aware 
that this is still an RT and we are only exploring ideas not committing 
the community to anything)

- create a documentation/test site

- build a number of input and output plugins for testing, such as:
	- OOo Input
         - RDBMS Input
	- PDF Output
	- RTF Output

- experiment with cocoon integration as a plugin (I *really* like this 
idea it seems to cover most of the drawbacks Tim has identified in my 
ideas, although I'd like to hear what Tim thinks about this)

- decide if we should continue experimenting along this line.


View raw message