You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ni...@apache.org on 2007/11/16 05:12:45 UTC
svn commit: r595541 - in /commons/proper/lang/trunk/src:
java/org/apache/commons/lang/StringEscapeUtils.java
test/org/apache/commons/lang/StringEscapeUtilsTest.java
Author: niallp
Date: Thu Nov 15 20:12:44 2007
New Revision: 595541
URL: http://svn.apache.org/viewvc?rev=595541&view=rev
Log:
LANG-374 - Add escaping for CSV columns to StringEscapeUtils
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=595541&r1=595540&r2=595541&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 Thu Nov 15 20:12:44 2007
@@ -688,4 +688,93 @@
return StringUtils.replace(str, "'", "''");
}
+ //-----------------------------------------------------------------------
+
+ /**
+ * <p>Returns a <code>String</code> value for a CSV column escaping with double quotes,
+ * if required.</p>
+ *
+ * <p>If the value contains a comma, newline or double quote, then the
+ * String value is returned enclosed in double quotes.</p>
+ * </p>
+ *
+ * <p>Any double quote characters in the value are escaped with another double quote.</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 string to escape, may be null
+ * @return a new String, escaped for CSV, <code>null</code> if null string input
+ * @since 2.4
+ */
+ public static String escapeCsv(String str) {
+ if (!containsCsvChars(str)) {
+ return str;
+ }
+ StringBuffer buffer = new StringBuffer(str.length() + 10);
+ buffer.append('"');
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == '"') {
+ buffer.append('"'); // escape double quote
+ }
+ buffer.append(c);
+ }
+ buffer.append('"');
+ return buffer.toString();
+ }
+
+ /**
+ * <p>Writes a <code>String</code> value for a CSV column escaping with double quotes,
+ * if required.</p>
+ *
+ * <p>If the value contains a comma, newline or double quote, then the
+ * String value is written enclosed in double quotes.</p>
+ * </p>
+ *
+ * <p>Any double quote characters in the value are escaped with another double quote.</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 string to escape, may be null
+ * @param out Writer to write escaped string into
+ * in double quotes or only when the value contains double quotes, commas or newline
+ * characters.
+ * @throws IOException if error occurs on underlying Writer
+ * @since 2.4
+ */
+ public static void escapeCsv(Writer out, String str) throws IOException {
+ if (!containsCsvChars(str)) {
+ if (str != null) {
+ out.write(str);
+ }
+ return;
+ }
+ out.write('"');
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == '"') {
+ out.write('"'); // escape double quote
+ }
+ out.write(c);
+ }
+ out.write('"');
+ }
+
+ /**
+ * Determine if the String contains any characters that need escaping for CSV files.
+ *
+ * @param str the string to escape, may be null
+ * @return <code>true</code> if the String contains characters that need escaping
+ * for CSV files, otherwise <code>false</code>
+ * @since 2.4
+ */
+ private static boolean containsCsvChars(String str) {
+ return (StringUtils.contains(str, '"') ||
+ StringUtils.contains(str, ',') ||
+ StringUtils.contains(str, CharUtils.CR) ||
+ StringUtils.contains(str, CharUtils.LF));
+ }
+
}
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=595541&r1=595540&r2=595541&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 Thu Nov 15 20:12:44 2007
@@ -332,4 +332,36 @@
assertEquals("& &", StringEscapeUtils.unescapeHtml("& &"));
}
+
+ public void testEscapeCsvString() throws Exception
+ {
+ assertEquals("foo.bar", StringEscapeUtils.escapeCsv("foo.bar"));
+ assertEquals("\"foo,bar\"", StringEscapeUtils.escapeCsv("foo,bar"));
+ assertEquals("\"foo\nbar\"", StringEscapeUtils.escapeCsv("foo\nbar"));
+ assertEquals("\"foo\rbar\"", StringEscapeUtils.escapeCsv("foo\rbar"));
+ assertEquals("\"foo\"\"bar\"", StringEscapeUtils.escapeCsv("foo\"bar"));
+ assertEquals("", StringEscapeUtils.escapeCsv(""));
+ assertEquals(null, StringEscapeUtils.escapeCsv(null));
+ }
+
+ public void testEscapeCsvWriter() throws Exception
+ {
+ checkCsvEscapeWriter("foo.bar", "foo.bar");
+ checkCsvEscapeWriter("\"foo,bar\"", "foo,bar");
+ checkCsvEscapeWriter("\"foo\nbar\"", "foo\nbar");
+ checkCsvEscapeWriter("\"foo\rbar\"", "foo\rbar");
+ checkCsvEscapeWriter("\"foo\"\"bar\"", "foo\"bar");
+ checkCsvEscapeWriter("", null);
+ checkCsvEscapeWriter("", "");
+ }
+
+ private void checkCsvEscapeWriter(String expected, String value) {
+ try {
+ StringWriter writer = new StringWriter();
+ StringEscapeUtils.escapeCsv(writer, value);
+ assertEquals(expected, writer.toString());
+ } catch (IOException e) {
+ fail("Threw: " + e);
+ }
+ }
}