| <?xml version="1.0" standalone="no"?> |
| <!-- |
| Copyright 1999-2006 The Apache Software Foundation |
| |
| Licensed 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 V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd"> |
| <!-- Embedding FOP --> |
| <document> |
| <header> |
| <title>Apache 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 <a href="running.html">Running FOP</a> for important information that applies |
| to embedded applications as well as command-line use, such as options and performance. |
| </p> |
| <p> |
| To embed Apache FOP in your application, instantiate org.apache.fop.apps.Fop. |
| You'll tell FOP in the constructor which output format (i.e. Renderer) to use. |
| Afterwards, you'll set the OutputStream to use to output the results of the |
| rendering (where applicable). You can customize FOP's behaviour by supplying |
| your own FOUserAgent instance. The FOUserAgent can, for example, be used to |
| set your own Renderer instance (details below). Finally, you retrieve a SAX |
| DefaultHandler instance from the Fop instance to which you can send your |
| FO file. |
| </p> |
| </section> |
| <section id="basics"> |
| <title>Basic Usage Pattern</title> |
| <p> |
| Apache FOP relies heavily on JAXP. It uses SAX events exclusively to receive the XSL-FO |
| input document. It is therefore a good idea that you know a few things about JAXP (which |
| is a good skill anyway). Let's look at the basic usage pattern for FOP... |
| </p> |
| <p>Here is the basic pattern to render an XSL-FO file to PDF: |
| </p> |
| <source><![CDATA[ |
| import org.apache.fop.apps.Fop; |
| import org.apache.fop.apps.MimeConstants; |
| |
| /*..*/ |
| |
| // Step 1: Construct fop with desired output format |
| Fop fop = new Fop(MimeConstants.MIME_PDF); |
| |
| // Step 2: Setup output stream. |
| // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). |
| OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("C:/Temp/myfile.pdf"))); |
| try { |
| fop.setOutputStream(out); |
| |
| // Step 3: Setup JAXP using identity transformer |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| Transformer transformer = factory.newTransformer(); // identity transformer |
| |
| // Step 4: Setup input and output for XSLT transformation |
| // Setup input stream |
| Source src = new StreamSource(new File("C:/Temp/myfile.fo")); |
| |
| // Resulting SAX events (the generated FO) must be piped through to FOP |
| Result res = new SAXResult(fop.getDefaultHandler()); |
| |
| // Step 5: Start XSLT transformation and FOP processing |
| transformer.transform(src, res); |
| |
| } finally { |
| //Clean-up |
| out.close(); |
| }]]></source> |
| <p> |
| Let's discuss these 5 steps in detail: |
| </p> |
| <ul> |
| <li> |
| <strong>Step 1:</strong> You create a new Fop instance and set it up for PDF |
| output. |
| </li> |
| <li> |
| <strong>Step 2:</strong> You tell FOP where to save the generated PDF file |
| later. It's a good idea to buffer the OutputStream as demonstrated to improve |
| performance. |
| </li> |
| <li> |
| <strong>Step 3:</strong> We recommend that you use JAXP Transformers even |
| if you don't do XSLT transformations to generate the XSL-FO file. This way |
| you can always use the same basic pattern. The example here sets up an |
| "identity transformer" which just passes the input (Source) unchanged to the |
| output (Result). You don't have to work with a SAXParser if you don't do any |
| XSLT transformations. |
| </li> |
| <li> |
| <strong>Step 4:</strong> Here you set up the input and output for the XSLT |
| transformation. The Source object is set up to load the "myfile.fo" file. |
| The Result is set up so the output of the XSLT transformation is sent to FOP. |
| The FO file is sent to FOP in the form of SAX events which is the most efficient |
| way. Please always avoid saving intermediate results to a file or a memory buffer |
| because that affects performance negatively. |
| </li> |
| <li> |
| <strong>Step 5:</strong> Finally, we start the XSLT transformation by starting |
| the JAXP Transformer. As soon as the JAXP Transformer starts to send its output |
| to FOP, FOP itself starts its processing in the background. When the |
| <code>transform()</code> method returns FOP will also have finished converting |
| the FO file to a PDF file and you can close the OutputStream. |
| <note label="Tip!"> |
| It's a good idea to enclose the whole conversion in a try..finally statement. If |
| you close the OutputStream in the finally section, this will make sure that the |
| OutputStream is properly closed even if an exception occurs during the conversion. |
| </note> |
| </li> |
| </ul> |
| <p> |
| If you're not totally familiar with JAXP Transformers, please have a look at the |
| <a href="#examples">Embedding examples</a> below. The section contains examples |
| for all sorts of use cases. If you look at all of them in turn you should be able |
| to see the patterns in use and the flexibility this approach offers without adding |
| too much complexity. |
| </p> |
| <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. An example for that |
| can be found in the <a href="#examples">Embedding examples</a> (See "ExampleXML2FO"). |
| </p> |
| <note> |
| Please be aware that you should not reuse a Fop instance for additional rendering runs. |
| Recreate a new instance for each rendering run. This is a relatively inexpensive |
| operation and will be further optimized shortly. |
| </note> |
| <section id="basic-logging"> |
| <title>Logging</title> |
| <p> |
| Logging is now a little different than it was in FOP 0.20.5. We've switched from |
| Avalon Logging to <a href="ext:jakarta/commons/logging">Jakarta Commons Logging</a>. |
| While with Avalon Logging the loggers were directly given to FOP, FOP now retrieves |
| its logger(s) through a statically available LogFactory. This is similar to the |
| general pattern that you use when you work with Apache Log4J directly, for example. |
| We call this "static logging" (Commons Logging, Log4J) as opposed to "instance logging" |
| (Avalon Logging). This has a consequence: You can't give FOP a logger for each |
| processing run anymore. The log output of multiple, simultaneously running FOP instances |
| is sent to the same logger. |
| </p> |
| <note> |
| We know this may be an issue in multi-threaded server environments if you'd like to |
| know what's going on in every single FOP processing run. We're planning to add an |
| additional feedback facility to FOP which can be used to obtain all sorts of specific |
| feedback (validation messages, layout problems etc.). "Static logging" is mainly |
| interesting for a developer working on FOP and for advanced users who are debugging |
| FOP. We don't consider the logging output to be useful to normal FOP users. Please |
| have some patience until we can add this feature or jump in and help us build it. We've |
| set up a <a href="http://wiki.apache.org/xmlgraphics-fop/ProcessingFeedback">Wiki page</a> |
| which documents what we're going to build. |
| </note> |
| <p> |
| By default, <a href="ext:jakarta/commons/logging">Jakarta Commons Logging</a> uses |
| JDK logging (available in JDKs 1.4 or higher) as its backend. You can configure Commons |
| Logging to use an alternative backend, for example Log4J. Please consult the |
| <a href="ext:jakarta/commons/logging">documentation for Jakarta Commons Logging</a> on |
| how to configure altentive backends. |
| </p> |
| </section> |
| |
| <section id="render"> |
| <title>Processing XSL-FO</title> |
| <p> |
| Once the Fop instance is set up, call <code>getDefaultHandler()</code> to obtain a SAX |
| DefaultHandler instance to which you can send the SAX events making up the XSL-FO |
| document you'd like to render. FOP processing starts as soon as the DefaultHandler's |
| <code>startDocument()</code> methods is called. Processing stops again when the |
| DefaultHandler's <code>endDocument()</code> method is called. Please refer to the basic |
| usage pattern shown above to render a simply XSL-FO document. |
| </p> |
| </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 |
| again using standard JAXP to do the XSLT part and piping the generated SAX |
| events directly through to FOP. The only thing you'd change to do that |
| on the basic usage pattern above is to set up the Transformer differently: |
| </p> |
| <source><![CDATA[ |
| //before (without XSLT): |
| //Transformer transformer = factory.newTransformer(); // identity transformer |
| |
| //after (with XSLT): |
| Source xslt = new StreamSource(new File("mystylesheet.xsl")); |
| Transformer transformer = factory.newTransformer(xslt);]]></source> |
| </section> |
| </section> |
| <section id="input"> |
| <title>Input Sources</title> |
| <p> |
| The input XSL-FO document is always handled internally as SAX (see the |
| <a href="../dev/design/parsing.html">Parsing Design Document</a> for the rationale). |
| </p> |
| <p> |
| However, you may not always have your input document available as a SAX stream. |
| But with JAXP it's easy to convert different input sources to a SAX stream so you |
| can pipe it into FOP. That sounds more difficult than it is. You simply have |
| to set up the right Source instance as input for the JAXP transformation. |
| A few examples: |
| </p> |
| <ul> |
| <li> |
| <strong>URL:</strong> <code>Source src = new StreamSource("http://localhost:8080/testfile.xml");</code> |
| </li> |
| <li> |
| <strong>File:</strong> <code>Source src = new StreamSource(new File("C:/Temp/myinputfile.xml"));</code> |
| </li> |
| <li> |
| <strong>String:</strong> <code>Source src = new StreamSource(new StringReader(myString)); //myString is a String</code> |
| </li> |
| <li> |
| <strong>InputStream:</strong> <code>Source src = new StreamSource(new MyInputStream(something));</code> |
| </li> |
| <li> |
| <strong>Byte Array:</strong> <code>Source src = new StreamSource(new ByteArrayInputStream(myBuffer)); //myBuffer is a byte[] here</code> |
| </li> |
| <li> |
| <strong>DOM:</strong> <code>Source src = new DOMSource(myDocument); //myDocument is a Document or a Node</code> |
| </li> |
| <li> |
| <strong>Java Objects:</strong> Please have a look at the <a href="#examples">Embedding examples</a> which contains an example for this. |
| </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 |
| <a href="http://xml.apache.org/xalan-j/usagepatterns.html">Xalan Basic Usage Patterns</a>. |
| </p> |
| </section> |
| <section id="config-internal"> |
| <title>Configuring Apache FOP Programmatically</title> |
| <p> |
| Apache FOP provides a class called FOUserAgent which is used to customize FOP's |
| behaviour. If you wish to do that, the first step is to create your own instance |
| of FOUserAgent and pass that to the Fop constructor: |
| </p> |
| <source><![CDATA[ |
| FOUserAgent userAgent = new FOUserAgent(); |
| Fop fop = new Fop(MimeConstants.MIME_POSTSCRIPT, userAgent);]]></source> |
| <p> |
| You can do all sorts of things on the user agent: |
| </p> |
| <ul> |
| <li> |
| <p> |
| The <strong>base URL</strong> to use when resolving relative URLs. Example: |
| </p> |
| <source>userAgent.setBaseURL("file:///C:/Temp/");</source> |
| </li> |
| <li> |
| <p> |
| The <strong>font base URL</strong> to use when resolving relative URLs for fonts. Example: |
| </p> |
| <source>userAgent.setFontBaseURL("file:///C:/Temp/fonts");</source> |
| </li> |
| <li> |
| <p> |
| Disable <strong>strict validation</strong>. When disabled FOP is less strict about the rules established by the XSL-FO specification. Example: |
| </p> |
| <source>userAgent.setStrictValidation(false);</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>producer</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. The default producer is "Apache FOP". Example: |
| </p> |
| <source>userAgent.setProducer("MyKillerApplication");</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>creating user</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. Example: |
| </p> |
| <source>userAgent.setCreator("John Doe");</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>author</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. Example: |
| </p> |
| <source>userAgent.setAuthor("John Doe");</source> |
| </li> |
| <li> |
| <p> |
| Override the <strong>creation date and time</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. Example: |
| </p> |
| <source>userAgent.setCreationDate(new Date());</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>title</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. Example: |
| </p> |
| <source>userAgent.setTitle("Invoice No 138716847");</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>keywords</strong> of the document. This is metadata information that can be used for certain output formats such as PDF. Example: |
| </p> |
| <source>userAgent.setKeywords("XML XSL-FO");</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>source resolution</strong> for the document. This is used internally to determine the pixel |
| size for SVG images and bitmap images without resolution information. Default: 72 dpi. Example: |
| </p> |
| <source>userAgent.setSourceResolution(96); //=96dpi (dots/pixels per Inch)</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>target resolution</strong> for the document. This is used to |
| specify the output resolution for bitmap images generated by bitmap renderers |
| (such as the TIFF renderer) and by bitmaps generated by Apache Batik for filter |
| effects and such. Default: 72 dpi. Example: |
| </p> |
| <source>userAgent.setTargetResolution(300); //=300dpi (dots/pixels per Inch)</source> |
| </li> |
| <li> |
| <p> |
| Set <strong>your own Renderer instance</strong>. If you want to supply your own renderer or |
| configure a Renderer in a special way you can give the instance to the FOUserAgent. Normally, |
| the Renderer instance is created by FOP. Example: |
| </p> |
| <source>userAgent.setRendererOverride(myRenderer); //myRenderer is an org.apache.fop.render.Renderer</source> |
| </li> |
| <li> |
| <p> |
| Set <strong>your own FOEventHandler instance</strong>. If you want to supply your own FOEventHandler or |
| configure an FOEventHandler subclass in a special way you can give the instance to the FOUserAgent. Normally, |
| the FOEventHandler instance is created by FOP. Example: |
| </p> |
| <source>userAgent.setFOEventHandlerOverride(myFOEventHandler); //myFOEventHandler is an org.apache.fop.fo.FOEventHandler</source> |
| </li> |
| <li> |
| <p> |
| Manually add a <strong>ElementMapping instance</strong>. If you want to supply a special FOP extension |
| you can give the instance to the FOUserAgent. Normally, the FOP extensions can be automatically detected |
| (see the documentation on extension for more info). |
| </p> |
| <source>userAgent.addElementMapping(myElementMapping); //myElementMapping is a org.apache.fop.fo.ElementMapping</source> |
| </li> |
| <li> |
| <p> |
| Set a <strong>URIResolver</strong> for custom URI resolution. By supplying a JAXP URIResolver you can add |
| custom URI resolution functionality to FOP. For example, you can use |
| <a href="ext:xml.apache.org/commons/resolver">Apache XML Commons Resolver</a> to make use of XCatalogs. |
| </p> |
| <source>userAgent.setURIResolver(myResolver); //myResolver is a javax.xml.transform.URIResolver</source> |
| </li> |
| <li> |
| <p> |
| Set the <strong>parameters for PDF encryption</strong> for the document. If you create PDF files you can |
| instantiate and set an org.apache.fop.pdf.PDFEncryptionParams object. Example: |
| </p> |
| <source>userAgent.setPDFEncryptionParams(new PDFEncryptionParams(null, "owner", false, false, true, true));</source> |
| </li> |
| <li> |
| <p> |
| Enable an <strong>alternative set of rules for text indents</strong> that tries to mimic the behaviour of many commercial |
| FO implementations that chose to break the specification in this aspect. The default of this option is |
| 'false' which causes Apache FOP to behave exactly as describes in the specification. To enable the |
| alternative behaviour, call: |
| </p> |
| <source>userAgent.setBreakIndentInheritanceOnReferenceAreaBoundary(true);</source> |
| </li> |
| </ul> |
| <note> |
| You should not reuse an FOUserAgent instance between FOP rendering runs although you can. Especially |
| in multi-threaded environment, this is a bad idea. |
| </note> |
| </section> |
| <section id="config-external"> |
| <title>Using a Configuration File</title> |
| <p> |
| Instead of setting the parameters manually in code as shown above you can also set |
| many values from an XML configuration file: |
| </p> |
| <source><![CDATA[ |
| import org.apache.avalon.framework.configuration.Configuration; |
| import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; |
| |
| /*..*/ |
| |
| DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); |
| Configuration cfg = cfgBuilder.buildFromFile(new File("C:/Temp/mycfg.xml")); |
| userAgent.setUserConfig(cfg);]]></source> |
| <p> |
| The layout of the configuration file is described on the <a href="configuration.html">Configuration page</a>. |
| </p> |
| </section> |
| <section id="hints"> |
| <title>Hints</title> |
| <section id="object-reuse"> |
| <title>Object reuse</title> |
| <p> |
| At the moment, the Fop instances shouldn't be reused. Please recreate |
| Fop and FOUserAgent instances for each rendering run until further notice. |
| We will likely add an additional object which will carry information |
| and configuration which can be reused between rendering runs to further |
| optimize this. |
| </p> |
| </section> |
| <section id="awt"> |
| <title>AWT issues</title> |
| <p> |
| If your XSL-FO files contain SVG then Apache Batik will be used. When Batik is |
| initialised it uses certain classes in <code>java.awt</code> that |
| intialise 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 JDK 1.4. |
| </p> |
| <p> |
| If you run into trouble running FOP on a head-less server, please see the |
| <a href="graphics.html#batik">notes on Batik</a>. |
| </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>Fop.getResults()</code>. This returns a <code>FormattingResults</code> 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>fop.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 |
| <a class="fork" href="http://www.javaworld.com/javaworld/jw-05-2003/jw-0502-xsl.html">here</a>.) |
| </li> |
| <li> |
| Use an XSLT compiler like <a class="fork" href="http://xml.apache.org/xalan-j/xsltc_usage.html">XSLTC</a> |
| that comes with Xalan-J. |
| </li> |
| </ul> |
| </section> |
| <section id="multithreading"> |
| <title>Multithreading FOP</title> |
| <p> |
| Apache FOP may currently not be completely thread safe. |
| FOP uses some static variables (for example for the image cache). This code |
| has not been fully tested for multi-threading issues, yet. |
| </p> |
| <p> |
| There is also a known issue with fonts being jumbled between threads when using |
| the Java2D/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 |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleFO2PDF.java?view=markup"> |
| example</a> |
| 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 |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleXML2FO.java?view=markup"> |
| example</a> |
| 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. <a href="http://xml.apache.org/xalan-j">Xalan</a>). |
| </p> |
| <figure src="images/EmbeddingExampleXML2FO.png" alt="Example XML to XSL-FO"/> |
| </section> |
| <section id="ExampleXML2PDF"> |
| <title>ExampleXML2PDF.java</title> |
| <p>This |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup"> |
| example</a> |
| 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 |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleObj2XML.java?view=markup"> |
| example</a> |
| 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. |
| <a class="fork" href="http://java.sun.com/xml/jaxp/dist/1.1/docs/tutorial/xslt/3_generate.html">An older JAXP tutorial</a>). |
| </p> |
| </section> |
| <section id="ExampleObj2PDF"> |
| <title>ExampleObj2PDF.java</title> |
| <p>This |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleObj2PDF.java?view=markup"> |
| example</a> |
| 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 |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleDOM2PDF.java?view=markup"> |
| example</a> |
| 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 |
| <a href="http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleSVG2PDF.java?view=markup"> |
| example</a> |
| 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-users or fop-dev |
| mailing lists. Finally, for more help please send your questions to the fop-users |
| mailing list. |
| </p> |
| </section> |
| </section> |
| </body> |
| </document> |
| |