protected void processXIncludeElement()

in core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/transformation/XIncludeTransformer.java [442:579]


        protected void processXIncludeElement(String href, String parse, String xpointer)
        throws SAXException,ProcessingException,IOException {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Processing XInclude element: href="+href+", parse="+parse+", xpointer="+xpointer);
            }

            // Default for @parse is "xml"
            if (parse == null) {
                parse = "xml";
            }
            Source url = null;

            try {
                int fragmentIdentifierPos = href.indexOf('#');
                if (fragmentIdentifierPos != -1) {
                    getLogger().warn("Fragment identifer found in 'href' attribute: " + href + 
                            "\nFragment identifiers are forbidden by the XInclude specification. " +
                            "They are still handled by XIncludeTransformer for backward " +
                            "compatibility, but their use is deprecated and will be prohibited " +
                            "in a future release.  Use the 'xpointer' attribute instead.");
                    if (xpointer == null) {
                        xpointer = href.substring(fragmentIdentifierPos + 1);
                    }
                    href = href.substring(0, fragmentIdentifierPos);
                }

                // An empty or absent href is a reference to the current document -- this can be different than the current base
                if (href == null || href.length() == 0) {
                    if (this.href == null) {
                        throw new SAXException("XIncludeTransformer: encountered empty href (= href pointing to the current document) but the location of the current document is unknown.");
                    }
                    // The following can be simplified once fragment identifiers are prohibited
                    int fragmentIdentifierPos2 = this.href.indexOf('#');
                    if (fragmentIdentifierPos2 != -1)
                        href = this.href.substring(0, fragmentIdentifierPos2);
                    else
                        href = this.href;
                }

                url = xmlBaseSupport.makeAbsolute(href);
                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("URL: " + url.getURI() + "\nXPointer: " + xpointer);
                }

                // add the source to the SourceValidity 
                validity.addSource(url); 

                if (parse.equals("text")) {
                    getLogger().debug("Parse type is text");
                    if (xpointer != null) {
                        throw new SAXException("xpointer attribute must not be present when parse='text': " + getLocation());
                    }
                    InputStream is = null;
                    InputStreamReader isr = null;
                    Reader reader = null;
                    try {
                        is = url.getInputStream();
                        isr = new InputStreamReader(is);
                        reader = new BufferedReader(isr);
                        int read;
                        char ary[] = new char[1024 * 4];
                        while ((read = reader.read(ary)) != -1) {
                            super.characters(ary,0,read);
                        }
                    } catch (SourceNotFoundException e) {
                        useFallbackLevel++;
                        fallBackException = new CascadingException("Resource not found: " + url.getURI());
                        getLogger().error("xIncluded resource not found: " + url.getURI(), e);
                    } finally {
                        if (reader != null) reader.close();
                        if (isr != null) isr.close();
                        if (is != null) is.close();
                    }
                } else if (parse.equals("xml")) {
                    getLogger().debug("Parse type is XML");

                    // Check loop inclusion
                    if (isLoopInclusion(url.getURI(), xpointer)) {
                        throw new ProcessingException("Detected loop inclusion of href=" + url.getURI() + ", xpointer=" + xpointer);
                    }

                    XIncludePipe subPipe = new XIncludePipe();
                    subPipe.init(url.getURI(), xpointer);
                    subPipe.setConsumer(xmlConsumer);
                    subPipe.setParent(this);

                    try {
                        if (xpointer != null && xpointer.length() > 0) {
                            XPointer xptr;
                            xptr = XPointerFrameworkParser.parse(NetUtils.decodePath(xpointer));
                            XPointerContext context = new XPointerContext(xpointer, url, subPipe, manager);
                            for (Iterator iter = namespaces.keySet().iterator(); iter.hasNext();) {
                                String prefix = (String) iter.next();
                                context.addPrefix(prefix, (String) namespaces.get(prefix));
                            }
                            xptr.process(context);
                        } else {
                            SourceUtil.toSAX(manager, url, new IncludeXMLConsumer(subPipe));
                        }
                        // restore locator on the consumer
                        if (locator != null)
                            xmlConsumer.setDocumentLocator(locator);
                    } catch (ResourceNotFoundException e) {
                        useFallbackLevel++;
                        fallBackException = new CascadingException("Resource not found: " + url.getURI());
                        getLogger().error("xIncluded resource not found: " + url.getURI(), e);
                    } catch (ParseException e) {
                        // this exception is thrown in case of an invalid xpointer expression
                        useFallbackLevel++;
                        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) {
                        useFallbackLevel++;
                        fallBackException = e;
                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
                    } catch(IOException e) {
                        useFallbackLevel++;
                        fallBackException = e;
                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
                    }
                } else {
                    throw new SAXException("Found 'parse' attribute with unknown value " + parse + " at " + getLocation());
                }
            } catch (SourceException se) {
                throw SourceUtil.handle(se);
            } finally {
                if (url != null) {
                    resolver.release(url);
                }
            }
        }