package org.tigris.juxy.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.xml.transform.Source; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.IOException; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; /** * @author Pavel Sher */ public class JuxyURIResolver implements URIResolver { private static final Log logger = LogFactory.getLog(JuxyURIResolver.class); public Source resolve(String href, String base) { logger.debug("Resolving URI: " + href + " against base URI: " + base); if (href == null) return null; URI hrefURI; try { hrefURI = new URI(href); } catch (URISyntaxException e) { hrefURI = new File(href).toURI(); } URI baseURI = null; if (base != null && base.length() > 0) { try { baseURI = new URI(base); } catch (URISyntaxException e) { try { baseURI = new File(base).getCanonicalFile().toURI(); } catch (IOException e1) { logger.error(e1); } } } URI resolvedHrefURI = hrefURI; if (baseURI != null) resolvedHrefURI = resolveFromBase(baseURI, hrefURI); if ("jar".equals(resolvedHrefURI.getScheme())) { return new StreamSource(resolvedHrefURI.toString()); } File file; if (resolvedHrefURI.isAbsolute() && "file".equals(resolvedHrefURI.getScheme())) file = new File(resolvedHrefURI); else file = new File(href); try { file = file.getCanonicalFile(); } catch (IOException e) { logger.error(e); } if (file != null && file.exists()) { String systemId = file.toURI().toString(); logger.debug("Resolved URI: " + systemId); return new StreamSource(systemId); } // attempt to resolve URI via classloader String resourceName = resolvedHrefURI.toString(); if (resolvedHrefURI.getScheme() != null) { resourceName = resolvedHrefURI.getSchemeSpecificPart(); } URL found = getClass().getResource(resourceName); if (found != null) { String resolved = found.toString(); logger.debug("URI was resolved via classloader resources: " + resolved); return new StreamSource(resolved); } logger.warn("Failed to resolve URI: " + href); return null; } private String getResourcePath(final String uri) { int absPathIdx = uri.indexOf("!"); if (absPathIdx == -1) return "/"; if (absPathIdx == uri.length() - 1) { return "/"; } return uri.substring(absPathIdx + 1); } private String getResourceBase(final String uri) { int absPathIdx = uri.indexOf("!"); if (absPathIdx == -1 || absPathIdx == uri.length() - 1) return uri; return uri.substring(0, absPathIdx); } private URI resolveFromBase(final URI baseURI, URI hrefURI) { if ("jar".equals(baseURI.getScheme())) { if ("jar".equals(hrefURI.getScheme())) return hrefURI; if (hrefURI.isAbsolute()) return hrefURI; String path = getResourcePath(baseURI.toString()); try { hrefURI = new URI(path).resolve(hrefURI); return new URI(getResourceBase(baseURI.toString()) + "!" + hrefURI.toString()); } catch (URISyntaxException e) { logger.debug(e.toString()); } } return baseURI.resolve(hrefURI); } private String toSystemId(File f) { String fpath=f.getAbsolutePath(); if (File.separatorChar != '/') { fpath = fpath.replace(File.separatorChar, '/'); } if( fpath.startsWith("/")) return "file://" + fpath; else return "file:///" + fpath; } }