bruno 2003/06/07 14:16:10
Modified: src/java/org/apache/cocoon/xml XMLBaseSupport.java Log: Refactored to use SourceResolver instead of java.net.URL to resolve paths. Revision Changes Path 1.2 +48 -38 cocoon-2.1/src/java/org/apache/cocoon/xml/XMLBaseSupport.java Index: XMLBaseSupport.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/xml/XMLBaseSupport.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- XMLBaseSupport.java 20 May 2003 11:58:23 -0000 1.1 +++ XMLBaseSupport.java 7 Jun 2003 21:16:10 -0000 1.2 @@ -52,10 +52,13 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.apache.excalibur.source.SourceResolver; +import org.apache.excalibur.source.Source; +import org.apache.avalon.framework.logger.Logger; -import java.net.URL; -import java.net.MalformedURLException; import java.util.Stack; +import java.util.Collections; +import java.io.IOException; /** * Helper class for handling xml:base attributes. @@ -68,9 +71,6 @@ * <li>to resolve a relative URL against the current base, call [EMAIL PROTECTED] #makeAbsolute}. * </ul> * - * Internally this class makes use of the java.net.URL class, and hence only supports - * URL schemes recognized by the JDK. - * * <p>External entities are not yet taken into account when determing the current base. */ public class XMLBaseSupport { @@ -84,52 +84,69 @@ * that contained an xml:base attribute (not for the other elements). */ private Stack bases = new Stack(); + private SourceResolver resolver; + private Logger logger; + + public XMLBaseSupport(SourceResolver resolver, Logger logger) { + this.resolver = resolver; + this.logger = logger; + } - public void setDocumentLocation(String loc) throws MalformedURLException { + public void setDocumentLocation(String loc) throws SAXException { // -2 is used as level to avoid this BaseInfo to be ever popped of the stack - bases.push(new BaseInfo(new URL(loc), -2)); + bases.push(new BaseInfo(loc, -2)); } public void startElement(String namespaceURI, String localName, String qName, Attributes attrs) throws SAXException { level++; String base = attrs.getValue(XMLBASE_NAMESPACE_URI, XMLBASE_ATTRIBUTE); if (base != null) { - URL baseUrl; - URL currentBaseUrl = getCurrentBase(); - try { - if (currentBaseUrl != null) - baseUrl = new URL(currentBaseUrl, base); - else - baseUrl = new URL(base); - } catch (MalformedURLException e) { - throw new SAXException("Problem with URL in xml:base attribute: \"" + base + "\": " + e.toString()); - } + String baseUrl = resolve(getCurrentBase(), base); bases.push(new BaseInfo(baseUrl, level)); } } public void endElement(String namespaceURI, String localName, String qName) { if (getCurrentBaseLevel() == level) - bases.peek(); + bases.pop(); level--; } + private String resolve(String baseURI, String location) throws SAXException { + try { + String url; + if (baseURI != null) { + Source source = resolver.resolveURI(location, baseURI, Collections.EMPTY_MAP); + try { + url = source.getURI(); + } finally { + resolver.release(source); + } + } else { + Source source = resolver.resolveURI(location); + try { + url = source.getURI(); + } finally { + resolver.release(source); + } + } + if (logger.isDebugEnabled()) + logger.debug("XMLBaseSupport: resolved location " + location + " against base URI " + baseURI + " to " + url); + return url; + } catch (IOException e) { + throw new SAXException("XMLBaseSupport: problem resolving uri.", e); + } + } + /** * Makes the given path absolute based on the current base URL. * @param spec any URL (relative or absolute, containing a scheme or not) */ - public String makeAbsolute(String spec) throws MalformedURLException { - if (containsScheme(spec)) - return spec; - - URL currentBaseUrl = getCurrentBase(); - if (currentBaseUrl != null) - return new URL(currentBaseUrl, spec).toExternalForm(); - else - return new URL(spec).toExternalForm(); + public String makeAbsolute(String spec) throws SAXException { + return resolve(getCurrentBase(), spec); } - private URL getCurrentBase() { + private String getCurrentBase() { if (bases.size() > 0) { BaseInfo baseInfo = (BaseInfo)bases.peek(); return baseInfo.getUrl(); @@ -145,23 +162,16 @@ return -1; } - /** - * Returns true if the specified path contains a scheme specification part. - */ - private boolean containsScheme(String path) { - return (path.indexOf(':') < path.indexOf('/')); - } - private static final class BaseInfo { - private URL url; + private String url; private int level; - public BaseInfo(URL url, int level) { + public BaseInfo(String url, int level) { this.url = url; this.level = level; } - public URL getUrl() { + public String getUrl() { return url; }