db-ddlutils-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r542749 - in /db/ddlutils/trunk/src: java/org/apache/ddlutils/io/DataWriter.java test/org/apache/ddlutils/io/TestDataReaderAndWriter.java
Date Wed, 30 May 2007 04:53:44 GMT
Author: tomdz
Date: Tue May 29 21:53:41 2007
New Revision: 542749

URL: http://svn.apache.org/viewvc?view=rev&rev=542749
Log:
Fix for DDLUTILS-174

Modified:
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java
    db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java?view=diff&rev=542749&r1=542748&r2=542749
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java Tue May 29 21:53:41
2007
@@ -22,9 +22,11 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.Writer;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.stream.XMLOutputFactory;
@@ -281,7 +283,7 @@
                 {
                     // we create an attribute only if the text is not too long
                     // and if it does not contain special characters
-                    if ((valueAsText.length() > MAX_ATTRIBUTE_LENGTH) || containsSpecialCharacters(valueAsText))
+                    if ((valueAsText.length() > MAX_ATTRIBUTE_LENGTH) || analyzeText(valueAsText,
null))
                     {
                         // we defer writing the sub elements
                         subElements.put(column.getName(), valueAsText);
@@ -294,6 +296,8 @@
             }
             if (!subElements.isEmpty())
             {
+                List cutPoints = new ArrayList();
+
                 for (Iterator it = subElements.entrySet().iterator(); it.hasNext();)
                 {
                     Map.Entry entry     = (Map.Entry)it.next();
@@ -304,15 +308,39 @@
                     _writer.writeStartElement(entry.getKey().toString());
 
                     // if the content contains special characters, we have to apply base64
encoding to it
-                    // if the content is too short, then it has to contain special characters,
otherwise we check
-                    if ((content.length() <= MAX_ATTRIBUTE_LENGTH) || containsSpecialCharacters(content))
+                    // if the content is too short, then it has to contain special characters
(otherwise
+                    // it would have been written as an attribute already), otherwise we
check
+                    cutPoints.clear();
+
+                    boolean writeBase64Encoded = analyzeText(content, cutPoints);
+
+                    if (writeBase64Encoded)
                     {
                         _writer.writeAttribute(DatabaseIO.BASE64_ATTR_NAME, "true");
                         _writer.writeCData(new String(Base64.encodeBase64(content.getBytes())));
                     }
                     else
                     {
-                        _writer.writeCData(content);
+                        if (cutPoints.isEmpty())
+                        {
+                            _writer.writeCData(content);
+                        }
+                        else
+                        {
+                            int lastPos = 0;
+
+                            for (Iterator cutPointIt = cutPoints.iterator(); cutPointIt.hasNext();)
+                            {
+                                int curPos = ((Integer)cutPointIt.next()).intValue();
+
+                                _writer.writeCData(content.substring(lastPos, curPos));
+                                lastPos = curPos;
+                            }
+                            if (lastPos < content.length())
+                            {
+                                _writer.writeCData(content.substring(lastPos));
+                            }
+                        }
                     }
 
                     _writer.writeEndElement();
@@ -335,14 +363,19 @@
 
     /**
      * Determines whether the given string contains special characters that cannot
-     * be used in XML.
+     * be used in XML, and if not, finds the cut points where to split the text
+     * when writing it in a CDATA section.
      * 
-     * @param text The text
+     * @param text      The text
+     * @param cutPoints Will be filled with cut points to split the text when writing it
+     *                  in a CDATA section (only if the method returns <code>false</code>)
      * @return <code>true</code> if the text contains special characters
      */
-    private boolean containsSpecialCharacters(String text)
+    private boolean analyzeText(String text, List cutPoints)
     {
-        int numChars = text.length();
+        List tmpCutPoints          = cutPoints == null ? null : new ArrayList();
+        int  numChars              = text.length();
+        int  numFoundCDataEndChars = 0;
 
         for (int charPos = 0; charPos < numChars; charPos++)
         {
@@ -352,6 +385,27 @@
             {
                 return true;
             }
+            else if (cutPoints != null)
+            {
+                if ((c == ']') && ((numFoundCDataEndChars == 0) || (numFoundCDataEndChars
== 1)))
+                {
+                    numFoundCDataEndChars++;
+                }
+                else if ((c == '>') && (numFoundCDataEndChars == 2))
+                {
+                    // we have to split the CDATA right here before the '>' (see DDLUTILS-174)
+                    tmpCutPoints.add(new Integer(charPos));
+                    numFoundCDataEndChars = 0;
+                }
+                else
+                {
+                    numFoundCDataEndChars = 0;
+                }
+            }
+        }
+        if (cutPoints != null)
+        {
+            cutPoints.addAll(tmpCutPoints);
         }
         return false;
     }

Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java?view=diff&rev=542749&r1=542748&r2=542749
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java Tue May
29 21:53:41 2007
@@ -246,11 +246,15 @@
             "    <column name=\"value1\" type=\"VARCHAR\" size=\"50\" required=\"true\"/>\n"+
             "    <column name=\"value2\" type=\"VARCHAR\" size=\"4000\" required=\"true\"/>\n"+
             "    <column name=\"value3\" type=\"LONGVARCHAR\" size=\"4000\" required=\"true\"/>\n"+
+            "    <column name=\"value4\" type=\"LONGVARCHAR\" size=\"4000\" required=\"true\"/>\n"+
+            "    <column name=\"value5\" type=\"LONGVARCHAR\" size=\"4000\" required=\"true\"/>\n"+
             "  </table>\n"+
             "</database>";
         final String testedValue1 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><test><![CDATA[some
text]]></test>";
         final String testedValue2 = StringUtils.repeat("a ", 1000) + testedValue1;
         final String testedValue3 = "<div>\n<h1><![CDATA[WfMOpen]]></h1>\n"
+ StringUtils.repeat("Make it longer\n", 99) +  "</div>";
+        final String testedValue4 = "<![CDATA[" + StringUtils.repeat("b \n", 1000) + 
"]]>";
+        final String testedValue5 = "<<![CDATA[" + StringUtils.repeat("b \n", 500)
+  "]]>><![CDATA[" + StringUtils.repeat("c \n", 500) +  "]]>";
 
         DatabaseIO modelIO = new DatabaseIO();
 
@@ -266,6 +270,8 @@
         bean.set("value1", testedValue1);
         bean.set("value2", testedValue2);
         bean.set("value3", testedValue3);
+        bean.set("value4", testedValue4);
+        bean.set("value5", testedValue5);
         dataWriter.writeDocumentStart();
         dataWriter.write(bean);
         dataWriter.writeDocumentEnd();
@@ -305,5 +311,9 @@
                      obj.get("value2").toString());
         assertEquals(testedValue3,
                      obj.get("value3").toString());
+        assertEquals(testedValue4,
+                     obj.get("value4").toString());
+        assertEquals(testedValue5,
+                     obj.get("value5").toString());
     }
 }



Mime
View raw message