cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anto...@apache.org
Subject svn commit: r409936 - in /cocoon/branches/BRANCH_2_1_X: ./ src/java/org/apache/cocoon/transformation/ src/webapp/samples/aggregation/content/
Date Sun, 28 May 2006 07:48:16 GMT
Author: antonio
Date: Sun May 28 00:48:14 2006
New Revision: 409936

URL: http://svn.apache.org/viewvc?rev=409936&view=rev
Log:
Fix COCOON-1753 XInclude transformer uses href fragment rather than xpointer attribute (spec
conformance). Thanks to Jason Johnston (cocoon@lojjic.net).

Modified:
    cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
    cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test.xml
    cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test4.xml
    cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/xhtml.xml
    cocoon/branches/BRANCH_2_1_X/status.xml

Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java?rev=409936&r1=409935&r2=409936&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
(original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
Sun May 28 00:48:14 2006
@@ -85,6 +85,7 @@
     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_XPOINTER_ATTRIBUTE = "xpointer";
     public static final String XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE = "parse";
 
     private static final String XINCLUDE_CACHE_KEY = "XInclude"; 
@@ -98,7 +99,7 @@
         this.validity = new MultiSourceValidity(resolver, MultiSourceValidity.CHECK_ALWAYS);

         this.xIncludePipe = new XIncludePipe(); 
         this.xIncludePipe.enableLogging(getLogger());
-        this.xIncludePipe.init(null);
+        this.xIncludePipe.init(null, null);
         super.setContentHandler(xIncludePipe);
         super.setLexicalHandler(xIncludePipe);
     }
@@ -163,10 +164,18 @@
          * XIncludePipe. Used to detect loop inclusions.
          * */
         private String href;
+
+        /**
+         * Value of the xpointer attribute of the xi:include element that caused the creation
of this
+         * XIncludePipe. Used to detect loop inclusions.
+         */
+        private String xpointer;
+
         private XIncludePipe parent;
 
-        public void init(String uri) {
+        public void init(String uri, String xpointer) {
             this.href = uri;
+            this.xpointer = xpointer;
             this.xmlBaseSupport = new XMLBaseSupport(resolver, getLogger());
         }
 
@@ -182,6 +191,10 @@
             return href;
         }
 
+        public String getXpointer() {
+            return xpointer;
+        }
+
         public void endDocument() throws SAXException { 
             // We won't be getting any more sources so mark the MultiSourceValidity as finished.

             validity.close(); 
@@ -208,17 +221,14 @@
             if (XINCLUDE_NAMESPACE_URI.equals(uri)) {
                 if (XINCLUDE_INCLUDE_ELEMENT.equals(name)) {
                     String href = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE);
-                    if (href == null) {
-                        throw new SAXException(raw + " must have a 'href' attribute at "
+ getLocation());
-                    }
 
                     String parse = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE);
+                    String xpointer = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_XPOINTER_ATTRIBUTE);
 
-                    if (null == parse) parse="xml";
                     xIncludeLevel++;
 
                     try {
-                        processXIncludeElement(href, parse);
+                        processXIncludeElement(href, parse, xpointer);
                     } catch (ProcessingException e) {
                         getLogger().debug("Rethrowing exception", e);
                         throw new SAXException(e);
@@ -366,25 +376,38 @@
             super.setDocumentLocator(locator);
         }
 
-        protected void processXIncludeElement(String href, String parse)
+        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);
+                getLogger().debug("Processing XInclude element: href="+href+", parse="+parse+",
xpointer="+xpointer);
             }
 
+            // Default for @parse is "xml"
+            if (parse == null) {
+                parse = "xml";
+            }
             Source url = null;
