It makes sense that the FOP driver only needs SAX events.  This solution is
pretty neat and I wish I had thought of it (I pretty much do your steps
1-3,5 but not 4).

However, I'm not sure that this is going to do much to solve any of the
memory problems most people are having.  In some of my typically reports, I
have a 3mb XML file (result of SQL query) which get transformed into about a
9mb FOP file.  When rendering the FOP file, it takes about 95mb of memory.
Regardless of whether you send FOP sax events or a DOM tree, FOP consumes
TONS of memory to do its magic.  The memory consumed in steps 1-3 are
nothing really compared to the FOP requirements, although I agree streaming
the FOP resuls out is a good thing.  However, the PDF files are typically
250KB or so in size, again, not the problem.

FOP's memory consumption is becomming the primary barrier for our use of the
product.  We have reports that can run 250-500 pages and its almost
impossible to render these types of PDF documents due to the excessive
memory requirements and processing overhead.

Does anyone know WHY FOP consumes so much memory, I assume its because it
has to maintain the area tree stuff.


-----Original Message-----
From: Shkuro, Yuri [mailto:[EMAIL PROTECTED]]
Sent: Monday, November 12, 2001 2:42 PM
Subject: RE: Question on XSLTInputHandler

I've already posted this code to the list, but 
will do it again.  I would like to see it finding 
its place on http://xml.apache.org/fop/embedding.html
one day - shouldn't we promote efficient use of FOP 
instead  of giving an example of embedding, which is 
technically correct but hardly userful for servlet 

The code below has the following benefits compared to
Jim's example:
  - all transformations are done in a single pass
    by chaining SAX events
  - the resulting PDF is not stored in memory, but
     streamed directly into the output stream
    (in Jim's example, it is first stored in a string,
     then converted to byte array, and only then is
     writted to the output stream)

import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import org.apache.fop.apps.Driver;

// -------
// 1. Get a Source for XML document
// -------

 // a) from string
Source strSource = new StreamSource(new StringReader(xmlString));

 // b) from file
Source fileSource = new StreamSource(xmlFile);

 // c) from JDOM Document 
Source domSource = new org.jdom.transform.JDOMSource( jdomDocument )

// -------
// 2. Get stylesheet transformer
// -------
 // from file, see above examples for other types of XSL input
Templates template = transformerFactory.newTemplates( new StreamSource(
xslFile ));
 // note - template object is multi-threaded and should be cached if you
 // to use the same XSL repeatedly
Transformer transformer = template.mewTransformer();

// -------
// 3. Create FOP driver and set rendering mode and output stream
// -------
Driver driver = new Driver();
driver.setOutputStream( response.getOutputStream() );
// initialize logger - see sample code on FOP website

// -------
// 4. Create SAXResult based on FOP Driver content handler 
// which will accept SAX events and build FOP tree
// -------
Result saxResult = new SAXResult( driver.getContentHandler() );

// 5. Use the Transformer to transform an XML Source and 
// send the output to a Result object. Implicitely it will 
// create the FOP tree by firing SAX events.
transformer.transform( whateverSource, saxResult );

// 6. Your user is already viewing the PDF!

Yuri Shkuro
HR - Information Technology
Goldman Sachs & Co., New York

-----Original Message-----
From: Jim Urban [mailto:[EMAIL PROTECTED]]
Sent: Monday, November 12, 2001 2:08 PM
Subject: RE: Question on XSLTInputHandler

Here is a block of code our of one my servlets. This code takes a string
containing XML, applies an XSL:FO style sheet to it, and runs the XML:FO
through FOP and send s the PDF directly back to the browser.

Writer      out             = new StringWriter();
Transformer pdfTransformer  =
String xmlString = .....
Source      xmlSource  = new StreamSource(new StringReader(xmlString));
pdfTransformer.transform(xmlSource, new StreamResult(out));
String fopstring = out.toString();
InputSource foSource = getInput(fopstring);
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 Driver driver = new Driver(iInputSource, out);
 byte[] content = out.toByteArray();
catch (Exception e){}


-----Original Message-----
Sent: Monday, November 12, 2001 12:49 PM
Subject: Question on XSLTInputHandler


I've looked at the example servlet and found that the XSLTInputHandler
takes as input a java.io.File. However, I am constructing the XML
document dynamically and have it as a java.lang.String in memory. It
seems unnecessary I/O to write it out to a temporary file, just to pass
it to the XSLTInputHandler. Looking at the source of
XSLTInputHandler.java I didn't find any alternate way to call it. What
would the recommended procedure be in this case, where I already have
the XML document in memory?

thanks in advance for any pointers,


Ulrich Mayring
DENIC eG, Systementwicklung

To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to