I am trying to write an embedded custom fop xml to pdf java application using a custom image redirect within fop
I have the following in an old xslt file
<fo:block text-indent="1mm" padding-before="20mm">
<xsl:variable name="barcode" select="concat('/prescriptions/', id, '/barcode.html')"/>
<fo:external-graphic>
<xsl:attribute name="src">
<xsl:value-of select="$barcode" />
</xsl:attribute>
</fo:external-graphic>
</fo:block>
I have written a customResourceResolver
package embedding;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;
import java.io.BufferedInputStream;
import java.net.URI;
import java.net.URISyntaxException;
public class CustomResourceResolver implements ResourceResolver {
String base;
String session;
String cookie;
String user_id;
String authorization;
static final Logger logger = Logger.getLogger("fop-log");
public String get_base(){
return base;
}
public CustomResourceResolver(String _base, String _session, String _cookie, String _user_id, String _authorization){
super();
base = _base;
session = _session;
cookie = _cookie;
user_id = _user_id;
authorization = _authorization;
}
@Override
public Resource getResource(URI uri) throws IOException {
HttpURLConnection urlConnection = null;
try {
String href = uri.getRawPath();
if (!href.startsWith("/") && !base.endsWith("/")) {
base = base + "/";
}
String new_uri;
if (href.startsWith("http://") || href.startsWith("https://")) {
new_uri = href;
} else {
new_uri = base + href;
}
uri = new URI(new_uri);
logger.log(Level.INFO, "loading: ({0})", new_uri);
URL url = uri.toURL();
urlConnection = (HttpURLConnection) url.openConnection();
if(session!= null){
urlConnection.setRequestProperty("Cookie", cookie + "=" + session);
}
if(authorization != null){
urlConnection.setRequestProperty("Fop-authorization", authorization );
}
if(user_id != null){
urlConnection.setRequestProperty("Fop-user",user_id );
}
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
return new Resource(in);
} catch (MalformedURLException e) {
logger.log(Level.SEVERE, null, e);
return null;
} catch (IOException | URISyntaxException ioe) {
logger.log(Level.SEVERE, null, ioe);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
@Override
public OutputStream getOutputStream(URI uri) throws IOException {
URL url = uri.toURL();
return url.openConnection().getOutputStream();
}
}
And this gets called by
CustomResourceResolver resolver = new CustomResourceResolver(base, session, cookie, user_id, authorization);
FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), (ResourceResolver)resolver);
final FopFactory fopFactory = builder.build();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
TransformerFactory factory = TransformerFactory.newInstance();
URIResolver uiResolver = new CustomUriResolver(base, session, cookie, user_id, authorization);
factory.setURIResolver(uiResolver);
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
// Set the value of a <param> in the stylesheet
transformer.setParameter("versionParam", "2.0");
// Setup input for XSLT transformation
Source src = new StreamSource(xmlfile);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
} finally {
out.close();
}
java is packaged inside a single FopXml2Pdf.jar and is called from the command line like
java -jar FopXml2Pdf.jar file.xml file.xsl file.config
but when I run the code I get
Sep 19, 2023 6:52:36 AM embedding.CustomResourceResolver getResource
INFO: loading: (http://localhost:3000/prescriptions/420/barcode.html)
Sep 19, 2023 6:52:36 AM org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext createImageSource
SEVERE: Unable to create ImageInputStream for InputStream from system identifier 'file:/media/sf_Clintel/careright/./' (stream is closed)
Sep 19, 2023 6:52:36 AM org.apache.fop.events.LoggingEventListener processEvent
SEVERE: Image not found. URI: /prescriptions/420/barcode.html. (No context info available)
I can see that the redirection is loading the correct url getting the correct data but
new File(".").toURI() is resolving to file:/media/sf_Clintel/careright/./
What should I set this to so that it saves the data from Resource getResource?
The issue has been solved. packaging of Batik-all-1.14.jar into a single fat Jar using ANT was causing this exception. changing the packaging to use MVN has fixed the problem