This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-4.0.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7e0f423b98bb374be772b46d7db7d8ee7f7cfc6e Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Feb 28 10:00:39 2024 +0100 Handle quote escape in bindy (#13270) --- .../dataformat/bindy/csv/BindyCsvDataFormat.java | 4 +- .../dataformat/bindy/csv/BindyEscapedCsvTest.java | 359 ++++++++++----------- 2 files changed, 181 insertions(+), 182 deletions(-) diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java index 12de5ca277d..cf149055fe7 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java @@ -254,8 +254,8 @@ public class BindyCsvDataFormat extends BindyAbstractDataFormat { escapedSubstringToHandle += pattern.split(substring).length - 1; } - String[] tokens = pattern.split(trimmedLine, factory.getAutospanLine() ? - factory.getMaxpos() + escapedSubstringToHandle : -1); + String[] tokens = pattern.split(trimmedLine, + factory.getAutospanLine() ? factory.getMaxpos() + escapedSubstringToHandle : -1); List<String> result = Arrays.asList(tokens); diff --git a/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/csv/BindyEscapedCsvTest.java b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/csv/BindyEscapedCsvTest.java index fa85e8b5b63..32ca6992637 100644 --- a/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/csv/BindyEscapedCsvTest.java +++ b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/csv/BindyEscapedCsvTest.java @@ -16,6 +16,10 @@ */ package org.apache.camel.dataformat.bindy.csv; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.apache.camel.EndpointInject; import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; @@ -28,194 +32,189 @@ import org.apache.camel.test.junit5.CamelTestSupport; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class BindyEscapedCsvTest extends CamelTestSupport { - @EndpointInject("mock:resultUnmarshal") - private MockEndpoint mockEndPointUnmarshal; - - @Test - public void testUnMarshallEscapedMessage() throws Exception { - mockEndPointUnmarshal.expectedMessageCount(1); - - String body = """ - #a,"b",c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,y - AA-01L,"Android,10,0",3,4,"test,1,2,hello",5,6,7,8,9,100,0,0,0,0,0,0,0,0,0,0,1,0,0,0 - """; - template.sendBody("direct:startUnmarshal", body); - - MockEndpoint.assertIsSatisfied(context); - - CsvRecordModel csvRecordModel = mockEndPointUnmarshal.getReceivedExchanges().get(0).getIn().getBody(CsvRecordModel.class); - - Assertions.assertEquals("AA-01L", csvRecordModel.a); - Assertions.assertEquals("Android,10,0", csvRecordModel.b); - Assertions.assertEquals("3", csvRecordModel.c); - Assertions.assertEquals("test,1,2,hello", csvRecordModel.e); - Assertions.assertEquals("5", csvRecordModel.f); - Assertions.assertEquals("6", csvRecordModel.g); - Assertions.assertTrue(csvRecordModel.list.contains("100")); - Assertions.assertTrue(csvRecordModel.list.contains("7")); - Assertions.assertTrue(csvRecordModel.list.contains("1")); - Assertions.assertTrue(csvRecordModel.list.contains("0")); - } - - @Override - protected RoutesBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - BindyCsvDataFormat camelDataFormat1 = new BindyCsvDataFormat(CsvRecordModel.class); - - from("direct:startUnmarshal") - .unmarshal(camelDataFormat1) - .process(exchange -> { - CsvRecordModel model = exchange.getIn().getBody(CsvRecordModel.class); - - if (model != null) { - String a = model.getA(); - String b = model.getB(); - String c = model.getC(); - String d = model.getD(); - String e = model.getE(); - String f = model.getF(); - String g = model.getG(); - List<String> list = model.getList(); - - log.info("a : \"{}\"", a); - log.info("b : \"{}\"", b); - log.info("c : \"{}\"", c); - log.info("d : \"{}\"", d); - log.info("e : \"{}\"", e); - log.info("f : \"{}\"", f); - log.info("g : \"{}\"", g); - log.info("list:"); - list = list == null ? - new ArrayList<>(0) : list; - list.forEach(id -> { - log.info("\tid: \"{}\"", id); - }); - } - }) - .to("mock:resultUnmarshal"); - } - }; - } - - - @CsvRecord(separator = ",", autospanLine = true, skipFirstLine = true) - public static class CsvRecordModel { - - @DataField(pos = 1) - private String a; - - @DataField(pos = 2) - private String b; - - @DataField(pos = 3) - private String c; - - @DataField(pos = 4) - private String d; - - @DataField(pos = 5) - private String e; - - @DataField(pos = 6) - private String f; - - @DataField(pos = 7) - private String g; - - @DataField(pos = 8) - @BindyConverter(AppIdentificationConvrtter.class) - private List<String> list; - - public CsvRecordModel() { - - } - - public static class AppIdentificationConvrtter implements Format<List<String>> { - - private static final String SEPARATOR = ","; - - @Override - public String format(List<String> object) throws Exception { - return String.join(SEPARATOR, object); - } - - @Override - public List<String> parse(String string) throws Exception { - return Arrays.asList((string == null ? "" : string).split(SEPARATOR, -1)); - } - - } - - public String getA() { - return a; - } - - public void setA(String a) { - this.a = a; - } - - public String getB() { - return b; - } - - public void setB(String b) { - this.b = b; - } - - public String getC() { - return c; - } - - public void setC(String c) { - this.c = c; - } - - public String getD() { - return d; - } - - public void setD(String d) { - this.d = d; - } + @EndpointInject("mock:resultUnmarshal") + private MockEndpoint mockEndPointUnmarshal; + + @Test + public void testUnMarshallEscapedMessage() throws Exception { + mockEndPointUnmarshal.expectedMessageCount(1); + + String body = """ + #a,"b",c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,y + AA-01L,"Android,10,0",3,4,"test,1,2,hello",5,6,7,8,9,100,0,0,0,0,0,0,0,0,0,0,1,0,0,0 + """; + template.sendBody("direct:startUnmarshal", body); + + MockEndpoint.assertIsSatisfied(context); + + CsvRecordModel csvRecordModel + = mockEndPointUnmarshal.getReceivedExchanges().get(0).getIn().getBody(CsvRecordModel.class); + + Assertions.assertEquals("AA-01L", csvRecordModel.a); + Assertions.assertEquals("Android,10,0", csvRecordModel.b); + Assertions.assertEquals("3", csvRecordModel.c); + Assertions.assertEquals("test,1,2,hello", csvRecordModel.e); + Assertions.assertEquals("5", csvRecordModel.f); + Assertions.assertEquals("6", csvRecordModel.g); + Assertions.assertTrue(csvRecordModel.list.contains("100")); + Assertions.assertTrue(csvRecordModel.list.contains("7")); + Assertions.assertTrue(csvRecordModel.list.contains("1")); + Assertions.assertTrue(csvRecordModel.list.contains("0")); + } + + @Override + protected RoutesBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + BindyCsvDataFormat camelDataFormat1 = new BindyCsvDataFormat(CsvRecordModel.class); + + from("direct:startUnmarshal") + .unmarshal(camelDataFormat1) + .process(exchange -> { + CsvRecordModel model = exchange.getIn().getBody(CsvRecordModel.class); + + if (model != null) { + String a = model.getA(); + String b = model.getB(); + String c = model.getC(); + String d = model.getD(); + String e = model.getE(); + String f = model.getF(); + String g = model.getG(); + List<String> list = model.getList(); + + log.info("a : \"{}\"", a); + log.info("b : \"{}\"", b); + log.info("c : \"{}\"", c); + log.info("d : \"{}\"", d); + log.info("e : \"{}\"", e); + log.info("f : \"{}\"", f); + log.info("g : \"{}\"", g); + log.info("list:"); + list = list == null ? new ArrayList<>(0) : list; + list.forEach(id -> { + log.info("\tid: \"{}\"", id); + }); + } + }) + .to("mock:resultUnmarshal"); + } + }; + } + + @CsvRecord(separator = ",", autospanLine = true, skipFirstLine = true) + public static class CsvRecordModel { + + @DataField(pos = 1) + private String a; + + @DataField(pos = 2) + private String b; + + @DataField(pos = 3) + private String c; + + @DataField(pos = 4) + private String d; + + @DataField(pos = 5) + private String e; + + @DataField(pos = 6) + private String f; + + @DataField(pos = 7) + private String g; + + @DataField(pos = 8) + @BindyConverter(AppIdentificationConvrtter.class) + private List<String> list; + + public CsvRecordModel() { + + } + + public static class AppIdentificationConvrtter implements Format<List<String>> { + + private static final String SEPARATOR = ","; + + @Override + public String format(List<String> object) throws Exception { + return String.join(SEPARATOR, object); + } + + @Override + public List<String> parse(String string) throws Exception { + return Arrays.asList((string == null ? "" : string).split(SEPARATOR, -1)); + } + + } + + public String getA() { + return a; + } + + public void setA(String a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } - public String getE() { - return e; - } + public String getE() { + return e; + } - public void setE(String e) { - this.e = e; - } + public void setE(String e) { + this.e = e; + } - public String getF() { - return f; - } + public String getF() { + return f; + } - public void setF(String f) { - this.f = f; - } + public void setF(String f) { + this.f = f; + } - public String getG() { - return g; - } + public String getG() { + return g; + } - public void setG(String g) { - this.g = g; - } + public void setG(String g) { + this.g = g; + } - public List<String> getList() { - return list; - } + public List<String> getList() { + return list; + } - public void setList(List<String> list) { - this.list = list; - } - } + public void setList(List<String> list) { + this.list = list; + } + } }