diff options
Diffstat (limited to 'src/documentation/content/xdocs/0.20.5/embedding.xml')
-rw-r--r-- | src/documentation/content/xdocs/0.20.5/embedding.xml | 521 |
1 files changed, 0 insertions, 521 deletions
diff --git a/src/documentation/content/xdocs/0.20.5/embedding.xml b/src/documentation/content/xdocs/0.20.5/embedding.xml deleted file mode 100644 index e3cff158a..000000000 --- a/src/documentation/content/xdocs/0.20.5/embedding.xml +++ /dev/null @@ -1,521 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!-- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<!-- $Id$ --> -<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" - "http://svn.apache.org/viewvc/forrest/trunk/main/webapp/resources/schema/dtd/document-v12.dtd?view=co"> - - -<!-- Embedding FOP --> -<document> - <header> - <title>FOP: Embedding</title> - <subtitle>How to Embed FOP in a Java application</subtitle> - <version>$Revision$</version> - </header> - - <body> - <section id="overview"> - <title>Overview</title> - <p>Review <link href="running.html">Running FOP</link> for important information that applies to embedded applications as well as command-line use, such as options and performance. - </p> - <p>To embed FOP in your application, instantiate org.apache.fop.apps.Driver. - Once this class is - instantiated, methods are called to set the - Renderer to use - and the OutputStream to use to output the results of the - rendering (where applicable). In the case of the Renderer and - ElementMapping(s), the Driver may be supplied either with the - object itself, or the name of the class, in which case Driver will - instantiate the class itself. The advantage of the latter is it - enables runtime determination of Renderer and ElementMapping(s). - </p> - </section> - <section id="basics"> - <title>Basics</title> - <p>The simplest way to use Driver is to instantiate it with the - InputSource and OutputStream, then set the renderer desired and - call the run method. - </p> - <p>Here is an example use of Driver which outputs PDF: - </p> - <source><![CDATA[ -import org.apache.fop.apps.Driver; - -/*..*/ - -Driver driver = new Driver(new InputSource(args[0]), - new FileOutputStream(args[1])); -driver.setRenderer(Driver.RENDER_PDF); -driver.run();]]></source> - <p> -In the example above, args[0] contains the path to an XSL-FO file, while -args[1] contains a path for the target PDF file. - </p> - <section id="basic-logging"> - <title>Logging</title> - <p> - You also need to set up logging. Global logging for all FOP - processes is managed by MessageHandler. Per-instance logging - is handled by Driver. You want to set both using an implementation - of org.apache.avalon.framework.logger.Logger. See - <jump href="#logging">below</jump> for more information. - </p> - <p> - Call <code>setLogger(Logger)</code> always immediately after - instantiating the Driver object. See here: - </p> - <source><![CDATA[ -import org.apache.avalon.framework.logger.Logger; -import org.apache.avalon.framework.logger.ConsoleLogger; - -/*..*/ - -Driver driver = new Driver(); -Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); -MessageHandler.setScreenLogger(logger); -driver.setLogger(logger);]]></source> - </section> - - <section id="basic-logging-new-version"> - <title>Logging (Upcoming FOP 1.0 Version only)</title> - <p> - Logging is handled automatically via Jakarta Commons-Logging, which uses - JDK logging by default. No special driver configuration is needed. - For specialized configuration of Commons-Logging (e.g. to use a - different logger or to change logging levels), please see the - <fork href="http://jakarta.apache.org/commons/logging/">Jakarta Commons-Logging</fork> - site. - </p> - </section> - - <section id="render"> - <title>Processing XSL-FO</title> - <p> - Once the Driver is set up, one of the <code>render()</code> methods - is called. Depending on whether DOM or an InputSource is being used, the - invocation of the method is either <code>render(Document)</code> or - <code>render(Parser, InputSource)</code> respectively. - </p> - <p> - <strong>Another possibility may be used to build the FO Tree: You can - call <code>getContentHandler()</code> and fire the SAX events yourself. - </strong> - You don't have to call <code>run()</code> or <code>render()</code> on the - Driver object if you use <code>getContentHandler()</code>. - </p> - <p>Here is an example use of Driver:</p> - <source><![CDATA[ -Driver driver = new Driver(); -//Setup logging here: driver.setLogger(... -driver.setRenderer(Driver.RENDER_PDF); -driver.setInputSource(new FileInputSource(args[0])); -driver.setOutputStream(new FileOutputStream(args[1])); -driver.run();]]></source> - </section> - - <section id="render-with-xslt"> - <title>Processing XSL-FO generated from XML+XSLT</title> - <p> - If you want to process XSL-FO generated from XML using XSLT we recommend - using standard JAXP to do the XSLT part and piping the generated SAX - events directly through to FOP. Here's how this would look like: - </p> - <source><![CDATA[ -Driver driver = new Driver(); -//Setup logging here: driver.setLogger(... -driver.setRenderer(Driver.RENDER_PDF); - -//Setup the OutputStream for FOP -driver.setOutputStream(new java.io.FileOutputStream(outFile)); - -//Make sure the XSL transformation's result is piped through to FOP -Result res = new SAXResult(driver.getContentHandler()); - -//Setup XML input -Source src = new StreamSource(xmlFile); - -//Setup Transformer -Source xsltSrc = new StreamSource(xslFile); -TransformerFactory transformerFactory = TransformerFactory.newInstance(); -Transformer transformer = transformerFactory.newTransformer(xsltSrc); - -//Start the transformation and rendering process -transformer.transform(src, res);]]></source> - <note>There's no need to call <code>run()</code> or <code>render()</code>.</note> - <p> - This may look complicated at first, but it's really just the combination of an - XSL transformation and a FOP run. It's also easy to comment out the FOP part - for debugging purposes, for example when you're tracking down a bug in your - stylesheet. You can easily write the XSL-FO output from the XSL transformation - to a file to check if that part generates the expected output. - </p> - <p> - For fully working examples of the above and hints to some interesting - possibilities, see the <link href="#examples">examples section</link> below. - </p> - </section> - </section> - <section id="logging"> - <title>Controlling logging</title> - <p> - Current FOP 0.20.x production uses the - <fork href="http://avalon.apache.org/framework/api/org/apache/avalon/framework/logger/package-summary.html">Logger package</fork> - from Apache Avalon Framework to do logging. See the - <fork href="http://avalon.apache.org/framework/">Apache Avalon Framework</fork> - for more information. - </p> - <p> - Per default FOP uses the SimpleLog which logs to System.out. If you want to do logging using a - logging framework (such as LogKit, Log4J or JDK 1.4 Logging) you can set a - different Logger implementation on the Driver object. Here's an example how you would use LogKit: - </p> - <source><![CDATA[ -Hierarchy hierarchy = Hierarchy.getDefaultHierarchy(); -PatternFormatter formatter = new PatternFormatter( - "[%{priority}]: %{message}\n%{throwable}" ); - -LogTarget target = null; -target = new StreamTarget(System.out, formatter); - -hierarchy.setDefaultLogTarget(target); -log = hierarchy.getLoggerFor("fop"); -log.setPriority(Priority.INFO); - -driver.setLogger(new org.apache.avalon.framework.logger.LogKitLogger(log));]]></source> - <p> - The LogKitLogger class implements the Logger interface so all logging calls are being redirected to LogKit. - More information on Jakarta LogKit can be found <fork href="http://jakarta.apache.org/avalon/logkit/index.html">here</fork>. - </p> - <p> - Similar implementations exist for Log4J (org.apache.avalon.framework.logger.Log4JLogger) and - JDK 1.4 logging (org.apache.avalon.framework.logger.Jdk14Logger). - </p> - <p> - If you want FOP to be totally silent you can also set an org.apache.avalon.framework.logger.NullLogger instance. - </p> - <p> - If you want to use yet another logging facility you simply have to create a class that - implements org.apache.avalon.framework.logging.Logger and set it on the Driver object. - See the existing implementations in Avalon Framework for examples. - </p> - </section> - <section id="input"> - <title>Input Sources</title> - <p> - The input XSL-FO document is always handled internally as SAX (see the - <link href="../dev/design/parsing.html">Parsing Design Document</link> for the rationale). - However, the input itself can be provided in a variety of ways to FOP, - which normalizes the input (if necessary) into SAX events: - </p> - <ul> - <li><strong>SAX Events through SAX Handler</strong>: <code>FOTreeBuilder</code> is the SAX Handler which is obtained through <code>getContentHandler</code> on <code>Driver</code>.</li> - <li><strong>DOM (which is converted into SAX Events)</strong>: The conversion of a DOM tree is done via the <code>render(Document)</code> method on <code>Driver</code>.</li> - <li><strong>Data Source (which is parsed and converted into SAX Events)</strong>: The <code>Driver</code> can take an <code>InputSource</code> as input. -This can use a <code>Stream</code>, <code>String</code> etc.</li> - <li><strong>XML+XSLT Transformation</strong> (which is transformed using an XSLT Processor and the result is fired as SAX Events: <code>XSLTInputHandler</code> is used as an <code>InputSource</code> in the render(<code>XMLReader</code>, <code>InputSource</code>) method on <code>Driver</code>.</li> - </ul> - <p> - There are a variety of upstream data manipulations possible. - For example, you may have a DOM and an XSL stylesheet; or you may want to - set variables in the stylesheet. Interface documentation and some cookbook - solutions to these situations are provided in - <fork href="http://xml.apache.org/xalan-j/usagepatterns.html">Xalan Basic Usage Patterns</fork>. - </p> - <p> - See the <link href="#examples">Examples</link> for some variations on input. - </p> - </section> - <section id="config-external"> - <title>Using a Configuration File</title> - <p> - To access an external configuration: - </p> - <source><![CDATA[ -import org.apache.fop.apps.Options; - -/*..*/ - -userConfigFile = new File(userConfig); -options = new Options(userConfigFile);]]></source> - <note> - This is all you need to do, it sets up a static configuration class. - </note> - <p> - No further reference to the <code>options</code> variable is necessary. - The "options = " is actually not even necessary. - </p> - <p> - See <link href="#multithreading">Multithreading FOP</link> for issues related to changing configuration in a multithreaded environment. - </p> - </section> - <section id="config-internal"> - <title>Setting the Configuration Programmatically</title> - <p> - If you wish to set configuration options from within your embedded application, use the <code>Configuration.put</code> method. Here is an example that sets the "baseDir" configuration in a Unix environment: - </p> - <source>org.apache.fop.configuration.Configuration.put("baseDir","/my/base/dir");</source> - <p> - Here is another that sets baseDir in a Windows environment: - </p> - <source>org.apache.fop.configuration.Configuration.put("baseDir","C:\my\base\dir");</source> - <p> - See <link href="#multithreading">Multithreading FOP</link> for issues related to changing configuration in a multithreaded environment. - </p> - </section> - <section id="hints"> - <title>Hints</title> - <section id="object-reuse"> - <title>Object reuse</title> - <p> -If FOP is going to be used multiple times within your application -it may be useful to reuse certain objects to save time. - </p> - <p> -The renderers and the driver can both be reused. A renderer is reusable -once the previous render has been completed. The driver is reuseable -after the rendering is complete and the <code>reset()</code> method is called. -You will need to setup the driver again with a new OutputStream, -IntputStream and renderer. - </p> - </section> - <section id="awt"> - <title>AWT issues</title> - <p> - If your XSL-FO files contain SVG then Batik will be used. When Batik is - initialised it uses certain classes in <code>java.awt</code> that - intialises the java AWT classes. This means that a daemon thread - is created by the JVM and on Unix it will need to connect to a - DISPLAY. - </p> - <p> - The thread means that the Java application may not automatically quit - when finished, you will need to call <code>System.exit()</code>. These - issues should be fixed in the upcoming JDK 1.4. - </p> - <p> - If you run into trouble running FOP on a head-less server, please see the - <link href="graphics.html#batik">notes on Batik</link>. - </p> - </section> - <section id="render-info"> - <title>Getting information on the rendering process</title> - <p> -To get the number of pages that were rendered by FOP you can call -<code>Driver.getResults()</code>. This returns a FormattingResults object -where you can lookup the number of pages produced. It also gives you the -page-sequences that were produced along with their id attribute and their -number of pages. This is particularly useful if you render multiple -documents (each enclosed by a page-sequence) and have to know the number of -pages of each document. - </p> - </section> - </section> - <section id="performance"> - <title>Improving performance</title> - <p> - There are several options to consider: - </p> - <ul> - <li> - Whenever possible, try to use SAX to couple the individual components involved - (parser, XSL transformer, SQL datasource etc.). - </li> - <li> - Depending on the target OutputStream (in case of an FileOutputStream, but not - for a ByteArrayOutputStream, for example) it may improve performance considerably - if you buffer the OutputStream using a BufferedOutputStream: - <code>driver.setOutputStream(new java.io.BufferedOutputStream(out));</code> - <br/> - Make sure you properly close the OutputStream when FOP is finished. - </li> - <li> - Cache the stylesheet. If you use the same stylesheet multiple times - you can setup a JAXP <code>Templates</code> object and reuse it each time you do - the XSL transformation. (More information can be found - <fork href="http://www.javaworld.com/javaworld/jw-05-2003/jw-0502-xsl.html">here</fork>.) - </li> - <li> - Use an XSLT compiler like <fork href="http://xml.apache.org/xalan-j/xsltc_usage.html">XSLTC</fork> - that comes with Xalan-J. - </li> - </ul> - </section> - <section id="multithreading"> - <title>Multithreading FOP</title> - <p> - FOP is not currently completely thread safe. -Although the relevant methods of the Driver object are synchronized, FOP uses static -variables for configuration data and loading images. -Here are some tips to mitigate these problems: - </p> - <ul> - <li> - To avoid having your threads blocked, create a Driver object for each thread. - </li> - <li> - If possible, do not change the configuration data while there is a Driver object rendering. - Setup the configuration only once, preferably in the <code>init()</code> method of the servlet. - </li> - <li> - If you must change the configuration data more often, or if you have multiple - servlets within the same webapp using FOP, consider implementing a singleton - class to encapsulate the configuration settings and to run FOP in synchronized methods. - </li> - </ul> - <p>There is also a known issue with fonts being jumbled between threads when using the AWT renderer (which is used by the -awt and -print output options). -In general, you cannot safely run multiple threads through the AWT renderer.</p> - </section> -<section id="examples"> - <title>Examples</title> - <p> -The directory "{fop-dir}/examples/embedding" contains several working examples. -In contrast to the examples above the examples here primarily use JAXP for -XML access. This may be easier to understand for people familiar with JAXP. - </p> - <section id="ExampleFO2PDF"> - <title>ExampleFO2PDF.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleFO2PDF.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleFO2PDF.java?view=markup"> - (future 1.0dev)</fork> -demonstrates the basic usage pattern to transform an XSL-FO -file to PDF using FOP. - </p> - <figure src="images/EmbeddingExampleFO2PDF.png" alt="Example XSL-FO to PDF"/> - </section> - <section id="ExampleXML2FO"> - <title>ExampleXML2FO.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleXML2FO.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleXML2FO.java?view=markup"> - (future 1.0dev)</fork> -has nothing to do with FOP. It is there to show you how an XML -file can be converted to XSL-FO using XSLT. The JAXP API is used to do the -transformation. Make sure you've got a JAXP-compliant XSLT processor in your -classpath (ex. <fork href="http://xml.apache.org/xalan-j">Xalan</fork>). - </p> - <figure src="images/EmbeddingExampleXML2FO.png" alt="Example XML to XSL-FO"/> - </section> - <section id="ExampleXML2PDF"> - <title>ExampleXML2PDF.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup"> - (future 1.0dev)</fork> -demonstrates how you can convert an arbitrary XML file to PDF -using XSLT and XSL-FO/FOP. It is a combination of the first two examples -above. The example uses JAXP to transform the XML file to XSL-FO and FOP to -transform the XSL-FO to PDF. - </p> - <figure src="images/EmbeddingExampleXML2PDF.png" alt="Example XML to PDF (via XSL-FO)"/> - <p> -The output (XSL-FO) from the XSL transformation is piped through to FOP using -SAX events. This is the most efficient way to do this because the -intermediate result doesn't have to be saved somewhere. Often, novice users -save the intermediate result in a file, a byte array or a DOM tree. We -strongly discourage you to do this if it isn't absolutely necessary. The -performance is significantly higher with SAX. - </p> - </section> - <section id="ExampleObj2XML"> - <title>ExampleObj2XML.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleObj2XML.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleObj2XML.java?view=markup"> - (future 1.0dev)</fork> -is a preparatory example for the next one. It's an example that -shows how an arbitrary Java object can be converted to XML. It's an often -needed task to do this. Often people create a DOM tree from a Java object and -use that. This is pretty straightforward. The example here however shows how -to do this using SAX which will probably be faster and not even more -complicated once you know how this works. - </p> - <figure src="images/EmbeddingExampleObj2XML.png" alt="Example Java object to XML"/> - <p> -For this example we've created two classes: ProjectTeam and ProjectMember -(found in xml-fop/examples/embedding/java/embedding/model). They represent -the same data structure found in -xml-fop/examples/embedding/xml/xml/projectteam.xml. We want to serialize a -project team with several members which exist as Java objects to XML. -Therefore we created the two classes: ProjectTeamInputSource and -ProjectTeamXMLReader (in the same place as ProjectTeam above). - </p> - <p> -The XMLReader implementation (regard it as a special kind of XML parser)is -responsible for creating SAX events from the Java object. The InputSource -class is only used to hold the ProjectTeam object to be used. - </p> - <p> -Have a look at the source of ExampleObj2XML.java to find out how this is -used. For more detailed information see other resources on JAXP (ex. -<fork href="http://java.sun.com/xml/jaxp/dist/1.1/docs/tutorial/xslt/3_generate.html">An older JAXP tutorial</fork>). - </p> - </section> - <section id="ExampleObj2PDF"> - <title>ExampleObj2PDF.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleObj2PDF.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleObj2PDF.java?view=markup"> - (future 1.0dev)</fork> -combines the previous and the third to demonstrate -how you can transform a Java object to a PDF directly in one smooth run -by generating SAX events from the Java object that get fed to an XSL -transformation. The result of the transformation is then converted to PDF -using FOP as before. - </p> - <figure src="images/EmbeddingExampleObj2PDF.png" alt="Example Java object to PDF (via XML and XSL-FO)"/> - </section> - <section id="ExampleDOM2PDF"> - <title>ExampleDOM2PDF.java</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/tags/fop-0_20_5/examples/embedding/java/embedding/ExampleDOM2PDF.java?view=markup"> - (current 0.20.5)</fork> - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleDOM2PDF.java?view=markup"> - (future 1.0dev)</fork> -has FOP use a DOMSource instead of a StreamSource in order to -use a DOM tree as input for an XSL transformation. - </p> - </section> - <section id="ExampleSVG2PDF"> - <title>ExampleSVG2PDF.java (PDF Transcoder example)</title> - <p>This example - <fork href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleSVG2PDF.java?view=markup"> - (applies to 0.20.5 and future 1.0dev)</fork> -shows use of the PDF Transcoder, a sub-application within FOP. -It is used to generate a PDF document from an SVG file. - </p> - </section> - <section id="example-notes"> - <title>Final notes</title> - <p> -These examples should give you an idea of what's possible. It should be easy -to adjust these examples to your needs. Also, if you have other examples that you -think should be added here, please let us know via either the FOP-USER or FOP-DEV -mailing lists. Finally, for more help please send your questions to the FOP-USER -mailing list. - </p> - </section> -</section> - </body> -</document> - |