Author: bayard
Date: Fri Jan  4 22:33:12 2008
New Revision: 609094

URL: http://svn.apache.org/viewvc?rev=609094&view=rev
Log:
Applying my patch from LANG-374 that adds an unescape method. It stays true to 
the spec and considers "foo.bar" to unescape as "foo.bar", ie) no unescaping, 
because "foo.bar" is illegal output from the escape method spec-wise. 

Modified:
    
commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringEscapeUtils.java
    
commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java

Modified: 
commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringEscapeUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringEscapeUtils.java?rev=609094&r1=609093&r2=609094&view=diff
==============================================================================
--- 
commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringEscapeUtils.java
 (original)
+++ 
commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringEscapeUtils.java
 Fri Jan  4 22:33:12 2008
@@ -772,4 +772,88 @@
         out.write(CSV_QUOTE);
     }
 
+    /**
+     * <p>Returns a <code>String</code> value for an unescaped CSV column. </p>
+     *
+     * <p>If the value is enclosed in double quotes, and contains a comma, 
newline 
+     *    or double quote, then quotes are removed. 
+     * </p>
+     *
+     * <p>Any double quote escaped characters (a pair of double quotes) are 
unescaped 
+     *    to just one double quote. </p>
+     *
+     * <p>If the value is not enclosed in double quotes, or is and does not 
contain a 
+     *    comma, newline or double quote, then the String value is returned 
unchanged.</p>
+     * </p>
+     *
+     * see <a 
href="http://en.wikipedia.org/wiki/Comma-separated_values";>Wikipedia</a> and
+     * <a href="http://tools.ietf.org/html/rfc4180";>RFC 4180</a>.
+     *
+     * @param str the input CSV column String, may be null
+     * @return the input String, with enclosing double quotes removed and 
embedded double 
+     * quotes unescaped, <code>null</code> if null string input
+     * @since 2.4
+     */
+    public static String unescapeCsv(String str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            StringWriter writer = new StringWriter();
+            unescapeCsv(writer, str);
+            return writer.toString();
+        } catch (IOException ioe) {
+            // this should never ever happen while writing to a StringWriter
+            ioe.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * <p>Returns a <code>String</code> value for an unescaped CSV column. </p>
+     *
+     * <p>If the value is enclosed in double quotes, and contains a comma, 
newline 
+     *    or double quote, then quotes are removed. 
+     * </p>
+     *
+     * <p>Any double quote escaped characters (a pair of double quotes) are 
unescaped 
+     *    to just one double quote. </p>
+     *
+     * <p>If the value is not enclosed in double quotes, or is and does not 
contain a 
+     *    comma, newline or double quote, then the String value is returned 
unchanged.</p>
+     * </p>
+     *
+     * see <a 
href="http://en.wikipedia.org/wiki/Comma-separated_values";>Wikipedia</a> and
+     * <a href="http://tools.ietf.org/html/rfc4180";>RFC 4180</a>.
+     *
+     * @param str the input CSV column String, may be null
+     * @param out Writer to write the input String to, with enclosing double 
quotes 
+     * removed and embedded double quotes unescaped, <code>null</code> if null 
string input
+     * @throws IOException if error occurs on underlying Writer
+     * @since 2.4
+     */
+    public static void unescapeCsv(Writer out, String str) throws IOException {
+        if (str == null) {
+            return;
+        }
+        if (str.length() < 2) {
+            out.write(str);
+            return;
+        }
+        if ( str.charAt(0) != CSV_QUOTE || str.charAt(str.length() - 1) != 
CSV_QUOTE ) {
+            out.write(str);
+            return;
+        }
+
+        // strip quotes
+        String quoteless = str.substring(1, str.length() - 1);
+
+        if ( StringUtils.containsAny(quoteless, CSV_SEARCH_CHARS) ) {
+            // deal with escaped quotes; ie) ""
+            str = StringUtils.replace(quoteless, "" + CSV_QUOTE + CSV_QUOTE, 
Character.toString(CSV_QUOTE));
+        }
+
+        out.write(str);
+    }
+
 }

Modified: 
commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java?rev=609094&r1=609093&r2=609094&view=diff
==============================================================================
--- 
commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
 (original)
+++ 
commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
 Fri Jan  4 22:33:12 2008
@@ -332,7 +332,6 @@
         assertEquals("& &", StringEscapeUtils.unescapeHtml("& &amp;"));
     }
 
-
     public void testEscapeCsvString() throws Exception
     {
         assertEquals("foo.bar",          
StringEscapeUtils.escapeCsv("foo.bar"));
@@ -359,6 +358,42 @@
         try {
             StringWriter writer = new StringWriter();
             StringEscapeUtils.escapeCsv(writer, value);
+            assertEquals(expected, writer.toString());
+        } catch (IOException e) {
+            fail("Threw: " + e);
+        }
+    }
+
+    public void testUnescapeCsvString() throws Exception
+    {
+        assertEquals("foo.bar",          
StringEscapeUtils.unescapeCsv("foo.bar"));
+        assertEquals("foo,bar",      
StringEscapeUtils.unescapeCsv("\"foo,bar\""));
+        assertEquals("foo\nbar",     
StringEscapeUtils.unescapeCsv("\"foo\nbar\""));
+        assertEquals("foo\rbar",     
StringEscapeUtils.unescapeCsv("\"foo\rbar\""));
+        assertEquals("foo\"bar",   
StringEscapeUtils.unescapeCsv("\"foo\"\"bar\""));
+        assertEquals("",   StringEscapeUtils.unescapeCsv(""));
+        assertEquals(null, StringEscapeUtils.unescapeCsv(null));
+
+        assertEquals("\"foo.bar\"",          
StringEscapeUtils.unescapeCsv("\"foo.bar\""));
+    }
+
+    public void testUnescapeCsvWriter() throws Exception
+    {
+        checkCsvUnescapeWriter("foo.bar",        "foo.bar");
+        checkCsvUnescapeWriter("foo,bar",    "\"foo,bar\"");
+        checkCsvUnescapeWriter("foo\nbar",   "\"foo\nbar\"");
+        checkCsvUnescapeWriter("foo\rbar",   "\"foo\rbar\"");
+        checkCsvUnescapeWriter("foo\"bar", "\"foo\"\"bar\"");
+        checkCsvUnescapeWriter("", null);
+        checkCsvUnescapeWriter("", "");
+
+        checkCsvUnescapeWriter("\"foo.bar\"",        "\"foo.bar\"");
+    }
+
+    private void checkCsvUnescapeWriter(String expected, String value) {
+        try {
+            StringWriter writer = new StringWriter();
+            StringEscapeUtils.unescapeCsv(writer, value);
             assertEquals(expected, writer.toString());
         } catch (IOException e) {
             fail("Threw: " + e);


Reply via email to