You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/07/11 00:16:40 UTC

svn commit: r962926 - in /myfaces/shared/trunk/core/src: main/java/org/apache/myfaces/shared/config/ main/java/org/apache/myfaces/shared/renderkit/html/ main/java/org/apache/myfaces/shared/util/ test/java/org/apache/myfaces/shared/renderkit/html/ test/...

Author: lu4242
Date: Sat Jul 10 22:16:40 2010
New Revision: 962926

URL: http://svn.apache.org/viewvc?rev=962926&view=rev
Log:
MYFACES-2801 HtmlResponseWriterImpl needs to deal with <script> and <style> tags properly on both html and xhtml 

Added:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/CommentUtils.java
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/FastWriter.java
    myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/util/CommentUtilsTest.java
Modified:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java
    myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImplTest.java

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=962926&r1=962925&r2=962926&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Sat Jul 10 22:16:40 2010
@@ -216,6 +216,13 @@ public class MyfacesConfig
     public final static String INIT_PARAM_VALIDATE_XML = "org.apache.myfaces.VALIDATE_XML";
     public final static boolean INIT_PARAM_VALIDATE_XML_DEFAULT = false;
     
+    /**
+     * Wrap content inside script with xml comment to prevent old browsers to display it. By default it is true. 
+     */
+    @JSFWebConfigParam(since="2.0.1", expectedValues="true,false", defaultValue="true")
+    public final static String INIT_PARAM_WRAP_SCRIPT_CONTENT_WITH_XML_COMMENT_TAG = "org.apache.myfaces.WRAP_SCRIPT_CONTENT_WITH_XML_COMMENT_TAG";
+    public final static boolean INIT_PARAM_WRAP_SCRIPT_CONTENT_WITH_XML_COMMENT_TAG_DEFAULT = true;
+    
     private boolean _prettyHtml;
     private boolean _detectJavascript;
     private boolean _allowJavascript;
@@ -236,6 +243,7 @@ public class MyfacesConfig
     private boolean _refreshTransientBuildOnPSSAuto;
     private boolean refreshTransientBuildOnPSSPreserveState;
     private boolean _validateXML;
+    private boolean _wrapScriptContentWithXmlCommentTag;
 
     private static final boolean TOMAHAWK_AVAILABLE;
     private static final boolean MYFACES_IMPL_AVAILABLE;
@@ -366,6 +374,9 @@ public class MyfacesConfig
                 INIT_PARAM_REFRESH_TRANSIENT_BUILD_ON_PSS_PRESERVE_STATE_DEFAULT));
         
         myfacesConfig.setValidateXML(getBooleanInitParameter(extCtx, INIT_PARAM_VALIDATE_XML, INIT_PARAM_VALIDATE_XML_DEFAULT));
+        
+        myfacesConfig.setWrapScriptContentWithXmlCommentTag(getBooleanInitParameter(extCtx, 
+                INIT_PARAM_WRAP_SCRIPT_CONTENT_WITH_XML_COMMENT_TAG, INIT_PARAM_WRAP_SCRIPT_CONTENT_WITH_XML_COMMENT_TAG_DEFAULT));
 
         if (TOMAHAWK_AVAILABLE)
         {
@@ -749,4 +760,15 @@ public class MyfacesConfig
     {
         _validateXML = validateXML;
     }
+
+    public boolean isWrapScriptContentWithXmlCommentTag()
+    {
+        return _wrapScriptContentWithXmlCommentTag;
+    }
+
+    public void setWrapScriptContentWithXmlCommentTag(
+            boolean wrapScriptContentWithXmlCommentTag)
+    {
+        this._wrapScriptContentWithXmlCommentTag = wrapScriptContentWithXmlCommentTag;
+    }
 }

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java?rev=962926&r1=962925&r2=962926&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java Sat Jul 10 22:16:40 2010
@@ -28,11 +28,12 @@ import java.util.logging.Logger;
 
 import javax.faces.FacesException;
 import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 
 import org.apache.myfaces.shared.renderkit.RendererUtils;
 import org.apache.myfaces.shared.renderkit.html.util.UnicodeEncoder;
+import org.apache.myfaces.shared.util.CommentUtils;
+import org.apache.myfaces.shared.util.FastWriter;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -49,12 +50,34 @@ public class HtmlResponseWriterImpl
     private static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
     private static final String UTF8 = "UTF-8";
 
-    private boolean _writeDummyForm = false;
-    private Set _dummyFormParams = null;
+    //private boolean _writeDummyForm = false;
+    //private Set _dummyFormParams = null;
 
-    private Writer _writer;
+    /**
+     * The writer used as output, or in other words, the one passed on the constructor
+     */
+    private Writer _outputWriter;
+    
+    /**
+     * The writer we are using to store data.
+     */
+    private Writer _currentWriter;
+    
+    /**
+     * The writer used to buffer script and style content
+     */
+    private FastWriter _bufferedWriter;
+    
     private String _contentType;
+    
+    /**
+     * This var prevents check if the contentType is for xhtml multiple times.
+     */
+    private boolean _isXhtmlContentType;
+    
     private String _characterEncoding;
