com.crabshue.commons.xslt.RelativeXsltUriResolver Maven / Gradle / Ivy
package com.crabshue.commons.xslt;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Stack;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import com.crabshue.commons.exceptions.SystemException;
import com.crabshue.commons.xslt.exceptions.XsltErrorContext;
import com.crabshue.commons.xslt.exceptions.XsltErrorType;
import lombok.NonNull;
/**
* A URI resolver for resources relative to the current XSLT.
*/
public class RelativeXsltUriResolver implements URIResolver {
private Stack xsltFileStack = new Stack<>();
RelativeXsltUriResolver(@NonNull URI currentXsltUri) {
this.xsltFileStack.push(currentXsltUri);
}
@Override
public Source resolve(@NonNull final String s,
@NonNull final String s1) throws TransformerException {
URI currentXsltUri;
try {
while (!uriReferenceExists((currentXsltUri = resolveUri(xsltFileStack.peek(), s))) && !xsltFileStack.empty()) {
xsltFileStack.pop();
}
xsltFileStack.push(currentXsltUri);
return new StreamSource(currentXsltUri.toURL().openStream());
} catch (IOException e) {
throw new SystemException(XsltErrorType.ERROR_FINDING_XSLT, e)
.addContextValue(XsltErrorContext.XSLT, s);
}
}
/**
* Resolve a path against an URI (even when opaque, i.e. in a jar).
*
* @param uri the URI.
* @param s the path.
* @return the resolved URI.
*/
private URI resolveUri(@NonNull final URI uri,
@NonNull final String s) {
// if URI describes a resource inside a jar, resolve URI manually.
return uri.isOpaque() ?
URI.create(FilenameUtils.getFullPath(uri.toString()) + s) : uri.resolve(s);
}
private boolean uriReferenceExists(@NonNull final URI uri) {
InputStream inputStream = null;
try {
inputStream = uri.toURL().openStream();
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy