You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by br...@apache.org on 2003/05/20 13:59:23 UTC

cvs commit: cocoon-2.1/src/java/org/apache/cocoon/transformation XIncludeTransformer.java

bruno       2003/05/20 04:59:23

  Modified:    src/java/org/apache/cocoon/transformation
                        XIncludeTransformer.java
  Log:
  refactored XIncludeTransformer:
   - better xpointer support
   - better xml:base handling
   - support for fallback element
   - do xinclude processing on included content
  
  Revision  Changes    Path
  1.2       +321 -235  cocoon-2.1/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
  
  Index: XIncludeTransformer.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XIncludeTransformer.java	9 Mar 2003 00:09:40 -0000	1.1
  +++ XIncludeTransformer.java	20 May 2003 11:59:22 -0000	1.2
  @@ -50,322 +50,408 @@
   */
   package org.apache.cocoon.transformation;
   
  -import org.apache.avalon.framework.activity.Disposable;
   import org.apache.avalon.framework.component.Component;
   import org.apache.avalon.framework.component.ComponentException;
   import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.avalon.framework.component.Composable;
   import org.apache.avalon.framework.parameters.Parameters;
  +import org.apache.avalon.framework.CascadingRuntimeException;
  +import org.apache.avalon.framework.CascadingException;
   import org.apache.cocoon.ProcessingException;
  -import org.apache.excalibur.xml.xpath.XPathProcessor;
  +import org.apache.cocoon.ResourceNotFoundException;
   import org.apache.cocoon.environment.SourceResolver;
   import org.apache.cocoon.components.source.SourceUtil;
  +import org.apache.cocoon.components.xpointer.XPointer;
  +import org.apache.cocoon.components.xpointer.parser.XPointerFrameworkParser;
  +import org.apache.cocoon.components.xpointer.parser.ParseException;
  +import org.apache.cocoon.components.xpointer.XPointerContext;
   import org.apache.cocoon.xml.IncludeXMLConsumer;
  -import org.apache.cocoon.xml.dom.DOMStreamer;
  +import org.apache.cocoon.xml.XMLBaseSupport;
  +import org.apache.cocoon.xml.AbstractXMLPipe;
  +import org.apache.cocoon.xml.XMLConsumer;
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceException;
  -import org.apache.excalibur.xml.dom.DOMParser;
   import org.apache.excalibur.xml.sax.SAXParser;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.NodeList;
  -import org.xml.sax.Attributes;
  -import org.xml.sax.InputSource;
  -import org.xml.sax.Locator;
  -import org.xml.sax.SAXException;
  +import org.xml.sax.*;
  +import org.xml.sax.ext.LexicalHandler;
   
   import java.io.*;
   import java.net.MalformedURLException;
   import java.util.Map;
  -import java.util.Stack;
   
   /**
  - * My first pass at an XInclude transformation. Currently it should set the base URI
  - * from the SAX Locator's system id but allow it to be overridden by xml:base
  - * elements as the XInclude spec mandates. It's also got some untested code
  - * that should handle inclusion of text includes, but that method isn't called
  - * by the SAX event FSM yet.
  + * Implementation of an XInclude transformer. It supports xml:base attributes,
  + * xpointer fragment identifiers (see the xpointer package to see what exactly is supported),
  + * fallback elements, and does xinclude processing on the included content and on the content
  + * of fallback elements (with loop inclusion detection).
    *
  - * @author <a href="mailto:balld@webslingerZ.com">Donald Ball</a>
  + * @author <a href="mailto:balld@webslingerZ.com">Donald Ball</a> (wrote the original version)
    * @version CVS $Id$
    */
  -public class XIncludeTransformer extends AbstractTransformer implements Composable, Disposable {
  -
  +public class XIncludeTransformer extends AbstractTransformer implements Composable {
       private SourceResolver resolver;
  -
  -    /** XPath Processor */
  -    private XPathProcessor processor = null;
  -
       protected ComponentManager manager = null;
  +    private XIncludePipe xIncludePipe;
   
       public static final String XMLBASE_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
       public static final String XMLBASE_ATTRIBUTE = "base";
   
       public static final String XINCLUDE_NAMESPACE_URI = "http://www.w3.org/2001/XInclude";
       public static final String XINCLUDE_INCLUDE_ELEMENT = "include";
  +    public static final String XINCLUDE_FALLBACK_ELEMENT = "fallback";
       public static final String XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE = "href";
       public static final String XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE = "parse";
   
  -    protected Source base_xmlbase_uri = null;
  -
  -    /** The current XMLBase URI. We start with an empty "dummy" URL. **/
  -    protected Source current_xmlbase_uri = null;
  -
  -    /** This is a stack of xml:base attributes which belong to our ancestors **/
  -    protected Stack xmlbase_stack = new Stack();
   
  -    /** namespace uri of the last element which had an xml:base attribute **/
  -    protected String last_xmlbase_element_uri = "";
  -
  -    protected Stack xmlbase_element_uri_stack = new Stack();
  +    public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters)
  +            throws ProcessingException, SAXException, IOException {
  +        this.resolver = resolver;
  +        this.xIncludePipe = new XIncludePipe(null);
  +        this.xIncludePipe.enableLogging(getLogger());
  +        super.setConsumer(xIncludePipe);
  +    }
   
  -    /** name of the last element which had an xml:base attribute **/
  -    protected String last_xmlbase_element_name = "";
  +    public void setConsumer(XMLConsumer consumer) {
  +        xIncludePipe.setConsumer(consumer);
  +    }
   
  -    protected Stack xmlbase_element_name_stack = new Stack();
  +    public void setContentHandler(ContentHandler handler) {
  +        xIncludePipe.setContentHandler(handler);
  +    }
   
  -    public void setup(SourceResolver resolver, Map objectModel,
  -                      String source, Parameters parameters)
  -            throws ProcessingException, SAXException, IOException {
  -        this.resolver = resolver;
  +    public void setLexicalHandler(LexicalHandler handler) {
  +        xIncludePipe.setLexicalHandler(handler);
       }
   
       public void compose(ComponentManager manager) {
           this.manager = manager;
  -        try {
  -            this.processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
  -        } catch (Exception e) {
  -            getLogger().error("cannot obtain XPathProcessor", e);
  -        }
       }
   
  -    public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException {
  -        String value;
  -        if ((value = attr.getValue(XMLBASE_NAMESPACE_URI,XMLBASE_ATTRIBUTE)) != null) {
  -            try {
  -                startXMLBaseAttribute(uri,name,value);
  -            } catch (ProcessingException e) {
  -                getLogger().debug("Rethrowing exception", e);
  -                throw new SAXException(e);
  +    public void recycle()
  +    {
  +        // Reset all variables to initial state.
  +        this.resolver = null;
  +        this.xIncludePipe = null;
  +        super.recycle();
  +    }
  +
  +    /**
  +     * XMLPipe that processes XInclude elements. To perform XInclude processing on included content,
  +     * this class is instantiated recursively.
  +     */
  +    private class XIncludePipe extends AbstractXMLPipe {
  +        /** Helper class to keep track of xml:base attributes */
  +        private XMLBaseSupport xmlBaseSupport = new XMLBaseSupport();
  +        /** Element nesting level when inside an xi:include element. */
  +        private int xIncludeLevel = 0;
  +        /** Should the content of the fallback element be inserted when it is encountered? */
  +        private boolean useFallback = false;
  +        /** Element nesting level when inside the fallback element. */
  +        private int fallbackLevel;
  +        /** In case {@link #useFallback} = true, then this should contain the exception that caused fallback to be needed. */
  +        private Exception fallBackException;
  +        /**
  +         * Locator of the current stream, stored here so that it can be restored after
  +         * another document send its content to the consumer.
  +         */
  +        private Locator locator;
  +        /**
  +         * Value of the href attribute of the xi:include element that caused the creation of the this
  +         * XIncludePipe. Used to detect loop inclusions.
  +         * */
  +        private String href;
  +        private XIncludePipe parent;
  +
  +        public XIncludePipe(String uri) {
  +            this.href = uri;
  +        }
  +
  +        public void setParent(XIncludePipe parent) {
  +            this.parent = parent;
  +        }
  +
  +        public XIncludePipe getParent() {
  +            return parent;
  +        }
  +
  +        public String getHref() {
  +            return href;
  +        }
  +
  +        public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException {
  +            if (xIncludeLevel == 1 && useFallback && uri.equals(XINCLUDE_NAMESPACE_URI)
  +                    && name.equals(XINCLUDE_FALLBACK_ELEMENT)) {
  +                fallbackLevel++;
  +
  +                // don't need these anymore
  +                useFallback = false;
  +                fallBackException = null;
  +
  +                return;
  +            } else if (xIncludeLevel > 0 && fallbackLevel < 1) {
  +                xIncludeLevel++;
  +                return;
               }
  -        }
  -        if (XINCLUDE_NAMESPACE_URI.equals(uri) && XINCLUDE_INCLUDE_ELEMENT.equals(name)) {
  -            String href = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE);
  -            String parse = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE);
   
  -            if (null == parse) parse="xml";
  +            xmlBaseSupport.startElement(uri, name, raw, attr);
  +            if (XINCLUDE_NAMESPACE_URI.equals(uri) && XINCLUDE_INCLUDE_ELEMENT.equals(name)) {
  +                String href = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE);
  +                String parse = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE);
   
  -            try {
  -                processXIncludeElement(href, parse);
  -            } catch (ProcessingException e) {
  -                getLogger().debug("Rethrowing exception", e);
  -                throw new SAXException(e);
  -            } catch (IOException e) {
  -                getLogger().debug("Rethrowing exception", e);
  -                throw new SAXException(e);
  -            }
  -            return;
  -        }
  -        super.startElement(uri,name,raw,attr);
  -    }
  +                if (null == parse) parse="xml";
  +                xIncludeLevel++;
   
  -    public void endElement(String uri, String name, String raw) throws SAXException {
  -        if (last_xmlbase_element_uri.equals(uri) && last_xmlbase_element_name.equals(name)) {
  -            endXMLBaseAttribute();
  -        }
  -        if (uri != null && name != null && uri.equals(XINCLUDE_NAMESPACE_URI) && name.equals(XINCLUDE_INCLUDE_ELEMENT)) {
  -            return;
  +                try {
  +                    processXIncludeElement(href, parse);
  +                } catch (ProcessingException e) {
  +                    getLogger().debug("Rethrowing exception", e);
  +                    throw new SAXException(e);
  +                } catch (IOException e) {
  +                    getLogger().debug("Rethrowing exception", e);
  +                    throw new SAXException(e);
  +                }
  +                return;
  +            }
  +            super.startElement(uri,name,raw,attr);
           }
  -        super.endElement(uri,name,raw);
  -    }
   
  -    public void setDocumentLocator(Locator locator) {
  -        try {
  -            if (getLogger().isDebugEnabled()) {
  -                getLogger().debug("setDocumentLocator called " + locator.getSystemId());
  +        public void endElement(String uri, String name, String raw) throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1) {
  +                xIncludeLevel--;
  +                if (xIncludeLevel == 0 && useFallback) {
  +                    // an error was encountered but a fallback element was not found: throw the error now
  +                    useFallback = false;
  +                    Exception localFallBackException = fallBackException;
  +                    fallBackException = null;
  +                    fallbackLevel = 0;
  +                    getLogger().error("Exception occured during xinclude processing, and did not find a fallback element.", localFallBackException);
  +                    throw new SAXException("Exception occured during xinclude processing, and did not find a fallback element: " + localFallBackException.getMessage());
  +                }
  +                return;
               }
   
  -            base_xmlbase_uri = this.resolver.resolveURI(locator.getSystemId());
  -
  -            // If url ends with .xxx then truncate to dir
  -            if (base_xmlbase_uri.getURI().lastIndexOf('.') > base_xmlbase_uri.getURI().lastIndexOf('/')) {
  -               String uri = base_xmlbase_uri.getURI().substring(0,base_xmlbase_uri.getURI().lastIndexOf('/')+1);
  -               this.resolver.release(base_xmlbase_uri);
  -               base_xmlbase_uri = null;
  -               base_xmlbase_uri = this.resolver.resolveURI(uri);
  +            if (fallbackLevel > 0) {
  +                fallbackLevel--;
  +                if (fallbackLevel == 0)
  +                    return;
               }
   
  -            if (current_xmlbase_uri == null) {
  -               current_xmlbase_uri = base_xmlbase_uri;
  -            }
  +            xmlBaseSupport.endElement(uri, name, raw);
  +            super.endElement(uri,name,raw);
  +        }
   
  -        } catch (Exception e) {
  -            getLogger().debug("Exception ignored", e);
  +        public void startPrefixMapping(String prefix, String uri)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.startPrefixMapping(prefix, uri);
  +        }
  +
  +        public void endPrefixMapping(String prefix)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.endPrefixMapping(prefix);
           }
  -        super.setDocumentLocator(locator);
  -    }
   
  -    protected void startXMLBaseAttribute(String uri, String name, String value) throws ProcessingException {
  -        String urlLoc = value;
  +        public void characters(char c[], int start, int len)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.characters(c, start, len);
  +        }
   
  -        if (! urlLoc.endsWith("/")) {
  -            urlLoc += "/";
  +        public void ignorableWhitespace(char c[], int start, int len)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.ignorableWhitespace(c, start, len);
           }
   
  -        if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("XMLBase = " + urlLoc);
  +        public void processingInstruction(String target, String data)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.processingInstruction(target, data);
           }
   
  -        if (current_xmlbase_uri != null) {
  -            xmlbase_stack.push(current_xmlbase_uri);
  +        public void skippedEntity(String name)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.skippedEntity(name);
           }
   
  -        try {
  -            current_xmlbase_uri = this.resolver.resolveURI(urlLoc);
  +        public void startEntity(String name)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.startEntity(name);
  +        }
   
  -            xmlbase_element_uri_stack.push(last_xmlbase_element_uri);
  -            last_xmlbase_element_uri = uri;
  +        public void endEntity(String name)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.endEntity(name);
  +        }
   
  -            xmlbase_element_name_stack.push(last_xmlbase_element_name);
  -            last_xmlbase_element_name = name;
  -        } catch (SourceException e) {
  -            throw SourceUtil.handle(e);
  -        } catch (Exception e) {
  -            throw new ProcessingException("Could not resolve '" + urlLoc + "'", e);
  +        public void startCDATA()
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.startCDATA();
           }
  -    }
   
  -    protected void endXMLBaseAttribute() {
  -        if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("XMLBase ended");
  +        public void endCDATA()
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.endCDATA();
           }
   
  -        if (xmlbase_stack.size() > 0) {
  -            current_xmlbase_uri = (Source)xmlbase_stack.pop();
  -        } else {
  -            current_xmlbase_uri = base_xmlbase_uri;
  +        public void comment(char ch[], int start, int len)
  +                throws SAXException {
  +            if (xIncludeLevel > 0 && fallbackLevel < 1)
  +                return;
  +            super.comment(ch, start, len);
           }
  -        last_xmlbase_element_uri = (String)xmlbase_element_uri_stack.pop();
  -        last_xmlbase_element_name = (String)xmlbase_element_name_stack.pop();
  -    }
   
  -    protected void processXIncludeElement(String href, String parse)
  -    throws SAXException,ProcessingException,IOException {
  -        if (getLogger().isDebugEnabled()) {
  -            getLogger().debug("Processing XInclude element: href="+href+", parse="+parse);
  -            if(current_xmlbase_uri == null)
  -                getLogger().debug("Base URI: null");
  -            else
  -                getLogger().debug("Base URI: " + current_xmlbase_uri.getURI());
  -        }
  -
  -        Source url = null;
  -        String suffix;
  -        try {
  -            int index = href.indexOf('#');
  -            if (index < 0) {
  -                if(current_xmlbase_uri == null)
  -                    url = this.resolver.resolveURI(href);
  -                else
  -                    url = this.resolver.resolveURI(current_xmlbase_uri.getURI() + href);
  -                suffix = "";
  -            } else {
  -                if(current_xmlbase_uri == null)
  -                    url = this.resolver.resolveURI(href.substring(0,index));
  -                else
  -                    url = this.resolver.resolveURI(current_xmlbase_uri.getURI() + href.substring(0,index));
  -                suffix = href.substring(index+1);
  +        public void setDocumentLocator(Locator locator) {
  +            try {
  +                if (getLogger().isDebugEnabled()) {
  +                    getLogger().debug("setDocumentLocator called " + locator.getSystemId());
  +                }
  +
  +                Source source = resolver.resolveURI(locator.getSystemId());
  +                try {
  +                    xmlBaseSupport.setDocumentLocation(source.getURI());
  +                    // only for the "root" XIncludePipe, we'll have to set the href here, in the other cases
  +                    // the href is taken from the xi:include href attribute
  +                    if (href == null)
  +                        href = source.getURI();
  +                } finally {
  +                    resolver.release(source);
  +                }
  +            } catch (Exception e) {
  +                throw new CascadingRuntimeException("Error in XIncludeTransformer while trying to resolve base URL for document", e);
               }
  +            this.locator = locator;
  +            super.setDocumentLocator(locator);
  +        }
  +
  +        protected void processXIncludeElement(String href, String parse)
  +        throws SAXException,ProcessingException,IOException {
               if (getLogger().isDebugEnabled()) {
  -                getLogger().debug("URL: "+url+"\nSuffix: "+suffix);
  +                getLogger().debug("Processing XInclude element: href="+href+", parse="+parse);
               }
   
  -            if (parse.equals("text")) {
  -                getLogger().debug("Parse type is text");
  -                InputStream input = url.getInputStream();
  -                Reader reader = new BufferedReader(new InputStreamReader(input));
  -                int read;
  -                char ary[] = new char[1024];
  -                if (reader != null) {
  -                    while ((read = reader.read(ary)) != -1) {
  -                        super.characters(ary,0,read);
  -                    }
  -                    reader.close();
  +            Source url = null;
  +            String suffix;
  +            try {
  +                int index = href.indexOf('#');
  +                if (index < 0) {
  +                    url = resolver.resolveURI(xmlBaseSupport.makeAbsolute(href));
  +                    suffix = "";
  +                } else {
  +                    url = resolver.resolveURI(xmlBaseSupport.makeAbsolute(href.substring(0, index)));
  +                    suffix = href.substring(index+1);
  +                }
  +                if (getLogger().isDebugEnabled()) {
  +                    getLogger().debug("URL: " + url.getURI() + "\nSuffix: " + suffix);
                   }
  -            } else if (parse.equals("xml")) {
  -                getLogger().debug("Parse type is XML");
  -                try {
  -
  -                    InputSource input = SourceUtil.getInputSource(url);
   
  -                    if (suffix.startsWith("xpointer(") && suffix.endsWith(")")) {
  -                        DOMParser parser = null;
  -                        try {
  -                            parser = (DOMParser)manager.lookup(DOMParser.ROLE);
  -                            String xpath = suffix.substring(9,suffix.length()-1);
  -                            getLogger().debug("XPath is "+xpath);
  -                            Document document = parser.parseDocument(input);
  -                            NodeList list = processor.selectNodeList(document,xpath);
  -                            DOMStreamer streamer = new DOMStreamer(super.contentHandler,super.lexicalHandler);
  -                            int length = list.getLength();
  -                            for (int i=0; i<length; i++) {
  -                                streamer.stream(list.item(i));
  -                            }
  -                        } finally {
  -                            this.manager.release((Component)parser);
  +                // check loop inclusion
  +                String canonicURI = url.getURI() + (suffix.length() > 0 ? "#" + suffix: "");
  +                if (isLoopInclusion(canonicURI))
  +                    throw new ProcessingException("Detected loop inclusion of " + canonicURI);
  +
  +                if (parse.equals("text")) {
  +                    getLogger().debug("Parse type is text");
  +                    InputStream input = url.getInputStream();
  +                    Reader reader = new BufferedReader(new InputStreamReader(input));
  +                    int read;
  +                    char ary[] = new char[1024];
  +                    if (reader != null) {
  +                        while ((read = reader.read(ary)) != -1) {
  +                            super.characters(ary,0,read);
                           }
  -                    } else {
  -                        SAXParser parser = null;
  -                        try {
  -                            parser = (SAXParser)manager.lookup(SAXParser.ROLE);
  -                            IncludeXMLConsumer xinclude_handler = new IncludeXMLConsumer(super.contentHandler,super.lexicalHandler);
  -                            parser.parse(input, xinclude_handler);
  -                        } finally {
  -                            this.manager.release((Component)parser);
  +                        reader.close();
  +                    }
  +                } else if (parse.equals("xml")) {
  +                    XIncludePipe subPipe = new XIncludePipe(canonicURI);
  +                    subPipe.enableLogging(getLogger());
  +                    subPipe.setConsumer(xmlConsumer);
  +                    subPipe.setParent(this);
  +
  +                    getLogger().debug("Parse type is XML");
  +                    try {
  +                        if (suffix.length() > 0) {
  +                            XPointer xpointer;
  +                            xpointer = XPointerFrameworkParser.parse(suffix);
  +                            XPointerContext context = new XPointerContext(suffix, url, subPipe, getLogger(), manager);
  +                            xpointer.process(context);
  +                        } else {
  +                            SAXParser parser = null;
  +                            try {
  +                                parser = (SAXParser)manager.lookup(SAXParser.ROLE);
  +                                IncludeXMLConsumer xinclude_handler = new IncludeXMLConsumer(subPipe);
  +                                InputSource input = SourceUtil.getInputSource(url);
  +                                parser.parse(input, xinclude_handler);
  +                            } finally {
  +                                manager.release((Component)parser);
  +                            }
                           }
  +                        // restore locator on the consumer
  +                        if (locator != null)
  +                            xmlConsumer.setDocumentLocator(locator);
  +                    } catch (ResourceNotFoundException e) {
  +                        useFallback = true;
  +                        fallBackException = e;
  +                        getLogger().error("xIncluded resource not found: " + url.getURI(), e);
  +                    } catch (ParseException e) {
  +                        // this exception is thrown in case of an invalid xpointer expression
  +                        useFallback = true;
  +                        fallBackException = new CascadingException("Error parsing xPointer expression", e);
  +                        fallBackException.fillInStackTrace();
  +                        getLogger().error("Error parsing XPointer expression, will try to use fallback.", e);
  +                    } catch(SAXException e) {
  +                        getLogger().error("Error in processXIncludeElement", e);
  +                        throw e;
  +                    } catch(ProcessingException e) {
  +                        getLogger().error("Error in processXIncludeElement", e);
  +                        throw e;
  +                    } catch(MalformedURLException e) {
  +                        useFallback = true;
  +                        fallBackException = e;
  +                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
  +                    } catch(IOException e) {
  +                        useFallback = true;
  +                        fallBackException = e;
  +                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
  +                    } catch(ComponentException e) {
  +                        getLogger().error("Error in processXIncludeElement", e);
  +                        throw new SAXException(e);
                       }
  -                } catch(SAXException e) {
  -                    getLogger().error("Error in processXIncludeElement", e);
  -                    throw e;
  -                } catch(ProcessingException e) {
  -                    getLogger().error("Error in processXIncludeElement", e);
  -                    throw e;
  -                } catch(MalformedURLException e) {
  -                    getLogger().error("Error in processXIncludeElement", e);
  -                    throw e;
  -                } catch(IOException e) {
  -                    getLogger().error("Error in processXIncludeElement", e);
  -                    throw e;
  -                } catch(ComponentException e) {
  -                    getLogger().error("Error in processXIncludeElement", e);
  -                    throw new SAXException(e);
                   }
  +            } catch (SourceException se) {
  +                throw SourceUtil.handle(se);
  +            } finally {
  +                resolver.release(url);
               }
  -        } catch (SourceException se) {
  -            throw SourceUtil.handle(se);
  -        } finally {
  -            this.resolver.release(url);
           }
  -    }
  -
  -    public void recycle()
  -    {
  -        // Reset all variables to initial state.
  -        if (base_xmlbase_uri != null) this.resolver.release(base_xmlbase_uri);
  -        base_xmlbase_uri = null;
  -        if (current_xmlbase_uri != null) this.resolver.release(current_xmlbase_uri);
  -        current_xmlbase_uri = null;
  -        this.resolver = null;
  -        xmlbase_stack = new Stack();
  -        last_xmlbase_element_uri = "";
  -        xmlbase_element_uri_stack = new Stack();
  -        last_xmlbase_element_name = "";
  -        xmlbase_element_name_stack = new Stack();
  -        super.recycle();
  -    }
   
  -    public void dispose()
  -    {
  -        if (this.processor instanceof Component)
  -            this.manager.release((Component)this.processor);
  +        public boolean isLoopInclusion(String uri) {
  +            if (uri.equals(this.href))
  +                return true;
  +
  +            XIncludePipe parent = getParent();
  +            while (parent != null) {
  +                if (uri.equals(parent.getHref()))
  +                    return true;
  +                parent = parent.getParent();
  +            }
  +            return false;
  +        }
       }
   }
  
  
  

Re: cvs commit: cocoon-2.1/src/java/org/apache/cocoon/transformation XIncludeTransformer.java

Posted by Bruno Dumon <br...@outerthought.org>.
On Tue, 2003-05-20 at 15:10, Vadim Gritsenko wrote:
> bruno@apache.org wrote:
> 
> >bruno       2003/05/20 04:59:23
> >
> >  Modified:    src/java/org/apache/cocoon/transformation
> >                        XIncludeTransformer.java
> >  Log:
> >  refactored XIncludeTransformer:
> >   - better xpointer support
> >
> 
> Quick question / confirmation: Old xpath syntax is still supported, right?
> 

The old syntax was a kind of very limited implementation, so yes, that's
still supported. (if I broke something: let me know)

-- 
Bruno Dumon                             http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
bruno@outerthought.org                          bruno@apache.org


Re: cvs commit: cocoon-2.1/src/java/org/apache/cocoon/transformation XIncludeTransformer.java

Posted by Vadim Gritsenko <va...@verizon.net>.
bruno@apache.org wrote:

>bruno       2003/05/20 04:59:23
>
>  Modified:    src/java/org/apache/cocoon/transformation
>                        XIncludeTransformer.java
>  Log:
>  refactored XIncludeTransformer:
>   - better xpointer support
>

Quick question / confirmation: Old xpath syntax is still supported, right?

Vadim



Re: cvs commit: cocoon-2.1/src/java/org/apache/cocoon/transformation XIncludeTransformer.java

Posted by Vadim Gritsenko <va...@verizon.net>.
bruno@apache.org wrote:

>bruno       2003/05/20 04:59:23
>
>  Modified:    src/java/org/apache/cocoon/transformation
>                        XIncludeTransformer.java
>  Log:
>  refactored XIncludeTransformer:
>   - better xpointer support
>

Quick question / confirmation: Old xpath syntax is still supported, right?

Vadim