use of org.apache.camel.dataformat.bindy.annotation.OneToMany in project camel by apache.
the class BindyCsvFactory method generateCsvPositionMap.
/**
* Generate a table containing the data formatted and sorted with their position/offset
* If the model is Ordered than a key is created combining the annotation @Section and Position of the field
* If a relation @OneToMany is defined, than we iterate recursively through this function
* The result is placed in the Map<Integer, List> results
*/
private void generateCsvPositionMap(Class<?> clazz, Object obj, Map<Integer, List<String>> results) throws Exception {
String result = "";
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
DataField datafield = field.getAnnotation(DataField.class);
if (datafield != null) {
if (obj != null) {
// Retrieve the format, pattern and precision associated to the type
Class<?> type = field.getType();
// Create format
FormattingOptions formattingOptions = ConverterUtils.convert(datafield, field.getType(), field.getAnnotation(BindyConverter.class), getLocale());
Format<?> format = formatFactory.getFormat(formattingOptions);
// Get field value
Object value = field.get(obj);
// If the field value is empty, populate it with the default value
if (ObjectHelper.isNotEmpty(datafield.defaultValue()) && ObjectHelper.isEmpty(value)) {
value = datafield.defaultValue();
}
result = formatString(format, value);
if (datafield.trim()) {
result = result.trim();
}
if (datafield.clip() && result.length() > datafield.length()) {
result = result.substring(0, datafield.length());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Value to be formatted: {}, position: {}, and its formatted value: {}", new Object[] { value, datafield.pos(), result });
}
} else {
result = "";
}
Integer key;
if (isMessageOrdered() && obj != null) {
// Generate a key using the number of the section
// and the position of the field
Integer key1 = sections.get(obj.getClass().getName());
Integer key2 = datafield.position();
Integer keyGenerated = generateKey(key1, key2);
if (LOG.isDebugEnabled()) {
LOG.debug("Key generated: {}, for section: {}", String.valueOf(keyGenerated), key1);
}
key = keyGenerated;
} else {
key = datafield.pos();
}
if (!results.containsKey(key)) {
List<String> list = new LinkedList<String>();
list.add(result);
results.put(key, list);
} else {
List<String> list = results.get(key);
list.add(result);
}
}
OneToMany oneToMany = field.getAnnotation(OneToMany.class);
if (oneToMany != null) {
// Set global variable
// Will be used during generation of CSV
isOneToMany = true;
List<?> list = (List<?>) field.get(obj);
if (list != null) {
Iterator<?> it = list.iterator();
while (it.hasNext()) {
Object target = it.next();
generateCsvPositionMap(target.getClass(), target, results);
}
} else {
// Call this function to add empty value
// in the table
generateCsvPositionMap(field.getClass(), null, results);
}
}
}
}
use of org.apache.camel.dataformat.bindy.annotation.OneToMany in project camel by apache.
the class BindyKeyValuePairFactory method generateModelFromKeyValueMap.
private void generateModelFromKeyValueMap(Class<?> clazz, Object obj, Map<Integer, List<String>> results, int line, Map<String, List<Object>> lists) throws Exception {
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
KeyValuePairField keyValuePairField = field.getAnnotation(KeyValuePairField.class);
if (keyValuePairField != null) {
// Key
int key = keyValuePairField.tag();
// Get Value
List<String> values = results.get(key);
String value = null;
// we don't received data
if (values == null) {
/*
* The relation is one to one So we check if we are in a
* target class and if the field is mandatory
*/
if (obj != null) {
// Check mandatory field
if (keyValuePairField.required()) {
throw new IllegalArgumentException("The mandatory key/tag : " + key + " has not been defined !");
}
Object result = getDefaultValueForPrimitive(field.getType());
try {
field.set(obj, result);
} catch (Exception e) {
throw new IllegalArgumentException("Setting of field " + field + " failed for object : " + obj + " and result : " + result);
}
} else {
/*
* The relation is one to many So, we create an object
* with empty fields and we don't check if the fields
* are mandatory
*/
// Get List from Map
List<Object> l = lists.get(clazz.getName());
if (l != null) {
// BigIntegerFormatFactory if object exist
if (!l.isEmpty()) {
obj = l.get(0);
} else {
obj = clazz.newInstance();
}
Object result = getDefaultValueForPrimitive(field.getType());
try {
field.set(obj, result);
} catch (Exception e) {
throw new IllegalArgumentException("Setting of field " + field + " failed for object : " + obj + " and result : " + result);
}
// Add object created to the list
if (!l.isEmpty()) {
l.set(0, obj);
} else {
l.add(0, obj);
}
// and to the Map
lists.put(clazz.getName(), l);
// Reset obj to null
obj = null;
} else {
throw new IllegalArgumentException("The list of values is empty for the following key : " + key + " defined in the class : " + clazz.getName());
}
}
// end of test if obj != null
} else {
// Data have been retrieved from message
if (values.size() >= 1) {
if (obj != null) {
// Relation OneToOne
value = values.get(0);
Object result = null;
if (value != null) {
// Create format object to format the field
FormattingOptions formattingOptions = ConverterUtils.convert(keyValuePairField, field.getType(), field.getAnnotation(BindyConverter.class), getLocale());
Format<?> format = formatFactory.getFormat(formattingOptions);
// format the value of the key received
result = formatField(format, value, key, line);
LOG.debug("Value formated : {}", result);
} else {
result = getDefaultValueForPrimitive(field.getType());
}
try {
field.set(obj, result);
} catch (Exception e) {
throw new IllegalArgumentException("Setting of field " + field + " failed for object : " + obj + " and result : " + result);
}
} else {
// Get List from Map
List<Object> l = lists.get(clazz.getName());
if (l != null) {
// Relation OneToMany
for (int i = 0; i < values.size(); i++) {
// BigIntegerFormatFactory if object exist
if ((!l.isEmpty()) && (l.size() > i)) {
obj = l.get(i);
} else {
obj = clazz.newInstance();
}
value = values.get(i);
// Create format object to format the field
FormattingOptions formattingOptions = ConverterUtils.convert(keyValuePairField, field.getType(), field.getAnnotation(BindyConverter.class), getLocale());
Format<?> format = formatFactory.getFormat(formattingOptions);
// format the value of the key received
Object result = formatField(format, value, key, line);
LOG.debug("Value formated : {}", result);
try {
if (value != null) {
field.set(obj, result);
} else {
field.set(obj, getDefaultValueForPrimitive(field.getType()));
}
} catch (Exception e) {
throw new IllegalArgumentException("Setting of field " + field + " failed for object: " + obj + " and result: " + result);
}
// Add object created to the list
if ((!l.isEmpty()) && (l.size() > i)) {
l.set(i, obj);
} else {
l.add(i, obj);
}
// and to the Map
lists.put(clazz.getName(), l);
// Reset obj to null
obj = null;
}
} else {
throw new IllegalArgumentException("The list of values is empty for the following key: " + key + " defined in the class: " + clazz.getName());
}
}
} else {
// No values found from message
Object result = getDefaultValueForPrimitive(field.getType());
try {
field.set(obj, result);
} catch (Exception e) {
throw new IllegalArgumentException("Setting of field " + field + " failed for object: " + obj + " and result: " + result);
}
}
}
}
OneToMany oneToMany = field.getAnnotation(OneToMany.class);
if (oneToMany != null) {
String targetClass = oneToMany.mappedTo();
if (!targetClass.equals("")) {
// Class cl = Class.forName(targetClass); Does not work in
// OSGI when class is defined in another bundle
Class<?> cl = null;
try {
cl = Thread.currentThread().getContextClassLoader().loadClass(targetClass);
} catch (ClassNotFoundException e) {
cl = getClass().getClassLoader().loadClass(targetClass);
}
if (!lists.containsKey(cl.getName())) {
lists.put(cl.getName(), new ArrayList<Object>());
}
generateModelFromKeyValueMap(cl, null, results, line, lists);
// Add list of objects
field.set(obj, lists.get(cl.getName()));
} else {
throw new IllegalArgumentException("No target class has been defined in @OneToMany annotation");
}
}
}
}
Aggregations