//$Id: DTDEntityResolver.java 10936 2009-05-21 19:27:34Z norman.richards@jboss.com $ //Contributed by Markus Meissner package org.jboss.seam.util; import java.io.InputStream; import java.io.Serializable; import org.jboss.seam.contexts.ServletLifecycle; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; /** * An {@link EntityResolver} implementation which attempts to resolve * various systemId URLs to local classpath lookups<ol> * <li>Any systemId URL beginning with <tt>http://jboss.com/products/seam/</tt> is * searched for as a classpath resource in the classloader which loaded the * Seam classes.</li> * <li>Any systemId URL using <tt>classpath</tt> as the scheme (i.e. starting * with <tt>classpath://</tt> is searched for as a classpath resource using first * the current thread context classloader and then the classloader which loaded * the Seam classes. * </ol> * <p/> * Any entity references which cannot be resolved in relation to the above * rules result in returning null, which should force the SAX reader to * handle the entity reference in its default manner. */ public class DTDEntityResolver implements EntityResolver, Serializable { private static final long serialVersionUID = -4553926061006790714L; private static final LogProvider log = Logging.getLogProvider(DTDEntityResolver.class); private static final String SEAM_NAMESPACE = "http://jboss.com/products/seam/"; private static final String USER_NAMESPACE = "classpath://"; public InputSource resolveEntity(String publicId, String systemId) { if (systemId != null) { log.trace("trying to resolve system-id [" + systemId + "]"); if (systemId.startsWith(SEAM_NAMESPACE)) { log.trace("recognized Seam namespace; attempting to resolve on classpath under org/jboss/seam/"); String path = "org/jboss/seam/" + systemId.substring(SEAM_NAMESPACE.length()); InputStream dtdStream = resolveInSeamNamespace(path); if (dtdStream == null) { log.warn("unable to locate [" + systemId + "] on classpath"); } else { log.debug("located [" + systemId + "] in classpath"); InputSource source = new InputSource(dtdStream); source.setPublicId(publicId); source.setSystemId(systemId); return source; } } else if (systemId.startsWith(USER_NAMESPACE)) { log.trace("recognized local namespace; attempting to resolve on classpath"); String path = systemId.substring(USER_NAMESPACE.length()); InputStream stream = resolveInLocalNamespace(path); if (stream == null) { log.warn("unable to locate [" + systemId + "] on classpath"); } else { log.debug("located [" + systemId + "] in classpath"); InputSource source = new InputSource(stream); source.setPublicId(publicId); source.setSystemId(systemId); return source; } } } // use default behavior return null; } protected InputStream resolveInSeamNamespace(String path) { return this.getClass().getClassLoader().getResourceAsStream(path); } protected InputStream resolveInLocalNamespace(String path) { try { return Resources.getResourceAsStream(path, ServletLifecycle.getServletContext()); } catch (Throwable t) { return null; } } }