Differences between revisions 6 and 7
Revision 6 as of 2006-04-04 10:32:05
Size: 6931
Comment: No such method as setConfiguration, its setUserConfig
Revision 7 as of 2009-09-20 23:52:35
Size: 6927
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
[wiki:ApiRequirements API requirements] are document [wiki:ApiRequirements elsewhere] and referenced from this page. [[ApiRequirements|API requirements]] are document [[ApiRequirements|elsewhere]] and referenced from this page.
Line 37: Line 37:
||D8||The Fop constructors will be deprecated. In a future release, Fop.java can be changed to an interface. (Optional. See [http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200602.mbox/%3c43E86C88.2050308@ptc.com%3e here])|| ||D8||The Fop constructors will be deprecated. In a future release, Fop.java can be changed to an interface. (Optional. See [[http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200602.mbox/%3c43E86C88.2050308@ptc.com%3e|here]])||

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

Requirements

API requirements are document elsewhere and referenced from this page.

Principles

  • Hard requirements are met
  • Nothing stands in the way to implement wishlist items
  • Static variables should not be used. Static initialization code should only be used to initialize constants.
  • Full backwards compatibility will be preserved for the next beta release but some methods will be deprecated. For the release after the next the deprecated methods will be removed.

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.

Design

D1

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.

D2

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.

D3

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.)

D4

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

D5

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

D6

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

D7

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.

D8

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

D9

Fop instances shall not be reused for multiple rendering runs.

D10

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.

D11

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.

D12

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

D13

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

D14

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

D15

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

  • RendererOverride

  • FO!EventHandlerOverride

  • Metadata such as:
    • Producer
    • Creator
    • CreationDate

    • Author
    • Title
    • Keywords
  • BaseURL
  • URIResolver
  • PDF!EncryptionParams

  • OutputFile

  • TargetResolution

Moved from FOUserAgent to FopFactory

  • AdditionalElementMappings

  • StrictValidation

  • BreakIndentInheritanceOnReferenceAreaBoundary

  • LayoutManagerMakerOverride

  • XML configuration
  • Font Base URL
  • SourceResolution

  • Default Page Width/Height
  • RendererFactory

  • XML!HandlerFactory

Addendum B

  • ElementMappings moved from FO!TreeBuilder

  • Image cache from static variable in ImageFactory

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 java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
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 {
    out.close();
}

Open Items

  • The feedback mechanism described in HR8 (see ApiRequirements) is not specified, yet. This will be done separately. The feedback mechanism will be located in FO!UserAgent.

  • As part of adding support for PDF/A-1, support for XMP Metadata will be added. This will be located in FO!UserAgent.

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