1
2
3
4
5
6 package gov.nist.secauto.metaschema.schemagen;
7
8 import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
9 import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
10 import gov.nist.secauto.metaschema.core.model.IDefinition;
11 import gov.nist.secauto.metaschema.core.model.IModule;
12 import gov.nist.secauto.metaschema.core.model.INamedInstance;
13 import gov.nist.secauto.metaschema.core.model.IValuedDefinition;
14 import gov.nist.secauto.metaschema.core.model.constraint.IAllowedValue;
15 import gov.nist.secauto.metaschema.core.model.constraint.IAllowedValuesConstraint;
16 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
17 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
18 import gov.nist.secauto.metaschema.schemagen.datatype.IDatatypeManager;
19
20 import java.util.ArrayList;
21 import java.util.LinkedList;
22 import java.util.List;
23
24 import edu.umd.cs.findbugs.annotations.NonNull;
25 import edu.umd.cs.findbugs.annotations.Nullable;
26
27 public abstract class AbstractGenerationState<WRITER, DATATYPE_MANAGER extends IDatatypeManager>
28 implements IGenerationState<WRITER> {
29 @NonNull
30 private final IModule module;
31 @NonNull
32 private final WRITER writer;
33 @NonNull
34 private final DATATYPE_MANAGER datatypeManager;
35 @NonNull
36 private final IInlineStrategy inlineStrategy;
37
38 @NonNull
39 private final ModuleIndex moduleIndex;
40
41 public AbstractGenerationState(
42 @NonNull IModule module,
43 @NonNull WRITER writer,
44 @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration,
45 @NonNull DATATYPE_MANAGER datatypeManager) {
46 this.module = module;
47 this.writer = writer;
48 this.datatypeManager = datatypeManager;
49 this.inlineStrategy = IInlineStrategy.newInlineStrategy(configuration);
50 this.moduleIndex = ModuleIndex.indexDefinitions(module, this.inlineStrategy);
51 }
52
53 @Override
54 public IModule getModule() {
55 return module;
56 }
57
58 @Override
59 public WRITER getWriter() {
60 return writer;
61 }
62
63 @NonNull
64 protected DATATYPE_MANAGER getDatatypeManager() {
65 return datatypeManager;
66 }
67
68 @NonNull
69 public ModuleIndex getMetaschemaIndex() {
70 return moduleIndex;
71 }
72
73 @Override
74 public boolean isInline(@NonNull IDefinition definition) {
75 return inlineStrategy.isInline(definition, getMetaschemaIndex());
76 }
77
78
79
80
81
82
83
84
85
86 @NonNull
87 protected static AllowedValueCollection getContextIndependentEnumeratedValues(
88 @NonNull IValuedDefinition definition) {
89 List<IAllowedValue> values = new LinkedList<>();
90 boolean closed = false;
91 for (IAllowedValuesConstraint constraint : definition.getAllowedValuesConstraints()) {
92 if (!constraint.isAllowedOther()) {
93 closed = true;
94 }
95
96 if (!MetapathExpression.CONTEXT_NODE.getPath().equals(constraint.getTarget())) {
97 values = CollectionUtil.emptyList();
98 break;
99 }
100
101 values.addAll(constraint.getAllowedValues().values());
102 }
103 return new AllowedValueCollection(closed, values);
104 }
105
106
107
108
109
110
111
112
113
114
115
116 private CharSequence getTypeContext(
117 @NonNull IDefinition definition,
118 @NonNull IModule childModule) {
119 StringBuilder builder = new StringBuilder();
120 if (definition.isInline()) {
121 INamedInstance inlineInstance = definition.getInlineInstance();
122 IDefinition parentDefinition = inlineInstance.getContainingDefinition();
123
124 builder
125 .append(getTypeContext(parentDefinition, childModule))
126 .append(IGenerationState.toCamelCase(inlineInstance.getEffectiveName()));
127 } else {
128 builder.append(IGenerationState.toCamelCase(definition.getName()));
129 }
130 return builder;
131 }
132
133 @Override
134 @NonNull
135 public String getTypeNameForDefinition(@NonNull IDefinition definition, @Nullable String suffix) {
136 StringBuilder builder = new StringBuilder()
137 .append(IGenerationState.toCamelCase(definition.getModelType().name()))
138 .append(IGenerationState.toCamelCase(definition.getContainingModule().getShortName()));
139
140 if (isInline(definition)) {
141 builder.append(IGenerationState.toCamelCase(definition.getEffectiveName()));
142 } else {
143
144 builder.append(getTypeContext(definition, definition.getContainingModule()));
145 }
146 if (suffix != null && !suffix.isBlank()) {
147 builder.append(suffix);
148 }
149 builder.append("Type");
150
151 return ObjectUtils.notNull(builder.toString());
152 }
153
154 public static class AllowedValueCollection {
155 private final boolean closed;
156 @NonNull
157 private final List<IAllowedValue> values;
158
159 public AllowedValueCollection(boolean closed, @NonNull List<IAllowedValue> values) {
160 this.closed = closed;
161 this.values = CollectionUtil.unmodifiableList(new ArrayList<>(values));
162 }
163
164 public boolean isClosed() {
165 return closed;
166 }
167
168 @NonNull
169 public List<IAllowedValue> getValues() {
170 return values;
171 }
172 }
173 }