diff --git a/src/main/java/org/javarosa/core/model/instance/CsvExternalInstance.java b/src/main/java/org/javarosa/core/model/instance/CsvExternalInstance.java index c3194d6c2..242130d96 100644 --- a/src/main/java/org/javarosa/core/model/instance/CsvExternalInstance.java +++ b/src/main/java/org/javarosa/core/model/instance/CsvExternalInstance.java @@ -1,6 +1,8 @@ package org.javarosa.core.model.instance; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.commons.csv.CSVFormat; @@ -13,7 +15,10 @@ public static TreeElement parse(String instanceId, String path) throws IOExcepti final TreeElement root = new TreeElement("root", 0); root.setInstanceName(instanceId); - final CSVParser csvParser = CSVParser.parse(new File(path), StandardCharsets.UTF_8, CSVFormat.DEFAULT.withFirstRecordAsHeader()); + final CSVFormat csvFormat = CSVFormat.DEFAULT + .withDelimiter(getDelimiter(path)) + .withFirstRecordAsHeader(); + final CSVParser csvParser = CSVParser.parse(new File(path), StandardCharsets.UTF_8, csvFormat); final String[] fieldNames = csvParser.getHeaderMap().keySet().toArray(new String[0]); int multiplicity = 0; @@ -32,4 +37,16 @@ public static TreeElement parse(String instanceId, String path) throws IOExcepti return root; } + + private static char getDelimiter(String path) throws IOException { + char delimiter = ','; + try (BufferedReader reader = new BufferedReader(new FileReader(path))) { + String header = reader.readLine(); + + if (header.contains(";")) { + delimiter = ';'; + } + } + return delimiter; + } } diff --git a/src/test/java/org/javarosa/core/model/instance/CsvExternalInstanceTest.java b/src/test/java/org/javarosa/core/model/instance/CsvExternalInstanceTest.java index 7f1a7e3cf..3e13bd362 100644 --- a/src/test/java/org/javarosa/core/model/instance/CsvExternalInstanceTest.java +++ b/src/test/java/org/javarosa/core/model/instance/CsvExternalInstanceTest.java @@ -8,32 +8,44 @@ import org.junit.Test; public class CsvExternalInstanceTest { - private TreeElement root; + private TreeElement commaSeparated; + private TreeElement tabSeparated; @Before public void setUp() throws IOException { - root = CsvExternalInstance.parse("id", r("non_trivial.csv").toString()); + commaSeparated = CsvExternalInstance.parse("id", r("external-secondary-comma-complex.csv").toString()); + tabSeparated = CsvExternalInstance.parse("id", r("external-secondary-semicolon-complex.csv").toString()); } @Test public void heading_has_no_extra_quotes() { - assertEquals("label", root.getChildAt(0).getChildAt(0).getName()); + assertEquals("label", commaSeparated.getChildAt(0).getChildAt(0).getName()); + assertEquals("label", tabSeparated.getChildAt(0).getChildAt(0).getName()); } @Test public void value_has_no_extra_quotes() { - assertEquals("A", root.getChildAt(0).getChildAt(0).getValue().getValue()); + assertEquals("A", commaSeparated.getChildAt(0).getChildAt(0).getValue().getValue()); + assertEquals("A", tabSeparated.getChildAt(0).getChildAt(0).getValue().getValue()); } @Test public void quoted_string_with_comma() { - assertEquals("121 Main St, NE", root.getChildAt(6).getChildAt(0).getValue().getValue()); + assertEquals("121 Main St, NE", commaSeparated.getChildAt(6).getChildAt(0).getValue().getValue()); + assertEquals("121 Main St, NE", tabSeparated.getChildAt(6).getChildAt(0).getValue().getValue()); + } + + @Test + public void quoted_string_with_semicolon() { + assertEquals("text; more text", commaSeparated.getChildAt(7).getChildAt(0).getValue().getValue()); + assertEquals("text; more text", tabSeparated.getChildAt(7).getChildAt(0).getValue().getValue()); } @Test public void missing_fields_replaced_with_spaces() { for (int fieldIndex = 1; fieldIndex < 2; fieldIndex++) { - assertEquals("", root.getChildAt(5).getChildAt(fieldIndex).getValue().getValue()); + assertEquals("", commaSeparated.getChildAt(5).getChildAt(fieldIndex).getValue().getValue()); + assertEquals("", tabSeparated.getChildAt(5).getChildAt(fieldIndex).getValue().getValue()); } } } diff --git a/src/test/resources/org/javarosa/core/model/instance/non_trivial.csv b/src/test/resources/org/javarosa/core/model/instance/external-secondary-comma-complex.csv similarity index 54% rename from src/test/resources/org/javarosa/core/model/instance/non_trivial.csv rename to src/test/resources/org/javarosa/core/model/instance/external-secondary-comma-complex.csv index 3ec94c7b6..20f509bfc 100644 --- a/src/test/resources/org/javarosa/core/model/instance/non_trivial.csv +++ b/src/test/resources/org/javarosa/core/model/instance/external-secondary-comma-complex.csv @@ -5,4 +5,5 @@ C,c AA,aa,a AB,ab,a AC -"121 Main St, NE", main, m +"121 Main St, NE",main,m +"text; more text",foo,bar diff --git a/src/test/resources/org/javarosa/core/model/instance/external-secondary-semicolon-complex.csv b/src/test/resources/org/javarosa/core/model/instance/external-secondary-semicolon-complex.csv new file mode 100644 index 000000000..50bb116d0 --- /dev/null +++ b/src/test/resources/org/javarosa/core/model/instance/external-secondary-semicolon-complex.csv @@ -0,0 +1,9 @@ +"label";"name";"first" +"A";"a"; +B;b; +C;c +AA;aa;a +AB;ab;a +AC +"121 Main St, NE";main;m +"text; more text";foo;bar