+    private boolean _wrapScriptContentWithXmlCommentTag;
+    
     private String _startElementName;
     private Boolean _isInsideScript;
     private Boolean _isStyle;
@@ -62,10 +85,11 @@ public class HtmlResponseWriterImpl
     private UIComponent _startElementUIComponent;
     private boolean _startTagOpen;
 
-    private static final Set s_emptyHtmlElements = new HashSet();
+    private static final Set<String> s_emptyHtmlElements = new HashSet<String>();
 
     private static final String CDATA_START = "<![CDATA[ \n";
     private static final String COMMENT_START = "<!--\n";
+    private static final String CDATA_COMMENT_START = "//<![CDATA[ \n";
     private static final String CDATA_COMMENT_END = "\n//]]>";
     private static final String CDATA_END = "\n]]>";
     private static final String COMMENT_COMMENT_END = "\n//-->";
@@ -89,15 +113,28 @@ public class HtmlResponseWriterImpl
     }
 
     public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding)
+    {
+        this(writer,contentType,characterEncoding,true);
+    }
+
+    public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding,
+             boolean wrapScriptContentWithXmlCommentTag)
     throws FacesException
     {
-        _writer = writer;
+        _outputWriter = writer;
+        //The current writer to be used is the one used as output 
+        _currentWriter = _outputWriter;
+        _bufferedWriter = new FastWriter(1024);
+        _wrapScriptContentWithXmlCommentTag = wrapScriptContentWithXmlCommentTag;
+        
         _contentType = contentType;
         if (_contentType == null)
         {
             if (log.isLoggable(Level.FINE)) log.fine("No content type given, using default content type " + DEFAULT_CONTENT_TYPE);
             _contentType = DEFAULT_CONTENT_TYPE;
         }
+        _isXhtmlContentType = HtmlRendererUtils.isXHTMLContentType(_contentType);
+        
         if (characterEncoding == null)
         {
             if (log.isLoggable(Level.FINE)) log.fine("No character encoding given, using default character encoding " + DEFAULT_CHARACTER_ENCODING);
@@ -159,7 +196,7 @@ public class HtmlResponseWriterImpl
 
     public void endDocument() throws IOException
     {
-        _writer.flush();
+        _currentWriter.flush();
     }
 
     public void startElement(String name, UIComponent uiComponent) throws IOException
@@ -170,8 +207,8 @@ public class HtmlResponseWriterImpl
         }
 
         closeStartTagIfNecessary();
-        _writer.write('<');
-        _writer.write(name);
+        _currentWriter.write('<');
+        _currentWriter.write(name);
 
         resetStartedElement();
 
@@ -179,13 +216,22 @@ public class HtmlResponseWriterImpl
         _startElementUIComponent = uiComponent;
         _startTagOpen = true;
         
-        // handle a <script> start
+        // Each time we start a element, it is necessary to check <script> or <style>,
+        // because we need to buffer all content to post process it later when it reach its end
+        // according to the initialization properties used.
         if(isScript(name))
         {
+            // handle a <script> start
             _isInsideScript = Boolean.TRUE;
             _isStyle = Boolean.FALSE;
             _isTextArea = Boolean.FALSE;
         }
+        else if (isStyle(name))
+        {
+            _isInsideScript = Boolean.FALSE;
+            _isStyle = Boolean.TRUE;
+            _isTextArea = Boolean.FALSE;
+        }
     }
 
     private void closeStartTagIfNecessary() throws IOException
