@accordproject/concerto-core 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.txt +1 -1
- package/dist/concerto-core.js +1 -1
- package/dist/concerto-core.js.LICENSE.txt +1 -1
- package/lib/introspect/classdeclaration.js +6 -1
- package/lib/introspect/field.js +91 -10
- package/lib/introspect/introspector.js +5 -1
- package/lib/introspect/modelfile.js +30 -6
- package/lib/introspect/numbervalidator.js +2 -1
- package/lib/introspect/property.js +22 -14
- package/lib/introspect/scalardeclaration.js +341 -0
- package/lib/introspect/stringvalidator.js +2 -1
- package/lib/introspect/validator.js +6 -6
- package/lib/model/typed.js +25 -20
- package/lib/modelutil.js +12 -0
- package/lib/serializer/instancegenerator.js +15 -11
- package/lib/serializer/jsongenerator.js +2 -0
- package/lib/serializer/jsonpopulator.js +3 -2
- package/lib/serializer/objectvalidator.js +2 -0
- package/lib/serializer/resourcevalidator.js +2 -0
- package/package.json +9 -7
- package/types/lib/introspect/field.d.ts +15 -2
- package/types/lib/introspect/modelfile.d.ts +8 -2
- package/types/lib/introspect/scalardeclaration.d.ts +162 -0
- package/types/lib/introspect/validator.d.ts +6 -7
- package/types/lib/modelutil.d.ts +7 -0
|
@@ -239,7 +239,12 @@ class ClassDeclaration extends Decorated {
|
|
|
239
239
|
}), this.modelFile, this.ast.location);
|
|
240
240
|
} else {
|
|
241
241
|
// check that identifiers are strings
|
|
242
|
-
|
|
242
|
+
const isPrimitiveString = idField.getType() === 'String';
|
|
243
|
+
const modelFile = idField.getParent().getModelFile();
|
|
244
|
+
const declaration = modelFile.getType(idField.getType());
|
|
245
|
+
const isScalarString = declaration !== null && declaration.isScalarDeclaration?.() && declaration.getType?.() === 'String';
|
|
246
|
+
|
|
247
|
+
if (!isPrimitiveString && !isScalarString) {
|
|
243
248
|
let formatter = Globalize('en').messageFormatter('classdeclaration-validate-identifiernotstring');
|
|
244
249
|
throw new IllegalModelException(formatter({
|
|
245
250
|
'class': this.name,
|
package/lib/introspect/field.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
const { MetaModelNamespace } = require('@accordproject/concerto-metamodel');
|
|
18
|
+
|
|
17
19
|
const Property = require('./property');
|
|
18
20
|
const NumberValidator = require('./numbervalidator');
|
|
19
21
|
const StringValidator = require('./stringvalidator');
|
|
@@ -46,6 +48,7 @@ class Field extends Property {
|
|
|
46
48
|
*/
|
|
47
49
|
constructor(parent, ast) {
|
|
48
50
|
super(parent, ast);
|
|
51
|
+
this.scalarField = null; // cache scalar field
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
/**
|
|
@@ -58,22 +61,28 @@ class Field extends Property {
|
|
|
58
61
|
|
|
59
62
|
this.validator = null;
|
|
60
63
|
|
|
61
|
-
switch(this.getType()) {
|
|
64
|
+
switch (this.getType()) {
|
|
62
65
|
case 'Integer':
|
|
63
66
|
case 'Double':
|
|
64
67
|
case 'Long':
|
|
65
|
-
if(this.ast.validator) {
|
|
66
|
-
this.validator = new NumberValidator(
|
|
68
|
+
if (this.ast.validator) {
|
|
69
|
+
this.validator = new NumberValidator(
|
|
70
|
+
this,
|
|
71
|
+
this.ast.validator
|
|
72
|
+
);
|
|
67
73
|
}
|
|
68
74
|
break;
|
|
69
75
|
case 'String':
|
|
70
|
-
if(this.ast.validator) {
|
|
71
|
-
this.validator = new StringValidator(
|
|
76
|
+
if (this.ast.validator) {
|
|
77
|
+
this.validator = new StringValidator(
|
|
78
|
+
this,
|
|
79
|
+
this.ast.validator
|
|
80
|
+
);
|
|
72
81
|
}
|
|
73
82
|
break;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
if(this.ast.defaultValue) {
|
|
85
|
+
if (this.ast.defaultValue) {
|
|
77
86
|
this.defaultValue = this.ast.defaultValue;
|
|
78
87
|
} else {
|
|
79
88
|
this.defaultValue = null;
|
|
@@ -93,10 +102,9 @@ class Field extends Property {
|
|
|
93
102
|
* @return {string | number} the default value for the field or null
|
|
94
103
|
*/
|
|
95
104
|
getDefaultValue() {
|
|
96
|
-
if(this.defaultValue) {
|
|
105
|
+
if (this.defaultValue) {
|
|
97
106
|
return this.defaultValue;
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
107
|
+
} else {
|
|
100
108
|
return null;
|
|
101
109
|
}
|
|
102
110
|
}
|
|
@@ -106,7 +114,17 @@ class Field extends Property {
|
|
|
106
114
|
* @return {String} the string version of the property.
|
|
107
115
|
*/
|
|
108
116
|
toString() {
|
|
109
|
-
return
|
|
117
|
+
return (
|
|
118
|
+
'Field {name=' +
|
|
119
|
+
this.name +
|
|
120
|
+
', type=' +
|
|
121
|
+
this.getFullyQualifiedTypeName() +
|
|
122
|
+
', array=' +
|
|
123
|
+
this.array +
|
|
124
|
+
', optional=' +
|
|
125
|
+
this.optional +
|
|
126
|
+
'}'
|
|
127
|
+
);
|
|
110
128
|
}
|
|
111
129
|
|
|
112
130
|
/**
|
|
@@ -117,6 +135,69 @@ class Field extends Property {
|
|
|
117
135
|
isField() {
|
|
118
136
|
return true;
|
|
119
137
|
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Returns true if the field's type is a scalar
|
|
141
|
+
* @returns {boolean} true if the field is a scalar type
|
|
142
|
+
*/
|
|
143
|
+
isTypeScalar() {
|
|
144
|
+
if (this.isPrimitive()) {
|
|
145
|
+
return false;
|
|
146
|
+
} else {
|
|
147
|
+
const type = this.getParent()
|
|
148
|
+
.getModelFile()
|
|
149
|
+
.getType(this.getType());
|
|
150
|
+
return type.isScalarDeclaration?.();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Unboxes a field that references a scalar type to an
|
|
156
|
+
* underlying Field definition.
|
|
157
|
+
* @throws {Error} throws an error if this field is not a scalar type.
|
|
158
|
+
* @returns {Field} the primitive field for this scalar
|
|
159
|
+
*/
|
|
160
|
+
getScalarField() {
|
|
161
|
+
if(this.scalarField) {
|
|
162
|
+
return this.scalarField;
|
|
163
|
+
}
|
|
164
|
+
if (!this.isTypeScalar()) {
|
|
165
|
+
throw new Error(`Field ${this.name} is not a scalar property.`);
|
|
166
|
+
}
|
|
167
|
+
const type = this.getParent().getModelFile().getType(this.getType());
|
|
168
|
+
const fieldAst = JSON.parse(JSON.stringify(type.ast));
|
|
169
|
+
|
|
170
|
+
switch (type.ast.$class) {
|
|
171
|
+
case `${MetaModelNamespace}.StringScalar`:
|
|
172
|
+
fieldAst.$class = `${MetaModelNamespace}.StringProperty`;
|
|
173
|
+
break;
|
|
174
|
+
case `${MetaModelNamespace}.BooleanScalar`:
|
|
175
|
+
fieldAst.$class = `${MetaModelNamespace}.BooleanProperty`;
|
|
176
|
+
break;
|
|
177
|
+
|
|
178
|
+
case `${MetaModelNamespace}.DateTimeScalar`:
|
|
179
|
+
fieldAst.$class = `${MetaModelNamespace}.DateTimeProperty`;
|
|
180
|
+
break;
|
|
181
|
+
|
|
182
|
+
case `${MetaModelNamespace}.DoubleScalar`:
|
|
183
|
+
fieldAst.$class = `${MetaModelNamespace}.DoubleProperty`;
|
|
184
|
+
break;
|
|
185
|
+
|
|
186
|
+
case `${MetaModelNamespace}.IntegerScalar`:
|
|
187
|
+
fieldAst.$class = `${MetaModelNamespace}.IntegerProperty`;
|
|
188
|
+
break;
|
|
189
|
+
|
|
190
|
+
case `${MetaModelNamespace}.LongScalar`:
|
|
191
|
+
fieldAst.$class = `${MetaModelNamespace}.LongProperty`;
|
|
192
|
+
break;
|
|
193
|
+
default:
|
|
194
|
+
throw new Error(`Unrecognized scalar type ${type.ast.$class}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
fieldAst.name = this.ast.name;
|
|
198
|
+
this.scalarField = new Field(this.getParent(), fieldAst);
|
|
199
|
+
return this.scalarField;
|
|
200
|
+
}
|
|
120
201
|
}
|
|
121
202
|
|
|
122
203
|
module.exports = Field;
|
|
@@ -59,7 +59,11 @@ class Introspector {
|
|
|
59
59
|
const modelFiles = this.modelManager.getModelFiles();
|
|
60
60
|
for(let n=0; n < modelFiles.length; n++) {
|
|
61
61
|
const modelFile = modelFiles[n];
|
|
62
|
-
result = result.concat(
|
|
62
|
+
result = result.concat(
|
|
63
|
+
modelFile.getAllDeclarations()
|
|
64
|
+
.filter(declaration => !declaration.isScalarDeclaration?.()
|
|
65
|
+
)
|
|
66
|
+
);
|
|
63
67
|
}
|
|
64
68
|
return result;
|
|
65
69
|
}
|
|
@@ -21,6 +21,7 @@ const semver = require('semver');
|
|
|
21
21
|
const AssetDeclaration = require('./assetdeclaration');
|
|
22
22
|
const EnumDeclaration = require('./enumdeclaration');
|
|
23
23
|
const ConceptDeclaration = require('./conceptdeclaration');
|
|
24
|
+
const ScalarDeclaration = require('./scalardeclaration');
|
|
24
25
|
const ParticipantDeclaration = require('./participantdeclaration');
|
|
25
26
|
const TransactionDeclaration = require('./transactiondeclaration');
|
|
26
27
|
const EventDeclaration = require('./eventdeclaration');
|
|
@@ -61,7 +62,7 @@ class ModelFile extends Decorated {
|
|
|
61
62
|
this.modelManager = modelManager;
|
|
62
63
|
this.external = false;
|
|
63
64
|
this.declarations = [];
|
|
64
|
-
this.localTypes =
|
|
65
|
+
this.localTypes = null;
|
|
65
66
|
this.imports = [];
|
|
66
67
|
this.importShortNames = new Map();
|
|
67
68
|
this.importWildcardNamespaces = [];
|
|
@@ -92,13 +93,13 @@ class ModelFile extends Decorated {
|
|
|
92
93
|
|
|
93
94
|
// Set up the decorators.
|
|
94
95
|
this.process();
|
|
95
|
-
|
|
96
96
|
// Populate from the AST
|
|
97
97
|
this.fromAst(this.ast);
|
|
98
98
|
// Check version compatibility
|
|
99
99
|
this.isCompatibleVersion();
|
|
100
100
|
|
|
101
101
|
// Now build local types from Declarations
|
|
102
|
+
this.localTypes = new Map();
|
|
102
103
|
for(let index in this.declarations) {
|
|
103
104
|
let classDeclaration = this.declarations[index];
|
|
104
105
|
let localType = this.getNamespace() + '.' + classDeclaration.getName();
|
|
@@ -451,6 +452,10 @@ class ModelFile extends Decorated {
|
|
|
451
452
|
* @return {ClassDeclaration} the ClassDeclaration, or null if the type does not exist
|
|
452
453
|
*/
|
|
453
454
|
getLocalType(type) {
|
|
455
|
+
if(!this.localTypes) {
|
|
456
|
+
throw new Error('Internal error: local types are not yet initialized. Do not try to resolve types inside `process`.');
|
|
457
|
+
}
|
|
458
|
+
|
|
454
459
|
if(!type.startsWith(this.getNamespace())) {
|
|
455
460
|
type = this.getNamespace() + '.' + type;
|
|
456
461
|
}
|
|
@@ -583,19 +588,28 @@ class ModelFile extends Decorated {
|
|
|
583
588
|
return this.getDeclarations(EnumDeclaration);
|
|
584
589
|
}
|
|
585
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Get the ScalarDeclaration defined in this ModelFile
|
|
593
|
+
* @return {ScalarDeclaration[]} the ScalarDeclaration defined in the model file
|
|
594
|
+
*/
|
|
595
|
+
getScalarDeclarations() {
|
|
596
|
+
return this.getDeclarations(ScalarDeclaration);
|
|
597
|
+
}
|
|
598
|
+
|
|
586
599
|
/**
|
|
587
600
|
* Get the instances of a given type in this ModelFile
|
|
588
601
|
* @param {Function} type - the type of the declaration
|
|
589
|
-
* @return {
|
|
602
|
+
* @return {Object[]} the ClassDeclaration defined in the model file
|
|
590
603
|
*/
|
|
591
604
|
getDeclarations(type) {
|
|
592
605
|
let result = [];
|
|
593
606
|
for(let n=0; n < this.declarations.length; n++) {
|
|
594
|
-
let
|
|
595
|
-
if(
|
|
596
|
-
result.push(
|
|
607
|
+
let declaration = this.declarations[n];
|
|
608
|
+
if(declaration instanceof type) {
|
|
609
|
+
result.push(declaration);
|
|
597
610
|
}
|
|
598
611
|
}
|
|
612
|
+
|
|
599
613
|
return result;
|
|
600
614
|
}
|
|
601
615
|
|
|
@@ -760,6 +774,16 @@ class ModelFile extends Decorated {
|
|
|
760
774
|
else if(thing.$class === `${MetaModelNamespace}.ConceptDeclaration`) {
|
|
761
775
|
this.declarations.push( new ConceptDeclaration(this, thing) );
|
|
762
776
|
}
|
|
777
|
+
else if([
|
|
778
|
+
`${MetaModelNamespace}.BooleanScalar`,
|
|
779
|
+
`${MetaModelNamespace}.IntegerScalar`,
|
|
780
|
+
`${MetaModelNamespace}.LongScalar`,
|
|
781
|
+
`${MetaModelNamespace}.DoubleScalar`,
|
|
782
|
+
`${MetaModelNamespace}.StringScalar`,
|
|
783
|
+
`${MetaModelNamespace}.DateTimeScalar`,
|
|
784
|
+
].includes(thing.$class)) {
|
|
785
|
+
this.declarations.push( new ScalarDeclaration(this, thing) );
|
|
786
|
+
}
|
|
763
787
|
else {
|
|
764
788
|
let formatter = Globalize('en').messageFormatter('modelfile-constructor-unrecmodelelem');
|
|
765
789
|
|
|
@@ -22,6 +22,7 @@ const Validator = require('./validator');
|
|
|
22
22
|
/* istanbul ignore next */
|
|
23
23
|
if (global === undefined) {
|
|
24
24
|
const Field = require('./field');
|
|
25
|
+
const ScalarDeclaration = require('./scalardeclaration');
|
|
25
26
|
}
|
|
26
27
|
/* eslint-enable no-unused-vars */
|
|
27
28
|
|
|
@@ -35,7 +36,7 @@ class NumberValidator extends Validator{
|
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Create a NumberValidator.
|
|
38
|
-
* @param {
|
|
39
|
+
* @param {Object} field - the field or scalar declaration this validator is attached to
|
|
39
40
|
* @param {Object} ast - The ast for the range defined as [lower,upper] (inclusive).
|
|
40
41
|
*
|
|
41
42
|
* @throws {IllegalModelException}
|
|
@@ -88,24 +88,33 @@ class Property extends Decorated {
|
|
|
88
88
|
throw new Error('No name for type ' + JSON.stringify(this.ast));
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
switch (this.ast.$class) {
|
|
92
|
+
case `${MetaModelNamespace}.EnumProperty`:
|
|
93
|
+
break;
|
|
94
|
+
case `${MetaModelNamespace}.BooleanProperty`:
|
|
92
95
|
this.type = 'Boolean';
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
break;
|
|
97
|
+
case `${MetaModelNamespace}.DateTimeProperty`:
|
|
98
|
+
this.type = 'DateTime';
|
|
99
|
+
break;
|
|
100
|
+
case `${MetaModelNamespace}.DoubleProperty`:
|
|
101
|
+
this.type = 'Double';
|
|
102
|
+
break;
|
|
103
|
+
case `${MetaModelNamespace}.IntegerProperty`:
|
|
96
104
|
this.type = 'Integer';
|
|
97
|
-
|
|
105
|
+
break;
|
|
106
|
+
case `${MetaModelNamespace}.LongProperty`:
|
|
98
107
|
this.type = 'Long';
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
break;
|
|
109
|
+
case `${MetaModelNamespace}.StringProperty`:
|
|
110
|
+
this.type = 'String';
|
|
111
|
+
break;
|
|
112
|
+
case `${MetaModelNamespace}.ObjectProperty`:
|
|
104
113
|
this.type = this.ast.type ? this.ast.type.name : null;
|
|
105
|
-
|
|
114
|
+
break;
|
|
115
|
+
case `${MetaModelNamespace}.RelationshipProperty`:
|
|
106
116
|
this.type = this.ast.type.name;
|
|
107
|
-
|
|
108
|
-
this.type = null;
|
|
117
|
+
break;
|
|
109
118
|
}
|
|
110
119
|
this.array = false;
|
|
111
120
|
|
|
@@ -176,7 +185,6 @@ class Property extends Decorated {
|
|
|
176
185
|
if(!modelFile) {
|
|
177
186
|
throw new Error('Parent of property ' + this.name + ' does not have a ModelFile!');
|
|
178
187
|
}
|
|
179
|
-
|
|
180
188
|
const result = modelFile.getFullyQualifiedTypeName(this.type);
|
|
181
189
|
if(!result) {
|
|
182
190
|
throw new Error('Failed to find fully qualified type name for property ' + this.name + ' with type ' + this.type );
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const { MetaModelNamespace } = require('@accordproject/concerto-metamodel');
|
|
18
|
+
|
|
19
|
+
const Decorated = require('./decorated');
|
|
20
|
+
const IllegalModelException = require('./illegalmodelexception');
|
|
21
|
+
const ModelUtil = require('../modelutil');
|
|
22
|
+
const NumberValidator = require('./numbervalidator');
|
|
23
|
+
const StringValidator = require('./stringvalidator');
|
|
24
|
+
|
|
25
|
+
// Types needed for TypeScript generation.
|
|
26
|
+
/* eslint-disable no-unused-vars */
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
if (global === undefined) {
|
|
29
|
+
const ModelFile = require('./modelfile');
|
|
30
|
+
const Validator = require('./validator');
|
|
31
|
+
}
|
|
32
|
+
/* eslint-enable no-unused-vars */
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* ScalarDeclaration defines the structure (model/schema) of composite data.
|
|
36
|
+
* It is composed of a set of Properties, may have an identifying field, and may
|
|
37
|
+
* have a super-type.
|
|
38
|
+
* A ScalarDeclaration is conceptually owned by a ModelFile which
|
|
39
|
+
* defines all the classes that are part of a namespace.
|
|
40
|
+
*
|
|
41
|
+
* @abstract
|
|
42
|
+
* @class
|
|
43
|
+
* @memberof module:concerto-core
|
|
44
|
+
*/
|
|
45
|
+
class ScalarDeclaration extends Decorated {
|
|
46
|
+
/**
|
|
47
|
+
* Create a ScalarDeclaration from an Abstract Syntax Tree. The AST is the
|
|
48
|
+
* result of parsing.
|
|
49
|
+
*
|
|
50
|
+
* @param {ModelFile} modelFile - the ModelFile for this class
|
|
51
|
+
* @param {Object} ast - the AST created by the parser
|
|
52
|
+
* @throws {IllegalModelException}
|
|
53
|
+
*/
|
|
54
|
+
constructor(modelFile, ast) {
|
|
55
|
+
super(ast);
|
|
56
|
+
this.modelFile = modelFile;
|
|
57
|
+
this.process();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns the ModelFile that defines this class.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
* @return {ModelFile} the owning ModelFile
|
|
65
|
+
*/
|
|
66
|
+
getModelFile() {
|
|
67
|
+
return this.modelFile;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Process the AST and build the model
|
|
72
|
+
*
|
|
73
|
+
* @throws {IllegalModelException}
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
process() {
|
|
77
|
+
super.process();
|
|
78
|
+
|
|
79
|
+
this.name = this.ast.name;
|
|
80
|
+
this.superType = null;
|
|
81
|
+
this.superTypeDeclaration = null;
|
|
82
|
+
this.idField = null;
|
|
83
|
+
this.timestamped = false;
|
|
84
|
+
this.abstract = false;
|
|
85
|
+
this.validator = null;
|
|
86
|
+
|
|
87
|
+
if (this.ast.$class === `${MetaModelNamespace}.BooleanScalar`) {
|
|
88
|
+
this.type = 'Boolean';
|
|
89
|
+
} else if (this.ast.$class === `${MetaModelNamespace}.IntegerScalar`) {
|
|
90
|
+
this.type = 'Integer';
|
|
91
|
+
} else if (this.ast.$class === `${MetaModelNamespace}.LongScalar`) {
|
|
92
|
+
this.type = 'Long';
|
|
93
|
+
} else if (this.ast.$class === `${MetaModelNamespace}.DoubleScalar`) {
|
|
94
|
+
this.type = 'Double';
|
|
95
|
+
} else if (this.ast.$class === `${MetaModelNamespace}.StringScalar`) {
|
|
96
|
+
this.type = 'String';
|
|
97
|
+
} else if (this.ast.$class === `${MetaModelNamespace}.DateTimeScalar`) {
|
|
98
|
+
this.type = 'DateTime';
|
|
99
|
+
} else {
|
|
100
|
+
this.type = null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
switch(this.getType()) {
|
|
104
|
+
case 'Integer':
|
|
105
|
+
case 'Double':
|
|
106
|
+
case 'Long':
|
|
107
|
+
if(this.ast.validator) {
|
|
108
|
+
this.validator = new NumberValidator(this, this.ast.validator);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
case 'String':
|
|
112
|
+
if(this.ast.validator) {
|
|
113
|
+
this.validator = new StringValidator(this, this.ast.validator);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if(this.ast.defaultValue) {
|
|
119
|
+
this.defaultValue = this.ast.defaultValue;
|
|
120
|
+
} else {
|
|
121
|
+
this.defaultValue = null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.fqn = ModelUtil.getFullyQualifiedName(this.modelFile.getNamespace(), this.name);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Semantic validation of the structure of this class. Subclasses should
|
|
129
|
+
* override this method to impose additional semantic constraints on the
|
|
130
|
+
* contents/relations of fields.
|
|
131
|
+
*
|
|
132
|
+
* @throws {IllegalModelException}
|
|
133
|
+
* @protected
|
|
134
|
+
*/
|
|
135
|
+
validate() {
|
|
136
|
+
super.validate();
|
|
137
|
+
|
|
138
|
+
const declarations = this.getModelFile().getAllDeclarations();
|
|
139
|
+
for (let n = 0; n < declarations.length; n++) {
|
|
140
|
+
let declaration = declarations[n];
|
|
141
|
+
|
|
142
|
+
// check we don't have an asset with the same name
|
|
143
|
+
for (let i = n + 1; i < declarations.length; i++) {
|
|
144
|
+
let otherDeclaration = declarations[i];
|
|
145
|
+
if (declaration.getFullyQualifiedName() === otherDeclaration.getFullyQualifiedName()) {
|
|
146
|
+
throw new IllegalModelException(`Duplicate class name ${declaration.getName()}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Returns the short name of a class. This name does not include the
|
|
154
|
+
* namespace from the owning ModelFile.
|
|
155
|
+
*
|
|
156
|
+
* @return {string} the short name of this class
|
|
157
|
+
*/
|
|
158
|
+
getName() {
|
|
159
|
+
return this.name;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Return the namespace of this class.
|
|
164
|
+
* @return {string} namespace - a namespace.
|
|
165
|
+
*/
|
|
166
|
+
getNamespace() {
|
|
167
|
+
return this.modelFile.getNamespace();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Returns the fully qualified name of this class.
|
|
172
|
+
* The name will include the namespace if present.
|
|
173
|
+
*
|
|
174
|
+
* @return {string} the fully-qualified name of this class
|
|
175
|
+
*/
|
|
176
|
+
getFullyQualifiedName() {
|
|
177
|
+
return this.fqn;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns false as scalars are never identified.
|
|
182
|
+
* @returns {Boolean} false as scalars are never identified
|
|
183
|
+
*/
|
|
184
|
+
isIdentified() {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Returns false as scalars are never identified.
|
|
190
|
+
* @returns {Boolean} false as scalars are never identified
|
|
191
|
+
*/
|
|
192
|
+
isSystemIdentified() {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Returns null as scalars are never identified.
|
|
198
|
+
* @return {null} null, as scalars are never identified
|
|
199
|
+
*/
|
|
200
|
+
getIdentifierFieldName() {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Returns the FQN of the super type for this class or null if this
|
|
207
|
+
* class does not have a super type.
|
|
208
|
+
*
|
|
209
|
+
* @return {string} the FQN name of the super type or null
|
|
210
|
+
*/
|
|
211
|
+
getType() {
|
|
212
|
+
return this.type;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Throws an error as scalars do not have supertypes.
|
|
217
|
+
*/
|
|
218
|
+
getSuperType() {
|
|
219
|
+
throw new Error('Scalars do not have super types.');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get the super type class declaration for this class.
|
|
224
|
+
* @return {ScalarDeclaration | null} the super type declaration, or null if there is no super type.
|
|
225
|
+
*/
|
|
226
|
+
getSuperTypeDeclaration() {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Returns the validator string for this scalar definition
|
|
232
|
+
* @return {Validator} the validator for the field or null
|
|
233
|
+
*/
|
|
234
|
+
getValidator() {
|
|
235
|
+
return this.validator;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Returns the default value for the field or null
|
|
240
|
+
* @return {string | number | null} the default value for the field or null
|
|
241
|
+
*/
|
|
242
|
+
getDefaultValue() {
|
|
243
|
+
if(this.defaultValue) {
|
|
244
|
+
return this.defaultValue;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Returns the string representation of this class
|
|
253
|
+
* @return {String} the string representation of the class
|
|
254
|
+
*/
|
|
255
|
+
toString() {
|
|
256
|
+
return 'ScalarDeclaration {id=' + this.getFullyQualifiedName() + '}';
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Returns true if this class is abstract.
|
|
261
|
+
*
|
|
262
|
+
* @return {boolean} true if the class is abstract
|
|
263
|
+
*/
|
|
264
|
+
isAbstract() {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Returns true if this class is the definition of an asset.
|
|
270
|
+
*
|
|
271
|
+
* @return {boolean} true if the class is an asset
|
|
272
|
+
*/
|
|
273
|
+
isAsset() {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Returns true if this class is the definition of a participant.
|
|
279
|
+
*
|
|
280
|
+
* @return {boolean} true if the class is a participant
|
|
281
|
+
*/
|
|
282
|
+
isParticipant() {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Returns true if this class is the definition of a transaction.
|
|
288
|
+
*
|
|
289
|
+
* @return {boolean} true if the class is a transaction
|
|
290
|
+
*/
|
|
291
|
+
isTransaction() {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Returns true if this class is the definition of an event.
|
|
297
|
+
*
|
|
298
|
+
* @return {boolean} true if the class is an event
|
|
299
|
+
*/
|
|
300
|
+
isEvent() {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Returns true if this class is the definition of a concept.
|
|
306
|
+
*
|
|
307
|
+
* @return {boolean} true if the class is a concept
|
|
308
|
+
*/
|
|
309
|
+
isConcept() {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Returns true if this class is the definition of an enum.
|
|
315
|
+
*
|
|
316
|
+
* @return {boolean} true if the class is an enum
|
|
317
|
+
*/
|
|
318
|
+
isEnum() {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Returns true if this class is the definition of a class declaration.
|
|
324
|
+
*
|
|
325
|
+
* @return {boolean} true if the class is a class
|
|
326
|
+
*/
|
|
327
|
+
isClassDeclaration() {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Returns true if this class is the definition of a scalar declaration.
|
|
333
|
+
*
|
|
334
|
+
* @return {boolean} true if the class is a scalar
|
|
335
|
+
*/
|
|
336
|
+
isScalarDeclaration() {
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
module.exports = ScalarDeclaration;
|