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.IMetapathExpression;
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 assert constraint != null;
93 if (!constraint.isAllowedOther()) {
94 closed = true;
95 }
96
97
98 if (!IMetapathExpression.contextNode().getPath().equals(constraint.getTarget().getPath())) {
99 values = CollectionUtil.emptyList();
100 break;
101 }
102
103 values.addAll(constraint.getAllowedValues().values());
104 }
105 return new AllowedValueCollection(closed, values);
106 }
107
108
109
110
111
112
113
114
115
116
117
118 private CharSequence getTypeContext(
119 @NonNull IDefinition definition,
120 @NonNull IModule childModule) {
121 StringBuilder builder = new StringBuilder();
122 if (definition.isInline()) {
123 INamedInstance inlineInstance = definition.getInlineInstance();
124 IDefinition parentDefinition = inlineInstance.getContainingDefinition();
125
126 builder
127 .append(getTypeContext(parentDefinition, childModule))
128 .append(IGenerationState.toCamelCase(inlineInstance.getEffectiveName()));
129 } else {
130 builder.append(IGenerationState.toCamelCase(definition.getName()));
131 }
132 return builder;
133 }
134
135 @Override
136 @NonNull
137 public String getTypeNameForDefinition(@NonNull IDefinition definition, @Nullable String suffix) {
138 StringBuilder builder = new StringBuilder()
139 .append(IGenerationState.toCamelCase(definition.getModelType().name()))
140 .append(IGenerationState.toCamelCase(definition.getContainingModule().getShortName()));
141
142 if (isInline(definition)) {
143 builder.append(IGenerationState.toCamelCase(definition.getEffectiveName()));
144 } else {
145
146 builder.append(getTypeContext(definition, definition.getContainingModule()));
147 }
148 if (suffix != null && !suffix.isBlank()) {
149 builder.append(suffix);
150 }
151 builder.append("Type");
152
153 return ObjectUtils.notNull(builder.toString());
154 }
155
156 public static class AllowedValueCollection {
157 private final boolean closed;
158 @NonNull
159 private final List<IAllowedValue> values;
160
161 public AllowedValueCollection(boolean closed, @NonNull List<IAllowedValue> values) {
162 this.closed = closed;
163 this.values = CollectionUtil.unmodifiableList(new ArrayList<>(values));
164 }
165
166 public boolean isClosed() {
167 return closed;
168 }
169
170 @NonNull
171 public List<IAllowedValue> getValues() {
172 return values;
173 }
174 }
175 }