private void generateModelFromKeyValueMap()

in components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/BindyKeyValuePairFactory.java [184:424]


    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.isEmpty()) {

                        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.isEmpty()) {
                    // 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<>());
                    }

                    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");
                }

            }

        }

    }