Thursday, February 9, 2017

How to write a WSO2 custom mediator to convert XSL-FO to PDF.

Description:

XSL-FO stands for Extensible Stylesheer Language Formatting Objects.

XSL-FO is an XML based markup language describing the formatting of XML data for output to sreen, paper or other media.

So, I'm going to describe the way we can convert XSL-FO to PDF using custom mediator.

Tested Environment:

WSO2 ESB 5.0.0
JDK 1.8

Steps

Step 1:

Add below listed depended JAR's to the project (pom.xml)

 <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>fop</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>xmlgraphics-commons</artifactId>
            <version>1.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-bridge</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-gvt</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-transcoder</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.avalon.framework</groupId>
            <artifactId>avalon-framework-api</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>batik</groupId>
            <artifactId>batik-1.5-fop</artifactId>
            <version>0.20-5</version>
        </dependency>

Step 2:

 Implement class mediator as below

package org.syntouch.esb.mediators;

import java.io.*;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPBody;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;

/**
 * Created by tharanga on 2/7/17.
 */
public class TestFile extends AbstractMediator {
    @Override
    public boolean mediate(MessageContext messageContext) {
        trace.info("PdfCreationMediator Process Started");

        SOAPBody soapBody = messageContext.getEnvelope().getBody();
        OMElement firstElement = soapBody.getFirstElement();

        OutputStream out = null;

        try {
            out = new BufferedOutputStream(new FileOutputStream(new File("/home/tharanga/workspace/home/XSL-FO-to-pdf/invoice.pdf")));

            final FopFactory fopFactory = FopFactory.newInstance();

            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();

            String firstElementAsString = firstElement.toString();
            Source src = new StreamSource(new StringReader(firstElementAsString));

            Result res = new SAXResult(fop.getDefaultHandler());

            transformer.transform(src, res);

            trace.info("PdfCreationMediator Process Finished successfully");
        } catch (FOPException | TransformerException | IOException e) {
            trace.info(new String("PdfCreationMediator Process Failed"));
            // e.printStackTrace();
        } finally {
            // Clean-up
            try {
                out.close();
            } catch (IOException e) {
                trace.info(new String("PdfCreationMediator Process Failed"));
                // e.printStackTrace();
            }
        }
        return true;
    }
}


Step 3:

Create a sample proxy to execute class mediator

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="Proxy1"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <class name="org.syntouch.esb.mediators.TestFile"/>
      </inSequence>
   </target>
   <description/>
</proxy>

With the above steps, we can properly convert XSL-FO to PDf. In the above class mediator, I assiume that, XSL-FO data comes with the request body.

When execute the above sample, PDF file successfully store in the mentioned location.

No comments:

Post a Comment