Repository: metamodel Updated Branches: refs/heads/master b2eca1c3a -> f779f43cd
METAMODEL-227: Fixed Fixes #83 Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/f779f43c Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/f779f43c Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/f779f43c Branch: refs/heads/master Commit: f779f43cd048ce9fb5c05bb92ee31a9039a3a4fa Parents: b2eca1c Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Authored: Sat Jan 2 20:34:23 2016 +0100 Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Committed: Sat Jan 2 20:34:23 2016 +0100 ---------------------------------------------------------------------- CHANGES.md | 4 ++ .../org/apache/metamodel/csv/CsvWriter.java | 37 ++++++++++++----- .../org/apache/metamodel/csv/CsvWriterTest.java | 43 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metamodel/blob/f779f43c/CHANGES.md ---------------------------------------------------------------------- diff --git a/CHANGES.md b/CHANGES.md index a5d8796..0a0d387 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +### Apache MetaModel 4.5.1 (work-in-progress) + + * [METAMODEL-227] - Fix for respecting CSV escape character also when no quote character is set. + ### Apache MetaModel 4.5.0 * [METAMODEL-212] - New module for ElasticSearch via REST client. http://git-wip-us.apache.org/repos/asf/metamodel/blob/f779f43c/csv/src/main/java/org/apache/metamodel/csv/CsvWriter.java ---------------------------------------------------------------------- diff --git a/csv/src/main/java/org/apache/metamodel/csv/CsvWriter.java b/csv/src/main/java/org/apache/metamodel/csv/CsvWriter.java index 1d0b424..bf640e1 100644 --- a/csv/src/main/java/org/apache/metamodel/csv/CsvWriter.java +++ b/csv/src/main/java/org/apache/metamodel/csv/CsvWriter.java @@ -59,7 +59,7 @@ public final class CsvWriter { sb.append(quoteChar); } - sb.append(stringContainsSpecialCharacters(nextElement) ? processLine(nextElement) : nextElement); + sb.append(valueNeedsEscaping(nextElement) ? processValue(nextElement) : nextElement); if (quoteChar != CsvConfiguration.NOT_A_CHAR) { sb.append(quoteChar); @@ -71,24 +71,39 @@ public final class CsvWriter { } - private boolean stringContainsSpecialCharacters(String line) { - return line.indexOf(_configuration.getQuoteChar()) != -1 || line.indexOf(_configuration.getEscapeChar()) != -1; + private boolean valueNeedsEscaping(String line) { + boolean result = line.indexOf(_configuration.getQuoteChar()) != -1 + || line.indexOf(_configuration.getEscapeChar()) != -1; + if (!result) { + result = _configuration.getQuoteChar() == CsvConfiguration.NOT_A_CHAR + && line.indexOf(_configuration.getSeparatorChar()) != -1; + } + return result; } - private StringBuilder processLine(String nextElement) { - final StringBuilder sb = new StringBuilder(INITIAL_STRING_SIZE); - for (int j = 0; j < nextElement.length(); j++) { - final char nextChar = nextElement.charAt(j); - final char escapeChar = _configuration.getEscapeChar(); - if (escapeChar != CsvConfiguration.NOT_A_CHAR && nextChar == _configuration.getQuoteChar()) { + private String processValue(String value) { + final char escapeChar = _configuration.getEscapeChar(); + if (escapeChar == CsvConfiguration.NOT_A_CHAR) { + return value; + } + + final char quoteChar = _configuration.getQuoteChar(); + final char separatorChar = _configuration.getSeparatorChar(); + + final StringBuilder sb = new StringBuilder(value.length() + 10); + for (int j = 0; j < value.length(); j++) { + final char nextChar = value.charAt(j); + if (nextChar == quoteChar) { + sb.append(escapeChar).append(nextChar); + } else if (nextChar == escapeChar) { sb.append(escapeChar).append(nextChar); - } else if (escapeChar != CsvConfiguration.NOT_A_CHAR && nextChar == escapeChar) { + } else if (quoteChar == CsvConfiguration.NOT_A_CHAR && nextChar == separatorChar) { sb.append(escapeChar).append(nextChar); } else { sb.append(nextChar); } } - return sb; + return sb.toString(); } } http://git-wip-us.apache.org/repos/asf/metamodel/blob/f779f43c/csv/src/test/java/org/apache/metamodel/csv/CsvWriterTest.java ---------------------------------------------------------------------- diff --git a/csv/src/test/java/org/apache/metamodel/csv/CsvWriterTest.java b/csv/src/test/java/org/apache/metamodel/csv/CsvWriterTest.java new file mode 100644 index 0000000..75f0c63 --- /dev/null +++ b/csv/src/test/java/org/apache/metamodel/csv/CsvWriterTest.java @@ -0,0 +1,43 @@ +/** + * 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.metamodel.csv; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class CsvWriterTest { + + @Test + public void testBuildLineWithSeparatorInValue() throws Exception { + CsvConfiguration configuration = new CsvConfiguration(1, "UTF-8", ',', '"', '\\'); + CsvWriter writer = new CsvWriter(configuration); + String line = writer.buildLine(new String[] {"0", "1,2", "3'4", "5\\6"}); + assertEquals("\"0\",\"1,2\",\"3'4\",\"5\\\\6\"\n", line); + } + + + @Test + public void testBuildLineWithSeparatorInValueAndNoQuoteCharacterSet() throws Exception { + CsvConfiguration configuration = new CsvConfiguration(1, "UTF-8", ',', CsvConfiguration.NOT_A_CHAR, '\\'); + CsvWriter writer = new CsvWriter(configuration); + String line = writer.buildLine(new String[] {"0", "1,2", "3'4", "5\\6"}); + assertEquals("0,1\\,2,3'4,5\\\\6\n", line); + } +}