@@ -194,28 +240,39 @@ public class HtmlResponseWriterImpl
         {
             if (s_emptyHtmlElements.contains(_startElementName.toLowerCase()))
             {
-                _writer.write(" />");
+                _currentWriter.write(" />");
                 // make null, this will cause NullPointer in some invalid element nestings
                 // (better than doing nothing)
                 resetStartedElement();
             }
             else
             {
-                _writer.write('>');
+                _currentWriter.write('>');
 
+                /*
                 if(isScript(_startElementName))
                 {
                     if(HtmlRendererUtils.isXHTMLContentType(_contentType))
                     {
                         if(HtmlRendererUtils.isAllowedCdataSection(FacesContext.getCurrentInstance()))
                         {
-                            _writer.write(CDATA_START);
+                            _currentWriter.write(CDATA_START);
                         }
                     }
                     else
                     {
-                        _writer.write(COMMENT_START);
+                        _currentWriter.write(COMMENT_START);
                     }
+                }*/
+                if (isScript(_startElementName) && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
+                {
+                    _bufferedWriter.reset();
+                    _currentWriter = _bufferedWriter;
+                }                
+                if (isStyle(_startElementName) && _isXhtmlContentType)
+                {
+                    _bufferedWriter.reset();
+                    _currentWriter = _bufferedWriter;
                 }
             }
             _startTagOpen = false;
@@ -258,6 +315,17 @@ public class HtmlResponseWriterImpl
             //tag was no empty tag - it has no accompanying end tag now.
             if(_startElementName!=null)
             {
+                if (isScript() && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
+                {
+                    writeScriptContent();
+                    _currentWriter = _outputWriter;
+                }
+                else if (isStyle() && _isXhtmlContentType)
+                {
+                    writeStyleContent();
+                    _currentWriter = _outputWriter;
+                }
+
                 //write closing tag
                 writeEndTag(name);
             }
@@ -275,37 +343,180 @@ public class HtmlResponseWriterImpl
             }
             else
             {
+                if (isScript() && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
+                {
+                    writeScriptContent();
+                    _currentWriter = _outputWriter;
+                }
+                else if (isStyle() && _isXhtmlContentType)
+                {
+                    writeStyleContent();
+                    _currentWriter = _outputWriter;
+                }
                 writeEndTag(name);
             }
         }
 
         resetStartedElement();
     }
+    
+    private void writeStyleContent() throws IOException
+    {
+        String content = _bufferedWriter.toString(); 
+        
+        if(_isXhtmlContentType)
+        {
+            // In xhtml, the content inside <style> tag is PCDATA, but
+            // in html the content is CDATA, so in order to preserve 
+            // compatibility we need to wrap the content inside proper
+            // CDATA tags.
+            // Since the response content type is xhtml, we can use
+            // simple CDATA without comments, but note we need to check
+            // when we are using any valid notation (simple CDATA, commented CDATA, xml comment) 
+            String trimmedContent = content.trim();
+            if (trimmedContent.startsWith(CommentUtils.CDATA_SIMPLE_START) && trimmedContent.endsWith(CommentUtils.CDATA_SIMPLE_END))
+            {
+                _outputWriter.write(content);
+                return;
+            }
+            else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) && CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
+            {
+                _outputWriter.write(content);
+                return;
+            }
+            else if (trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) && trimmedContent.endsWith(CommentUtils.COMMENT_SIMPLE_END))
+            {
+                //Use comment wrap is valid, but for xhtml it is preferred to use CDATA
+                _outputWriter.write(CDATA_START);
+                _outputWriter.write(trimmedContent.substring(4,trimmedContent.length()-3));
+                _outputWriter.write(CDATA_END);
+                return;
+            }
+            else
+            {
+                _outputWriter.write(CDATA_START);
+                _outputWriter.write(content);
+                _outputWriter.write(CDATA_END);
+                return;                
+            }
+        }
+        // If the response is handled as text/html, 
+        // it is not necessary to wrap with xml comment tag,
+        // so we can just write the content as is.
+        _outputWriter.write(content);
+    }
+    
+    private void writeScriptContent() throws IOException
+    {
+        String content = _bufferedWriter.toString();
+        String trimmedContent = null;
+        
+        if(_isXhtmlContentType)
+        {
+            trimmedContent = content.trim();
+            
+            if ( trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) && 
+                    CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag(trimmedContent))
+            {
+                // In xhtml use xml comment to wrap is invalid, so it is only required to remove the <!--
+                // the ending //--> will be parsed as a comment, so it will not be a problem. Let it on the content.
+                _outputWriter.write(CDATA_COMMENT_START);
+                _outputWriter.write(trimmedContent.substring(4));
+                _outputWriter.write(CDATA_COMMENT_END);
+                return;
+            }
+            else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) && CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
+            {
+                _outputWriter.write(content);
+                return;
+            }
+            else if (CommentUtils.isStartMatchWithInlineCommentedCDATA(trimmedContent) && CommentUtils.isEndMatchWithInlineCommentedCDATA(trimmedContent))
+            {
+                _outputWriter.write(content);
+                return;
+            }
+            else
+            {
+                // <script> in xhtml has as content type PCDATA, but in html it is CDATA,
+                // so we need to wrap here to prevent problems.
+                _outputWriter.write(CDATA_COMMENT_START);
+                _outputWriter.write(content);
+                _outputWriter.write(CDATA_COMMENT_END);
+                return;
+            }
+        }
+        else
+        {
+            if (_wrapScriptContentWithXmlCommentTag)
+            {
+                trimmedContent = content.trim();
+                
+                if ( trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) && 
+                        CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag(trimmedContent))
+                {
+                    _outputWriter.write(content);
+                    return;
+                }
+                else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) && CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
+                {
+                    _outputWriter.write(content);
+                    return;
+                }
+                else if (CommentUtils.isStartMatchWithInlineCommentedCDATA(trimmedContent) && CommentUtils.isEndMatchWithInlineCommentedCDATA(trimmedContent))
+                {
+                    _outputWriter.write(content);
+                    return;
+                }
+                else
+                {
+                    _outputWriter.write(COMMENT_START);
+                    _outputWriter.write(content);
+                    _outputWriter.write(COMMENT_COMMENT_END);
+                    return;
+                }
+            }
+        }
+        
+        //If no return, just write everything
+        _outputWriter.write(content);
+    }
+    
 
     private void writeEndTag(String name)
         throws IOException
     {
+        /*
         if(isScript(name)) 
         {
             if(HtmlRendererUtils.isXHTMLContentType(_contentType))
             {
                 if(HtmlRendererUtils.isAllowedCdataSection(FacesContext.getCurrentInstance()))
                 {
-                    _writer.write(CDATA_COMMENT_END);
+                    _currentWriter.write(CDATA_COMMENT_END);
                 }
             }
             else
             {
-                _writer.write(COMMENT_COMMENT_END);
+                _currentWriter.write(COMMENT_COMMENT_END);
             }
             
             // reset _isInsideScript
             _isInsideScript = Boolean.FALSE;
+        }*/
+        
+        if (isScript(name))
+        {
+            // reset _isInsideScript
+            _isInsideScript = Boolean.FALSE;
+        }
+        else if (isStyle(name))
+        {
+            _isStyle = Boolean.FALSE;
         }
 
-        _writer.write("</");
-        _writer.write(name);
-        _writer.write('>');
+        _currentWriter.write("</");
+        _currentWriter.write(name);
+        _currentWriter.write('>');
     }
 
     public void writeAttribute(String name, Object value, String componentPropertyName) throws IOException
