I'm trying to package up resources into a jar, but I'm having trouble getting Flying Saucer to find the css on the classpath - I can't construct a URL easily to be able to resolve this seamlessly.
Does Flying saucer have a way of specifying resource packages on the classpath to resolve items and images?
Note: I'm running this in a webstart application that does not have file system writing permissions, so jar expansion is not really an option.
You should implement a UserAgentCallback that you feed to the XHTMLPanel, something like this:
private static class UAC extends NaiveUserAgent {
@Override
public String resolveURI(String uri) {
return uri;
}
@Override
protected InputStream resolveAndOpenStream(String uri) {
java.io.InputStream is = null;
URL url = UAC.class.getResource(uri);
if (url == null) {
XRLog.load("Didn't find resource [" + uri + "].");
return null;
}
try {
is = url.openStream();
}
catch (java.net.MalformedURLException e) {
XRLog.exception("bad URL given: " + uri, e);
}
catch (java.io.FileNotFoundException e) {
XRLog.exception("item at URI " + uri + " not found");
}
catch (java.io.IOException e) {
XRLog.exception("IO problem for " + uri, e);
}
return is;
}
}
XHTMLPanel panel = new XHTMLPanel(new UAC());
My solution is
private static class UserAgentCallback extends ITextUserAgent {
public UserAgentCallback(ITextOutputDevice outputDevice, SharedContext sharedContext) {
super(outputDevice);
setSharedContext(sharedContext);
}
@Override
public String resolveURI(String uri) {
return uri;
}
@Override
protected InputStream resolveAndOpenStream(String uri) {
java.io.InputStream is = null;
URL url = null;
try {
url = new ClassPathResource("/META-INF/pdfTemplates/" + uri).getURL();
} catch (IOException e) {
XRLog.exception("bad URL given: " + uri, e);
}
if (url == null) {
XRLog.load("Didn't find resource [" + uri + "].");
return null;
}
try {
is = url.openStream();
} catch (java.net.MalformedURLException e) {
XRLog.exception("bad URL given: " + uri, e);
} catch (java.io.FileNotFoundException e) {
XRLog.exception("item at URI " + uri + " not found");
} catch (java.io.IOException e) {
XRLog.exception("IO problem for " + uri, e);
}
return is;
}
}
and invocation:
renderer.getSharedContext()
.setUserAgentCallback(new UserAgentCallback(renderer.getOutputDevice(), renderer.getSharedContext()));
It would seem that flying saucer does not have a way of specifying resources on the classpath, so I work around by making a classpath: protocol url handler at the linked question
Post Implementation Findings
It would seem that the some of the premises of this question are invalid. After writing my own classpath URL loader, I found that you need to request <all-permissions/>
in the jnlp to be able to use URL.setURLStreamHandlerFactory()
. In fact, you need to request all permissions to do just about anything fancy (even though you're only modifying your own sand-box). See the full list here.
In short, this means that I am able to extract files to the operating system. But it's nice having a classpath loader now...