private boolean generateSetValue()

in dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java [674:1232]


    private boolean generateSetValue(
            Schema descriptor,
            String modelName,
            CodeBlock.Builder cb,
            FieldInfo field,
            Collection<AnnotationSpec> annotations) {

        if (hasAnnotation(field, XML_TRANSIENT_CLASS) && !hasAnnotation(field, DSL_PROPERTY_ANNOTATION)) {
            return false;
        }

        //
        // XmlElements
        //
        if (hasAnnotation(field, XML_ELEMENTS_ANNOTATION_CLASS)) {
            AnnotationInstance[] elements = field.annotation(XML_ELEMENTS_ANNOTATION_CLASS).value().asNestedArray();

            if (elements.length > 1) {
                cb.beginControlFlow("case $S:", field.name());
                cb.addStatement("$T val = asMappingNode(node)", CN_MAPPING_NODE);
                cb.addStatement("setProperties(target, val)");
                cb.addStatement("break");
                cb.endControlFlow();
            }

            if (field.type().name().equals(LIST_CLASS)) {
                Type parameterized = field.type().asParameterizedType().arguments().get(0);

                for (AnnotationInstance element : elements) {
                    AnnotationValue name = element.value("name");
                    AnnotationValue type = element.value("type");

                    if (name != null && type != null) {
                        String fieldName = name.asString();
                        String paramType = parameterized.name().toString();

                        cb.beginControlFlow("case $S:", fieldName);
                        cb.addStatement("$L val = asType(node, $L.class)", type.asString(), type.asString());
                        cb.addStatement("java.util.List<$L> existing = target.get$L()", paramType,
                                StringHelper.capitalize(field.name()));
                        cb.beginControlFlow("if (existing == null)");
                        cb.addStatement("existing = new java.util.ArrayList<>()");
                        cb.endControlFlow();
                        cb.addStatement("existing.add(val)");
                        cb.addStatement("target.set$L(existing)", StringHelper.capitalize(field.name()));
                        cb.addStatement("break");
                        cb.endControlFlow();

                        annotations.add(
                                YamlProperties.annotation(fieldName, "object")
                                        .withSubType(type.asString())
                                        .withRequired(isRequired(field))
                                        .withDescription(descriptor.description(fieldName))
                                        .withDisplayName(descriptor.displayName(fieldName))
                                        .withDefaultValue(descriptor.defaultValue(fieldName))
                                        .withIsSecret(descriptor.isSecret(fieldName))
                                        .build());
                    }
                }
            } else {
                for (AnnotationInstance element : elements) {
                    AnnotationValue name = element.value("name");
                    AnnotationValue type = element.value("type");

                    if (name != null && type != null) {
                        String fieldName = name.asString();

                        cb.beginControlFlow("case $S:", fieldName);
                        cb.addStatement("$L val = asType(node, $L.class)", type.asString(), type.asString());
                        cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                        cb.addStatement("break");
                        cb.endControlFlow();

                        annotations.add(
                                YamlProperties.annotation(fieldName, "object")
                                        .withSubType(type.asString())
                                        .withRequired(isRequired(field))
                                        .withDescription(descriptor.description(fieldName))
                                        .withDisplayName(descriptor.displayName(fieldName))
                                        .withDefaultValue(descriptor.defaultValue(fieldName))
                                        .withIsSecret(descriptor.isSecret(fieldName))
                                        .withOneOf(field.name())
                                        .build());
                    }
                }
            }

            return true;
        }

        //
        // XmlElementRef
        //
        if (hasAnnotation(field, XML_ELEMENT_REF_ANNOTATION_CLASS)) {
            if (field.type().name().equals(LIST_CLASS)) {
                Type parameterized = field.type().asParameterizedType().arguments().get(0);
                ClassInfo refType = view.getClassByName(parameterized.name());

                // special handling for Rest + Verb definition
                if (extendsType(refType, VERB_DEFINITION_CLASS)) {
                    implementsOrExtends(parameterized).forEach(ci -> {
                        Optional<String> name = annotationValue(ci, XML_ROOT_ELEMENT_ANNOTATION_CLASS,
                                "name")
                                .map(AnnotationValue::asString)
                                .filter(value -> !"##default".equals(value));

                        if (!name.isPresent()) {
                            return;
                        }

                        String fieldName = name.get();
                        String fieldType = ci.name().toString();

                        cb.beginControlFlow("case $S:", fieldName);
                        cb.addStatement("java.util.List<$L> existing = target.get$L()", refType.name().toString(),
                                StringHelper.capitalize(field.name()));
                        cb.beginControlFlow("if (existing == null)");
                        cb.addStatement("existing = new java.util.ArrayList<>()");
                        cb.endControlFlow();
                        cb.addStatement("java.util.List val = asFlatList(node, $L.class)", fieldType);
                        cb.addStatement("existing.addAll(val)");
                        cb.addStatement("target.set$L(existing)", StringHelper.capitalize(field.name()));
                        cb.addStatement("break");
                        cb.endControlFlow();

                        annotations.add(
                                YamlProperties.annotation(fieldName, "array")
                                        .withSubType(fieldType)
                                        .withRequired(isRequired(field))
                                        .withDescription(descriptor.description(fieldName))
                                        .withDisplayName(descriptor.displayName(fieldName))
                                        .withDefaultValue(descriptor.defaultValue(fieldName))
                                        .withIsSecret(descriptor.isSecret(fieldName))
                                        .build());
                    });
                    return true;
                }
            }
        }

        //
        // Skip elements with unsupported annotations.
        //
        if (!hasAnnotation(field, XML_ATTRIBUTE_ANNOTATION_CLASS) &&
                !hasAnnotation(field, XML_VALUE_ANNOTATION_CLASS) &&
                !hasAnnotation(field, XML_ELEMENT_ANNOTATION_CLASS) &&
                !hasAnnotation(field, XML_ELEMENT_REF_ANNOTATION_CLASS) &&
                !hasAnnotation(field, XML_TRANSIENT_CLASS)) {
            return false;
        }

        final String fieldName = fieldName(field);

        //
        // Parametrized
        //
        if (field.type().kind() == Type.Kind.PARAMETERIZED_TYPE) {
            ParameterizedType parameterized = field.type().asParameterizedType();

            if (!parameterized.name().equals(CLASS_CLASS) && parameterized.arguments().size() == 1) {
                final Type parametrizedType = parameterized.arguments().get(0);
                if (parametrizedType.name().equals(PROCESSOR_DEFINITION_CLASS)) {
                    return false;
                }

                switch (parameterized.name().toString()) {
                    case "java.util.List":
                        if (parametrizedType.name().equals(STRING_CLASS)) {
                            cb.beginControlFlow("case $S:", fieldName);
                            cb.addStatement("java.util.List<String> val = asStringList(node)");
                            cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                            cb.addStatement("break");
                            cb.endControlFlow();

                            annotations.add(
                                    YamlProperties.annotation(fieldName, "array")
                                            .withSubType("string")
                                            .withRequired(isRequired(field))
                                            .withDescription(descriptor.description(fieldName))
                                            .withDisplayName(descriptor.displayName(fieldName))
                                            .withDefaultValue(descriptor.defaultValue(fieldName))
                                            .withIsSecret(descriptor.isSecret(fieldName))
                                            .build());
                        } else {
                            ClassInfo ci = view.getClassByName(parametrizedType.name());
                            String name = fieldName(ci, field);

                            cb.beginControlFlow("case $S:", name);
                            cb.addStatement("java.util.List<$L> val = asFlatList(node, $L.class)",
                                    parametrizedType.name().toString(), parametrizedType.name().toString());
                            cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                            cb.addStatement("break");
                            cb.endControlFlow();

                            annotations.add(
                                    YamlProperties
                                            .annotation(name, "array")
                                            .withSubType(parametrizedType.name().toString())
                                            .withRequired(isRequired(field))
                                            .withDescription(descriptor.description(name))
                                            .withDisplayName(descriptor.displayName(name))
                                            .withDefaultValue(descriptor.defaultValue(name))
                                            .withIsSecret(descriptor.defaultValue(name))
                                            .build());
                        }
                        return true;
                    case "java.util.Set":
                        if (parametrizedType.name().equals(STRING_CLASS)) {
                            cb.beginControlFlow("case $S:", fieldName);
                            cb.addStatement("java.util.Set<String> val = asStringSet(node)");
                            cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                            cb.addStatement("break");
                            cb.endControlFlow();

                            annotations.add(
                                    YamlProperties.annotation(fieldName, "array")
                                            .withSubType("string")
                                            .withRequired(isRequired(field))
                                            .withDescription(descriptor.description(fieldName))
                                            .withDisplayName(descriptor.displayName(fieldName))
                                            .withDefaultValue(descriptor.defaultValue(fieldName))
                                            .withIsSecret(descriptor.isSecret(fieldName))
                                            .build());
                        } else {
                            ClassInfo ci = view.getClassByName(parametrizedType.name());
                            String name = fieldName(ci, field);

                            cb.beginControlFlow("case $S:", name);
                            cb.addStatement("var val = asFlatSet(node, $L.class)", parametrizedType.name().toString());
                            cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                            cb.addStatement("break");
                            cb.endControlFlow();

                            annotations.add(
                                    YamlProperties
                                            .annotation(name, "array")
                                            .withSubType(parametrizedType.name().toString())
                                            .withRequired(isRequired(field))
                                            .withDescription(descriptor.description(name))
                                            .withDisplayName(descriptor.displayName(name))
                                            .withDefaultValue(descriptor.defaultValue(name))
                                            .withIsSecret(descriptor.defaultValue(name))
                                            .build());
                        }
                        return true;
                    default:
                        throw new UnsupportedOperationException(
                                "Unable to handle field: " + field.name() + " with type: " + field.type().name());
                }
            }
        }

        if ("expression".equals(fieldName) && !expressionRequired(modelName)) {
            // special for some language models which does not have required expression
            // which should be skipped
            return true;
        }

        //
        // Others
        //
        if ("enableCORS".equals(fieldName)) {
            // special hack for this name
            cb.beginControlFlow("case $S:", "enableCors");
        } else {
            cb.beginControlFlow("case $S:", fieldName);
        }

        ClassInfo c = view.getClassByName(field.type().name());
        if (hasAnnotation(field, XML_JAVA_TYPE_ADAPTER_CLASS)) {
            // conversion using JAXB Adapter of known class
            Optional<AnnotationValue> adapter = annotationValue(field, XML_JAVA_TYPE_ADAPTER_CLASS, "value");
            if (adapter.isEmpty()) {
                return false;
            }
            ClassInfo adapterClassInfo = view.getClassByName(adapter.get().asClass().name());
            if (adapterClassInfo.superClassType().kind() == Type.Kind.PARAMETERIZED_TYPE) {
                List<Type> arguments = adapterClassInfo.superClassType().asParameterizedType().arguments();
                if (arguments.size() == 2) {
                    // this is for extends XmlAdapter<BeanPropertiesDefinition, Map<String, Object>>
                    // we can't use JaxbUnmarshaller here (as in XML DSL) and we have to convert to map directly
                    Type type = arguments.get(1);
                    if (type.name().toString().equals("java.util.Map")) {
                        cb.addStatement("$L val = asMap(node)", field.type().name().toString());
                        cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                        cb.addStatement("break");

                        annotations.add(
                                YamlProperties.annotation(fieldName, "object")
                                        .withRequired(isRequired(field))
                                        .withDeprecated(isDeprecated(field))
                                        .withDescription(descriptor.description(fieldName))
                                        .withDisplayName(descriptor.displayName(fieldName))
                                        .withDefaultValue(descriptor.defaultValue(fieldName))
                                        .withIsSecret(descriptor.isSecret(fieldName))
                                        .build());
                    }
                }
            }
        } else if (c != null && c.isEnum()) {
            cb.addStatement("target.set$L(asEnum(node, $L.class))", StringHelper.capitalize(field.name()),
                    field.type().name().toString());
            cb.addStatement("break");

            Set<String> values = new TreeSet<>();

            // gather enum values
            List<FieldInfo> fields = c.fields();
            for (int i = 1; i < fields.size(); i++) {
                FieldInfo f = fields.get(i);
                if (f.isEnumConstant()) {
                    values.add(f.name());
                }
            }

            annotations.add(
                    YamlProperties.annotation(fieldName, "enum:" + String.join(",", values))
                            .withRequired(isRequired(field))
                            .withRequired(isDeprecated(field))
                            .withDescription(descriptor.description(fieldName))
                            .withDisplayName(descriptor.displayName(fieldName))
                            .withDefaultValue(descriptor.defaultValue(fieldName))
                            .withIsSecret(descriptor.isSecret(fieldName))
                            .build());
        } else if (isEnum(field)) {
            // this is a fake enum where the model is text based by have enum values to represent the user to choose between
            cb.addStatement("String val = asText(node)");
            cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
            cb.addStatement("break");

            annotations.add(
                    YamlProperties.annotation(fieldName, "enum:" + getEnums(field))
                            .withRequired(isRequired(field))
                            .withRequired(isDeprecated(field))
                            .withDescription(descriptor.description(fieldName))
                            .withDisplayName(descriptor.displayName(fieldName))
                            .withDefaultValue(descriptor.defaultValue(fieldName))
                            .withIsSecret(descriptor.isSecret(fieldName))
                            .build());

        } else {
            switch (field.type().name().toString()) {
                case "[B":
                    cb.addStatement("byte[] val = asByteArray(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "string")
                                    .withFormat("binary")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "Z":
                case "boolean":
                    cb.addStatement("boolean val = asBoolean(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "boolean")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "I":
                case "int":
                    cb.addStatement("int val = asInt(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "number")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "J":
                case "long":
                    cb.addStatement("long val = asLong(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "number")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "D":
                case "double":
                    cb.addStatement("double val = asDouble(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "number")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "java.lang.String":
                    cb.addStatement("String val = asText(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    String javaType = annotationValue(field, METADATA_ANNOTATION_CLASS, "javaType")
                            .map(AnnotationValue::asString)
                            .orElse("string");

                    switch (javaType) {
                        case "java.lang.Boolean":
                            annotations.add(
                                    YamlProperties.annotation(fieldName, "boolean")
                                            .withRequired(isRequired(field))
                                            .withDeprecated(isDeprecated(field))
                                            .withDescription(descriptor.description(fieldName))
                                            .withDisplayName(descriptor.displayName(fieldName))
                                            .withDefaultValue(descriptor.defaultValue(fieldName))
                                            .withIsSecret(descriptor.isSecret(fieldName))
                                            .build());
                            break;
                        case "java.lang.Integer":
                        case "java.lang.Short":
                        case "java.lang.Long":
                        case "java.lang.Float":
                        case "java.lang.Double":
                            annotations.add(
                                    YamlProperties.annotation(fieldName, "number")
                                            .withRequired(isRequired(field))
                                            .withDeprecated(isDeprecated(field))
                                            .withDescription(descriptor.description(fieldName))
                                            .withDisplayName(descriptor.displayName(fieldName))
                                            .withDefaultValue(descriptor.defaultValue(fieldName))
                                            .withIsSecret(descriptor.isSecret(fieldName))
                                            .build());
                            break;
                        default:
                            annotations.add(
                                    YamlProperties.annotation(fieldName, "string")
                                            .withRequired(isRequired(field))
                                            .withDeprecated(isDeprecated(field))
                                            .withDescription(descriptor.description(fieldName))
                                            .withDisplayName(descriptor.displayName(fieldName))
                                            .withDefaultValue(descriptor.defaultValue(fieldName))
                                            .withIsSecret(descriptor.isSecret(fieldName))
                                            .build());
                    }

                    break;
                case "java.lang.Class":
                    cb.addStatement("java.lang.Class<?> val = asClass(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "string")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());

                    break;
                case "[Ljava.lang.Class;":
                    cb.addStatement("java.lang.Class<?>[] val = asClassArray(node)");
                    cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                    cb.addStatement("break");
                    break;
                case "java.lang.Integer":
                case "java.lang.Short":
                case "java.lang.Long":
                case "java.lang.Float":
                case "java.lang.Double":
                    cb.addStatement("String val = asText(node)");
                    cb.addStatement("target.set$L($L.valueOf(val))", StringHelper.capitalize(field.name()),
                            field.type().name().toString());
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "number")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                case "java.lang.Boolean":
                    cb.addStatement("String val = asText(node)");
                    cb.addStatement("target.set$L($L.valueOf(val))", StringHelper.capitalize(field.name()),
                            field.type().name().toString());
                    cb.addStatement("break");

                    annotations.add(
                            YamlProperties.annotation(fieldName, "boolean")
                                    .withRequired(isRequired(field))
                                    .withRequired(isDeprecated(field))
                                    .withDescription(descriptor.description(fieldName))
                                    .withDisplayName(descriptor.displayName(fieldName))
                                    .withDefaultValue(descriptor.defaultValue(fieldName))
                                    .withIsSecret(descriptor.isSecret(fieldName))
                                    .build());
                    break;
                default:
                    if (field.type().kind() == Type.Kind.CLASS) {
                        cb.addStatement("$L val = asType(node, $L.class)", field.type().name().toString(),
                                field.type().name().toString());
                        cb.addStatement("target.set$L(val)", StringHelper.capitalize(field.name()));
                        cb.addStatement("break");

                        annotations.add(
                                YamlProperties.annotation(fieldName, "object")
                                        .withSubType(field.type().name().toString())
                                        .withRequired(isRequired(field))
                                        .withRequired(isDeprecated(field))
                                        .withDescription(descriptor.description(fieldName))
                                        .withDisplayName(descriptor.displayName(fieldName))
                                        .withDefaultValue(descriptor.defaultValue(fieldName))
                                        .withIsSecret(descriptor.isSecret(fieldName))
                                        .withOneOf("expression".equals(fieldName) ? "expression" : "")
                                        .build());
                    } else {
                        throw new UnsupportedOperationException(
                                "Unable to handle field: " + field.name() + " with type: " + field.type().name());
                    }
            }
        }

        cb.endControlFlow();

        return true;
    }