1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.databind.testing.model;
7   
8   import static org.junit.jupiter.api.Assertions.assertAll;
9   import static org.junit.jupiter.api.Assertions.assertEquals;
10  import static org.junit.jupiter.api.Assertions.assertNull;
11  import static org.junit.jupiter.api.Assertions.assertTrue;
12  
13  import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
14  import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
15  import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
16  import gov.nist.secauto.metaschema.databind.IBindingContext;
17  import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly;
18  import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag;
19  import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelField;
20  import gov.nist.secauto.metaschema.databind.model.annotations.BoundField;
21  import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
22  import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
23  import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil;
24  
25  import java.lang.reflect.Field;
26  import java.util.Optional;
27  
28  import edu.umd.cs.findbugs.annotations.NonNull;
29  
30  @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
31  public abstract class ModelTestBase {
32    public static void assertAssemblyDefinition(
33        @NonNull Class<?> assemblyClass,
34        @NonNull IBoundDefinitionModelAssembly assembly) {
35      MetaschemaAssembly annotation = assemblyClass.getAnnotation(MetaschemaAssembly.class);
36  
37      assertAll(
38          "assembly failed",
39          () -> assertEquals(
40              annotation.name(),
41              assembly.getName(),
42              "rootName"),
43          () -> assertEquals(
44              annotation.moduleClass(),
45              assembly.getContainingModule().getClass(),
46              "moduleClass"),
47          () -> assertEquals(
48              ModelUtil.resolveNoneOrValue(annotation.formalName()),
49              assembly.getFormalName(),
50              "formalName"),
51          () -> assertEquals(
52              ModelUtil.resolveNoneOrValue(annotation.description()),
53              Optional.ofNullable(assembly.getDescription()).map(MarkupLine::toMarkdown).orElse(null),
54              "description"),
55          () -> assertEquals(
56              ModelUtil.resolveNoneOrValue(annotation.remarks()),
57              Optional.ofNullable(assembly.getRemarks()).map(MarkupMultiline::toMarkdown).orElse(null),
58              "remarks"),
59          () -> {
60            String rootName = ModelUtil.resolveNoneOrValue(annotation.rootName());
61            if (rootName != null) {
62              assertAll(
63                  () -> assertEquals(
64                      rootName,
65                      assembly.getRootName(),
66                      "rootName"),
67                  () -> assertEquals(
68                      assembly.getContainingModule().getXmlNamespace().toASCIIString(),
69                      assembly.getRootXmlQName().getNamespaceURI(),
70                      "rootNamespace"),
71                  () -> assertTrue(true));
72            } else {
73              assertEquals(
74                  null,
75                  assembly.getRootXmlQName(),
76                  "rootNamespace");
77            }
78          });
79    }
80  
81    public static void assertFlagInstance(
82        @NonNull Class<?> fieldOrAssemblyClass,
83        @NonNull String flagJavaFieldName,
84        @NonNull IBoundInstanceFlag flag,
85        @NonNull IBindingContext context) throws NoSuchFieldException, SecurityException {
86      Field field = fieldOrAssemblyClass.getDeclaredField(flagJavaFieldName);
87      BoundFlag annotation = field.getAnnotation(BoundFlag.class);
88  
89      IDataTypeAdapter<?> adapter = ModelUtil.getDataTypeAdapter(annotation.typeAdapter(), context);
90  
91      String name = Optional.ofNullable(ModelUtil.resolveNoneOrValue(annotation.name())).orElse(field.getName());
92  
93      assertAll(
94          flagJavaFieldName + " flag failed",
95          () -> assertEquals(
96              name,
97              flag.getName(),
98              "name"),
99          () -> assertNull(
100             flag.getUseName(),
101             "useNname"),
102         () -> assertEquals(
103             adapter,
104             flag.getDefinition().getJavaTypeAdapter(),
105             "typeAdapter"),
106         () -> assertEquals(
107             annotation.required(),
108             flag.isRequired(),
109             "required"),
110         () -> assertEquals(
111             ModelUtil.resolveDefaultValue(annotation.defaultValue(), adapter),
112             flag.getDefaultValue(),
113             "defaultValue"),
114         () -> assertEquals(
115             ModelUtil.resolveNoneOrValue(annotation.formalName()),
116             flag.getFormalName(),
117             "formalName"),
118         () -> assertEquals(
119             ModelUtil.resolveNoneOrValue(annotation.description()),
120             Optional.ofNullable(flag.getDescription()).map(MarkupLine::toMarkdown).orElse(null),
121             "description"),
122         () -> assertEquals(
123             ModelUtil.resolveNoneOrValue(annotation.remarks()),
124             Optional.ofNullable(flag.getRemarks()).map(MarkupMultiline::toMarkdown).orElse(null),
125             "remarks"));
126   }
127 
128   public static void assertFieldInstance(
129       @NonNull Class<?> assemblyClass,
130       @NonNull String fieldJavaFieldName,
131       @NonNull IBoundInstanceModelField<?> field,
132       @NonNull IBindingContext context) throws NoSuchFieldException, SecurityException {
133     Field javaField = assemblyClass.getDeclaredField(fieldJavaFieldName);
134     BoundField annotation = javaField.getAnnotation(BoundField.class);
135 
136     IDataTypeAdapter<?> adapter = ModelUtil.getDataTypeAdapter(annotation.typeAdapter(), context);
137 
138     String name;
139     String useName;
140     if (field.getDefinition().hasChildren()) {
141       name = field.getDefinition().getName();
142       useName = ModelUtil.resolveNoneOrValue(annotation.useName());
143     } else {
144       name = Optional.ofNullable(ModelUtil.resolveNoneOrValue(annotation.useName())).orElse(javaField.getName());
145       useName = null;
146     }
147 
148     assertAll(
149         fieldJavaFieldName + " field failed",
150         () -> assertEquals(
151             name,
152             field.getName(),
153             "name"),
154         () -> assertEquals(
155             useName,
156             field.getUseName(),
157             "useName"),
158         () -> assertEquals(
159             adapter,
160             field.getDefinition().getJavaTypeAdapter(),
161             "typeAdapter"),
162         () -> assertEquals(
163             ModelUtil.resolveDefaultValue(annotation.defaultValue(), adapter),
164             field.getDefaultValue(),
165             "defaultValue"),
166         () -> assertEquals(
167             field.getContainingModule().getXmlNamespace().toASCIIString(),
168             field.getXmlNamespace(),
169             "namespace"),
170         () -> assertEquals(
171             annotation.inXmlWrapped(),
172             field.isInXmlWrapped(),
173             "inXmlWrapped"),
174         () -> assertEquals(
175             annotation.minOccurs(),
176             field.getMinOccurs(),
177             "minOccurs"),
178         () -> assertEquals(
179             annotation.maxOccurs(),
180             field.getMaxOccurs(),
181             "maxOccurs"),
182         () -> assertEquals(
183             ModelUtil.resolveNoneOrValue(annotation.formalName()),
184             field.getFormalName(),
185             "formalName"),
186         () -> assertEquals(
187             ModelUtil.resolveNoneOrValue(annotation.description()),
188             Optional.ofNullable(field.getDescription()).map(MarkupLine::toMarkdown).orElse(null),
189             "description"),
190         () -> assertEquals(
191             ModelUtil.resolveNoneOrValue(annotation.remarks()),
192             Optional.ofNullable(field.getRemarks()).map(MarkupMultiline::toMarkdown).orElse(null),
193             "remarks"));
194     // groupAs
195   }
196 }