package er.pdf.builder;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.Date;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSForwardException;
import com.webobjects.foundation.NSMutableDictionary;
public class Fop2PdfImpl implements FOPBuilder {
public static final String GENERATOR_NAME_KEY = "GENERATOR_NAME";
public static final String GENERATOR_NAME = "ERPDFGeneration";
public static final String AUTHOR_KEY = "DEFAULT_AUTHOR";
public static final String DEFAULT_AUTHOR = "ERPDFGeneration";
public static final String TARGET_RESOLUTION_KEY = "TARGET_RESOLUTION";
public static final int DEFAULT_RESOLUTION = 300;
private String _fopxslLocation;
private String _xmlToTransform;
private String _outputType = MimeConstants.MIME_PDF;
private NSMutableDictionary<String, Object> _config;
private static final Logger log = LoggerFactory.getLogger(Fop2PdfImpl.class);
protected static FopFactory fopFactory;
public Fop2PdfImpl() {
}
public void setXSL(String fopxslLocation) {
_fopxslLocation = fopxslLocation;
}
public void setXML(String xmlToTransform) {
_xmlToTransform = xmlToTransform;
}
/**
* some basic defaults for configuring the fop agent. This should be
* property driven, but I'll do that later (yeah... right)
*
* @return a configuration dictionary
*/
public NSDictionary<String, Object> agentDefaults() {
NSMutableDictionary<String, Object> d = new NSMutableDictionary<>();
d.setObjectForKey(DEFAULT_RESOLUTION, TARGET_RESOLUTION_KEY);
d.setObjectForKey(DEFAULT_AUTHOR, AUTHOR_KEY);
d.setObjectForKey(GENERATOR_NAME, GENERATOR_NAME_KEY);
return d.immutableClone();
}
public void createDocument(OutputStream os) throws Throwable {
createDocument(os, agentDefaults());
}
public void createDocument(OutputStream os, NSDictionary<String, Object> agentAttributes) throws Throwable {
log.debug("createDocument(OutputStream os={}, NSDictionary<String,Object> agentAttributes={}) - start", os, agentAttributes);
fopFactory = FopFactory.newInstance();
log.debug("createDocument(OutputStream) - initializing FOUserAgent");
// get the defaults, but immediately override them with whatever was
// passed in
// from the program. This is meant to ensure that we have all the
// attributes we need
// before initializing the agent. If there is a better way, help
// yourself.
NSMutableDictionary<String, Object> _agentAtts = agentDefaults().mutableClone();
_agentAtts.addEntriesFromDictionary(agentAttributes);
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setCreator((String) _agentAtts.get(GENERATOR_NAME_KEY));
foUserAgent.setAuthor((String) _agentAtts.get(AUTHOR_KEY));
foUserAgent.setCreationDate(new Date());
foUserAgent.setTargetResolution((Integer) _agentAtts.get(TARGET_RESOLUTION_KEY));
foUserAgent.setTitle("FOP Referral Package Test");
foUserAgent.setKeywords("Referral Package Vasc-Alert");
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, os);
if (log.isDebugEnabled()) {
log.debug("createDocument(OutputStream) - Fop initialized with: - _fopxslLocation={}, os={}, foUserAgent={}", _fopxslLocation, os, foUserAgent);
log.debug("xsl resource: {}", Fop2PdfImpl.class.getClassLoader().getResourceAsStream(_fopxslLocation));
}
TransformerFactory txfac = TransformerFactory.newInstance();
Transformer tx = txfac.newTransformer(new SAXSource(new InputSource(Fop2PdfImpl.class.getClassLoader().getResourceAsStream(_fopxslLocation))));
tx.setParameter("versionParam", "2.0");
Source src = new StreamSource(new StringReader(_xmlToTransform));
Result res = new SAXResult(fop.getDefaultHandler());
tx.transform(src, res);
} catch (FOPException e) {
log.error("createDocument(OutputStream, NSDictionary<String,Object>)", e);
e.printStackTrace();
throw NSForwardException._runtimeExceptionForThrowable(e);
} catch (TransformerConfigurationException e) {
log.error("createDocument(OutputStream, NSDictionary<String,Object>)", e);
e.printStackTrace();
throw NSForwardException._runtimeExceptionForThrowable(e);
} catch (TransformerException e) {
log.error("createDocument(OutputStream, NSDictionary<String,Object>)", e);
e.printStackTrace();
throw NSForwardException._runtimeExceptionForThrowable(e);
}
if (log.isDebugEnabled()) {
log.debug("createDocument(OutputStream, NSDictionary<String,Object>) - end");
}
}
public void setConfiguration(NSMutableDictionary<String, Object> config) {
_config = config;
}
}