Author: hlship
Date: Tue Feb 10 18:58:33 2009
New Revision: 743058

URL: http://svn.apache.org/viewvc?rev=743058&view=rev
Log:
TAP5-507: Comments between the DOCTYPE and the root element now cause render 
errors

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/preamble_content.txt
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset2.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathConverter.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/MarkupWriterImplTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset2.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset2.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset2.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset2.java
 Tue Feb 10 18:58:33 2009
@@ -21,14 +21,13 @@
  * the invariance of the binding from the asset (and assumes variant unless 
the asset object implements this
  * interface).
  *
- * @see org.apache.tapestry5.services.AssetPathConverter#isInvariant()
  * @since 5.1.0.0
  */
 public interface Asset2 extends Asset
 {
     /**
      * Returns true if the Asset is invariant (meaning that it returns the 
same value from {...@link Asset#toClientURL()}
-     * at all times}. Assets that are used as binding values will be cached 
more aggresively by Tapestry is they are
+     * at all times}. Assets that are used as binding values will be cached 
more aggresively by Tapestry as they are
      * invariant.
      *
      * @return true if invariant

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
 Tue Feb 10 18:58:33 2009
@@ -19,6 +19,7 @@
 
 import java.io.PrintWriter;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -44,6 +45,11 @@
 
     private final String encoding;
 
+    /**
+     * Non-element content that comes between the DOCTYPE and the root element.
+     */
+    private List<Node> preamble;
+
     public Document(MarkupModel model)
     {
         this(model, null);
@@ -145,6 +151,12 @@
             dtd.toMarkup(writer);
         }
 
+        if (preamble != null)
+        {
+            for (Node n : preamble)
+                n.toMarkup(this, writer, namespaceURIToPrefix);
+        }
+
         Map<String, String> initialNamespaceMap = CollectionFactory.newMap();
 
         initialNamespaceMap.put("xml", "http://www.w3.org/XML/1998/namespace";);
@@ -203,4 +215,61 @@
     {
         rootElement.visit(visitor);
     }
+
+    private <T extends Node> T newChild(T child)
+    {
+        if (preamble == null)
+            preamble = CollectionFactory.newList();
+
+        preamble.add(child);
+
+        return child;
+    }
+
+    /**
+     * Adds the comment and returns this document for further construction.
+     *
+     * @since 5.1.0.0
+     */
+    public Document comment(String text)
+    {
+        newChild(new Comment(this, text));
+
+        return this;
+    }
+
+    /**
+     * Adds the raw text and returns this document for further construction.
+     *
+     * @since 5.1.0.0
+     */
+    public Document raw(String text)
+    {
+        newChild(new Raw(this, text));
+
+        return this;
+    }
+
+    /**
+     * Adds and returns a new text node (the text node is returned so that 
{...@link Text#write(String)} or [...@link {...@link
+     * Text#writef(String, Object[])} may be invoked .
+     *
+     * @param text initial text for the node
+     * @return the new Text node
+     */
+    public Text text(String text)
+    {
+        return newChild(new Text(this, text));
+    }
+
+    /**
+     * Adds and returns a new CDATA node.
+     *
+     * @param content the content to be rendered by the node
+     * @return the newly created node
+     */
+    public CData cdata(String content)
+    {
+        return newChild(new CData(this, content));
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
 Tue Feb 10 18:58:33 2009
@@ -270,7 +270,7 @@
     }
 
     /**
-     * Adds an returns a new CDATA node.
+     * Adds and returns a new CDATA node.
      *
      * @param content the content to be rendered by the node
      * @return the newly created node

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterImpl.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MarkupWriterImpl.java
 Tue Feb 10 18:58:33 2009
@@ -19,7 +19,6 @@
 import org.apache.tapestry5.dom.*;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.Defense;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
 import java.io.PrintWriter;
 import java.util.Collection;
@@ -76,25 +75,29 @@
 
     public void cdata(String content)
     {
-        ensureCurrentElement();
-
-        current.cdata(content);
-
         currentText = null;
+
+        if (current == null)
+        {
+            document.cdata(content);
+        }
+        else
+        {
+            current.cdata(content);
+        }
     }
 
     public void write(String text)
     {
-        // Whitespace before and after the root element is quietly ignored.
-        if (current == null && InternalUtils.isBlank(text)) return;
-
-        ensureCurrentElement();
-
         if (text == null) return;
 
         if (currentText == null)
         {
-            currentText = current.text(text);
+            currentText =
+                    current == null
+                    ? document.text(text)
+                    : current.text(text);
+
             return;
         }
 
@@ -130,7 +133,8 @@
 
     private void ensureCurrentElement()
     {
-        if (current == null) throw new 
IllegalStateException(ServicesMessages.markupWriterNoCurrentElement());
+        if (current == null)
+            throw new 
IllegalStateException(ServicesMessages.markupWriterNoCurrentElement());
     }
 
     public Element element(String name, Object... namesAndValues)
@@ -162,11 +166,16 @@
 
     public void writeRaw(String text)
     {
-        ensureCurrentElement();
-
         currentText = null;
 
-        current.raw(text);
+        if (current == null)
+        {
+            document.raw(text);
+        }
+        else
+        {
+            current.raw(text);
+        }
     }
 
     public Element end()
@@ -184,11 +193,16 @@
 
     public void comment(String text)
     {
-        ensureCurrentElement();
-
-        current.comment(text);
-
         currentText = null;
+
+        if (current == null)
+        {
+            document.comment(text);
+        }
+        else
+        {
+            current.comment(text);
+        }
     }
 
     public Element attributeNS(String namespace, String attributeName, String 
attributeValue)

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathConverter.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathConverter.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathConverter.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathConverter.java
 Tue Feb 10 18:58:33 2009
@@ -28,9 +28,9 @@
 {
     /**
      * Returns true if the converter returns that same converted path for any 
specific asset path (in which case, the
-     * converted asset path may be cached more aggresively).  This value 
should be false if the the converted path can
-     * vary for the same input path ... that is, if external factors (such as 
the identity of the user, or information
-     * obtained from the request) is involved in generating the final client 
URI.
+     * converted asset path may be cached in component instance variables more 
aggresively). This value should be false
+     * if the converted path can vary for the same input path ... that is, if 
external factors (such as the identity of
+     * the user, or information obtained from the request) is involved in 
generating the final client URI.
      *
      * @return true if invariant (and therefore cachable)
      */

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/MarkupWriterImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/MarkupWriterImplTest.java?rev=743058&r1=743057&r2=743058&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/MarkupWriterImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/MarkupWriterImplTest.java
 Tue Feb 10 18:58:33 2009
@@ -23,13 +23,6 @@
 
 public class MarkupWriterImplTest extends InternalBaseTestCase
 {
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void write_with_no_current_element()
-    {
-        MarkupWriter w = new MarkupWriterImpl();
-
-        w.write("fail!");
-    }
 
     /**
      * TAP5-349
@@ -55,7 +48,7 @@
     }
 
     @Test
-    public void write_whitespace_before_start_of_root_element_is_ignored()
+    public void write_whitespace_before_start_of_root_element_is_retained()
     {
         MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
 
@@ -64,11 +57,12 @@
         w.element("root");
         w.end();
 
-        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n<root/>");
+        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n" +
+                "  <root/>");
     }
 
     @Test
-    public void write_whitespace_after_end_of_root_element_is_ignored()
+    public void 
write_whitespace_after_end_of_root_element_is_retained_in_preamble()
     {
         MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
 
@@ -77,15 +71,25 @@
 
         w.write("  ");
 
-        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n<root/>");
+        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n  <root/>");
     }
 
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void comment_with_no_current_element()
+    @Test()
+    public void preamble_content() throws Exception
     {
-        MarkupWriter w = new MarkupWriterImpl();
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        w.comment("preamble start");
+        w.write("preamble text");
+        w.cdata("CDATA content");
+        w.writeRaw("&nbsp;");
+        w.element("root");
+        w.end();
+        // You really shouldn't have any text after the close tag of the 
document, so it
+        // gets moved to the top, to the "preamble", before the first element.
+        w.comment("content after root element in preamble");
 
-        w.comment("fail!");
+        assertEquals(w.getDocument().toString(), 
readFile("preamble_content.txt"));
     }
 
     @Test(expectedExceptions = IllegalStateException.class)

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/preamble_content.txt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/preamble_content.txt?rev=743058&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/preamble_content.txt
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/preamble_content.txt
 Tue Feb 10 18:58:33 2009
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<!-- preamble start -->preamble text<![CDATA[CDATA content]]>&nbsp;<!-- 
content after root element in preamble --><root/>
\ No newline at end of file


Reply via email to