This is an automated email from the ASF dual-hosted git repository. onders pushed a commit to branch camel-2.19.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3dc164d0c0b31d57eb117ef88fbaed2eac00c8a4 Author: onders86 <[email protected]> AuthorDate: Tue Nov 7 09:37:46 2017 +0300 CAMEL-11932 - add new option for fixedlengthcvs unmarshalling because Scanner is used and it needs delimiter --- .../src/main/docs/bindy-dataformat.adoc | 9 +- .../dataformat/bindy/BindyAbstractFactory.java | 8 + .../dataformat/bindy/BindyFixedLengthFactory.java | 3 + .../bindy/annotation/FixedLengthRecord.java | 15 +- .../bindy/fixed/BindyFixedLengthDataFormat.java | 25 ++- ...indyMarshallUnmarshallWithDefaultValueTest.java | 193 +++++++++++++++++++++ 6 files changed, 243 insertions(+), 10 deletions(-) diff --git a/components/camel-bindy/src/main/docs/bindy-dataformat.adoc b/components/camel-bindy/src/main/docs/bindy-dataformat.adoc index 1d59e8d..0d7c383 100644 --- a/components/camel-bindy/src/main/docs/bindy-dataformat.adoc +++ b/components/camel-bindy/src/main/docs/bindy-dataformat.adoc @@ -704,7 +704,14 @@ field, we can then add 'padd' characters. |crlf |string |optional - possible values = WINDOWS,UNIX,MAC, or custom; default value. WINDOWS - allow to define the carriage return character to use. If you specify a value other than the three listed before, the value you enter -(custom) will be used as the CRLF character(s) +(custom) will be used as the CRLF character(s). This option is used only during marshalling, +whereas unmarshalling uses system default JDK provided line delimiter unless eol is customized + +|eol |string |optional - default="" which is empty string. Character to be used to process +considering end of line after each record while unmarshalling (optional - default = "" +which help default JDK provided line delimiter to be used unless any other line delimiter +provided). This option is used only during unmarshalling, where marshalling uses system default +provided line delimiter as "WINDOWS" unless any other value is provided |paddingChar |char |mandatory - default value = ' ' diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java index 1108a68..7beea26 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java @@ -41,6 +41,7 @@ public abstract class BindyAbstractFactory implements BindyFactory { protected Set<Class<?>> models; protected Set<String> modelClassNames; protected String crlf; + protected String eol; private String locale; private Class<?> type; @@ -222,6 +223,13 @@ public abstract class BindyAbstractFactory implements BindyFactory { } /** + * Find the carriage return set + */ + public String getEndOfLine() { + return eol; + } + + /** * Format the object into a string according to the format rule defined */ @SuppressWarnings("unchecked") diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java index 99b3670..d4d9c82 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java @@ -533,6 +533,9 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin // Get carriage return parameter crlf = record.crlf(); LOG.debug("Carriage return defined for the CSV: {}", crlf); + + eol = record.eol(); + LOG.debug("EOL(end-of-line) defined for the CSV: {}", crlf); // Get header parameter header = record.header(); diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java index ba1e25b..1ae745a 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java @@ -39,12 +39,25 @@ public @interface FixedLengthRecord { /** * Character to be used to add a carriage return after each record * (optional) Three values can be used : WINDOWS, UNIX or MAC - * + * This option is used only during marshalling, whereas unmarshalling + * uses system default JDK provided line delimiter unless eol is customized * @return String */ String crlf() default "WINDOWS"; /** + * Character to be used to process considering end of line + * after each record while unmarshalling (optional - default = "" + * which help default JDK provided line delimiter to be used + * unless any other line delimiter provided) + * This option is used only during unmarshalling, where marshalling + * uses system default provided line delimiter as "WINDOWS" unless + * any other value is provided + * @return String + */ + String eol() default ""; + + /** * The char to pad with. * @return the char to pad with if the record is set to a fixed length; */ diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java index 23fce52..3626046 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java @@ -189,16 +189,21 @@ public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat { // Scanner is used to read big file Scanner scanner = new Scanner(in); + boolean isEolSet = false; + if (!"".equals(factory.getEndOfLine())) { + scanner.useDelimiter(factory.getEndOfLine()); + isEolSet = true; + } AtomicInteger count = new AtomicInteger(0); try { // Parse the header if it exists - if (scanner.hasNextLine() && factory.hasHeader()) { + if (((isEolSet && scanner.hasNext()) || (!isEolSet && scanner.hasNextLine())) && factory.hasHeader()) { // Read the line (should not trim as its fixed length) - String line = getNextNonEmptyLine(scanner, count); + String line = getNextNonEmptyLine(scanner, count, isEolSet); if (!factory.skipHeader()) { Map<String, Object> headerObjMap = createModel(headerFactory, line, count.intValue()); @@ -206,11 +211,11 @@ public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat { } } - String thisLine = getNextNonEmptyLine(scanner, count); + String thisLine = getNextNonEmptyLine(scanner, count, isEolSet); String nextLine = null; if (thisLine != null) { - nextLine = getNextNonEmptyLine(scanner, count); + nextLine = getNextNonEmptyLine(scanner, count, isEolSet); } // Parse the main file content @@ -222,7 +227,7 @@ public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat { models.add(model); thisLine = nextLine; - nextLine = getNextNonEmptyLine(scanner, count); + nextLine = getNextNonEmptyLine(scanner, count, isEolSet); } // this line should be the last non-empty line from the file @@ -254,11 +259,15 @@ public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat { } - private String getNextNonEmptyLine(Scanner scanner, AtomicInteger count) { + private String getNextNonEmptyLine(Scanner scanner, AtomicInteger count, boolean isEolSet) { String line = ""; - while (ObjectHelper.isEmpty(line) && scanner.hasNextLine()) { + while (ObjectHelper.isEmpty(line) && ((isEolSet && scanner.hasNext()) || (!isEolSet && scanner.hasNextLine()))) { count.incrementAndGet(); - line = scanner.nextLine(); + if (!isEolSet) { + line = scanner.nextLine(); + } else { + line = scanner.next(); + } } if (ObjectHelper.isEmpty(line)) { diff --git a/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/BindyMarshallUnmarshallWithDefaultValueTest.java b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/BindyMarshallUnmarshallWithDefaultValueTest.java index 5c6fd2a..77598be 100644 --- a/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/BindyMarshallUnmarshallWithDefaultValueTest.java +++ b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/BindyMarshallUnmarshallWithDefaultValueTest.java @@ -45,6 +45,20 @@ public class BindyMarshallUnmarshallWithDefaultValueTest extends CamelTestSuppor Assert.assertEquals("Doe", order.getLastName()); Assert.assertEquals("Hello ", order.getComment()); } + + @Test + public void testUnMarshallMessageWithEol() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:resultUnmarshalEol"); + template.sendBody("direct:unmarshaleol", "10A9 ISINXD12345678BUYShare000002500.45USD01-08-2009Hello QWERTY"); + + // check the model + OrderEol order = mock.getReceivedExchanges().get(0).getIn().getBody(OrderEol.class); + Assert.assertEquals(10, order.getOrderNr()); + // Default values are set + Assert.assertEquals("John", order.getFirstName()); + Assert.assertEquals("Doe", order.getLastName()); + Assert.assertEquals("Hello ", order.getComment()); + } @Test public void testMarshallMessage() throws Exception { @@ -55,6 +69,16 @@ public class BindyMarshallUnmarshallWithDefaultValueTest extends CamelTestSuppor template.sendBody("direct:marshal", createOrder()); mock.assertIsSatisfied(); } + + @Test + public void testMarshallMessageWithEol() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:resultMarshalEol"); + + mock.expectedBodiesReceived("10A9 JohnDoe ISINXD12345678BUYShare000002500.45USD01-08-2009 \r\n"); + + template.sendBody("direct:marshaleol", createOrderEol()); + mock.assertIsSatisfied(); + } @Override protected RouteBuilder createRouteBuilder() throws Exception { @@ -64,6 +88,14 @@ public class BindyMarshallUnmarshallWithDefaultValueTest extends CamelTestSuppor from("direct:marshal") .marshal().bindy(BindyType.Fixed, Order.class) .to("mock:resultMarshal"); + + from("direct:marshaleol") + .marshal().bindy(BindyType.Fixed, OrderEol.class) + .to("mock:resultMarshalEol"); + + from("direct:unmarshaleol") + .unmarshal().bindy(BindyType.Fixed, OrderEol.class) + .to("mock:resultUnmarshalEol"); from("direct:unmarshal") .unmarshal().bindy(BindyType.Fixed, Order.class) @@ -91,6 +123,24 @@ public class BindyMarshallUnmarshallWithDefaultValueTest extends CamelTestSuppor return order; } + private OrderEol createOrderEol() { + OrderEol order = new OrderEol(); + order.setOrderNr(10); + order.setOrderType("BUY"); + order.setClientNr("A9"); + order.setAmount(new BigDecimal("2500.45")); + order.setInstrumentCode("ISIN"); + order.setInstrumentNumber("XD12345678"); + order.setInstrumentType("Share"); + order.setCurrency("USD"); + + Calendar calendar = new GregorianCalendar(); + calendar.set(2009, 7, 1); + order.setOrderDate(calendar.getTime()); + + return order; + } + @FixedLengthRecord(length = 75) public static class Order { @@ -233,5 +283,148 @@ public class BindyMarshallUnmarshallWithDefaultValueTest extends CamelTestSuppor + String.valueOf(this.orderDate); } } + + @FixedLengthRecord(length = 75, eol = "QWERTY") + public static class OrderEol { + + @DataField(pos = 1, length = 2) + private int orderNr; + + @DataField(pos = 3, length = 2) + private String clientNr; + + @DataField(pos = 5, length = 9, defaultValue = "John", trim = true) + private String firstName; + + @DataField(pos = 14, length = 5, align = "L", defaultValue = "Doe", trim = true) + private String lastName; + + @DataField(pos = 19, length = 4) + private String instrumentCode; + + @DataField(pos = 23, length = 10) + private String instrumentNumber; + + @DataField(pos = 33, length = 3) + private String orderType; + + @DataField(pos = 36, length = 5) + private String instrumentType; + + @DataField(pos = 41, precision = 2, length = 12, paddingChar = '0') + private BigDecimal amount; + + @DataField(pos = 53, length = 3) + private String currency; + + @DataField(pos = 56, length = 10, pattern = "dd-MM-yyyy") + private Date orderDate; + + @DataField(pos = 66, length = 10) + private String comment; + + public int getOrderNr() { + return orderNr; + } + + public void setOrderNr(int orderNr) { + this.orderNr = orderNr; + } + + public String getClientNr() { + return clientNr; + } + + public void setClientNr(String clientNr) { + this.clientNr = clientNr; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getInstrumentCode() { + return instrumentCode; + } + + public void setInstrumentCode(String instrumentCode) { + this.instrumentCode = instrumentCode; + } + + public String getInstrumentNumber() { + return instrumentNumber; + } + + public void setInstrumentNumber(String instrumentNumber) { + this.instrumentNumber = instrumentNumber; + } + + public String getOrderType() { + return orderType; + } + + public void setOrderType(String orderType) { + this.orderType = orderType; + } + + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Date getOrderDate() { + return orderDate; + } + + public void setOrderDate(Date orderDate) { + this.orderDate = orderDate; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + @Override + public String toString() { + return "Model : " + Order.class.getName() + " : " + this.orderNr + ", " + this.orderType + ", " + String.valueOf(this.amount) + ", " + this.instrumentCode + ", " + + this.instrumentNumber + ", " + this.instrumentType + ", " + this.currency + ", " + this.clientNr + ", " + this.firstName + ", " + this.lastName + ", " + + String.valueOf(this.orderDate); + } + } } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
