Right now we're inhabiting in the java world, thus all our tasks are (in)directly related to this environment.
We want to store stylesheets as resources of java application, and at the same time to point to these stylesheets without jar qualification. In .NET this idea would not appear at all, as there are well defined boundaries between assemblies, but java uses rather different approach. Whenever you have a resource name, it's up to ClassLoader to find this resource. To exploit this feature we've created an uri resolver for the stylesheet transformation. The protocol we use has a following format: "resource:/resource-path".
ClassLoader
resource:/resource-path
For example to store stylesheets in the META-INF/stylesheets folder we use uri "resource:/META-INF/stylesheets/java/main.xslt". Relative path is resolved naturally. A path "../jxom/java-serializer.xslt" in previously mentioned stylesheet is resolved to "resource:/META-INF/stylesheets/jxom/java-serializer.xslt".
META-INF/stylesheets
resource:/META-INF/stylesheets/java/main.xslt
../jxom/java-serializer.xslt
resource:/META-INF/stylesheets/jxom/java-serializer.xslt
We've created a small class ResourceURIResolver. You need to supply an instance of TransformerFactory with this resolver: transformerFactory.setURIResolver(new ResourceURIResolver());
ResourceURIResolver
TransformerFactory
transformerFactory.setURIResolver(new ResourceURIResolver());
The class itself is so small that we qoute it here:
import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamSource; /** * This class implements an interface that can be called by the processor * to turn a URI used in document(), xsl:import, or xsl:include into a * Source object. */ public class ResourceURIResolver implements URIResolver { /** * Called by the processor when it encounters * an xsl:include, xsl:import, or document() function. * * This resolver supports protocol "resource:". * Format of uri is: "resource:/resource-path", where "resource-path" is an * argument of a {@link ClassLoader#getResourceAsStream(String)} call. * @param href - an href attribute, which may be relative or absolute. * @param base - a base URI against which the first argument will be made * absolute if the absolute URI is required. * @return a Source object, or null if the href cannot be resolved, and * the processor should try to resolve the URI itself. */ public Source resolve(String href, String base) throws TransformerException { if (href == null) { return null; } URI uri; try { if (base == null) { uri = new URI(href); } else { uri = new URI(base).resolve(href); } } catch(URISyntaxException e) { // Unsupported uri. return null; } if (!"resource".equals(uri.getScheme())) { return null; } String resourceName = uri.getPath(); if ((resourceName == null) || (resourceName.length() == 0)) { return null; } if (resourceName.charAt(0) == '/') { resourceName = resourceName.substring(1); } ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream stream = classLoader.getResourceAsStream(resourceName); if (stream == null) { return null; } return new StreamSource(stream, uri.toString()); } }
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u