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.ParameterizedTypeName;
12 import com.squareup.javapoet.TypeName;
13 import com.squareup.javapoet.TypeSpec;
14
15 import java.util.LinkedHashMap;
16 import java.util.LinkedHashSet;
17 import java.util.LinkedList;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21
22 import dev.metaschema.core.model.IGroupable;
23 import dev.metaschema.core.model.IModelDefinition;
24 import dev.metaschema.core.model.IModelInstanceAbsolute;
25 import dev.metaschema.core.model.JsonGroupAsBehavior;
26 import dev.metaschema.core.model.XmlGroupAsBehavior;
27 import dev.metaschema.core.util.ObjectUtils;
28 import dev.metaschema.databind.codegen.typeinfo.def.IAssemblyDefinitionTypeInfo;
29 import dev.metaschema.databind.model.annotations.GroupAs;
30 import edu.umd.cs.findbugs.annotations.NonNull;
31 import edu.umd.cs.findbugs.annotations.Nullable;
32
33 abstract class AbstractModelInstanceTypeInfo<INSTANCE extends IModelInstanceAbsolute>
34 extends AbstractInstanceTypeInfo<INSTANCE, IAssemblyDefinitionTypeInfo>
35 implements IModelInstanceTypeInfo {
36
37 protected AbstractModelInstanceTypeInfo(
38 @NonNull INSTANCE instance,
39 @NonNull IAssemblyDefinitionTypeInfo parentDefinition) {
40 super(instance, parentDefinition);
41 }
42
43 @Override
44 public String getBaseName() {
45 INSTANCE instance = getInstance();
46 String baseName = getInstance().getGroupAsName();
47 if (baseName == null) {
48 throw new IllegalStateException(String.format(
49 "Unable to derive the property name, due to missing group as name, for '%s' in the module '%s'.",
50 instance.toCoordinates(),
51 instance.getContainingModule().getLocation()));
52 }
53 return baseName;
54 }
55
56 @NonNull
57 @Override
58 public TypeName getJavaFieldType() {
59 TypeName item = getJavaItemType();
60
61 @NonNull
62 TypeName retval;
63 IModelInstanceAbsolute instance = getInstance();
64 int maxOccurance = instance.getMaxOccurs();
65 if (maxOccurance == -1 || maxOccurance > 1) {
66 if (JsonGroupAsBehavior.KEYED.equals(instance.getJsonGroupAsBehavior())) {
67 retval = ObjectUtils.notNull(
68 ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), item));
69 } else {
70 retval = ObjectUtils.notNull(ParameterizedTypeName.get(ClassName.get(List.class), item));
71 }
72 } else {
73 retval = item;
74 }
75
76 return retval;
77 }
78
79 @Override
80 public boolean isCollectionType() {
81 IModelInstanceAbsolute instance = getInstance();
82 int maxOccurs = instance.getMaxOccurs();
83 return maxOccurs == -1 || maxOccurs > 1;
84 }
85
86 @Nullable
87 @Override
88 public Class<?> getCollectionImplementationClass() {
89 IModelInstanceAbsolute instance = getInstance();
90 int maxOccurs = instance.getMaxOccurs();
91 if (maxOccurs == -1 || maxOccurs > 1) {
92
93 if (JsonGroupAsBehavior.KEYED.equals(instance.getJsonGroupAsBehavior())) {
94 return LinkedHashMap.class;
95 }
96 return LinkedList.class;
97 }
98
99 return null;
100 }
101
102 @NonNull
103 protected abstract AnnotationSpec.Builder newBindingAnnotation();
104
105 @Override
106 public Set<IModelDefinition> buildField(
107 TypeSpec.Builder typeBuilder,
108 FieldSpec.Builder fieldBuilder) {
109 Set<IModelDefinition> retval = new LinkedHashSet<>(super.buildField(typeBuilder, fieldBuilder));
110
111 AnnotationSpec.Builder annotation = newBindingAnnotation();
112
113 retval.addAll(buildBindingAnnotation(typeBuilder, fieldBuilder, annotation));
114
115 fieldBuilder.addAnnotation(annotation.build());
116
117 return retval;
118 }
119
120 @NonNull
121 protected AnnotationSpec.Builder generateGroupAsAnnotation() {
122 AnnotationSpec.Builder groupAsAnnoation = AnnotationSpec.builder(GroupAs.class);
123
124 IModelInstanceAbsolute modelInstance = getInstance();
125
126 groupAsAnnoation.addMember("name", "$S",
127 ObjectUtils.requireNonNull(modelInstance.getGroupAsName(), "The grouping name must be non-null"));
128
129
130
131 JsonGroupAsBehavior jsonGroupAsBehavior = modelInstance.getJsonGroupAsBehavior();
132 assert jsonGroupAsBehavior != null;
133 if (!IGroupable.DEFAULT_JSON_GROUP_AS_BEHAVIOR.equals(jsonGroupAsBehavior)) {
134 groupAsAnnoation.addMember("inJson", "$T.$L",
135 JsonGroupAsBehavior.class, jsonGroupAsBehavior.toString());
136 }
137
138 XmlGroupAsBehavior xmlGroupAsBehavior = modelInstance.getXmlGroupAsBehavior();
139 assert xmlGroupAsBehavior != null;
140 if (!IGroupable.DEFAULT_XML_GROUP_AS_BEHAVIOR.equals(xmlGroupAsBehavior)) {
141 groupAsAnnoation.addMember("inXml", "$T.$L",
142 XmlGroupAsBehavior.class, xmlGroupAsBehavior.toString());
143 }
144 return groupAsAnnoation;
145 }
146 }