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