-            String suffix = "";
+
             try {
                 int fragmentIdentifierPos = href.indexOf('#');
                 if (fragmentIdentifierPos != -1) {
-                    suffix = href.substring(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 href is a reference to the current document -- this can be different
than the current base
-                if (href.length() == 0) {
-                    if (this.href == null)
+                // 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);
@@ -394,19 +417,17 @@
 
                 url = xmlBaseSupport.makeAbsolute(href);
                 if (getLogger().isDebugEnabled()) {
-                    getLogger().debug("URL: " + url.getURI() + "\nSuffix: " + suffix);
+                    getLogger().debug("URL: " + url.getURI() + "\nXPointer: " + xpointer);
                 }
 
                 // add the source to the SourceValidity 
                 validity.addSource(url); 
- 
-                // 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");
+                    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;
@@ -425,19 +446,25 @@
                         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.enableLogging(getLogger());
-                    subPipe.init(canonicURI);
+                    subPipe.init(url.getURI(), xpointer);
                     subPipe.setConsumer(xmlConsumer);
                     subPipe.setParent(this);
 
-                    getLogger().debug("Parse type is XML");
                     try {
-                        if (suffix.length() > 0) {
-                            XPointer xpointer;
-                            xpointer = XPointerFrameworkParser.parse(NetUtils.decodePath(suffix));
-                            XPointerContext context = new XPointerContext(suffix, url, subPipe,
getLogger(), manager);
-                            xpointer.process(context);
+                        if (xpointer != null && xpointer.length() > 0) {
+                            XPointer xptr;
+                            xptr = XPointerFrameworkParser.parse(NetUtils.decodePath(xpointer));
+                            XPointerContext context = new XPointerContext(xpointer, url,
subPipe, getLogger(), manager);
+                            xptr.process(context);
                         } else {
                             SourceUtil.toSAX(url, new IncludeXMLConsumer(subPipe));
                         }
@@ -469,6 +496,8 @@
                         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);
@@ -479,14 +508,18 @@
             }
         }
 
-        public boolean isLoopInclusion(String uri) {
-            if (uri.equals(this.href)) {
+        public boolean isLoopInclusion(String uri, String xpointer) {
+            if (xpointer == null) {
+                xpointer = "";
+            }
+
+            if (uri.equals(this.href) && xpointer.equals(this.xpointer == null ?
"" : this.xpointer)) {
                 return true;
             }
 
             XIncludePipe parent = getParent();
             while (parent != null) {
-                if (uri.equals(parent.getHref())) {
+                if (uri.equals(parent.getHref()) && xpointer.equals(parent.getXpointer()
== null ? "" : parent.getXpointer())) {
                     return true;
                 }
                 parent = parent.getParent();

Modified: cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test.xml?rev=409936&r1=409935&r2=409936&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test.xml Sun May 28
00:48:14 2006
@@ -21,18 +21,18 @@
     <xi:include href="test3.xml"/>
     <hr/>
 
-    <para><b><![CDATA[<xi:include href="test2.xml#xpointer(/page/content/para[2])"/>]]></b></para>
-    <xi:include href="test2.xml#xpointer(/page/content/para[2])"/>
+    <para><b><![CDATA[<xi:include href="test2.xml" xpointer="xpointer(/page/content/para[2])"/>]]></b></para>
+    <xi:include href="test2.xml" xpointer="xpointer(/page/content/para[2])"/>
     <hr/>
 
-    <para><b><![CDATA[<xi:include href="test2.xml#xmlns(my=http://localhost/my)xpointer(/page/content/my:abc/*)"/>]]></b></para>
-    <xi:include href="test2.xml#xmlns(my=http://localhost/my)xpointer(/page/content/my:abc/*)"/>
+    <para><b><![CDATA[<xi:include href="test2.xml" xpointer="xmlns(my=http://localhost/my)xpointer(/page/content/my:abc/*)"/>]]></b></para>
+    <xi:include href="test2.xml" xpointer="xmlns(my=http://localhost/my)xpointer(/page/content/my:abc/*)"/>
     <hr/>
 
     <para><b>Inclusion with an invalid xpointer expression, will cause fallback
         element content to be inserted:</b></para>
-    <para><b><![CDATA[<xi:include href="test2.xml#xpointer(">]]></b></para>
-    <xi:include href="test2.xml#xpointer(">
+    <para><b><![CDATA[<xi:include href="test2.xml" xpointer(">]]></b></para>
+    <xi:include href="test2.xml" xpointer="xpointer(">
       <a>
         <b>
           Any random content inside the xi:include element will be ignored.
@@ -46,9 +46,9 @@
     <hr/>
 
     <para><b><![CDATA[
-    <xi:include href="#xmlns(xi=http://www.w3.org/2001/XInclude)xpointer(/page/content/xi:include[1])"/>
+    <xi:include href="" xpointer="xmlns(xi=http://www.w3.org/2001/XInclude)xpointer(/page/content/xi:include[1])"/>
         ]]></b></para>
-    <xi:include href="#xmlns(xi=http://www.w3.org/2001/XInclude)xpointer(/page/content/xi:include[1])"/>
+    <xi:include href="" xpointer="xmlns(xi=http://www.w3.org/2001/XInclude)xpointer(/page/content/xi:include[1])"/>
     <hr/>
 
     <para><b>This sample demonstrates the recursive inclusion: here file4.xml
@@ -61,8 +61,8 @@
         one after the other. If one doesn't return a result, it is skipped and
         the next one is evaluated, until one is found that returns a
         result.</b></para>
-    <para><b><![CDATA[<xi:include href="test2.xml#xpointer(/x)xpointer(/y)xpointer(/z)xpointer(/page/content/para[2])"/>]]></b></para>
-    <xi:include href="test2.xml#xpointer(/x)xpointer(/y)xpointer(/z)xpointer(/page/content/para[2])"/>
+    <para><b><![CDATA[<xi:include href="test2.xml" xpointer="xpointer(/x)xpointer(/y)xpointer(/z)xpointer(/page/content/para[2])"/>]]></b></para>
+    <xi:include href="test2.xml" xpointer="xpointer(/x)xpointer(/y)xpointer(/z)xpointer(/page/content/para[2])"/>
     <hr/>
   
   </content>

Modified: cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test4.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test4.xml?rev=409936&r1=409935&r2=409936&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test4.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/test4.xml Sun May
28 00:48:14 2006
@@ -16,5 +16,5 @@
 -->
 <para xmlns:xi="http://www.w3.org/2001/XInclude">
   This is content in test4.xml, will do a include of test5.xml here:
-  <xi:include href="test5.xml#xpointer(/para/node())"/>
+  <xi:include href="test5.xml" xpointer="xpointer(/para/node())"/>
 </para>

Modified: cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/xhtml.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/xhtml.xml?rev=409936&r1=409935&r2=409936&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/xhtml.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/src/webapp/samples/aggregation/content/xhtml.xml Sun May
28 00:48:14 2006
@@ -20,7 +20,7 @@
     <para>This sample will include the content of the /html/body tag of the
       file sample.xhtml. This is done using the custom 'elementpath' XPointer
       scheme, which avoids building a DOM (which the xpointer() scheme does).</para>
-    <para><b><![CDATA[sample.xhtml#xmlns(c=http://apache.org/cocoon/xpointer)c:elementpath(/html/body)]]></b></para>
-    <xi:include href="sample.xhtml#xmlns(c=http://apache.org/cocoon/xpointer)c:elementpath(/html/body)"/>
+    <para><b><![CDATA[<xi:include href="sample.xhtml" xpointer="xmlns(c=http://apache.org/cocoon/xpointer)c:elementpath(/html/body)"/>]]></b></para>
+    <xi:include href="sample.xhtml" xpointer="xmlns(c=http://apache.org/cocoon/xpointer)c:elementpath(/html/body)"/>
   </content>
 </page>

Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/status.xml?rev=409936&r1=409935&r2=409936&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Sun May 28 00:48:14 2006
@@ -182,6 +182,17 @@
   <release version="@version@" date="@date@">
 -->
   <release version="2.1.10" date="TBD">
+    <action dev="AG" type="add" fixes-bug="COCOON-1753" due-to="Jason Johnston" due-to-email="cocoon@lojjic.net">
+      XInclude transformer uses href fragment rather than xpointer attribute (spec conformance).
+      The XInclude 1.0 spec (see http://www.w3.org/TR/xinclude/#include_element) states the
following
+      about the href attribute:
+      <br/>
+      'Fragment identifiers must not be used; their appearance is a fatal error.'
+      <br/>
+      Cocoon's XIncludeTransformer incorrectly allows xpointer fragments to be specified
using
+      a fragment identifier in the href attribute. The correct way to support xpointers is
the
+      'xpointer' attribute on xi:include, which the transformer does not currently recognize.
+    </action>
     <action dev="AG" type="update">
       Cocoon htmlunit testcases are now compatible with htmlunit 1.8.
     </action>



Mime
View raw message