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 2014/02/18 04:06:47 UTC

svn commit: r1569170 - in /myfaces/core/trunk/impl/src: main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java

Author: lu4242
Date: Tue Feb 18 03:06:47 2014
New Revision: 1569170

URL: http://svn.apache.org/r1569170
Log:
MYFACES-3854 oam-compress-spaces remove carriage return / line feed in CDATA sections

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java?rev=1569170&r1=1569169&r2=1569170&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TextUnit.java Tue Feb 18 03:06:47 2014
@@ -406,37 +406,74 @@ final class TextUnit extends Compilation
     
     final static String compressELText(String text)
     {
-        int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-        int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-        if (firstCharLocation == 0 && lastCharLocation == text.length()-1)
-        {
-            return text;
-        }
-        else
+        //int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
+        int firstCharLocation = -1;
+        int leftChar = 0; // 0=first char on left 1=\n 2=\r 3=\r\n
+        int lenght = text.length();
+        String leftText = null;
+        for (int j = 0; j < lenght; j++)
         {
-            if (lastCharLocation+1 < text.length())
+            char c = text.charAt(j);
+            if (leftChar == 0)
             {
-                lastCharLocation = lastCharLocation+1;
+                if (c == '\r')
+                {
+                    leftChar = 2;
+                    if (j+1 < lenght)
+                    {
+                        if (text.charAt(j+1) == '\n')
+                        {
+                            leftChar = 3;
+                        }
+                    }
+                }
+                if (c == '\n')
+                {
+                    leftChar = 1;
+                }
             }
-            if (firstCharLocation == 0)
+            if (Character.isWhitespace(c))
             {
-                return text.substring(firstCharLocation, lastCharLocation+1);
+                continue;
             }
             else
             {
-                return text.substring(0,1)+text.substring(firstCharLocation, lastCharLocation+1);
+                firstCharLocation = j;
+                break;
             }
         }
-    }
-    
-    /*
-    final static ELText compressELText(ELText parsedText, String text)
-    {
-        int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
+        if (firstCharLocation == -1)
+        {
+            firstCharLocation = lenght;
+        }
+        // Define the character on the left
+        if (firstCharLocation > 0)
+        {
+            switch (leftChar)
+            {
+                case 1:
+                    leftText = "\n";
+                    break;
+                case 2:
+                    leftText = "\r";
+                    break;
+                case 3:
+                    leftText = "\r\n";
+                    break;
+                default:
+                    leftText = (lenght > 1) ? text.substring(0,1) : text;
+                    break;
+            }                
+        }
+        else
+        {
+            leftText = "";
+        }
+                
         int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
         if (firstCharLocation == 0 && lastCharLocation == text.length()-1)
         {
-            return parsedText;
+            return text;
         }
         else
         {
@@ -446,91 +483,142 @@ final class TextUnit extends Compilation
             }
             if (firstCharLocation == 0)
             {
-                return ELText.parse(text.substring(firstCharLocation, lastCharLocation+1));
+                return text.substring(firstCharLocation, lastCharLocation+1);
             }
             else
             {
-                return ELText.parse(text.substring(0,1)+text.substring(firstCharLocation, lastCharLocation+1));
+                return leftText+text.substring(firstCharLocation, lastCharLocation+1);
             }
         }
     }
-    */
     
