I want to build a pdf-file from a jaxb-object using apache fop to generate and itext PdfStamper to modify it. since fop writes to an outputStream and PdfStamper reads from InputStream my idea was to use Piped[I|O]Streams for this. here is what I tried:
public void transform2XSLFO_onthefly(Medium medium, OutputStream out) throws Exception {
PipedInputStream pInputPipe = new PipedInputStream();
PipedOutputStream outputTemp = new PipedOutputStream(pInputPipe);
try {
JAXBSource source = new JAXBSource( JAXBContext.newInstance(medium.getClass()) , medium );
FOUserAgent userAgent = fopFactory.newFOUserAgent();
// settings
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent ,outputTemp);
InputStream XSLinputStream = xslfoStylesheet.getInputStream();
StreamSource XSLsource = new StreamSource(XSLinputStream);
Result res = new SAXResult(fop.getDefaultHandler());
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(XSLsource);
// run transformation
t.transform(source, res);
// does not come so far, no use closing the stream
outputTemp.close();
PdfReader reader = new PdfReader(pInputPipe);
pdfStamper = new PdfStamper(reader, out);
//..... postProcess...
pdfStamper.close();
} catch (Exception ex) {
log.error("ERROR", ex);
}
However it hangs in the line "t.transform(source, res);", looks like he is waiting for something in the middle of the fop-transformation. It works using BypeArrayOutputStream and convert it to inputstream and use it for PdfStamper input:
InputStream pdfInput = new ByteArrayInputStream(((ByteArrayOutputStream) outputTemp).toByteArray());
but the files can get quite large (few MB) so i think the piped version would perform better! what do you think?
You should read up on how to use PipeInput/OutputStream. FOP and the PdfStamper will need to run in separate threads. Basically, this has nothing to do with FOP per se. I'm sure you'll find various examples on the net on how this works. If you're not comfortable with multi-threaded programming, I suggest you just buffer FOP's output in a byte[] or a temporary file.