|
7 | 7 | package com.metaobjects.field; |
8 | 8 |
|
9 | 9 | import com.metaobjects.DataTypes; |
10 | | -import com.metaobjects.MetaData; |
11 | | -import com.metaobjects.MetaDataException; |
12 | | -import com.metaobjects.attr.MetaAttribute; |
13 | 10 | import com.metaobjects.attr.StringAttribute; |
14 | 11 | import com.metaobjects.registry.MetaDataRegistry; |
15 | | -import com.metaobjects.util.ErrorMessageConstants; |
16 | 12 | import org.slf4j.Logger; |
17 | 13 | import org.slf4j.LoggerFactory; |
18 | 14 |
|
|
32 | 28 | * member must match {@code ^[A-Za-z_][A-Za-z0-9_]*$}. These constraints mirror the |
33 | 29 | * cross-language validation contract shared with TS and C# (conformance error code |
34 | 30 | * {@code ERR_BAD_ATTR_VALUE}). The static {@link #validateEnumValues(Object)} method |
35 | | - * enforces this contract; call it after loading to validate the content. A |
36 | | - * load-time-enforcement hook is deferred (see the comment in |
37 | | - * {@link #registerTypes(MetaDataRegistry)}).</p> |
| 31 | + * is the lower-level content helper; the loader's |
| 32 | + * {@link com.metaobjects.loader.ValidationPhase} invokes it in a post-load pass to |
| 33 | + * enforce this contract.</p> |
38 | 34 | * |
39 | 35 | * @version 6.0 |
40 | 36 | */ |
@@ -81,10 +77,11 @@ public EnumField(String name) { |
81 | 77 | * {@code attr.stringarray} type was removed; the pattern mirrors {@code identity.primary |
82 | 78 | * @fields}). Per-element content validation (non-empty, identifier-safe members, |
83 | 79 | * no duplicates — equivalent to cross-language {@code ERR_BAD_ATTR_VALUE}) is |
84 | | - * available via the static {@link #validateEnumValues(Object)} method. Wiring it |
85 | | - * as a load-time constraint is deferred because the constraint enforcer fires at |
86 | | - * node-creation time (before {@code @values} is parsed), so enforcement would |
87 | | - * require a dedicated post-parse validation pass.</p> |
| 80 | + * available via the static {@link #validateEnumValues(Object)} method. It is not |
| 81 | + * wired as a node-creation constraint because the constraint enforcer fires before |
| 82 | + * {@code @values} is parsed; instead the loader's |
| 83 | + * {@link com.metaobjects.loader.ValidationPhase} runs it as a dedicated post-load |
| 84 | + * validation pass.</p> |
88 | 85 | * |
89 | 86 | * @param registry The MetaDataRegistry to register with |
90 | 87 | */ |
@@ -113,78 +110,6 @@ public static void registerTypes(MetaDataRegistry registry) { |
113 | 110 | } |
114 | 111 | } |
115 | 112 |
|
116 | | - // ----------------------------------------------------------------------- |
117 | | - // Post-parse validation hook — called by CanonicalJsonParser after the |
118 | | - // full field.enum node (attributes + children) has been built. |
119 | | - // ----------------------------------------------------------------------- |
120 | | - |
121 | | - /** |
122 | | - * Post-parse validation for a freshly-built {@code field.enum} node. |
123 | | - * |
124 | | - * <p>Enforces the cross-language {@code @values} contract at load time:</p> |
125 | | - * <ol> |
126 | | - * <li>Missing {@code @values} → throws with {@code ERR_MISSING_REQUIRED_ATTR}</li> |
127 | | - * <li>Empty / non-identifier member / duplicate → throws with {@code ERR_BAD_ATTR_VALUE}</li> |
128 | | - * </ol> |
129 | | - * |
130 | | - * <p>Called from {@code CanonicalJsonParser.processNode()} after the node's |
131 | | - * attributes and children have been processed, so {@code @values} is already |
132 | | - * set on the node. Mirrors the TS and C# loader validation that fires at the |
133 | | - * equivalent point in those pipelines.</p> |
134 | | - * |
135 | | - * @param enumNode the {@code field.enum} node to validate; ignored if not |
136 | | - * type=field / subtype=enum |
137 | | - * @param filename the source filename — included in error messages |
138 | | - * @throws MetaDataException with code {@code ERR_MISSING_REQUIRED_ATTR} if |
139 | | - * {@code @values} is absent, or {@code ERR_BAD_ATTR_VALUE} if the |
140 | | - * members fail the identifier / uniqueness contract |
141 | | - */ |
142 | | - public static void validateNodeAfterParse(MetaData enumNode, String filename) { |
143 | | - if (enumNode == null) return; |
144 | | - if (!TYPE_FIELD.equals(enumNode.getType()) || !SUBTYPE_ENUM.equals(enumNode.getSubType())) return; |
145 | | - |
146 | | - // --- Content check (own @values only) --- |
147 | | - // Validate OWN @values regardless of whether the node is abstract or concrete. |
148 | | - // A node that merely inherits @values from a super has nothing to content-validate here. |
149 | | - // This matches the TS (attr-schema-validate.ts) and C# (ValidationPasses.ValidateEnumValues) |
150 | | - // own-only contracts. |
151 | | - if (enumNode.hasMetaAttr(ATTR_VALUES, false)) { |
152 | | - MetaAttribute<?> valuesAttr; |
153 | | - try { |
154 | | - @SuppressWarnings("unchecked") |
155 | | - MetaAttribute<?> attr = (MetaAttribute<?>) enumNode.getMetaAttr(ATTR_VALUES, false); |
156 | | - valuesAttr = attr; |
157 | | - } catch (Exception e) { |
158 | | - // hasMetaAttr(false) returned true above, so this should not occur in practice. |
159 | | - throw new MetaDataException( |
160 | | - ErrorMessageConstants.ERR_MISSING_REQUIRED_ATTR + ": field.enum '" + enumNode.getName() |
161 | | - + "' could not read own @values attribute in file [" + filename + "]", e); |
162 | | - } |
163 | | - if (!validateEnumValues(valuesAttr.getValue())) { |
164 | | - throw new MetaDataException( |
165 | | - ErrorMessageConstants.ERR_BAD_ATTR_VALUE + ": field.enum '" + enumNode.getName() |
166 | | - + "' @values must be a non-empty list of identifier-safe, unique members" |
167 | | - + " (e.g. [\"DRAFT\",\"PUBLISHED\"]) in file [" + filename + "]"); |
168 | | - } |
169 | | - // Own @values present and valid — no need for the required check below. |
170 | | - return; |
171 | | - } |
172 | | - |
173 | | - // --- Required check --- |
174 | | - // The node has no own @values. It is valid ONLY if it has a super reference |
175 | | - // (inheriting @values from the super, which is validated on its own node). |
176 | | - // getSuperData() is non-null iff an "extends" was given AND the super was found |
177 | | - // (if extends was given but not found, BaseMetaDataParser already threw). |
178 | | - // This check is therefore load-order-independent — no dependency on getSuperData() |
179 | | - // resolution state beyond the guarantee that createOrOverlayMetaData provides. |
180 | | - if (enumNode.getSuperData() == null) { |
181 | | - throw new MetaDataException( |
182 | | - ErrorMessageConstants.ERR_MISSING_REQUIRED_ATTR + ": field.enum '" + enumNode.getName() |
183 | | - + "' is missing required @values attribute in file [" + filename + "]"); |
184 | | - } |
185 | | - // Has a super — inherits @values from the super, which is validated on its own node. OK. |
186 | | - } |
187 | | - |
188 | 113 | // ----------------------------------------------------------------------- |
189 | 114 | // @values validation — cross-language contract |
190 | 115 | // ----------------------------------------------------------------------- |
|
0 commit comments