1
2
3
4
5
6 package dev.metaschema.databind.codegen.typeinfo;
7
8 import com.squareup.javapoet.AnnotationSpec;
9 import com.squareup.javapoet.ClassName;
10 import com.squareup.javapoet.FieldSpec;
11 import com.squareup.javapoet.TypeName;
12 import com.squareup.javapoet.TypeSpec;
13
14 import java.util.Set;
15
16 import dev.metaschema.core.datatype.IDataTypeAdapter;
17 import dev.metaschema.core.datatype.markup.MarkupLine;
18 import dev.metaschema.core.datatype.markup.MarkupMultiline;
19 import dev.metaschema.core.model.IFieldDefinition;
20 import dev.metaschema.core.model.IFlagDefinition;
21 import dev.metaschema.core.model.IFlagInstance;
22 import dev.metaschema.core.model.IModelDefinition;
23 import dev.metaschema.core.util.CollectionUtil;
24 import dev.metaschema.core.util.ObjectUtils;
25 import dev.metaschema.databind.codegen.impl.AnnotationGenerator;
26 import dev.metaschema.databind.codegen.typeinfo.def.IDefinitionTypeInfo;
27 import dev.metaschema.databind.model.annotations.BoundFlag;
28 import dev.metaschema.databind.model.annotations.JsonFieldValueKeyFlag;
29 import dev.metaschema.databind.model.annotations.JsonKey;
30 import edu.umd.cs.findbugs.annotations.NonNull;
31
32 public class FlagInstanceTypeInfoImpl
33 extends AbstractInstanceTypeInfo<IFlagInstance, IDefinitionTypeInfo>
34 implements IFlagInstanceTypeInfo {
35
36
37
38
39
40
41
42
43
44 public FlagInstanceTypeInfoImpl(@NonNull IFlagInstance instance, @NonNull IDefinitionTypeInfo parentDefinition) {
45 super(instance, parentDefinition);
46 }
47
48 @Override
49 public String getBaseName() {
50 return getInstance().getEffectiveName();
51 }
52
53 @Override
54 public boolean isRequired() {
55 return getInstance().isRequired();
56 }
57
58 @Override
59 public TypeName getJavaFieldType() {
60 return ObjectUtils.notNull(ClassName.get(getInstance().getDefinition().getJavaTypeAdapter().getJavaClass()));
61 }
62
63 @Override
64 public Set<IModelDefinition> buildField(
65 TypeSpec.Builder typeBuilder,
66 FieldSpec.Builder fieldBuilder) {
67 super.buildField(typeBuilder, fieldBuilder);
68
69 IFlagInstance instance = getInstance();
70
71 fieldBuilder.addAnnotation(buildBoundFlagAnnotation(instance).build());
72
73 IModelDefinition parent = instance.getContainingDefinition();
74 IFlagInstance jsonKey = parent.getJsonKey();
75 if (instance.equals(jsonKey)) {
76 fieldBuilder.addAnnotation(JsonKey.class);
77 }
78
79 if (parent instanceof IFieldDefinition) {
80 IFieldDefinition parentField = (IFieldDefinition) parent;
81
82 if (parentField.hasJsonValueKeyFlagInstance() && instance.equals(parentField.getJsonValueKeyFlagInstance())) {
83 fieldBuilder.addAnnotation(JsonFieldValueKeyFlag.class);
84 }
85 }
86 return CollectionUtil.emptySet();
87 }
88
89 private static AnnotationSpec.Builder buildBoundFlagAnnotation(@NonNull IFlagInstance instance) {
90 AnnotationSpec.Builder annotation = AnnotationSpec.builder(BoundFlag.class);
91
92 String formalName = instance.getEffectiveFormalName();
93 if (formalName != null) {
94 annotation.addMember("formalName", "$S", formalName);
95 }
96
97 MarkupLine description = instance.getEffectiveDescription();
98 if (description != null) {
99 annotation.addMember("description", "$S", description.toMarkdown());
100 }
101
102 annotation.addMember("name", "$S", instance.getEffectiveName());
103
104 Integer index = instance.getEffectiveIndex();
105 if (index != null) {
106 annotation.addMember("useIndex", "$L", index);
107 }
108
109
110
111 IFlagDefinition definition = instance.getDefinition();
112
113 IDataTypeAdapter<?> valueDataType = definition.getJavaTypeAdapter();
114 Object defaultValue = instance.getEffectiveDefaultValue();
115 if (defaultValue != null) {
116 annotation.addMember("defaultValue", "$S", valueDataType.asString(defaultValue));
117 }
118
119 if (instance.isRequired()) {
120 annotation.addMember("required", "$L", true);
121 }
122 annotation.addMember("typeAdapter", "$T.class", valueDataType.getClass());
123
124 MarkupMultiline remarks = instance.getRemarks();
125 if (remarks != null) {
126 annotation.addMember("remarks", "$S", remarks.toMarkdown());
127 }
128
129 AnnotationGenerator.buildValueConstraints(annotation, definition);
130
131 return annotation;
132 }
133 }