This page describes the design of Apache FOP's API.


API requirements are document elsewhere and referenced from this page.


Current Status

The Fop class is a one-use class which provides access to the receiving SAX DefaultHandler and the FormattingResults. Arguments to the constructor are the MIME type for the desired output format and an instance of FO!UserAgent.

Main problem

Currently, a lot of initialization code is repeated for each rendering run. Furthermore, reusable objects are instantiated in every rendering run. This means that there is room for optimization. Another symptom is the fact the the image cache is bound to a static variable.

The other problem is that we finally need to finalize the API before the first production release. The current API does not meet all the ApiRequirements.

The idea

Separate an environment/factory class from the FO!UserAgent that holds references to all information (cfg, caches) that should be reused over multiple rendering runs and is responsible for instantiating classes to handle individual rendering runs.



A new class FopFactory is created. It holds references to configuration items that usually don't change between rendering runs and to cached items that can be reused by multiple rendering runs.


FopFactory has protected constructors and a public static newInstance() just like the JAXP TransformerFactory which might, in the future, enable replacing the factory class if desired. Primarily however, this is done to improve similarity to JAXP so people feel at home with the construct. People are free to construct a singleton instance of the FopFactory if they desire so.


FO!UserAgent receives a constructor that has as its sole parameter an instance of FopFactory. (for use by FopFactory. User should instantiate FOUserAgent through FopFactory.)


FO!UserAgent's default constructor automatically instantiates a new FopFactory class. (deprecated, for backwards temporary backwards compatibility)


The FO!UserAgent can return the FopFactory instance. (needed internally by FOP)


FopFactory receives a newFO!UserAgent() method that creates a new FO!UserAgent instance with defaults set from the XML configuration if available.


FopFactory receives the following methods to create Fop instances: newFop(String outputFormat), newFop(String outputFormat, FO!UserAgent userAgent) and newFop(FO!UserAgent). The last method is an addition for the case where a custom FO!EventHandler or Renderer is set on the FO!UserAgent and the specification of an outputFormat will be misleading as this value may not be used at all. It will be an error to omit the outputFormat and to forget setting an overriding FO!EventHandler/Renderer.


The Fop constructors will be deprecated. In a future release, can be changed to an interface. (Optional. See here)


Fop instances shall not be reused for multiple rendering runs.


FO!UserAgent instances can be reused for multiple rendering runs if the future facilities for rendering run feedback are not used. Reusing FO!UserAgent instances will be discouraged, however.


For temporary backwards-compatibility, FO!UserAgent will be rewritten to retrieve the values formerly held in FO!UserAgent from FopFactory. The methods involved will be deprecated.


The XML configuration will primarily contain settings for FopFactory but also provide defaults for the FO!UserAgent.


The splitting of settings between FopFactory and FO!UserAgent is listed below in addendum A.


Items held by and moved to FopFactory in addition to D11 above are listed in addendum B.


The FO!UserAgent should not contain any renderer-specific values (like the PDF encryption parameters). Instead the existing renderer options Map (see get!RendererOptions()) should be used, i.e. setPDF!EncryptionParams() will be deprecated.

Addendum A

Remaining in FOUserAgent

Moved from FOUserAgent to FopFactory

Addendum B

Example of API Usage after the Changes

FopFactory fopFactory = FopFactory.newInstance();
fopFactory.setUserConfig(new File("C:/FOP/fop.xconf"));

FOUserAgent userAgent = fopFactory.newFOUserAgent();
userAgent.setTitle("My document");

// Setup output
OutputStream out = new;
out = new;
try {

    // Construct fop with desired output format
    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out);

    // Setup XSLT
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
    // Set the value of a <param> in the stylesheet
    transformer.setParameter("versionParam", "2.0");

    // Setup input for XSLT transformation
    Source src = new StreamSource(xmlfile);

    // Resulting SAX events (the generated FO) must be piped through to FOP
    Result res = new SAXResult(fop.getDefaultHandler());

    // Start XSLT transformation and FOP processing
    transformer.transform(src, res);

    FormattingResults results = fop.getResults();
    System.out.println("Generated " + results.getPageCount() + " pages.");
} finally {

Open Items

ApiDesign (last edited 2009-09-20 23:52:35 by localhost)