2 * @(#)MetaValidator.java $Rev: 4 $ $Release: 0.5.1 $
4 * copyright(c) 2005 kuwata-lab all rights reserved.
9 import org.onap.sdc.common.onaplog.OnapLoggerDebug;
10 import org.onap.sdc.common.onaplog.OnapLoggerError;
11 import org.onap.sdc.common.onaplog.Enums.LogLevel;
14 import java.util.List;
15 import java.util.Iterator;
16 import java.util.regex.Pattern;
17 import java.util.regex.Matcher;
18 import java.util.regex.PatternSyntaxException;
21 * meta validator to validate schema definition
24 * @release $Release: 0.5.1 $
26 public class MetaValidator extends Validator {
28 private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
29 private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
31 public static final String META_SCHEMA = ""
35 + "mapping: &main-rule\n"
78 + " pattern: /\\bval\\b/\n"
106 + " name: SEQUENCE\n"
110 + " mapping: *main-rule\n"
112 + " #required: yes\n"
119 + " mapping: *main-rule\n"
121 + " #required: yes\n"
129 * MetaValidator meta_validator = MetaValidator();
130 * Map schema = YamlUtil.loadFile("schema.yaml");
131 * List errors = meta_validator.validate(schema);
132 * if (errors != null && errors.size() > 0) {
133 * for (Iterator it = errors.iterator(); it.hasNext(); ) {
134 * ValidationException error = (ValidationException)it.next();
135 * System.err.println(" - [" + error.getPath() + "] " + error.getMessage());
141 private static Validator __instance;
143 public static Validator instance() {
144 synchronized (MetaValidator.class) {
145 if (__instance == null) {
147 Map schema = (Map) YamlUtil.load(META_SCHEMA);
148 __instance = new MetaValidator(schema);
149 } catch (SyntaxException ex) {
158 private MetaValidator(Map schema) {
162 public void postValidationHook(Object value, Rule rule, ValidationContext theContext) {
166 if (! "MAIN".equals(rule.getName())) {
170 assert value instanceof Map;
171 Map map = (Map)value;
172 String type = (String)map.get("type");
174 type = Types.getDefaultType();
176 //Class type_class = Types.typeClass(type);
177 //if (type_class == null) {
178 // theContext.addError(validationError("type.unknown", rule, path + "/type", type, null));
182 //if ((pattern = (String)map.get("pattern")) != null) {
183 if (map.containsKey("pattern")) {
184 String pattern = (String)map.get("pattern");
185 Matcher m = Util.matcher(pattern, "\\A\\/(.*)\\/([mi]?[mi]?)\\z");
186 String pat = m.find() ? m.group(1) : pattern;
188 Pattern.compile(pat);
189 } catch (PatternSyntaxException ex) {
190 theContext.addError("pattern.syntaxerr", rule, "pattern", pattern, null);
195 //if ((enum_list = (List)map.get("enum")) != null) {
196 if (map.containsKey("enum")) {
197 List enum_list = (List)map.get("enum");
198 if (Types.isCollectionType(type)) {
199 theContext.addError("enum.notscalar", rule, "enum:", (Object[])null);
201 for (Iterator it = enum_list.iterator(); it.hasNext(); ) {
202 Object elem = it.next();
203 if (! Types.isCorrectType(elem, type)) {
204 theContext.addError("enum.type.unmatch", rule, "enum", elem, new Object[] { Types.typeName(type) });
211 //if ((assert_str = (String)map.get("assert")) != null) {
212 if (map.containsKey("assert")) {
213 errLogger.log(LogLevel.ERROR, this.getClass().getName(), "*** warning: sorry, 'assert:' is not supported in current version of Kwalify-java.");
214 //String assert_str = (String)map.get("assert");
215 //if (! Util.matches(assert_str, "\\bval\\b")) {
216 // theContext.addError(validationError("assert.noval", rule, path + "/assert", assert_str, null);
219 // Expression.parse(assert_str);
220 //} catch (InvalidExpressionException ex) {
221 // theContext.addError(validationError("assert.syntaxerr", rule, path + "/assert", assert_str, null));
226 //if ((range = (Map)map.get("range")) != null) {
227 if (map.containsKey("range")) {
228 Map range = (Map)map.get("range");
229 //if (! (range instanceof Map)) {
230 // theContext.addError(validtionError("range.notmap", rule, path + "/range", range, null));
232 if (Types.isCollectionType(type) || type.equals("bool") || type.equals("any")) {
233 theContext.addError("range.notscalar", rule, "range:", null, null);
235 for (Iterator it = range.keySet().iterator(); it.hasNext(); ) {
236 String k = (String)it.next();
237 Object v = range.get(k);
238 if (! Types.isCorrectType(v, type)) {
239 theContext.addError("range.type.unmatch", rule, "range/" + k, v, new Object[] { Types.typeName(type) });
243 if (range.containsKey("max") && range.containsKey("max-ex")) {
244 theContext.addError("range.twomax", rule, "range", null, null);
246 if (range.containsKey("min") && range.containsKey("min-ex")) {
247 theContext.addError("range.twomin", rule, "range", null, null);
249 Object max = range.get("max");
250 Object min = range.get("min");
251 Object max_ex = range.get("max-ex");
252 Object min_ex = range.get("min-ex");
253 Object[] args = null;
254 //String error_symbol = null;
256 if (min != null && Util.compareValues(max, min) < 0) {
257 args = new Object[] { max, min };
258 theContext.addError("range.maxltmin", rule, "range", null, args);
259 } else if (min_ex != null && Util.compareValues(max, min_ex) <= 0) {
260 args = new Object[] { max, min_ex };
261 theContext.addError("range.maxleminex", rule, "range", null, args);
263 } else if (max_ex != null) {
264 if (min != null && Util.compareValues(max_ex, min) <= 0) {
265 args = new Object[] { max_ex, min };
266 theContext.addError("range.maxexlemin", rule, "range", null, args);
267 } else if (min_ex != null && Util.compareValues(max_ex, min_ex) <= 0) {
268 args = new Object[] { max_ex, min_ex };
269 theContext.addError("range.maxexleminex", rule, "range", null, args);
275 //if ((length = (Map)map.get("length")) != null) {
276 if (map.containsKey("length")) {
277 Map length = (Map)map.get("length");
278 //if (! (length instanceof Map)) {
279 // theContext.addError(validtionError("length.notmap", rule, path + "/length", length, null));
281 if (! (type.equals("str") || type.equals("text"))) {
282 theContext.addError("length.nottext", rule, "length:", (Object[])null);
284 //for (Iterator it = length.keySet().iterator(); it.hasNext(); ) {
285 // String k = (String)it.next();
286 // Object v = length.get(k);
287 // if (k == null || ! (k.equals("max") || k.equals("min") || k.equals("max-ex") || k.equals("min-ex"))) {
288 // theContext.addError(validationError("length.undefined", rule, path + "/length/" + k, "" + k + ":", null));
289 // } else if (! (v instanceof Integer)) {
290 // theContext.addError(validationError("length.notint", rule, path + "/length/" + k, v, null));
293 if (length.containsKey("max") && length.containsKey("max-ex")) {
294 theContext.addError("length.twomax", rule, "length", (Object[])null);
296 if (length.containsKey("min") && length.containsKey("min-ex")) {
297 theContext.addError("length.twomin", rule, "length", (Object[])null);
299 Integer max = (Integer)length.get("max");
300 Integer min = (Integer)length.get("min");
301 Integer max_ex = (Integer)length.get("max-ex");
302 Integer min_ex = (Integer)length.get("min-ex");
303 Object[] args = null;
304 //String error_symbol = null;
306 if (min != null && max.compareTo(min) < 0) {
307 args = new Object[] { max, min };
308 theContext.addError("length.maxltmin", rule, "length", null, args);
309 } else if (min_ex != null && max.compareTo(min_ex) <= 0) {
310 args = new Object[] { max, min_ex };
311 theContext.addError("length.maxleminex", rule, "length", null, args);
313 } else if (max_ex != null) {
314 if (min != null && max_ex.compareTo(min) <= 0) {
315 args = new Object[] { max_ex, min };
316 theContext.addError("length.maxexlemin", rule, "length", null, args);
317 } else if (min_ex != null && max_ex.compareTo(min_ex) <= 0) {
318 args = new Object[] { max_ex, min_ex };
319 theContext.addError("length.maxexleminex", rule, "length", null, args);
325 //if ((unique = (Boolean)map.get("unique")) != null) {
326 if (map.containsKey("unique")) {
327 Boolean unique = (Boolean)map.get("unique");
328 if (unique.booleanValue() == true && Types.isCollectionType(type)) {
329 theContext.addError("unique.notscalar", rule, "unique:", (Object[])null);
331 if (theContext.getPath().length() == 0) {
332 theContext.addError("unique.onroot", rule, "", "unique:", null);
337 //if ((ident = (Boolean)map.get("ident")) != null) {
338 if (map.containsKey("ident")) {
339 Boolean ident = (Boolean)map.get("ident");
340 if (ident.booleanValue() == true && Types.isCollectionType(type)) {
341 theContext.addError("ident.notscalar", rule, "ident:", (Object[])null);
343 if (theContext.getPath().length() == 0) {
344 theContext.addError("ident.onroot", rule, "/", "ident:", (Object[])null);
349 //if ((seq = (List)map.get("sequence")) != null) {
350 if (map.containsKey("sequence")) {
351 List seq = (List)map.get("sequence");
352 //if (! (seq instanceof List)) {
353 // theContext.addError(validationError("sequence.notseq", rule, path + "/sequence", seq, null));
355 if (seq == null || seq.size() == 0) {
356 theContext.addError("sequence.noelem", rule, "sequence", seq, null);
357 } else if (seq.size() > 1) {
358 theContext.addError("sequence.toomany", rule, "sequence", seq, null);
360 Object item = seq.get(0);
361 assert item instanceof Map;
363 Boolean ident2 = (Boolean)m.get("ident");
364 if (ident2 != null && ident2.booleanValue() == true && ! "map".equals(m.get("type"))) {
365 theContext.addError("ident.notmap", null, "sequence/0", "ident:", null);
371 //if ((mapping = (Map)map.get("mapping")) != null) {
372 if (map.containsKey("mapping")) {
373 Map mapping = (Map)map.get("mapping");
374 //if (mapping != null && ! (mapping instanceof Map)) {
375 // theContext.addError(validationError("mapping.notmap", rule, path + "/mapping", mapping, null));
377 Object default_value = null;
378 if (mapping != null && mapping instanceof Defaultable) {
379 default_value = ((Defaultable)mapping).getDefault();
381 if (mapping == null || (mapping.size() == 0 && default_value == null)) {
382 theContext.addError("mapping.noelem", rule, "mapping", mapping, null);
386 if (type.equals("seq")) {
387 if (! map.containsKey("sequence")) {
388 theContext.addError("seq.nosequence", rule, null, (Object[])null);
390 //if (map.containsKey("enum")) {
391 // theContext.addError(validationError("seq.conflict", rule, path, "enum:", null));
393 if (map.containsKey("pattern")) {
394 theContext.addError("seq.conflict", rule, "pattern:", (Object[])null);
396 if (map.containsKey("mapping")) {
397 theContext.addError("seq.conflict", rule, "mapping:", (Object[])null);
399 //if (map.containsKey("range")) {
400 // theContext.addError(validationError("seq.conflict", rule, path, "range:", null));
402 //if (map.containsKey("length")) {
403 // theContext.addError(validationError("seq.conflict", rule, path, "length:", null));
405 } else if (type.equals("map")) {
406 if (! map.containsKey("mapping")) {
407 theContext.addError("map.nomapping", rule, null, (Object[])null);
409 //if (map.containsKey("enum")) {
410 // theContext.addError(validationError("map.conflict", rule, path, "enum:", null));
412 if (map.containsKey("pattern")) {
413 theContext.addError("map.conflict", rule, "pattern:", (Object[])null);
415 if (map.containsKey("sequence")) {
416 theContext.addError("map.conflict", rule, "sequence:", (Object[])null);
418 //if (map.containsKey("range")) {
419 // theContext.addError(validationError("map.conflict", rule, path, "range:", null));
421 //if (map.containsKey("length")) {
422 // theContext.addError(validationError("map.conflict", rule, path, "length:", null));
425 if (map.containsKey("sequence")) {
426 theContext.addError("scalar.conflict", rule, "sequence:", (Object[])null);
428 if (map.containsKey("mapping")) {
429 theContext.addError("scalar.conflict", rule, "mapping:", (Object[])null);
431 if (map.containsKey("enum")) {
432 if (map.containsKey("range")) {
433 theContext.addError("enum.conflict", rule, "range:", (Object[])null);
435 if (map.containsKey("length")) {
436 theContext.addError("enum.conflict", rule, "length:", (Object[])null);
438 if (map.containsKey("pattern")) {
439 theContext.addError("enum.conflict", rule, "pattern:", (Object[])null);