+    /**
+     * Compress spaces around a list of instructions, following these rules:
+     * 
+     * - The first instruction that is on the left usually make contact with a component.
+     * 
+     * @param instructionBuffer
+     * @param size
+     * @return 
+     */
     final static int compressSpaces(List<Instruction> instructionBuffer, int size)
     {
         boolean addleftspace = true;
         boolean addrightspace = false;
+        boolean skipnext = false;
         for (int i = 0; i < size; i++)
         {
+            String text = null;
+            String newText = null;
+            int instructionType = 0;
+            if (skipnext)
+            {
+                skipnext = false;
+                continue;
+            }
             Instruction ins = instructionBuffer.get(i);
             if (i+1 == size)
             {
                 addrightspace = true;
             }
-            //boolean isNextStartExpression = i+1<size ? 
-            //        (this.instructions[i+1] instanceof StartElementInstruction) : false;
+            
             if (ins instanceof LiteralTextInstruction)
             {
-                String text = ((LiteralTextInstruction)ins).getText();
-                int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-                if (firstCharLocation == text.length() && text.length() > 1)
+                text = ((LiteralTextInstruction)ins).getText();
+                instructionType = 1;
+            }
+            else if (ins instanceof LiteralNonExcapedTextInstruction)
+            {
+                text = ((LiteralTextInstruction)ins).getText();
+                instructionType = 2;
+            }
+            else if (ins instanceof LiteralXMLInstruction)
+            {
+                skipnext = true;
+                continue;
+            }
+            
+            if (text != null && text.length() > 0)
+            {
+                int firstCharLocation = -1;
+                int leftChar = 0; // 0=first char on left 1=\n 2=\r 3=\r\n
+                int lenght = text.length();
+                String leftText = null;
+                for (int j = 0; j < lenght; j++)
                 {
-                    // All the instruction is space, replace with an instruction 
-                    // with only one space
-                    if (addleftspace || addrightspace)
+                    char c = text.charAt(j);
+                    if (leftChar == 0)
+                    {
+                        if (c == '\r')
+                        {
+                            leftChar = 2;
+                            if (j+1 < lenght)
+                            {
+                                if (text.charAt(j+1) == '\n')
+                                {
+                                    leftChar = 3;
+                                }
+                            }
+                        }
+                        if (c == '\n')
+                        {
+                            leftChar = 1;
+                        }
+                    }
+                    if (Character.isWhitespace(c))
                     {
-                        instructionBuffer.set(i, new LiteralTextInstruction(text.substring(0,1)));
+                        continue;
                     }
                     else
                     {
-                        instructionBuffer.remove(i);
-                        i--;
-                        size--;
+                        firstCharLocation = j;
+                        break;
                     }
                 }
-                else if (firstCharLocation > 0)
+                if (firstCharLocation == -1)
                 {
-                    int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-                    // If right space, increment in 1
-                    if (lastCharLocation+1 < text.length())
+                    firstCharLocation = lenght;
+                }
+                // Define the character on the left
+                if (firstCharLocation > 0)
+                {
+                    switch (leftChar)
                     {
-                        lastCharLocation = lastCharLocation+1;
-                    }
-                    instructionBuffer.set(i, new LiteralTextInstruction(
-                            text.substring(0,1)+text.substring(firstCharLocation, lastCharLocation+1)));
+                        case 1:
+                            leftText = "\n";
+                            break;
+                        case 2:
+                            leftText = "\r";
+                            break;
+                        case 3:
+                            leftText = "\r\n";
+                            break;
+                        default:
+                            leftText = (lenght > 1) ? text.substring(0,1) : text;
+                            break;
+                    }                
                 }
                 else
                 {
-                    int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-                    // If right space, increment in 1
-                    if (lastCharLocation+1 < text.length())
-                    {
-                        lastCharLocation = lastCharLocation+1;
-                    }
-                    instructionBuffer.set(i, new LiteralTextInstruction(
-                            text.substring(firstCharLocation, lastCharLocation+1)));
+                    leftText = "";
                 }
-            }
-            else if (ins instanceof LiteralNonExcapedTextInstruction)
-            {
-                String text = ((LiteralTextInstruction)ins).getText();
-                int firstCharLocation = getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-                if (firstCharLocation == text.length())
+                
+                if (firstCharLocation == lenght && lenght > 1)
                 {
                     // All the instruction is space, replace with an instruction 
                     // with only one space
                     if (addleftspace || addrightspace)
                     {
-                        instructionBuffer.set(i, new LiteralNonExcapedTextInstruction(text.substring(0,1)));
+                        newText = leftText;
                     }
                     else
                     {
                         instructionBuffer.remove(i);
                         i--;
                         size--;
-                    }                    
+                    }
                 }
-                else if (firstCharLocation > 1)
+                else
                 {
                     int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
                     // If right space, increment in 1
@@ -538,26 +626,34 @@ final class TextUnit extends Compilation
                     {
                         lastCharLocation = lastCharLocation+1;
                     }
-                    instructionBuffer.set(i, new LiteralNonExcapedTextInstruction(
-                            text.substring(0,1)+text.substring(firstCharLocation, lastCharLocation+1)));
+                    if (firstCharLocation > 0)
+                    {
+                        newText = leftText+
+                            text.substring(firstCharLocation, lastCharLocation+1);
+                    }
+                    else
+                    {
+                        newText = text.substring(firstCharLocation, lastCharLocation+1);
+                    }
                 }
-                else
+                
+                if (newText != null)
                 {
-                    int lastCharLocation = getLastTextCharLocationIgnoringSpacesTabsAndCarriageReturn(text);
-                    // If right space, increment in 1
-                    if (lastCharLocation+1 < text.length())
+                    if (instructionType == 1)
                     {
-                        lastCharLocation = lastCharLocation+1;
+                        instructionBuffer.set(i, new LiteralTextInstruction(newText));
+                    }
+                    else if (instructionType == 2)
+                    {
+                        instructionBuffer.set(i, new LiteralNonExcapedTextInstruction(newText));
                     }
-                    instructionBuffer.set(i, new LiteralNonExcapedTextInstruction(
-                            text.substring(firstCharLocation, lastCharLocation+1)));
                 }
             }
             addleftspace = false;
         }
         return size;
     }
