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 2016/03/22 16:33:07 UTC
camel git commit: CAMEL-6163: camel-bindy add custom data converter.
Thanks to Roberto Coral Azambuja for the patch.
Repository: camel
Updated Branches:
refs/heads/master 274957ad6 -> 1f9dc80da
CAMEL-6163: camel-bindy add custom data converter. Thanks to Roberto Coral Azambuja for the patch.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1f9dc80d
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1f9dc80d
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1f9dc80d
Branch: refs/heads/master
Commit: 1f9dc80da113ea4fd29b9bde6a5fe12dc346df5d
Parents: 274957a
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Mar 22 16:32:54 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Mar 22 16:32:54 2016 +0100
----------------------------------------------------------------------
.../camel/dataformat/bindy/BindyCsvFactory.java | 9 +-
.../bindy/BindyFixedLengthFactory.java | 115 +++++++--------
.../bindy/BindyKeyValuePairFactory.java | 21 +--
.../camel/dataformat/bindy/FormatFactory.java | 13 +-
.../bindy/annotation/BindyConverter.java | 34 +++++
.../fixed/converter/BindyConverterTest.java | 139 +++++++++++++++++++
6 files changed, 261 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyCsvFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyCsvFactory.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyCsvFactory.java
index a699c04..045970d 100755
--- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyCsvFactory.java
+++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyCsvFactory.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
+import org.apache.camel.dataformat.bindy.annotation.BindyConverter;
import org.apache.camel.dataformat.bindy.annotation.CsvRecord;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.Link;
@@ -155,6 +156,7 @@ public class BindyCsvFactory extends BindyAbstractFactory implements BindyFactor
}
}
+ @Override
public void bind(List<String> tokens, Map<String, Object> model, int line) throws Exception {
int pos = 1;
@@ -190,7 +192,7 @@ public class BindyCsvFactory extends BindyAbstractFactory implements BindyFactor
}
// Create format object to format the field
- Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField);
+ Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField, field.getAnnotation(BindyConverter.class));
// field object to be set
Object modelField = model.get(field.getDeclaringClass().getName());
@@ -232,6 +234,7 @@ public class BindyCsvFactory extends BindyAbstractFactory implements BindyFactor
}
+ @Override
public String unbind(Map<String, Object> model) throws Exception {
StringBuilder buffer = new StringBuilder();
@@ -393,7 +396,7 @@ public class BindyCsvFactory extends BindyAbstractFactory implements BindyFactor
Class<?> type = field.getType();
// Create format
- Format<?> format = FormatFactory.getFormat(type, getLocale(), datafield);
+ Format<?> format = FormatFactory.getFormat(type, getLocale(), datafield, field.getAnnotation(BindyConverter.class));
// Get field value
Object value = field.get(obj);
@@ -586,7 +589,7 @@ public class BindyCsvFactory extends BindyAbstractFactory implements BindyFactor
DataField dataField = dataFields.get(i);
Object modelField = model.get(field.getDeclaringClass().getName());
if (field.get(modelField) == null && !dataField.defaultValue().isEmpty()) {
- Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField);
+ Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField, field.getAnnotation(BindyConverter.class));
Object value = format.parse(dataField.defaultValue());
field.set(modelField, value);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyFixedLengthFactory.java
----------------------------------------------------------------------
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 920d9e6..d6b8aed 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
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
+import org.apache.camel.dataformat.bindy.annotation.BindyConverter;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
import org.apache.camel.dataformat.bindy.annotation.Link;
@@ -48,7 +49,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
private Map<Integer, DataField> dataFields = new TreeMap<Integer, DataField>();
private Map<Integer, Field> annotatedFields = new TreeMap<Integer, Field>();
-
+
private int numberOptionalFields;
private int numberMandatoryFields;
private int totalFields;
@@ -62,27 +63,27 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
private char paddingChar;
private int recordLength;
private boolean ignoreTrailingChars;
-
+
private Class<?> header;
private Class<?> footer;
public BindyFixedLengthFactory(Class<?> type) throws Exception {
super(type);
-
+
header = void.class;
footer = void.class;
-
+
// initialize specific parameters of the fixed length model
initFixedLengthModel();
}
-
+
/**
* method uses to initialize the model representing the classes who will
* bind the data. This process will scan for classes according to the
* package name provided, check the annotated classes and fields
*/
- public void initFixedLengthModel() throws Exception {
-
+ public void initFixedLengthModel() throws Exception {
+
// Find annotated fields declared in the Model classes
initAnnotatedFields();
@@ -91,6 +92,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
initFixedLengthRecordParameters();
}
+ @Override
public void initAnnotatedFields() {
for (Class<?> cl : models) {
@@ -104,7 +106,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
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});
}
@@ -144,9 +146,9 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
}
}
-
+
// Will not be used in the case of a Fixed Length record
- // as we provide the content of the record and
+ // as we provide the content of the record and
// we don't split it as this is the case for a CSV record
@Override
public void bind(List<String> data, Map<String, Object> model, int line) throws Exception {
@@ -175,7 +177,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
dataField = itr.next();
length = dataField.length();
delimiter = dataField.delimiter();
-
+
if (length == 0 && dataField.lengthPos() != 0) {
Field lengthField = annotatedFields.get(dataField.lengthPos());
lengthField.setAccessible(true);
@@ -196,7 +198,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
LOG.debug("skipping ahead [" + (dataField.pos() - offset) + "] chars.");
offset = dataField.pos();
}
-
+
if (length > 0) {
token = record.substring(offset - 1, offset + length - 1);
offset += length;
@@ -227,7 +229,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
+ " is empty for the line: " + line);
}
}
-
+
// Get Field to be set
field = annotatedFields.get(dataField.pos());
field.setAccessible(true);
@@ -237,7 +239,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
}
// Create format object to format the field
- Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField);
+ Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField, field.getAnnotation(BindyConverter.class));
// field object to be set
Object modelField = model.get(field.getDeclaringClass().getName());
@@ -258,11 +260,11 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
}
field.set(modelField, value);
-
+
++pos;
-
+
}
-
+
// check for unmapped non-whitespace data at the end of the line
if (offset <= record.length() && !(record.substring(offset - 1, record.length())).trim().equals("") && !isIgnoreTrailingChars()) {
throw new IllegalArgumentException("Unexpected / unmapped characters found at the end of the fixed-length record at line : " + line);
@@ -276,10 +278,11 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
if (counterMandatoryFields < numberMandatoryFields) {
throw new IllegalArgumentException("Some mandatory fields are missing, line: " + line);
- }
-
+ }
+
}
+ @Override
public String unbind(Map<String, Object> model) throws Exception {
StringBuilder buffer = new StringBuilder();
@@ -312,15 +315,15 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
// Get list of values
List<String> val = entry.getValue();
String value = val.get(0);
-
+
buffer.append(value);
}
-
+
return buffer.toString();
}
/**
- *
+ *
* Generate a table containing the data formatted and sorted with their position/offset
* The result is placed in the Map<Integer, List> results
*/
@@ -342,7 +345,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
Class<?> type = field.getType();
// Create format
- Format<?> format = FormatFactory.getFormat(type, getLocale(), datafield);
+ Format<?> format = FormatFactory.getFormat(type, getLocale(), datafield, field.getAnnotation(BindyConverter.class));
// Get field value
Object value = field.get(obj);
@@ -353,19 +356,19 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
if (datafield.trim()) {
result = result.trim();
}
-
+
int fieldLength = datafield.length();
-
+
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: "
+ 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 {
@@ -375,10 +378,10 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
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
@@ -386,7 +389,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
} else {
padChar = padCharField;
}
-
+
if (align.contains("R")) {
temp.append(generatePaddingChars(padChar, fieldLength, result.length()));
temp.append(result);
@@ -397,11 +400,11 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
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);
@@ -437,7 +440,7 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
}
}
-
+
private String generatePaddingChars(char pad, int lengthField, int lengthString) {
StringBuilder buffer = new StringBuilder();
int size = lengthField - lengthString;
@@ -467,28 +470,28 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
// Get header parameter
header = record.header();
- LOG.debug("Header: {}", header);
+ LOG.debug("Header: {}", header);
hasHeader = header != void.class;
LOG.debug("Has Header: {}", hasHeader);
-
+
// Get skipHeader parameter
skipHeader = record.skipHeader();
LOG.debug("Skip Header: {}", skipHeader);
// Get footer parameter
footer = record.footer();
- LOG.debug("Footer: {}", footer);
+ LOG.debug("Footer: {}", footer);
hasFooter = record.footer() != void.class;
LOG.debug("Has Footer: {}", hasFooter);
-
+
// Get skipFooter parameter
skipFooter = record.skipFooter();
LOG.debug("Skip Footer: {}", skipFooter);
-
+
// Get isHeader parameter
isHeader = hasHeader ? cl.equals(header) : false;
LOG.debug("Is Header: {}", isHeader);
-
+
// Get isFooter parameter
isFooter = hasFooter ? cl.equals(footer) : false;
LOG.debug("Is Footer: {}", isFooter);
@@ -506,80 +509,80 @@ public class BindyFixedLengthFactory extends BindyAbstractFactory implements Bin
LOG.debug("Ignore trailing chars: {}", ignoreTrailingChars);
}
}
-
+
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'");
}
-
+
}
-
+
/**
- *
+ *
* @return
*/
public Class<?> header() {
return header;
}
-
+
/**
* Flag indicating if we have a header
*/
public boolean hasHeader() {
return hasHeader;
- }
-
+ }
+
/**
- *
+ *
* @return
*/
public Class<?> footer() {
return footer;
}
-
+
/**
* Flag indicating if we have a footer
*/
public boolean hasFooter() {
return hasFooter;
}
-
+
/**
* 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
*/
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java
index 625a415..6625be0 100644
--- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java
+++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import org.apache.camel.dataformat.bindy.annotation.BindyConverter;
import org.apache.camel.dataformat.bindy.annotation.KeyValuePairField;
import org.apache.camel.dataformat.bindy.annotation.Link;
import org.apache.camel.dataformat.bindy.annotation.Message;
@@ -54,7 +55,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
private String pairSeparator;
private boolean messageOrdered;
-
+
public BindyKeyValuePairFactory(Class<?> type) throws Exception {
super(type);
@@ -67,7 +68,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
* bind the data This process will scan for classes according to the package
* name provided, check the annotated classes and fields. Next, we retrieve
* the parameters required like : Pair Separator & key value pair separator
- *
+ *
* @throws Exception
*/
public void initKeyValuePairModel() throws Exception {
@@ -80,6 +81,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
}
+ @Override
public void initAnnotatedFields() {
for (Class<?> cl : models) {
@@ -277,7 +279,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
if (value != null) {
// Create format object to format the field
- Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), keyValuePairField);
+ Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), keyValuePairField, field.getAnnotation(BindyConverter.class));
// format the value of the key received
result = formatField(format, value, key, line);
@@ -313,7 +315,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
value = values.get(i);
// Create format object to format the field
- Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), keyValuePairField);
+ Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), keyValuePairField, field.getAnnotation(BindyConverter.class));
// format the value of the key received
Object result = formatField(format, value, key, line);
@@ -399,8 +401,9 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
}
/**
- *
+ *
*/
+ @Override
public String unbind(Map<String, Object> model) throws Exception {
StringBuilder builder = new StringBuilder();
@@ -441,7 +444,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
// Create format
@SuppressWarnings("unchecked")
- Format<Object> format = (Format<Object>)FormatFactory.getFormat(type, getLocale(), keyValuePairField);
+ Format<Object> format = (Format<Object>)FormatFactory.getFormat(type, getLocale(), keyValuePairField, field.getAnnotation(BindyConverter.class));
// Get object to be formatted
Object obj = model.get(field.getDeclaringClass().getName());
@@ -456,9 +459,9 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
// and the position of the field
Integer key1 = sections.get(obj.getClass().getName());
Integer key2 = keyValuePairField.position();
-
+
LOG.debug("Key of the section: {}, and the field: {}", key1, key2);
-
+
Integer keyGenerated = generateKey(key1, key2);
if (LOG.isDebugEnabled()) {
@@ -575,7 +578,7 @@ public class BindyKeyValuePairFactory extends BindyAbstractFactory implements Bi
/**
* Flag indicating if the message must be ordered
- *
+ *
* @return boolean
*/
public boolean isMessageOrdered() {
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/FormatFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/FormatFactory.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/FormatFactory.java
index 48230a1..7a63f77 100755
--- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/FormatFactory.java
+++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/FormatFactory.java
@@ -22,6 +22,7 @@ import java.math.BigInteger;
import java.util.Date;
import java.util.Locale;
+import org.apache.camel.dataformat.bindy.annotation.BindyConverter;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.KeyValuePairField;
import org.apache.camel.dataformat.bindy.format.BigDecimalFormat;
@@ -128,7 +129,11 @@ public final class FormatFactory {
* @return Format the formatter
* @throws IllegalArgumentException if not suitable formatter is found
*/
- public static Format<?> getFormat(Class<?> clazz, String locale, DataField data) throws Exception {
+ public static Format<?> getFormat(Class<?> clazz, String locale, DataField data, BindyConverter converter) throws Exception {
+ if (converter != null) {
+ return converter.value().newInstance();
+ }
+
String pattern = data.pattern();
String timezone = data.timezone();
int precision = data.precision();
@@ -148,7 +153,11 @@ public final class FormatFactory {
* @throws IllegalArgumentException if not suitable formatter is found
* TODO : Check if KeyValuePair could also use decimal/groupingSeparator/rounding for BigDecimal
*/
- public static Format<?> getFormat(Class<?> clazz, String locale, KeyValuePairField data) throws Exception {
+ public static Format<?> getFormat(Class<?> clazz, String locale, KeyValuePairField data, BindyConverter converter) throws Exception {
+ if (converter != null) {
+ return converter.value().newInstance();
+ }
+
String pattern = data.pattern();
String timezone = data.timezone();
int precision = data.precision();
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/BindyConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/BindyConverter.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/BindyConverter.java
new file mode 100644
index 0000000..7dfed7e
--- /dev/null
+++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/annotation/BindyConverter.java
@@ -0,0 +1,34 @@
+/**
+ * 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.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import org.apache.camel.dataformat.bindy.Format;
+
+
+/**
+ * An annotation used to identify which converter class will be used to convert
+ * the String field to the attribute's data type.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BindyConverter {
+ Class<? extends Format<?>> value();
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1f9dc80d/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/converter/BindyConverterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/converter/BindyConverterTest.java b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/converter/BindyConverterTest.java
new file mode 100644
index 0000000..7ff80b3
--- /dev/null
+++ b/components/camel-bindy/src/test/java/org/apache/camel/dataformat/bindy/fixed/converter/BindyConverterTest.java
@@ -0,0 +1,139 @@
+/**
+ * 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.converter;
+
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.bindy.Format;
+import org.apache.camel.dataformat.bindy.annotation.BindyConverter;
+import org.apache.camel.dataformat.bindy.annotation.DataField;
+import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
+import org.apache.camel.model.dataformat.BindyDataFormat;
+import org.apache.camel.model.dataformat.BindyType;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+
+@ContextConfiguration
+public class BindyConverterTest 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";
+
+ // *************************************************************************
+ //
+ // *************************************************************************
+
+ @Produce(uri = URI_DIRECT_MARSHALL)
+ private ProducerTemplate mtemplate;
+
+ @EndpointInject(uri = URI_MOCK_MARSHALL_RESULT)
+ private MockEndpoint mresult;
+
+ @Produce(uri = URI_DIRECT_UNMARSHALL)
+ private ProducerTemplate utemplate;
+
+ @EndpointInject(uri = URI_MOCK_UNMARSHALL_RESULT)
+ private MockEndpoint uresult;
+
+ // *************************************************************************
+ // TEST
+ // *************************************************************************
+
+ @Test
+ @DirtiesContext
+ public void testMarshall() throws Exception {
+ DataModel rec = new DataModel();
+ rec.field1 = "0123456789";
+ mresult.expectedBodiesReceived("9876543210\r\n");
+
+ mtemplate.sendBody(rec);
+ mresult.assertIsSatisfied();
+ }
+
+ @Test
+ @DirtiesContext
+ public void testUnMarshall() throws Exception {
+ utemplate.sendBody("9876543210\r\n");
+
+ uresult.expectedMessageCount(1);
+ uresult.assertIsSatisfied();
+
+ // check the model
+ Exchange exc = uresult.getReceivedExchanges().get(0);
+ DataModel data = exc.getIn().getBody(DataModel.class);
+
+ Assert.assertEquals("0123456789", data.field1);
+ }
+
+ // *************************************************************************
+ // ROUTES
+ // *************************************************************************
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ RouteBuilder routeBuilder = new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ BindyDataFormat bindy = new BindyDataFormat();
+ bindy.setClassType(DataModel.class);
+ bindy.setType(BindyType.Fixed);
+
+ from(URI_DIRECT_MARSHALL)
+ .marshal(bindy)
+ .to(URI_MOCK_MARSHALL_RESULT);
+ from(URI_DIRECT_UNMARSHALL)
+ .unmarshal().bindy(BindyType.Fixed, DataModel.class)
+ .to(URI_MOCK_UNMARSHALL_RESULT);
+ }
+ };
+
+ return routeBuilder;
+ }
+
+ // *************************************************************************
+ // DATA MODEL
+ // *************************************************************************
+
+ @FixedLengthRecord(length = 10, paddingChar = ' ')
+ public static class DataModel {
+ @DataField(pos = 1, length = 10, trim = true)
+ @BindyConverter(CustomConverter.class)
+ public String field1;
+ }
+
+ public static class CustomConverter implements Format<String> {
+ @Override
+ public String format(String object) throws Exception {
+ return (new StringBuilder(object)).reverse().toString();
+ }
+
+ @Override
+ public String parse(String string) throws Exception {
+ return (new StringBuilder(string)).reverse().toString();
+ }
+ }
+}