@@ -324,21 +535,21 @@ public class HtmlResponseWriterImpl
             if (((Boolean)value).booleanValue())
             {
                 // name as value for XHTML compatibility
-                _writer.write(' ');
-                _writer.write(name);
-                _writer.write("=\"");
-                _writer.write(name);
-                _writer.write('"');
+                _currentWriter.write(' ');
+                _currentWriter.write(name);
+                _currentWriter.write("=\"");
+                _currentWriter.write(name);
+                _currentWriter.write('"');
             }
         }
         else
         {
             String strValue = (value==null)?"":value.toString();
-            _writer.write(' ');
-            _writer.write(name);
-            _writer.write("=\"");
-            _writer.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
-            _writer.write('"');
+            _currentWriter.write(' ');
+            _currentWriter.write(name);
+            _currentWriter.write("=\"");
+            _currentWriter.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
+            _currentWriter.write('"');
         }
     }
 
@@ -354,12 +565,12 @@ public class HtmlResponseWriterImpl
         }
 
         String strValue = value.toString();
-        _writer.write(' ');
-        _writer.write(name);
-        _writer.write("=\"");
+        _currentWriter.write(' ');
+        _currentWriter.write(name);
+        _currentWriter.write("=\"");
         if (strValue.toLowerCase().startsWith("javascript:"))
         {
-            _writer.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
+            _currentWriter.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
         }
         else
         {
@@ -391,9 +602,9 @@ public class HtmlResponseWriterImpl
             }
             */
             //_writer.write(strValue);
-            _writer.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encodeURIAtributte(strValue, _characterEncoding));
+            _currentWriter.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encodeURIAtributte(strValue, _characterEncoding));
         }
-        _writer.write('"');
+        _currentWriter.write('"');
     }
 
     public void writeComment(Object value) throws IOException
@@ -404,9 +615,9 @@ public class HtmlResponseWriterImpl
         }
 
         closeStartTagIfNecessary();
-        _writer.write("<!--");
-        _writer.write(value.toString());    //TODO: Escaping: must not have "-->" inside!
-        _writer.write("-->");
+        _currentWriter.write("<!--");
+        _currentWriter.write(value.toString());    //TODO: Escaping: must not have "-->" inside!
+        _currentWriter.write("-->");
     }
 
     public void writeText(Object value, String componentPropertyName) throws IOException
@@ -423,12 +634,12 @@ public class HtmlResponseWriterImpl
         if (isScriptOrStyle())
         {
             // Don't bother encoding anything if chosen character encoding is UTF-8
-            if (UTF8.equals(_characterEncoding)) _writer.write(strValue);
-            else _writer.write(UnicodeEncoder.encode(strValue) );
+            if (UTF8.equals(_characterEncoding)) _currentWriter.write(strValue);
+            else _currentWriter.write(UnicodeEncoder.encode(strValue) );
         }
         else
         {
-            _writer.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
+            _currentWriter.write(org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(strValue, false, false, !UTF8.equals(_characterEncoding)));
         }
     }
 