-    
+
     private static int getFirstTextCharLocationIgnoringSpacesTabsAndCarriageReturn(String text)
     {
         for (int i = 0; i < text.length(); i++)

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java?rev=1569170&r1=1569169&r2=1569170&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/compiler/CompressSpacesTextUnitTestCase.java Tue Feb 18 03:06:47 2014
@@ -143,11 +143,35 @@ public class CompressSpacesTextUnitTestC
             i.write(facesContext);
         }
         
-        Assert.assertEquals(fw.toString(), " ");
+        Assert.assertEquals(fw.toString(), "\n");
 
     }
 
     @Test
+    public void testSimpleCompress4_1() throws Exception {
+        
+        List<Instruction> instructions = new ArrayList<Instruction>();
+        
+        instructions.add(new LiteralTextInstruction("  \r\n     "));
+
+        int size = instructions.size();
+        size = TextUnit.compressSpaces(instructions, size);
+
+        FastWriter fw = new FastWriter();
+        ResponseWriter rw = facesContext.getResponseWriter();
+        rw = rw.cloneWithWriter(fw);
+        facesContext.setResponseWriter(rw);
+
+        for (Instruction i : instructions)
+        {
+            i.write(facesContext);
+        }
+        
+        Assert.assertEquals(fw.toString(), "\r\n");
+
+    }    
+    
+    @Test
     public void testSimpleCompress5() throws Exception {
         
         List<Instruction> instructions = new ArrayList<Instruction>();
@@ -170,6 +194,39 @@ public class CompressSpacesTextUnitTestC
         Assert.assertEquals(fw.toString(), "&amp;#160;\n");
 
     }
+    
+    @Test
+    public void testSimpleCompress6() throws Exception {
+        
+        List<Instruction> instructions = new ArrayList<Instruction>();
+
+        instructions.add(new LiteralTextInstruction("    \r\n"));
+        instructions.add(new StartElementInstruction("script"));
+        instructions.add(new LiteralAttributeInstruction("type", "text/javascript"));
+        instructions.add(new LiteralTextInstruction("\r\n    //"));
+        instructions.add(new LiteralXMLInstruction("<![CDATA[ "));
+        instructions.add(new LiteralTextInstruction("  \r\n     someJavascript();\r\n     //"));
+        instructions.add(new LiteralXMLInstruction("]]>"));
+        instructions.add(new LiteralTextInstruction("\r\n"));
+        instructions.add(new EndElementInstruction("script"));
+        instructions.add(new LiteralTextInstruction("        "));
+        
+        int size = instructions.size();
+        size = TextUnit.compressSpaces(instructions, size);
+        
+        FastWriter fw = new FastWriter();
+        ResponseWriter rw = facesContext.getResponseWriter();
+        rw = rw.cloneWithWriter(fw);
+        facesContext.setResponseWriter(rw);
+
+        for (Instruction i : instructions)
+        {
+            i.write(facesContext);
+        }        
+        
+        Assert.assertEquals(fw.toString(), "\r\n<script type=\"text/javascript\">\r\n//<![CDATA[   "+
+            "\r\n     someJavascript();\r\n     //]]>\r\n</script> ");
+    }
 
     @Test
     public void testCompressOnELExpressions() throws Exception
@@ -180,6 +237,7 @@ public class CompressSpacesTextUnitTestC
         String text = tryCompress("  #{bean.name}  ");
         Assert.assertEquals(tryCompress("  #{bean.name}  "), " #{bean.name} ");
         Assert.assertEquals(tryCompress("\n #{bean.name}\n "), "\n#{bean.name}\n");
+        Assert.assertEquals(tryCompress(" \r\n #{bean.name} \r\n "), "\r\n#{bean.name} ");
     }
     
     public String tryCompress(String value)