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