You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2013/02/07 18:59:43 UTC
svn commit: r1443631 [1/2] - in /camel/trunk/components/camel-bindy/src:
main/java/org/apache/camel/dataformat/bindy/
main/java/org/apache/camel/dataformat/bindy/annotation/
main/java/org/apache/camel/dataformat/bindy/fixed/
main/java/org/apache/camel/...
Author: davsclaus
Date: Thu Feb 7 17:59:42 2013
New Revision: 1443631
URL: http://svn.apache.org/r1443631
Log:
CAMEL-6039: fixed length record improvements. Thanks to Rich Newcomb for the patch.
Added:
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/ordinal/
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/ordinal/BindySimpleFixedLengthOrdinalPosTest.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/skipheader/
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/skipheader/BindyFixedLengthHeaderFooterSkipHeaderTest.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/skipheader/Order.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/skipheader/OrderFooter.java (with props)
camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/skipheader/OrderHeader.java (with props)
Modified:
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java
camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/util/AnnotationModelLoader.java
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyAbstractFactory.java Thu Feb 7 17:59:42 2013
@@ -19,6 +19,7 @@ package org.apache.camel.dataformat.bind
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,7 @@ import java.util.Set;
import org.apache.camel.dataformat.bindy.util.AnnotationModelLoader;
import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,9 +40,10 @@ public abstract class BindyAbstractFacto
private static final transient Logger LOG = LoggerFactory.getLogger(BindyAbstractFactory.class);
protected final Map<String, List<Field>> annotatedLinkFields = new LinkedHashMap<String, List<Field>>();
protected Set<Class<?>> models;
+ protected Set<String> modelClassNames;
protected String crlf;
-
private AnnotationModelLoader modelsLoader;
+
private String[] packageNames;
private String locale;
private Class<?> type;
@@ -57,14 +60,38 @@ public abstract class BindyAbstractFacto
initModel();
}
-
+
public BindyAbstractFactory(PackageScanClassResolver resolver, Class<?> type) throws Exception {
this.modelsLoader = new AnnotationModelLoader(resolver);
this.type = type;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Class name: {}", type.getName());
+ }
+
+ initModel();
+ }
+ public BindyAbstractFactory(PackageScanClassResolver resolver, Class<?> type, PackageScanFilter scanFilter) throws Exception {
+ this.modelsLoader = new AnnotationModelLoader(resolver, scanFilter);
+ this.type = type;
+
if (LOG.isDebugEnabled()) {
LOG.debug("Class name: {}", type.getName());
}
+
+ initModel();
+ }
+
+ public BindyAbstractFactory(PackageScanClassResolver resolver, String[] packageNames, PackageScanFilter scanFilter) throws Exception {
+ this.modelsLoader = new AnnotationModelLoader(resolver, scanFilter);
+ this.packageNames = packageNames;
+
+ if (LOG.isDebugEnabled()) {
+ for (String str : this.packageNames) {
+ LOG.debug("Package name: {}", str);
+ }
+ }
initModel();
}
@@ -84,9 +111,15 @@ public abstract class BindyAbstractFacto
// use the package name from the type as it may refer to types in the same package
String pckName = type.getPackage().getName();
initModelClasses(pckName);
+
} else {
throw new IllegalArgumentException("Either packagenames or type should be configured");
}
+
+ modelClassNames = new HashSet<String>();
+ for (Class<?> clazz : models) {
+ modelClassNames.add(clazz.getName());
+ }
}
/**
@@ -150,6 +183,15 @@ public abstract class BindyAbstractFacto
return mapModel;
}
+
+ /**
+ * Indicates whether this factory can support a row comprised of the identified classes
+ * @param classes the names of the classes in the row
+ * @return true if the model supports the identified classes
+ */
+ public boolean supportsModel(Set<String> classes) {
+ return modelClassNames.containsAll(classes);
+ }
/**
* Generate a unique key
@@ -217,7 +259,7 @@ public abstract class BindyAbstractFacto
/**
* Format the object into a string according to the format rule defined
*/
- @SuppressWarnings({"unchecked", "rawtypes"})
+ @SuppressWarnings({"unchecked"})
public String formatString(Format format, Object value) throws Exception {
String strValue = "";
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java Thu Feb 7 17:59:42 2013
@@ -28,12 +28,12 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
-
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
import org.apache.camel.dataformat.bindy.annotation.Link;
import org.apache.camel.dataformat.bindy.format.FormatException;
import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -53,13 +53,17 @@ public class BindyFixedLengthFactory ext
private Map<Integer, DataField> dataFields = new LinkedHashMap<Integer, DataField>();
private Map<Integer, Field> annotatedFields = new LinkedHashMap<Integer, Field>();
-
+
private int numberOptionalFields;
private int numberMandatoryFields;
private int totalFields;
private boolean hasHeader;
+ private boolean skipHeader;
+ private boolean isHeader;
private boolean hasFooter;
+ private boolean skipFooter;
+ private boolean isFooter;
private char paddingChar;
private int recordLength;
@@ -69,14 +73,24 @@ public class BindyFixedLengthFactory ext
// initialize specific parameters of the fixed length model
initFixedLengthModel();
}
+
+ public BindyFixedLengthFactory(PackageScanClassResolver resolver, PackageScanFilter scanFilter, String... packageNames) throws Exception {
+ super(resolver, packageNames, scanFilter);
+ initFixedLengthModel();
+ }
public BindyFixedLengthFactory(PackageScanClassResolver resolver, Class<?> type) throws Exception {
super(resolver, type);
-
+
// initialize specific parameters of the fixed length model
initFixedLengthModel();
}
+ public BindyFixedLengthFactory(PackageScanClassResolver resolver, PackageScanFilter scanFilter, Class<?> type) throws Exception {
+ super(resolver, type, scanFilter);
+ initFixedLengthModel();
+ }
+
/**
* method uses to initialize the model representing the classes who will
* bind the data. This process will scan for classes according to the
@@ -105,6 +119,7 @@ public class BindyFixedLengthFactory ext
for (Field field : cl.getDeclaredFields()) {
DataField dataField = field.getAnnotation(DataField.class);
if (dataField != null) {
+
if (LOG.isDebugEnabled()) {
LOG.debug("Position defined in the class: {}, position: {}, Field: {}", new Object[]{cl.getName(), dataField.pos(), dataField});
}
@@ -159,8 +174,9 @@ public class BindyFixedLengthFactory ext
int counterMandatoryFields = 0;
DataField dataField;
String token;
- int offset;
+ int offset = 1;
int length;
+ String delimiter;
Field field;
// Iterate through the list of positions
@@ -169,20 +185,41 @@ public class BindyFixedLengthFactory ext
Collection<DataField> c = dataFields.values();
Iterator<DataField> itr = c.iterator();
+ // this iterator is for a link list that was built using items in order
while (itr.hasNext()) {
dataField = itr.next();
- offset = dataField.pos();
length = dataField.length();
+ delimiter = dataField.delimiter();
ObjectHelper.notNull(offset, "Position/offset is not defined for the field: " + dataField.toString());
- ObjectHelper.notNull(offset, "Length is not defined for the field: " + dataField.toString());
-
+
+ if (length == 0 && dataField.lengthPos() != 0) {
+ Field lengthField = annotatedFields.get(dataField.lengthPos());
+ lengthField.setAccessible(true);
+ Object modelObj = model.get(lengthField.getDeclaringClass().getName());
+ Object lengthObj = (Integer) lengthField.get(modelObj);
+ length = ((Integer)lengthObj).intValue();
+ }
+ if (length < 1 && delimiter == null && dataField.lengthPos() == 0) {
+ throw new IllegalArgumentException("Either length or delimiter must be specified for the field : " + dataField.toString());
+ }
if (offset - 1 <= -1) {
throw new IllegalArgumentException("Offset/Position of the field " + dataField.toString()
+ " cannot be negative");
}
-
- token = record.substring(offset - 1, offset + length - 1);
+
+ if (length > 0) {
+ token = record.substring(offset - 1, offset + length - 1);
+ offset += length;
+ } else if (!delimiter.equals("")) {
+ String tempToken = record.substring(offset - 1, record.length());
+ token = tempToken.substring(0, tempToken.indexOf(delimiter));
+ // include the delimiter in the offset calculation
+ offset += token.length() + 1;
+ } else {
+ // defined as a zero-length field
+ token = "";
+ }
if (dataField.trim()) {
token = token.trim();
@@ -202,8 +239,8 @@ public class BindyFixedLengthFactory ext
}
}
- // Get Field to be setted
- field = annotatedFields.get(offset);
+ // Get Field to be set
+ field = annotatedFields.get(dataField.pos());
field.setAccessible(true);
if (LOG.isDebugEnabled()) {
@@ -232,7 +269,7 @@ public class BindyFixedLengthFactory ext
}
field.set(modelField, value);
-
+
++pos;
}
@@ -322,20 +359,32 @@ public class BindyFixedLengthFactory ext
if (datafield.trim()) {
result = result.trim();
}
-
- // Get length of the field, alignment (LEFT or RIGHT), pad
+
int fieldLength = datafield.length();
- String align = datafield.align();
- char padCharField = datafield.paddingChar();
- char padChar;
- if (fieldLength > 0) {
-
- StringBuilder temp = new StringBuilder();
+ if (fieldLength == 0 && (datafield.lengthPos() > 0)) {
+ List<String> resultVals = results.get(datafield.lengthPos());
+ fieldLength = Integer.valueOf(resultVals.get(0));
+ }
+
+ if (fieldLength <= 0 && datafield.delimiter().equals("") && datafield.lengthPos() == 0) {
+ throw new IllegalArgumentException("Either a delimiter value or length for the field: "
+ + field.getName() + " is mandatory.");
+ }
+
+ if (!datafield.delimiter().equals("")) {
+ result = result + datafield.delimiter();
+ } else {
+ // Get length of the field, alignment (LEFT or RIGHT), pad
+ String align = datafield.align();
+ char padCharField = datafield.paddingChar();
+ char padChar;
+ StringBuilder temp = new StringBuilder();
+
// Check if we must pad
if (result.length() < fieldLength) {
-
+
// No padding defined for the field
if (padCharField == 0) {
// We use the padding defined for the Record
@@ -343,7 +392,7 @@ public class BindyFixedLengthFactory ext
} else {
padChar = padCharField;
}
-
+
if (align.contains("R")) {
temp.append(generatePaddingChars(padChar, fieldLength, result.length()));
temp.append(result);
@@ -354,11 +403,11 @@ public class BindyFixedLengthFactory ext
throw new IllegalArgumentException("Alignment for the field: " + field.getName()
+ " must be equal to R for RIGHT or L for LEFT");
}
-
+
result = temp.toString();
} else if (result.length() > fieldLength) {
// we are bigger than allowed
-
+
// is clipped enabled? if so clip the field
if (datafield.clip()) {
result = result.substring(0, fieldLength);
@@ -367,10 +416,6 @@ public class BindyFixedLengthFactory ext
+ " must not be larger than allowed, was: " + result.length() + ", allowed: " + fieldLength);
}
}
-
- } else {
- throw new IllegalArgumentException("Length of the field: " + field.getName()
- + " is a mandatory field and cannot be equal to zero or to be negative, was: " + fieldLength);
}
if (LOG.isDebugEnabled()) {
@@ -429,10 +474,22 @@ public class BindyFixedLengthFactory ext
// Get hasHeader parameter
hasHeader = record.hasHeader();
LOG.debug("Has Header: {}", hasHeader);
+
+ // Get skipHeader parameter
+ skipHeader = record.skipHeader();
// Get hasFooter parameter
hasFooter = record.hasFooter();
LOG.debug("Has Footer: {}", hasFooter);
+
+ // Get skipFooter parameter
+ skipFooter = record.skipFooter();
+
+ // Get isHeader parameter
+ isHeader = record.isHeader();
+
+ // Get isFooter parameter
+ isFooter = record.isFooter();
// Get padding character
paddingChar = record.paddingChar();
@@ -447,8 +504,22 @@ public class BindyFixedLengthFactory ext
LOG.debug("Length of the record: {}", recordLength);
}
}
+
+ if (hasHeader && isHeader) {
+ throw new java.lang.IllegalArgumentException("Record can not be configured with both 'isHeader=true' and 'hasHeader=true'");
+ }
+
+ if (hasFooter && isFooter) {
+ throw new java.lang.IllegalArgumentException("Record can not be configured with both 'isFooter=true' and 'hasFooter=true'");
+ }
+
+ if ((isHeader || isFooter) && (skipHeader || skipFooter)) {
+ throw new java.lang.IllegalArgumentException(
+ "skipHeader and/or skipFooter can not be configured on a record where 'isHeader=true' or 'isFooter=true'");
+ }
+
}
-
+
/**
* Flag indicating if we have a header
*/
@@ -464,6 +535,34 @@ public class BindyFixedLengthFactory ext
}
/**
+ * Flag indicating whether to skip the header parsing
+ */
+ public boolean skipHeader() {
+ return skipHeader;
+ }
+
+ /**
+ * Flag indicating whether to skip the footer processing
+ */
+ public boolean skipFooter() {
+ return skipFooter;
+ }
+
+ /**
+ * Flag indicating whether this factory is for a header
+ */
+ public boolean isHeader() {
+ return isHeader;
+ }
+
+ /**
+ * Flag indicating whether this factory is for a footer
+ */
+ public boolean isFooter() {
+ return isFooter;
+ }
+
+ /**
* Padding char used to fill the field
*/
public char paddingchar() {
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/DataField.java Thu Feb 7 17:59:42 2013
@@ -31,7 +31,9 @@ import java.lang.annotation.RetentionPol
* precision(optional) reflects the precision to be used with BigDecimal number
* The position (optional) identify the position of the field in the CSV
* generated The required (optional) property identifies a field which is
- * mandatory.
+ * mandatory. The lengthPos (optional) identifies a field in this record that
+ * defines the fixed length for this field. The delimiter (optional) defines a
+ * character that is used to demarcate the field, if it has a variable length.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@@ -63,6 +65,11 @@ public @interface DataField {
int length() default 0;
/**
+ * Identifies a data field in the record that defines the expected fixed length for this field
+ */
+ int lengthPos() default 0;
+
+ /**
* Align the text to the right or left. Use values <tt>R</tt> or <tt>L</tt>.
*/
String align() default "R";
@@ -98,6 +105,11 @@ public @interface DataField {
boolean clip() default false;
/**
+ * Optional delimiter to be used if the field has a variable length
+ */
+ String delimiter() default "";
+
+ /**
* Field's default value in case no value is set
*/
String defaultValue() default "";
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/FixedLengthRecord.java Thu Feb 7 17:59:42 2013
@@ -56,8 +56,34 @@ public @interface FixedLengthRecord {
*/
int length() default 0;
+ /**
+ * Indicates that the record(s) of this type may be preceded by a single header record at the beginning of in the file
+ */
boolean hasHeader() default false;
+ /**
+ * Indicates that the record(s) of this type may be followed by a single footer record at the end of the file
+ */
boolean hasFooter() default false;
+
+ /**
+ * Configures the data format to skip marshalling / unmarshalling of the header record
+ */
+ boolean skipHeader() default false;
+
+ /**
+ * Configures the data format to skip marshalling / unmarshalling of the footer record
+ */
+ boolean skipFooter() default false;
+
+ /**
+ * Identifies this FixedLengthRecord as a header record, which may precede all other records in the file
+ */
+ boolean isHeader() default false;
+
+ /**
+ * Identifies this FixedLengthRecord as a footer record, which may be used as the last record in the file
+ */
+ boolean isFooter() default false;
}
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java Thu Feb 7 17:59:42 2013
@@ -25,16 +25,21 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.camel.Exchange;
import org.apache.camel.dataformat.bindy.BindyAbstractDataFormat;
import org.apache.camel.dataformat.bindy.BindyAbstractFactory;
import org.apache.camel.dataformat.bindy.BindyFixedLengthFactory;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
import org.apache.camel.dataformat.bindy.util.ConverterUtils;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,8 +48,15 @@ import org.slf4j.LoggerFactory;
* {@link DataFormat}) using Bindy to marshal to and from Fixed Length
*/
public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat {
- private static final transient Logger LOG = LoggerFactory.getLogger(BindyFixedLengthDataFormat.class);
+
+ public static final String CAMEL_BINDY_FIXED_LENGTH_HEADER = "CamelBindyFixedLengthHeader";
+ public static final String CAMEL_BINDY_FIXED_LENGTH_FOOTER = "CamelBindyFixedLengthFooter";
+ private static final transient Logger LOG = LoggerFactory.getLogger(BindyFixedLengthDataFormat.class);
+
+ private BindyFixedLengthFactory headerFactory;
+ private BindyFixedLengthFactory footerFactory;
+
public BindyFixedLengthDataFormat() {
}
@@ -58,8 +70,8 @@ public class BindyFixedLengthDataFormat
@SuppressWarnings("unchecked")
public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception {
-
- BindyFixedLengthFactory factory = (BindyFixedLengthFactory) getFactory(exchange.getContext().getPackageScanClassResolver());
+ PackageScanClassResolver resolver = exchange.getContext().getPackageScanClassResolver();
+ BindyFixedLengthFactory factory = (BindyFixedLengthFactory) getFactory(resolver);
ObjectHelper.notNull(factory, "not instantiated");
// Get CRLF
@@ -82,11 +94,55 @@ public class BindyFixedLengthDataFormat
// cast to the expected type
models = (List<Map<String, Object>>) body;
}
+
+ // add the header if it is in the exchange header
+ Map<String, Object> headerRow = (Map<String, Object>) exchange.getIn().getHeader(CAMEL_BINDY_FIXED_LENGTH_HEADER);
+ if (headerRow != null) {
+ models.add(0, headerRow);
+ }
+
+ // add the footer if it is in the exchange header
+ Map<String, Object> footerRow = (Map<String, Object>) exchange.getIn().getHeader(CAMEL_BINDY_FIXED_LENGTH_FOOTER);
+ if (headerRow != null) {
+ models.add(models.size(), footerRow);
+ }
+ int row = 0;
for (Map<String, Object> model : models) {
-
- String result = factory.unbind(model);
-
+ row++;
+ String result = null;
+
+ if (row == 1 && headerFactory != null) {
+ // marshal the first row as a header if the models match
+ Set<String> modelClassNames = model.keySet();
+ // only use the header factory if the row is the header
+ if (headerFactory.supportsModel(modelClassNames)) {
+ if (factory.skipHeader()) {
+ LOG.warn("Skipping marshal of header row; 'skipHeader=true'");
+ continue;
+ } else {
+ result = headerFactory.unbind(model);
+ }
+ }
+ } else if (row == models.size() && footerFactory != null) {
+ // marshal the last row as a footer if the models match
+ Set<String> modelClassNames = model.keySet();
+ // only use the header factory if the row is the header
+ if (footerFactory.supportsModel(modelClassNames)) {
+ if (factory.skipFooter()) {
+ LOG.warn("Skipping marshal of footer row; 'skipFooter=true'");
+ continue;
+ } else {
+ result = footerFactory.unbind(model);
+ }
+ }
+ }
+
+ if (result == null) {
+ // marshal as a normal / default row
+ result = factory.unbind(model);
+ }
+
byte[] bytes = exchange.getContext().getTypeConverter().convertTo(byte[].class, exchange, result);
outputStream.write(bytes);
@@ -96,9 +152,10 @@ public class BindyFixedLengthDataFormat
}
public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception {
- BindyFixedLengthFactory factory = (BindyFixedLengthFactory) getFactory(exchange.getContext().getPackageScanClassResolver());
+ PackageScanClassResolver resolver = exchange.getContext().getPackageScanClassResolver();
+ BindyFixedLengthFactory factory = (BindyFixedLengthFactory) getFactory(resolver);
ObjectHelper.notNull(factory, "not instantiated");
-
+
// List of Pojos
List<Map<String, Object>> models = new ArrayList<Map<String, Object>>();
@@ -110,52 +167,59 @@ public class BindyFixedLengthDataFormat
// Scanner is used to read big file
Scanner scanner = new Scanner(in);
- int count = 0;
+ AtomicInteger count = new AtomicInteger(0);
try {
- // TODO Test if we have a Header
- // TODO Test if we have a Footer (containing by example checksum)
-
- while (scanner.hasNextLine()) {
- String line;
+ // Parse the header if it exists
+ if (scanner.hasNextLine() && factory.hasHeader()) {
// Read the line (should not trim as its fixed length)
- line = scanner.nextLine();
-
- if (ObjectHelper.isEmpty(line)) {
- // skip if line is empty
- continue;
- }
-
- // Increment counter
- count++;
+ String line = getNextNonEmptyLine(scanner, count);
- // Check if the record length corresponds to the parameter
- // provided in the @FixedLengthRecord
- if ((line.length() < factory.recordLength()) || (line.length() > factory.recordLength())) {
- throw new java.lang.IllegalArgumentException("Size of the record: " + line.length() + " is not equal to the value provided in the model: " + factory.recordLength());
+ if (!factory.skipHeader()) {
+ Map<String, Object> headerObjMap = createModel(headerFactory, line, count.intValue());
+ exchange.getOut().setHeader(CAMEL_BINDY_FIXED_LENGTH_HEADER, headerObjMap);
}
+ }
- // Create POJO where Fixed data will be stored
- model = factory.factory();
-
- // Bind data from Fixed record with model classes
- factory.bind(line, model, count);
+ String thisLine = getNextNonEmptyLine(scanner, count);
- // Link objects together
- factory.link(model);
+ String nextLine = null;
+ if (thisLine != null) {
+ nextLine = getNextNonEmptyLine(scanner, count);
+ }
+
+ // Parse the main file content
+ while (thisLine != null && nextLine != null) {
+
+ model = createModel(factory, thisLine, count.intValue());
// Add objects graph to the list
models.add(model);
- LOG.debug("Graph of objects created: {}", model);
+ thisLine = nextLine;
+ nextLine = getNextNonEmptyLine(scanner, count);
+ }
+
+ // this line should be the last non-empty line from the file
+ // optionally parse the line as a footer
+ if (thisLine != null) {
+ if (factory.hasFooter()) {
+ if (!factory.skipFooter()) {
+ Map<String, Object> footerObjMap = createModel(footerFactory, thisLine, count.intValue());
+ exchange.getOut().setHeader(CAMEL_BINDY_FIXED_LENGTH_FOOTER, footerObjMap);
+ }
+ } else {
+ model = createModel(factory, thisLine, count.intValue());
+ models.add(model);
+ }
}
// Test if models list is empty or not
// If this is the case (correspond to an empty stream, ...)
if (models.size() == 0) {
- throw new java.lang.IllegalArgumentException("No records have been defined in the CSV");
+ throw new java.lang.IllegalArgumentException("No records have been defined in the the file");
} else {
return extractUnmarshalResult(models);
}
@@ -167,13 +231,98 @@ public class BindyFixedLengthDataFormat
}
+ private String getNextNonEmptyLine(Scanner scanner, AtomicInteger count) {
+ String line = "";
+ while (ObjectHelper.isEmpty(line) && scanner.hasNextLine()) {
+ count.incrementAndGet();
+ line = scanner.nextLine();
+ }
+
+ if (ObjectHelper.isEmpty(line)) {
+ return null;
+ } else {
+ return line;
+ }
+ }
+
+ protected Map<String, Object> createModel(BindyFixedLengthFactory factory, String line, int count) throws Exception {
+ // Check if the record length corresponds to the parameter
+ // provided in the @FixedLengthRecord
+ if (factory.recordLength() > 0) {
+ if ((line.length() < factory.recordLength()) || (line.length() > factory.recordLength())) {
+ throw new java.lang.IllegalArgumentException("Size of the record: " + line.length()
+ + " is not equal to the value provided in the model: " + factory.recordLength());
+ }
+ }
+
+ // Create POJO where Fixed data will be stored
+ Map<String, Object> model = factory.factory();
+
+ // Bind data from Fixed record with model classes
+ factory.bind(line, model, count);
+
+ // Link objects together
+ factory.link(model);
+
+ LOG.debug("Graph of objects created: {}", model);
+ return model;
+ }
+
@Override
protected BindyAbstractFactory createModelFactory(PackageScanClassResolver resolver) throws Exception {
+
+ // Initialize the primary (body) model factory ignoring header and footer model classes
+ PackageScanFilter defaultRecordScanFilter = new PackageScanFilter() {
+ @Override
+ public boolean matches(Class<?> type) {
+ FixedLengthRecord record = type.getAnnotation(FixedLengthRecord.class);
+ return record != null && !record.isFooter() && !record.isHeader();
+ }
+ };
+
+ BindyFixedLengthFactory factory;
if (getClassType() != null) {
- return new BindyFixedLengthFactory(resolver, getClassType());
+ factory = new BindyFixedLengthFactory(resolver, defaultRecordScanFilter, getClassType());
} else {
- return new BindyFixedLengthFactory(resolver, getPackages());
+ factory = new BindyFixedLengthFactory(resolver, defaultRecordScanFilter, getPackages());
+ }
+
+ // Optionally initialize the header factory... using header model classes
+ if (factory.hasHeader()) {
+ PackageScanFilter headerScanFilter = new PackageScanFilter() {
+ @Override
+ public boolean matches(Class<?> type) {
+ FixedLengthRecord record = type.getAnnotation(FixedLengthRecord.class);
+ return record != null && record.isHeader();
+ }
+ };
+
+ if (getClassType() != null) {
+ this.headerFactory = new BindyFixedLengthFactory(resolver, headerScanFilter, getClassType());
+ } else {
+ this.headerFactory = new BindyFixedLengthFactory(resolver, headerScanFilter, getPackages());
+ }
}
+
+ // Optionally initialize the footer factory... using footer model classes
+ if (factory.hasFooter()) {
+
+ PackageScanFilter footerScanFilter = new PackageScanFilter() {
+ @Override
+ public boolean matches(Class<?> type) {
+ FixedLengthRecord record = type.getAnnotation(FixedLengthRecord.class);
+ return record != null && record.isFooter();
+ }
+ };
+
+ if (getClassType() != null) {
+ this.footerFactory = new BindyFixedLengthFactory(resolver, footerScanFilter, getClassType());
+ } else {
+ this.footerFactory = new BindyFixedLengthFactory(resolver, footerScanFilter, getPackages());
+ }
+ }
+
+ return factory;
}
-
+
}
Modified: camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/util/AnnotationModelLoader.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/util/AnnotationModelLoader.java?rev=1443631&r1=1443630&r2=1443631&view=diff
==============================================================================
--- camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/util/AnnotationModelLoader.java (original)
+++ camel/trunk/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/util/AnnotationModelLoader.java Thu Feb 7 17:59:42 2013
@@ -17,6 +17,7 @@
package org.apache.camel.dataformat.bindy.util;
import java.lang.annotation.Annotation;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -26,6 +27,7 @@ import org.apache.camel.dataformat.bindy
import org.apache.camel.dataformat.bindy.annotation.Message;
import org.apache.camel.dataformat.bindy.annotation.Section;
import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanFilter;
/**
* Annotation based loader for model classes with Bindy annotations.
@@ -33,6 +35,7 @@ import org.apache.camel.spi.PackageScanC
public class AnnotationModelLoader {
private PackageScanClassResolver resolver;
+ private PackageScanFilter filter;
private Set<Class<? extends Annotation>> annotations;
public AnnotationModelLoader(PackageScanClassResolver resolver) {
@@ -45,8 +48,27 @@ public class AnnotationModelLoader {
annotations.add(Section.class);
annotations.add(FixedLengthRecord.class);
}
+
+ public AnnotationModelLoader(PackageScanClassResolver resolver, PackageScanFilter filter) {
+ this(resolver);
+ this.filter = filter;
+ }
public Set<Class<?>> loadModels(String... packageNames) throws Exception {
- return resolver.findAnnotated(annotations, packageNames);
+ Set<Class<?>> results = resolver.findAnnotated(annotations, packageNames);
+
+ //TODO; this logic could be moved into the PackageScanClassResolver by creating:
+ // findAnnotated(annotations, packageNames, filter)
+ Set<Class<?>> resultsToRemove = new HashSet<Class<?>>();
+ if (filter != null) {
+ for (Class<?> clazz : results) {
+ if (!filter.matches(clazz)) {
+ resultsToRemove.add(clazz);
+ }
+ }
+ }
+ results.removeAll(resultsToRemove);
+ return results;
}
+
}
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,254 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.delimited;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import org.apache.camel.EndpointInject;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+
+import org.apache.camel.model.dataformat.BindyType;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This test validates the marshalling / unmarshalling of delimited, variable-length fields within a 'fixed-length' record.
+ */
+public class BindyFixedLengthDelimitedFieldTest extends CamelTestSupport {
+
+ public static final String URI_DIRECT_MARSHALL = "direct:marshall";
+ public static final String URI_DIRECT_UNMARSHALL = "direct:unmarshall";
+ public static final String URI_MOCK_MARSHALL_RESULT = "mock:marshall-result";
+ public static final String URI_MOCK_UNMARSHALL_RESULT = "mock:unmarshall-result";
+
+ private static final String TEST_RECORD = "10A9Pauline^M^ISINXD12345678BUYShare000002500.45USD01-08-2009\r\n";
+
+ @EndpointInject(uri = URI_MOCK_MARSHALL_RESULT)
+ private MockEndpoint marshallResult;
+
+ @EndpointInject(uri = URI_MOCK_UNMARSHALL_RESULT)
+ private MockEndpoint unmarshallResult;
+
+ // *************************************************************************
+ // TESTS
+ // *************************************************************************
+ @Test
+ public void testUnmarshallMessage() throws Exception {
+
+ unmarshallResult.expectedMessageCount(1);
+ template.sendBody(URI_DIRECT_UNMARSHALL, TEST_RECORD);
+
+ unmarshallResult.assertIsSatisfied();
+
+ // check the model
+ BindyFixedLengthDelimitedFieldTest.Order order =
+ (BindyFixedLengthDelimitedFieldTest.Order) unmarshallResult.getReceivedExchanges().get(0).getIn().getBody();
+ Assert.assertEquals(10, order.getOrderNr());
+ Assert.assertEquals("Pauline", order.getFirstName());
+ Assert.assertEquals("M", order.getLastName());
+ }
+
+ @Test
+ public void testMarshallMessage() throws Exception {
+ BindyFixedLengthDelimitedFieldTest.Order order = new Order();
+ order.setOrderNr(10);
+ order.setOrderType("BUY");
+ order.setClientNr("A9");
+ order.setFirstName("Pauline");
+ order.setLastName("M");
+ 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());
+
+ marshallResult.expectedMessageCount(1);
+ marshallResult.expectedBodiesReceived(Arrays.asList(new String[] {TEST_RECORD}));
+ template.sendBody(URI_DIRECT_MARSHALL, order);
+ marshallResult.assertIsSatisfied();
+ }
+
+ // *************************************************************************
+ // ROUTES
+ // *************************************************************************
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ RouteBuilder routeBuilder = new RouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ from(URI_DIRECT_MARSHALL)
+ .marshal().bindy(BindyType.Fixed, BindyFixedLengthDelimitedFieldTest.Order.class)
+ .to(URI_MOCK_MARSHALL_RESULT);
+
+ from(URI_DIRECT_UNMARSHALL)
+ .unmarshal().bindy(BindyType.Fixed, BindyFixedLengthDelimitedFieldTest.Order.class)
+ .to(URI_MOCK_UNMARSHALL_RESULT);
+ }
+ };
+
+ return routeBuilder;
+ }
+
+ // *************************************************************************
+ // DATA MODEL
+ // *************************************************************************
+ @FixedLengthRecord()
+ public static class Order {
+
+ @DataField(pos = 1, length = 2)
+ private int orderNr;
+
+ @DataField(pos = 2, length = 2)
+ private String clientNr;
+
+ @DataField(pos = 3, delimiter = "^")
+ private String firstName;
+
+ @DataField(pos = 4, delimiter = "^")
+ private String lastName;
+
+ @DataField(pos = 5, length = 4)
+ private String instrumentCode;
+
+ @DataField(pos = 6, length = 10)
+ private String instrumentNumber;
+
+ @DataField(pos = 7, length = 3)
+ private String orderType;
+
+ @DataField(pos = 8, length = 5)
+ private String instrumentType;
+
+ @DataField(pos = 9, precision = 2, length = 12, paddingChar = '0')
+ private BigDecimal amount;
+
+ @DataField(pos = 10, length = 3)
+ private String currency;
+
+ @DataField(pos = 11, length = 10, pattern = "dd-MM-yyyy")
+ private Date orderDate;
+
+ 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;
+ }
+
+ @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);
+ }
+ }
+
+}
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/delimited/BindyFixedLengthDelimitedFieldTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,271 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.dynamic;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import org.apache.camel.EndpointInject;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+
+import org.apache.camel.model.dataformat.BindyType;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+/**
+ * This test validates the marshalling / unmarshalling of a fixed-length data field for which the length of the
+ * field is defined by the value of another field in the record.
+ */
+public class BindyFixedLengthDynamicFieldTest extends CamelTestSupport {
+
+ public static final String URI_DIRECT_MARSHALL = "direct:marshall";
+ public static final String URI_DIRECT_UNMARSHALL = "direct:unmarshall";
+ public static final String URI_MOCK_MARSHALL_RESULT = "mock:marshall-result";
+ public static final String URI_MOCK_UNMARSHALL_RESULT = "mock:unmarshall-result";
+
+ private static final String TEST_RECORD = "10A9Pauline^M^ISIN10XD12345678BUYShare000002500.45USD01-08-2009\r\n";
+
+ @EndpointInject(uri = URI_MOCK_MARSHALL_RESULT)
+ private MockEndpoint marshallResult;
+
+ @EndpointInject(uri = URI_MOCK_UNMARSHALL_RESULT)
+ private MockEndpoint unmarshallResult;
+
+ // *************************************************************************
+ // TESTS
+ // *************************************************************************
+
+ @Test
+ public void testUnmarshallMessage() throws Exception {
+
+ unmarshallResult.expectedMessageCount(1);
+ template.sendBody(URI_DIRECT_UNMARSHALL, TEST_RECORD);
+
+ unmarshallResult.assertIsSatisfied();
+
+ // check the model
+ BindyFixedLengthDynamicFieldTest.Order order =
+ (BindyFixedLengthDynamicFieldTest.Order) unmarshallResult.getReceivedExchanges().get(0).getIn().getBody();
+ Assert.assertEquals(10, order.getOrderNr());
+ // the field is not trimmed
+ Assert.assertEquals("Pauline", order.getFirstName());
+ Assert.assertEquals("M", order.getLastName());
+ Assert.assertEquals("XD12345678", order.getInstrumentNumber());
+ }
+
+ @Test
+ public void testMarshallMessage() throws Exception {
+ BindyFixedLengthDynamicFieldTest.Order order = new Order();
+ order.setOrderNr(10);
+ order.setOrderType("BUY");
+ order.setClientNr("A9");
+ order.setFirstName("Pauline");
+ order.setLastName("M");
+ order.setAmount(new BigDecimal("2500.45"));
+ order.setInstrumentCode("ISIN");
+ order.setInstrumentNumberLen(10);
+ order.setInstrumentNumber("XD12345678");
+ order.setInstrumentType("Share");
+ order.setCurrency("USD");
+ Calendar calendar = new GregorianCalendar();
+ calendar.set(2009, 7, 1);
+ order.setOrderDate(calendar.getTime());
+
+ marshallResult.expectedMessageCount(1);
+ marshallResult.expectedBodiesReceived(Arrays.asList(new String[] {TEST_RECORD}));
+ template.sendBody(URI_DIRECT_MARSHALL, order);
+ marshallResult.assertIsSatisfied();
+ }
+
+ // *************************************************************************
+ // ROUTES
+ // *************************************************************************
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ RouteBuilder routeBuilder = new RouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ from(URI_DIRECT_MARSHALL)
+ .marshal().bindy(BindyType.Fixed, BindyFixedLengthDynamicFieldTest.Order.class)
+ .to(URI_MOCK_MARSHALL_RESULT);
+
+ from(URI_DIRECT_UNMARSHALL)
+ .unmarshal().bindy(BindyType.Fixed, BindyFixedLengthDynamicFieldTest.Order.class)
+ .to(URI_MOCK_UNMARSHALL_RESULT);
+ }
+ };
+
+ return routeBuilder;
+ }
+
+ // *************************************************************************
+ // DATA MODEL
+ // *************************************************************************
+ @FixedLengthRecord()
+ public static class Order {
+
+ @DataField(pos = 1, length = 2)
+ private int orderNr;
+
+ @DataField(pos = 2, length = 2)
+ private String clientNr;
+
+ @DataField(pos = 3, delimiter = "^")
+ private String firstName;
+
+ @DataField(pos = 4, delimiter = "^")
+ private String lastName;
+
+ @DataField(pos = 5, length = 4)
+ private String instrumentCode;
+
+ @DataField(pos = 6, length = 2, align = "R", paddingChar = '0')
+ private int instrumentNumberLen;
+
+ @DataField(pos = 7, length = 10)
+ private String instrumentNumber;
+
+ @DataField(pos = 8, length = 3)
+ private String orderType;
+
+ @DataField(pos = 9, length = 5)
+ private String instrumentType;
+
+ @DataField(pos = 10, precision = 2, length = 12, paddingChar = '0')
+ private BigDecimal amount;
+
+ @DataField(pos = 11, length = 3)
+ private String currency;
+
+ @DataField(pos = 12, length = 10, pattern = "dd-MM-yyyy")
+ private Date orderDate;
+
+ 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 void setInstrumentNumberLen(int instrumentNumberLen) {
+ this.instrumentNumberLen = instrumentNumberLen;
+ }
+
+ public int getInstrumentNumberLen() {
+ return instrumentNumberLen;
+ }
+
+ 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;
+ }
+
+ @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);
+ }
+ }
+
+}
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/dynamic/BindyFixedLengthDynamicFieldTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,224 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.headerfooter;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.bindy.fixed.BindyFixedLengthDataFormat;
+
+import org.apache.camel.model.dataformat.BindyType;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+/**
+ * This test validates that header and footer records are successfully marshalled / unmarshalled in conjunction
+ * with the primary data records defined for the bindy data format.
+ */
+public class BindySimpleFixedLengthHeaderFooterTest extends CamelTestSupport {
+
+ public static final String URI_DIRECT_MARSHALL = "direct:marshall";
+ public static final String URI_DIRECT_UNMARSHALL = "direct:unmarshall";
+ public static final String URI_MOCK_MARSHALL_RESULT = "mock:marshall-result";
+ public static final String URI_MOCK_UNMARSHALL_RESULT = "mock:unmarshall-result";
+
+ private static final String TEST_HEADER = "101-08-2009\r\n";
+ private static final String TEST_RECORD = "10A9 PaulineM ISINXD12345678BUYShare000002500.45USD01-08-2009\r\n";
+ private static final String TEST_FOOTER = "9000000001\r\n";
+
+ @EndpointInject(uri = URI_MOCK_MARSHALL_RESULT)
+ private MockEndpoint marshallResult;
+
+ @EndpointInject(uri = URI_MOCK_UNMARSHALL_RESULT)
+ private MockEndpoint unmarshallResult;
+
+ // *************************************************************************
+ // TESTS
+ // *************************************************************************
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testUnmarshallMessage() throws Exception {
+
+ StringBuffer buff = new StringBuffer();
+ buff.append(TEST_HEADER).append(TEST_RECORD).append(TEST_FOOTER);
+
+ unmarshallResult.expectedMessageCount(1);
+
+ template.sendBody(URI_DIRECT_UNMARSHALL, buff.toString());
+
+ unmarshallResult.assertIsSatisfied();
+
+ // check the model
+ Exchange exchange = unmarshallResult.getReceivedExchanges().get(0);
+ Order order = (Order) exchange.getIn().getBody();
+ assertEquals(10, order.getOrderNr());
+ // the field is not trimmed
+ assertEquals(" Pauline", order.getFirstName());
+ assertEquals("M ", order.getLastName());
+
+ Map<String, Object> receivedHeaderMap =
+ (Map<String, Object>) exchange.getIn().getHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_HEADER);
+
+ Map<String, Object> receivedFooterMap =
+ (Map<String, Object>) exchange.getIn().getHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_FOOTER);
+
+ assertNotNull(receivedHeaderMap);
+ assertNotNull(receivedFooterMap);
+
+ OrderHeader receivedHeader = (OrderHeader) receivedHeaderMap.get(OrderHeader.class.getName());
+ OrderFooter receivedFooter = (OrderFooter) receivedFooterMap.get(OrderFooter.class.getName());
+
+ assertNotNull(receivedHeader);
+ assertNotNull(receivedFooter);
+
+ OrderHeader expectedHeader = new OrderHeader();
+ Calendar calendar = new GregorianCalendar();
+ calendar.set(2009, 7, 1, 0, 0, 0);
+ calendar.clear(Calendar.MILLISECOND);
+ expectedHeader.setRecordDate(calendar.getTime());
+
+ assertEquals(receivedHeader.getRecordType(), expectedHeader.getRecordType());
+ assertTrue(receivedHeader.getRecordDate().equals(expectedHeader.getRecordDate()));
+ }
+
+ /**
+ * Verifies that header & footer provided as part of message body are marshalled successfully
+ */
+ @Test
+ public void testMarshallMessageWithDirectHeaderAndFooterInput() throws Exception {
+ Order order = new Order();
+ order.setOrderNr(10);
+ order.setOrderType("BUY");
+ order.setClientNr("A9");
+ order.setFirstName("Pauline");
+ order.setLastName("M");
+ 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, 0, 0, 0);
+ order.setOrderDate(calendar.getTime());
+
+ ArrayList<Map<String, Object>> input = new ArrayList<Map<String, Object>>();
+ Map<String, Object> bodyRow = new HashMap<String, Object>();
+ bodyRow.put(Order.class.getName(), order);
+ input.add(createHeaderRow());
+ input.add(bodyRow);
+ input.add(createFooterRow());
+
+ marshallResult.expectedMessageCount(1);
+ StringBuffer buff = new StringBuffer();
+ buff.append(TEST_HEADER).append(TEST_RECORD).append(TEST_FOOTER);
+ marshallResult.expectedBodiesReceived(Arrays.asList(new String[] {buff.toString()}));
+ template.sendBody(URI_DIRECT_MARSHALL, input);
+ marshallResult.assertIsSatisfied();
+ }
+
+ /**
+ * Verifies that header & footer provided via message headers are marshalled successfully
+ */
+ @Test
+ public void testMarshallMessageWithIndirectHeaderAndFooterInput() throws Exception {
+ Order order = new Order();
+ order.setOrderNr(10);
+ order.setOrderType("BUY");
+ order.setClientNr("A9");
+ order.setFirstName("Pauline");
+ order.setLastName("M");
+ 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, 0, 0, 0);
+ order.setOrderDate(calendar.getTime());
+
+ ArrayList<Map<String, Object>> input = new ArrayList<Map<String, Object>>();
+ Map<String, Object> bodyRow = new HashMap<String, Object>();
+ bodyRow.put(Order.class.getName(), order);
+
+ input.add(bodyRow);
+
+ Map<String, Object> headers = new HashMap<String, Object>();
+ headers.put(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_HEADER, createHeaderRow());
+ headers.put(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_FOOTER, createFooterRow());
+
+ marshallResult.reset();
+ marshallResult.expectedMessageCount(1);
+ StringBuffer buff = new StringBuffer();
+ buff.append(TEST_HEADER).append(TEST_RECORD).append(TEST_FOOTER);
+ marshallResult.expectedBodiesReceived(Arrays.asList(new String[] {buff.toString()}));
+ template.sendBodyAndHeaders(URI_DIRECT_MARSHALL, input, headers);
+ marshallResult.assertIsSatisfied();
+ }
+
+ private Map<String, Object> createHeaderRow() {
+ Map<String, Object> headerMap = new HashMap<String, Object>();
+ OrderHeader header = new OrderHeader();
+ Calendar calendar = new GregorianCalendar();
+ calendar.set(2009, 7, 1, 0, 0, 0);
+ header.setRecordDate(calendar.getTime());
+ headerMap.put(OrderHeader.class.getName(), header);
+ return headerMap;
+ }
+
+ private Map<String, Object> createFooterRow() {
+ Map<String, Object> footerMap = new HashMap<String, Object>();
+ OrderFooter footer = new OrderFooter();
+ footer.setNumberOfRecordsInTheFile(1);
+ footerMap.put(OrderFooter.class.getName(), footer);
+ return footerMap;
+ }
+
+ // *************************************************************************
+ // ROUTES
+ // *************************************************************************
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ RouteBuilder routeBuilder = new RouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ from(URI_DIRECT_MARSHALL)
+ .marshal().bindy(BindyType.Fixed, Order.class)
+ .to(URI_MOCK_MARSHALL_RESULT);
+
+ from(URI_DIRECT_UNMARSHALL)
+ .unmarshal().bindy(BindyType.Fixed, Order.class)
+ .to(URI_MOCK_UNMARSHALL_RESULT);
+
+ }
+ };
+
+ return routeBuilder;
+ }
+}
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/BindySimpleFixedLengthHeaderFooterTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,156 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.headerfooter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+
+@FixedLengthRecord(hasHeader = true, hasFooter = true)
+public class Order {
+
+ @DataField(pos = 1, length = 2)
+ private int orderNr;
+
+ @DataField(pos = 2, length = 2)
+ private String clientNr;
+
+ @DataField(pos = 3, length = 9)
+ private String firstName;
+
+ @DataField(pos = 4, length = 5, align = "L")
+ private String lastName;
+
+ @DataField(pos = 5, length = 4)
+ private String instrumentCode;
+
+ @DataField(pos = 6, length = 10)
+ private String instrumentNumber;
+
+ @DataField(pos = 7, length = 3)
+ private String orderType;
+
+ @DataField(pos = 8, length = 5)
+ private String instrumentType;
+
+ @DataField(pos = 9, precision = 2, length = 12, paddingChar = '0')
+ private BigDecimal amount;
+
+ @DataField(pos = 10, length = 3)
+ private String currency;
+
+ @DataField(pos = 11, length = 10, pattern = "dd-MM-yyyy")
+ private Date orderDate;
+
+ 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;
+ }
+
+ @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);
+ }
+}
+
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/Order.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,46 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.headerfooter;
+
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+
+@FixedLengthRecord(isFooter = true)
+public class OrderFooter {
+
+ @DataField(pos = 1, length = 1)
+ private int recordType = 9;
+
+ @DataField(pos = 2, length = 9, align = "R", paddingChar = '0')
+ private int numberOfRecordsInTheFile;
+
+ public int getRecordType() {
+ return recordType;
+ }
+
+ public void setRecordType(int recordType) {
+ this.recordType = recordType;
+ }
+
+ public int getNumberOfRecordsInTheFile() {
+ return numberOfRecordsInTheFile;
+ }
+
+ public void setNumberOfRecordsInTheFile(int numberOfRecordsInTheFile) {
+ this.numberOfRecordsInTheFile = numberOfRecordsInTheFile;
+ }
+}
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderFooter.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java?rev=1443631&view=auto
==============================================================================
--- camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java (added)
+++ camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java Thu Feb 7 17:59:42 2013
@@ -0,0 +1,47 @@
+/**
+ * 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.camel.dataformat.bindy.fixed.headerfooter;
+
+import java.util.Date;
+
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+
+@FixedLengthRecord(isHeader = true)
+public class OrderHeader {
+ @DataField(pos = 1, length = 1)
+ private int recordType = 1;
+
+ @DataField(pos = 2, length = 10, pattern = "dd-MM-yyyy")
+ private Date recordDate;
+
+ public int getRecordType() {
+ return recordType;
+ }
+
+ public void setRecordType(int recordType) {
+ this.recordType = recordType;
+ }
+
+ public void setRecordDate(Date recordDate) {
+ this.recordDate = recordDate;
+ }
+
+ public Date getRecordDate() {
+ return recordDate;
+ }
+}
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/headerfooter/OrderHeader.java
------------------------------------------------------------------------------
svn:keywords = Rev Date