From b7177d8e57bb470ce48837dad5bbc4b34eea10c9 Mon Sep 17 00:00:00 2001 From: jeromesimeon Date: Wed, 4 Aug 2021 09:52:59 -0400 Subject: [PATCH] feature(metamodel) Add support for validators (range and regex) Signed-off-by: jeromesimeon --- .../concerto-core/lib/introspect/metamodel.js | 64 ++++++++++ .../concerto-core/test/data/model/person.cto | 14 ++- .../concerto-core/test/data/model/person.json | 115 +++++++++++++++--- .../test/data/model/personResolved.json | 115 +++++++++++++++--- 4 files changed, 268 insertions(+), 40 deletions(-) diff --git a/packages/concerto-core/lib/introspect/metamodel.js b/packages/concerto-core/lib/introspect/metamodel.js index ba60150def..80a8eedb97 100644 --- a/packages/concerto-core/lib/introspect/metamodel.js +++ b/packages/concerto-core/lib/introspect/metamodel.js @@ -381,18 +381,54 @@ function fieldToMetaModel(ast) { if (ast.default) { field.defaultValue = parseInt(ast.default); } + if (ast.range) { + const validator = { + $class: 'concerto.metamodel.IntegerDomainValidator', + }; + if (ast.range.lower) { + validator.lower = parseInt(ast.range.lower); + } + if (ast.range.upper) { + validator.upper = parseInt(ast.range.upper); + } + field.validator = validator; + } break; case 'Long': field.$class = 'concerto.metamodel.LongFieldDeclaration'; if (ast.default) { field.defaultValue = parseInt(ast.default); } + if (ast.range) { + const validator = { + $class: 'concerto.metamodel.LongDomainValidator', + }; + if (ast.range.lower) { + validator.lower = parseInt(ast.range.lower); + } + if (ast.range.upper) { + validator.upper = parseInt(ast.range.upper); + } + field.validator = validator; + } break; case 'Double': field.$class = 'concerto.metamodel.DoubleFieldDeclaration'; if (ast.default) { field.defaultValue = parseFloat(ast.default); } + if (ast.range) { + const validator = { + $class: 'concerto.metamodel.DoubleDomainValidator', + }; + if (ast.range.lower) { + validator.lower = parseFloat(ast.range.lower); + } + if (ast.range.upper) { + validator.upper = parseFloat(ast.range.upper); + } + field.validator = validator; + } break; case 'Boolean': field.$class = 'concerto.metamodel.BooleanFieldDeclaration'; @@ -412,6 +448,12 @@ function fieldToMetaModel(ast) { if (ast.default) { field.defaultValue = ast.default; } + if (ast.regex) { + field.validator = { + $class: 'concerto.metamodel.StringRegexValidator', + regex: ast.regex + }; + } break; default: field.$class = 'concerto.metamodel.ObjectFieldDeclaration'; @@ -643,11 +685,14 @@ function modelFileToMetaModel(modelFile, validate) { function fieldFromMetaModel(mm) { let result = ''; let defaultString = ''; + let validatorString = ''; + if (mm.$class === 'concerto.metamodel.RelationshipDeclaration') { result += '-->'; } else { result += 'o'; } + switch (mm.$class) { case 'concerto.metamodel.EnumFieldDeclaration': break; @@ -671,24 +716,42 @@ function fieldFromMetaModel(mm) { defaultString += ` default=${doubleString}`; } + if (mm.validator) { + const lowerString = mm.validator.lower ? mm.validator.lower : ''; + const upperString = mm.validator.upper ? mm.validator.upper : ''; + validatorString += ` range=[${lowerString},${upperString}]`; + } break; case 'concerto.metamodel.IntegerFieldDeclaration': result += ' Integer'; if (mm.defaultValue) { defaultString += ` default=${mm.defaultValue.toString()}`; } + if (mm.validator) { + const lowerString = mm.validator.lower ? mm.validator.lower : ''; + const upperString = mm.validator.upper ? mm.validator.upper : ''; + validatorString += ` range=[${lowerString},${upperString}]`; + } break; case 'concerto.metamodel.LongFieldDeclaration': result += ' Long'; if (mm.defaultValue) { defaultString += ` default=${mm.defaultValue.toString()}`; } + if (mm.validator) { + const lowerString = mm.validator.lower ? mm.validator.lower : ''; + const upperString = mm.validator.upper ? mm.validator.upper : ''; + validatorString += ` range=[${lowerString},${upperString}]`; + } break; case 'concerto.metamodel.StringFieldDeclaration': result += ' String'; if (mm.defaultValue) { defaultString += ` default="${mm.defaultValue}"`; } + if (mm.validator) { + validatorString += ` regex=${mm.validator.regex}`; + } break; case 'concerto.metamodel.ObjectFieldDeclaration': result += ` ${mm.type.name}`; @@ -708,6 +771,7 @@ function fieldFromMetaModel(mm) { result += ' optional'; } result += defaultString; + result += validatorString; return result; } diff --git a/packages/concerto-core/test/data/model/person.cto b/packages/concerto-core/test/data/model/person.cto index e97a1adfb9..3a5ee5e069 100644 --- a/packages/concerto-core/test/data/model/person.cto +++ b/packages/concerto-core/test/data/model/person.cto @@ -29,7 +29,7 @@ abstract participant Individual { } participant Person extends Individual { - o String firstName + o String firstName regex=/[a-zA-Z]*/u o String lastName o Address address o Address address2 default="USAddress" @@ -57,9 +57,15 @@ concept Address identified { } concept USAddress extends Address { - o Integer zip4 - o Long zip5 - o Double zip6 + o Integer zip4 range=[-365,365] + o Integer zip41 range=[,365] + o Integer zip42 range=[-365,] + o Long zip5 range=[-365,365] + o Long zip51 range=[,365] + o Long zip52 range=[-365,] + o Double zip6 range=[-3.14,3.14] + o Double zip61 range=[-3.14,] + o Double zip62 range=[,3.14] } asset A { diff --git a/packages/concerto-core/test/data/model/person.json b/packages/concerto-core/test/data/model/person.json index 3977c7ded8..7b4082270c 100644 --- a/packages/concerto-core/test/data/model/person.json +++ b/packages/concerto-core/test/data/model/person.json @@ -17,6 +17,7 @@ "enumDeclarations": [ { "$class": "concerto.metamodel.EnumDeclaration", + "name": "Gender", "fields": [ { "$class": "concerto.metamodel.EnumFieldDeclaration", @@ -30,19 +31,19 @@ "$class": "concerto.metamodel.EnumFieldDeclaration", "name": "OTHER" } - ], - "name": "Gender" + ] } ], "classDeclarations": [ { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Individual", "isAbstract": true, - "fields": [], - "name": "Individual" + "fields": [] }, { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Person", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -51,6 +52,10 @@ "fields": [ { "$class": "concerto.metamodel.StringFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.StringRegexValidator", + "regex": "/[a-zA-Z]*/u" + }, "name": "firstName", "isArray": false, "isOptional": false @@ -128,11 +133,11 @@ "isArray": false, "isOptional": true } - ], - "name": "Person" + ] }, { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Employee", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -151,11 +156,11 @@ "isArray": false, "isOptional": false } - ], - "name": "Employee" + ] }, { "$class": "concerto.metamodel.ConceptDeclaration", + "name": "Address", "isAbstract": false, "identified": { "$class": "concerto.metamodel.Identified" @@ -216,11 +221,11 @@ "isArray": false, "isOptional": false } - ], - "name": "Address" + ] }, { "$class": "concerto.metamodel.ConceptDeclaration", + "name": "USAddress", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -229,39 +234,114 @@ "fields": [ { "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "lower": -365, + "upper": 365 + }, "name": "zip4", "isArray": false, "isOptional": false }, + { + "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "upper": 365 + }, + "name": "zip41", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "lower": -365 + }, + "name": "zip42", + "isArray": false, + "isOptional": false + }, { "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "lower": -365, + "upper": 365 + }, "name": "zip5", "isArray": false, "isOptional": false }, + { + "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "upper": 365 + }, + "name": "zip51", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "lower": -365 + }, + "name": "zip52", + "isArray": false, + "isOptional": false + }, { "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "lower": -3.14, + "upper": 3.14 + }, "name": "zip6", "isArray": false, "isOptional": false + }, + { + "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "lower": -3.14 + }, + "name": "zip61", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "upper": 3.14 + }, + "name": "zip62", + "isArray": false, + "isOptional": false } - ], - "name": "USAddress" + ] }, { "$class": "concerto.metamodel.AssetDeclaration", + "name": "A", "isAbstract": false, - "fields": [], - "name": "A" + "fields": [] }, { "$class": "concerto.metamodel.EventDeclaration", + "name": "E", "isAbstract": false, - "fields": [], - "name": "E" + "fields": [] }, { "$class": "concerto.metamodel.TransactionDeclaration", + "name": "T", "isAbstract": false, "identified": { "$class": "concerto.metamodel.IdentifiedBy", @@ -294,8 +374,7 @@ "isArray": false, "isOptional": false } - ], - "name": "T" + ] } ] } diff --git a/packages/concerto-core/test/data/model/personResolved.json b/packages/concerto-core/test/data/model/personResolved.json index 6bfb937823..40d561c928 100644 --- a/packages/concerto-core/test/data/model/personResolved.json +++ b/packages/concerto-core/test/data/model/personResolved.json @@ -17,6 +17,7 @@ "enumDeclarations": [ { "$class": "concerto.metamodel.EnumDeclaration", + "name": "Gender", "fields": [ { "$class": "concerto.metamodel.EnumFieldDeclaration", @@ -30,19 +31,19 @@ "$class": "concerto.metamodel.EnumFieldDeclaration", "name": "OTHER" } - ], - "name": "Gender" + ] } ], "classDeclarations": [ { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Individual", "isAbstract": true, - "fields": [], - "name": "Individual" + "fields": [] }, { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Person", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -52,6 +53,10 @@ "fields": [ { "$class": "concerto.metamodel.StringFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.StringRegexValidator", + "regex": "/[a-zA-Z]*/u" + }, "name": "firstName", "isArray": false, "isOptional": false @@ -135,11 +140,11 @@ "isArray": false, "isOptional": true } - ], - "name": "Person" + ] }, { "$class": "concerto.metamodel.ParticipantDeclaration", + "name": "Employee", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -159,11 +164,11 @@ "isArray": false, "isOptional": false } - ], - "name": "Employee" + ] }, { "$class": "concerto.metamodel.ConceptDeclaration", + "name": "Address", "isAbstract": false, "identified": { "$class": "concerto.metamodel.Identified" @@ -224,11 +229,11 @@ "isArray": false, "isOptional": false } - ], - "name": "Address" + ] }, { "$class": "concerto.metamodel.ConceptDeclaration", + "name": "USAddress", "isAbstract": false, "superType": { "$class": "concerto.metamodel.TypeIdentifier", @@ -238,39 +243,114 @@ "fields": [ { "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "lower": -365, + "upper": 365 + }, "name": "zip4", "isArray": false, "isOptional": false }, + { + "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "upper": 365 + }, + "name": "zip41", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.IntegerFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.IntegerDomainValidator", + "lower": -365 + }, + "name": "zip42", + "isArray": false, + "isOptional": false + }, { "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "lower": -365, + "upper": 365 + }, "name": "zip5", "isArray": false, "isOptional": false }, + { + "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "upper": 365 + }, + "name": "zip51", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.LongFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.LongDomainValidator", + "lower": -365 + }, + "name": "zip52", + "isArray": false, + "isOptional": false + }, { "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "lower": -3.14, + "upper": 3.14 + }, "name": "zip6", "isArray": false, "isOptional": false + }, + { + "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "lower": -3.14 + }, + "name": "zip61", + "isArray": false, + "isOptional": false + }, + { + "$class": "concerto.metamodel.DoubleFieldDeclaration", + "validator": { + "$class": "concerto.metamodel.DoubleDomainValidator", + "upper": 3.14 + }, + "name": "zip62", + "isArray": false, + "isOptional": false } - ], - "name": "USAddress" + ] }, { "$class": "concerto.metamodel.AssetDeclaration", + "name": "A", "isAbstract": false, - "fields": [], - "name": "A" + "fields": [] }, { "$class": "concerto.metamodel.EventDeclaration", + "name": "E", "isAbstract": false, - "fields": [], - "name": "E" + "fields": [] }, { "$class": "concerto.metamodel.TransactionDeclaration", + "name": "T", "isAbstract": false, "identified": { "$class": "concerto.metamodel.IdentifiedBy", @@ -305,8 +385,7 @@ "isArray": false, "isOptional": false } - ], - "name": "T" + ] } ] }