@@ -449,24 +660,24 @@ public class HtmlResponseWriterImpl
         {
             String strValue = new String(cbuf, off, len);
             // Don't bother encoding anything if chosen character encoding is UTF-8
-            if (UTF8.equals(_characterEncoding)) _writer.write(strValue);
-            else _writer.write(UnicodeEncoder.encode(strValue) );
+            if (UTF8.equals(_characterEncoding)) _currentWriter.write(strValue);
+            else _currentWriter.write(UnicodeEncoder.encode(strValue) );
         }
         else if (isTextarea())
         {
             // For textareas we must *not* map successive spaces to &nbsp or Newlines to <br/>
-            org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(cbuf, off, len, false, false, !UTF8.equals(_characterEncoding), _writer);
+            org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(cbuf, off, len, false, false, !UTF8.equals(_characterEncoding), _currentWriter);
         }
         else
         {
             // We map successive spaces to &nbsp; and Newlines to <br/>
-            org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(cbuf, off, len, true, true, !UTF8.equals(_characterEncoding), _writer);
+            org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(cbuf, off, len, true, true, !UTF8.equals(_characterEncoding), _currentWriter);
         }
     }
 
     private boolean isScriptOrStyle()
     {
-        initializeStartedTagInfo();
+        //initializeStartedTagInfo();
 
         return (_isStyle != null && _isStyle.booleanValue()) ||
                 (_isInsideScript != null && _isInsideScript.booleanValue());
@@ -481,6 +692,21 @@ public class HtmlResponseWriterImpl
     {
         return (HTML.SCRIPT_ELEM.equalsIgnoreCase(element));
     }
+    
+    private boolean isScript()
+    {
+        return (_isInsideScript != null && _isInsideScript.booleanValue());
+    }
+    
+    private boolean isStyle(String element)
+    {
+        return (HTML.STYLE_ELEM.equalsIgnoreCase(element));
+    }
+    
+    private boolean isStyle()
+    {
+        return (_isStyle != null && _isStyle.booleanValue());
+    }
 
     private boolean isTextarea()
     {
@@ -493,6 +719,7 @@ public class HtmlResponseWriterImpl
     {
         if(_startElementName != null)
         {
+            /*
             if(_isStyle == null)
             {
                 if(_startElementName.equalsIgnoreCase(org.apache.myfaces.shared.renderkit.html.HTML.STYLE_ELEM))
@@ -504,7 +731,7 @@ public class HtmlResponseWriterImpl
                 {
                     _isStyle = Boolean.FALSE;
                 }
-            }
+            }*/
 
             if(_isTextArea == null)
             {
@@ -523,9 +750,9 @@ public class HtmlResponseWriterImpl
     public ResponseWriter cloneWithWriter(Writer writer)
     {
         HtmlResponseWriterImpl newWriter
-                = new HtmlResponseWriterImpl(writer, getContentType(), getCharacterEncoding());
-        newWriter._writeDummyForm = _writeDummyForm;
-        newWriter._dummyFormParams = _dummyFormParams;
+                = new HtmlResponseWriterImpl(writer, getContentType(), getCharacterEncoding(), _wrapScriptContentWithXmlCommentTag);
+        //newWriter._writeDummyForm = _writeDummyForm;
+        //newWriter._dummyFormParams = _dummyFormParams;
         return newWriter;
     }
 
@@ -535,7 +762,7 @@ public class HtmlResponseWriterImpl
     public void close() throws IOException
     {
         closeStartTagIfNecessary();
-        _writer.close();
+        _currentWriter.close();
     }
 
     public void write(char cbuf[], int off, int len) throws IOException
@@ -543,14 +770,14 @@ public class HtmlResponseWriterImpl
         closeStartTagIfNecessary();
         String strValue = new String(cbuf, off, len);
         // Don't bother encoding anything if chosen character encoding is UTF-8
-        if (UTF8.equals(_characterEncoding)) _writer.write(strValue);
-        else _writer.write(UnicodeEncoder.encode(strValue) );
+        if (UTF8.equals(_characterEncoding)) _currentWriter.write(strValue);
+        else _currentWriter.write(UnicodeEncoder.encode(strValue) );
     }
 
     public void write(int c) throws IOException
     {
         closeStartTagIfNecessary();
-        _writer.write(c);
+        _currentWriter.write(c);
     }
 
     public void write(char cbuf[]) throws IOException
@@ -558,8 +785,8 @@ public class HtmlResponseWriterImpl
         closeStartTagIfNecessary();
         String strValue = new String(cbuf);
         // Don't bother encoding anything if chosen character encoding is UTF-8
-        if (UTF8.equals(_characterEncoding)) _writer.write(strValue);
-        else _writer.write(UnicodeEncoder.encode(strValue) );
+        if (UTF8.equals(_characterEncoding)) _currentWriter.write(strValue);
+        else _currentWriter.write(UnicodeEncoder.encode(strValue) );
     }
 
     public void write(String str) throws IOException
@@ -570,8 +797,8 @@ public class HtmlResponseWriterImpl
         if (str.length() > 0)
         {
             // Don't bother encoding anything if chosen character encoding is UTF-8
-            if (UTF8.equals(_characterEncoding)) _writer.write(str);
-            else _writer.write(UnicodeEncoder.encode(str) );
+            if (UTF8.equals(_characterEncoding)) _currentWriter.write(str);
+            else _currentWriter.write(UnicodeEncoder.encode(str) );
         }
     }
 
@@ -580,8 +807,8 @@ public class HtmlResponseWriterImpl
         closeStartTagIfNecessary();
         String strValue = str.substring(off, off+len);
         // Don't bother encoding anything if chosen character encoding is UTF-8
-        if (UTF8.equals(_characterEncoding)) _writer.write(strValue);
-        else _writer.write(UnicodeEncoder.encode(strValue) );
+        if (UTF8.equals(_characterEncoding)) _currentWriter.write(strValue);
+        else _currentWriter.write(UnicodeEncoder.encode(strValue) );
     }
     
     /**

Added: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/CommentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/CommentUtils.java?rev=962926&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/CommentUtils.java (added)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/CommentUtils.java Sat Jul 10 22:16:40 2010
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.shared.util;
+
+/**
+ * This class contains utility methods to detect special cases to be handled on "script" or
+ * "style" tags by HtmlResponseWriterImpl.
+ * 
+ * @author Leonardo Uribe (latest modification by $Author: jakobk $)
+ * @version $Revision: 937069 $ $Date: 2010-04-22 16:19:29 -0500 (Jue, 22 Abr 2010) $
+ */
+public class CommentUtils
+{
+    public static final String INLINE_SCRIPT_COMMENT = "//";
+    public static final String START_SCRIPT_COMMENT = "/*";
+    public static final String END_SCRIPT_COMMENT = "*/";
+    public static final String CDATA_SIMPLE_START = "<![CDATA[";
+    public static final String CDATA_SIMPLE_END = "]]>";
+    public static final String COMMENT_SIMPLE_START = "<!--";
+    public static final String COMMENT_SIMPLE_END = "-->";
+
+    public static boolean isStartMatchWithCommentedCDATA(String trimmedContent)
+    {
+        if (trimmedContent.startsWith(START_SCRIPT_COMMENT))
+        {
+            int offset = 2;
+            while (trimmedContent.charAt(offset) <= ' ')
+            {
+                offset++;
+            }
+            if (trimmedContent.startsWith(CDATA_SIMPLE_START, offset))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public static boolean isEndMatchWithCommentedCDATA(String trimmedContent)
+    {
+        if (trimmedContent.endsWith(END_SCRIPT_COMMENT))
+        {
+            int offset = trimmedContent.length()-3;
+            while (trimmedContent.charAt(offset) <= ' ')
+            {
+                offset--;
+            }
+            // CDATA_SIMPLE_END.length() = 3
+            // So, -3 +1 = -2
+            if (trimmedContent.startsWith(CDATA_SIMPLE_END, offset - 2))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isEndMatchtWithInlineCommentedXmlCommentTag(String trimmedContent)
+    {
+        if (trimmedContent.endsWith(COMMENT_SIMPLE_END))
+        {
+            int offset = trimmedContent.length()-4;
+            while (trimmedContent.charAt(offset) <= ' ' &&
+                    trimmedContent.charAt(offset) != '\n')
+            {
+                offset--;
+            }
+            // INLINE_SCRIPT_COMMENT.length() = 2
+            // So, -2 +1 = -1
+            if (trimmedContent.startsWith(INLINE_SCRIPT_COMMENT, offset - 1))
+            {
+                return true;
+            }
+        }
+        return false;        
+    }
+    
+    public static boolean isStartMatchWithInlineCommentedCDATA(String trimmedContent)
+    {
+        if (trimmedContent.startsWith(INLINE_SCRIPT_COMMENT))
+        {
+            int offset = 2;
+            while (trimmedContent.charAt(offset) <= ' ' &&
+                    trimmedContent.charAt(offset) != '\n')
+            {
+                offset++;
+            }
+            if (trimmedContent.startsWith(CDATA_SIMPLE_START, offset))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public static boolean isEndMatchWithInlineCommentedCDATA(String trimmedContent)
+    {
+        if (trimmedContent.endsWith(CDATA_SIMPLE_END))
+        {
+            int offset = trimmedContent.length()- 4;
+            while (trimmedContent.charAt(offset) <= ' ' &&
+                    trimmedContent.charAt(offset) != '\n')
+            {
+                offset--;
+            }
+            // INLINE_SCRIPT_COMMENT.length() = 2
+            // So, -2 +1 = -1
+            if (trimmedContent.startsWith(INLINE_SCRIPT_COMMENT, offset - 1))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+}

Added: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/FastWriter.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/FastWriter.java?rev=962926&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/FastWriter.java (added)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/FastWriter.java Sat Jul 10 22:16:40 2010
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.shared.util;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * StringWriter cannot be reused without create a new object over and over.
+ * This class provide a simple implementation that allows reuse the same buffer
+ * in a efficient way.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: FastWriter.java,v 1.4 2008/07/13 19:01:34 rlubke Exp $
+ */
+public final class FastWriter extends Writer
+{
+
+    private char[] buff;
+    private int size;
+
+    public FastWriter()
+    {
+        this(1024);
+    }
+
+    public FastWriter(int initialSize)
+    {
+        if (initialSize < 0)
+        {
+            throw new IllegalArgumentException("Initial Size cannot be less than 0");
+        }
+        this.buff = new char[initialSize];
+    }
+
+    public void close() throws IOException
+    {
+        // do nothing
+    }
+
+    public void flush() throws IOException
+    {
+        // do nothing
+    }
+
+    private final void overflow(int len)
+    {
+        if (this.size + len > this.buff.length)
+        {
+            char[] next = new char[(this.size + len) * 2];
+            System.arraycopy(this.buff, 0, next, 0, this.size);
+            this.buff = next;
+        }
+    }
+
+    public void write(char[] cbuf, int off, int len) throws IOException
+    {
+        overflow(len);
+        System.arraycopy(cbuf, off, this.buff, this.size, len);
+        this.size += len;
+    }
+
+    public void write(char[] cbuf) throws IOException
+    {
+        this.write(cbuf, 0, cbuf.length);
+    }
+
+    public void write(int c) throws IOException
+    {
+        this.overflow(1);
+        this.buff[this.size] = (char) c;
+        this.size++;
+    }
+
+    public void write(String str, int off, int len) throws IOException
+    {
+        this.write(str.toCharArray(), off, len);
+    }
+
+    public void write(String str) throws IOException
+    {
+        this.write(str.toCharArray(), 0, str.length());
+    }
+
+    public void reset()
+    {
+        this.size = 0;
+    }
+
+    public String toString()
+    {
+        return new String(this.buff, 0, this.size);
+    }
+}

Modified: myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImplTest.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImplTest.java?rev=962926&r1=962925&r2=962926&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImplTest.java (original)
+++ myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImplTest.java Sat Jul 10 22:16:40 2010
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.StringWriter;
 import java.lang.reflect.Field;
 
+import org.apache.myfaces.shared.util.CommentUtils;
 import org.apache.myfaces.test.base.AbstractJsfTestCase;
 
 /**
@@ -143,4 +144,235 @@ public class HtmlResponseWriterImplTest 
         return b == null ? defaultValue : b;
     }
 
-}
+    public void testScriptOnHtmlIsoEncodingAndScriptXhmlComments() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "text/html", "ISO-8859-1", true);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start comment <!-- ", output.contains(CommentUtils.COMMENT_SIMPLE_START));
+        assertTrue("script does not have end comment --> ", output.contains("//"+CommentUtils.COMMENT_SIMPLE_END));
+    }
+    
+    public void testScriptOnHtmlIsoEncodingAndNoScriptXhmlComments() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "text/html", "ISO-8859-1", false);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertFalse("script have start comment <!-- ", output.contains(CommentUtils.COMMENT_SIMPLE_START));
+        assertFalse("script have end comment --> ", output.contains("//"+CommentUtils.COMMENT_SIMPLE_END));
+    }
+
+    public void testScriptOnHtmlUTF8AndScriptXhmlComments() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "text/html", "UTF-8", true);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start comment <!-- ", output.contains(CommentUtils.COMMENT_SIMPLE_START));
+        assertTrue("script does not have end comment --> ", output.contains("//"+CommentUtils.COMMENT_SIMPLE_END));
+    }
+    
+    public void testScriptOnHtmlUTF8AndNoScriptXhmlComments() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "text/html", "UTF-8", false);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertFalse("script have start comment <!-- ", output.contains(CommentUtils.COMMENT_SIMPLE_START));
+        assertFalse("script have end comment --> ", output.contains("//"+CommentUtils.COMMENT_SIMPLE_END));
+    }
+
+    public void testScriptOnXhtmlIsoEncoding() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xhtml+xml", "ISO-8859-1", true);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start <![CDATA[ ", output.contains(CommentUtils.INLINE_SCRIPT_COMMENT+CommentUtils.CDATA_SIMPLE_START));
+        assertTrue("script does not have end ]]> ", output.contains(CommentUtils.INLINE_SCRIPT_COMMENT+CommentUtils.CDATA_SIMPLE_END));
+    }
+
+    public void testScriptOnXhtmlUTF8Encoding() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xhtml+xml", "UTF-8", false);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.SCRIPT_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.SCRIPT_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start <![CDATA[ ", output.contains(CommentUtils.INLINE_SCRIPT_COMMENT+CommentUtils.CDATA_SIMPLE_START));
+        assertTrue("script does not have end ]]> ", output.contains(CommentUtils.INLINE_SCRIPT_COMMENT+CommentUtils.CDATA_SIMPLE_END));
+    }
+    
+    public void testStyleOnXhtmlIsoEncoding() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xhtml+xml", "ISO-8859-1", true);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.STYLE_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.STYLE_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start <![CDATA[ ", output.contains(CommentUtils.CDATA_SIMPLE_START));
+        assertTrue("script does not have end ]]> ", output.contains(CommentUtils.CDATA_SIMPLE_END));
+    }
+
+    public void testStyleOnXhtmlUTF8Encoding() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xhtml+xml", "UTF-8", false);
+        String innerScript = "document.write('HELLO');"; 
+        _writer.startDocument();
+        _writer.startElement(HTML.STYLE_ELEM, null);
+        _writer.write(innerScript);
+        _writer.endElement(HTML.STYLE_ELEM);
+        _writer.endDocument();
+        
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue("script does not contain body:" + innerScript, output.contains(innerScript));
+        assertTrue("script does not have start <![CDATA[ ", output.contains(CommentUtils.CDATA_SIMPLE_START));
+        assertTrue("script does not have end ]]> ", output.contains(CommentUtils.CDATA_SIMPLE_END));
+    }
+    
+    /**
+     * In html, it is not valid to have an empty tag with content
+     * 
+     * @throws IOException
+     */
+    public void testEmptyTagNotRenderEnd() throws IOException
+    {
+        _writer.startDocument();
+        _writer.startElement("body", null);
+        _writer.startElement("br", null);
+        _writer.writeText("hello", null);
+        _writer.endElement("br");
+        _writer.endElement("body");
+        _writer.endDocument();
+       
+        // the following should render <br />hello
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue(output.contains("<br />"));
+        assertFalse(output.contains("</br>"));
+    }
+    
+    /**
+     * In xhtml, it is valid to have an html empty tag with content.
+     * 
+     * @throws IOException
+     */
+    /* Test not valid because backward compatibility
+    public void testEmptyTagNotRenderEndOnXml() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xml", "UTF-8", false);
+        
+        _writer.startDocument();
+        _writer.startElement("body", null);
+        _writer.startElement("br", null);
+        _writer.writeText("hello", null);
+        _writer.endElement("br");
+        _writer.endElement("body");
+        _writer.endDocument();
+        
+     // the following should render <br>hello</br>
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue(output.contains("<br>"));
+        assertTrue(output.contains("</br>"));
+    }
+    */
+    
+    /**
+     * In html, it is not valid to have an empty tag with content
+     * 
+     * @throws IOException
+     */
+    /* Test not valid because backward compatibility
+    public void testEmptyTagNotRenderEndUppercase() throws IOException
+    {
+        _writer.startDocument();
+        _writer.startElement("body", null);
+        _writer.startElement("BR", null);
+        _writer.writeText("hello", null);
+        _writer.endElement("BR");
+        _writer.endElement("body");
+        _writer.endDocument();
+       
+        // the following should render <br />hello
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue(output.contains("<BR />"));
+        assertFalse(output.contains("</BR>"));
+    }*/
+    
+    /**
+     * In xhtml, it is valid to have an html empty tag with content.
+     * 
+     * @throws IOException
+     */
+    /* Test not valid because backward compatibility
+    public void testEmptyTagNotRenderEndOnXhtmlUppercase() throws IOException
+    {
+        _writer = new HtmlResponseWriterImpl(_stringWriter, "application/xml", "UTF-8", false);
+        
+        _writer.startDocument();
+        _writer.startElement("body", null);
+        _writer.startElement("BR", null);
+        _writer.writeText("hello", null);
+        _writer.endElement("BR");
+        _writer.endElement("body");
+        _writer.endDocument();
+        
+     // the following should render <br>hello</br>
+        String output = _stringWriter.toString();
+        assertNotNull(output);
+        assertTrue(output.contains("<BR>"));
+        assertTrue(output.contains("</BR>"));
+    }*/
+}
\ No newline at end of file

Added: myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/util/CommentUtilsTest.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/util/CommentUtilsTest.java?rev=962926&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/util/CommentUtilsTest.java (added)
+++ myfaces/shared/trunk/core/src/test/java/org/apache/myfaces/shared/util/CommentUtilsTest.java Sat Jul 10 22:16:40 2010
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.shared.util;
+
+import java.io.IOException;
+
+import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
+import org.junit.Test;
+
+public class CommentUtilsTest extends AbstractJsfTestCase
+{
+    @Test
+    public void testIsStartMatchWithCommentedCDATA() throws IOException
+    {
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithCommentedCDATA("/*"+CommentUtils.CDATA_SIMPLE_START));
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithCommentedCDATA("/* "+CommentUtils.CDATA_SIMPLE_START));
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithCommentedCDATA("/* \n\t"+CommentUtils.CDATA_SIMPLE_START));        
+    }
+    
+    @Test
+    public void testIsEndMatchWithCommentedCDATA() throws IOException
+    {
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithCommentedCDATA("fkdjslkfjsl "+CommentUtils.CDATA_SIMPLE_END+"*/"));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithCommentedCDATA("fkdjslkfjsl "+CommentUtils.CDATA_SIMPLE_END+" */"));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithCommentedCDATA("fkdjslkfjsl "+CommentUtils.CDATA_SIMPLE_END+"\n\t */"));
+    }
+    
+    @Test
+    public void testIsStartMatchWithInlineCommentedCDATA() throws IOException
+    {
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithInlineCommentedCDATA("//"+CommentUtils.CDATA_SIMPLE_START));
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithInlineCommentedCDATA("// "+CommentUtils.CDATA_SIMPLE_START));
+        org.junit.Assert.assertTrue(CommentUtils.isStartMatchWithInlineCommentedCDATA("// \t"+CommentUtils.CDATA_SIMPLE_START));
+        org.junit.Assert.assertFalse(CommentUtils.isStartMatchWithInlineCommentedCDATA("// \n"+CommentUtils.CDATA_SIMPLE_START));
+    }
+
+    @Test
+    public void testIsEndMatchWithInlineCommentedCDATA() throws IOException
+    {
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithInlineCommentedCDATA("fkdjslkfjsl //"+CommentUtils.CDATA_SIMPLE_END));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithInlineCommentedCDATA("fkdjslkfjsl // "+CommentUtils.CDATA_SIMPLE_END));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchWithInlineCommentedCDATA("fkdjslkfjsl //\t "+CommentUtils.CDATA_SIMPLE_END));
+        org.junit.Assert.assertFalse(CommentUtils.isEndMatchWithInlineCommentedCDATA("fkdjslkfjsl //\n\t "+CommentUtils.CDATA_SIMPLE_END));
+    }
+    
+    @Test
+    public void testIsEndMatchtWithInlineCommentedXmlCommentTag() throws IOException
+    {
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag("fkdjslkfjsl //"+CommentUtils.COMMENT_SIMPLE_END));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag("fkdjslkfjsl // "+CommentUtils.COMMENT_SIMPLE_END));
+        org.junit.Assert.assertTrue(CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag("fkdjslkfjsl //\t "+CommentUtils.COMMENT_SIMPLE_END));
+        org.junit.Assert.assertFalse(CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag("fkdjslkfjsl //\n\t "+CommentUtils.COMMENT_SIMPLE_END));        
+    }
+}