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 | ;
|
16 |
|
17 | const Concept = require('./concept');
|
18 | const TypedStack = require('../serializer/typedstack');
|
19 |
|
20 | /**
|
21 | *
|
22 | * Resource is an instance that has a type. The type of the resource
|
23 | * specifies a set of properites (which themselves have types).
|
24 | *
|
25 | *
|
26 | * Type information in Concerto is used to validate the structure of
|
27 | * Resource instances and for serialization.
|
28 | *
|
29 | *
|
30 | * Resources are used in Concerto to represent Assets, Participants, Transactions and
|
31 | * other domain classes that can be serialized for long-term persistent storage.
|
32 | *
|
33 | * @extends Concept
|
34 | * @see See {@link Resource}
|
35 | * @class
|
36 | * @memberof module:concerto-core
|
37 | */
|
38 | class ValidatedConcept extends Concept {
|
39 | /**
|
40 | * This constructor should not be called directly.
|
41 | * <p>
|
42 | * <strong>Note: Only to be called by framework code. Applications should
|
43 | * retrieve instances from {@link Factory}</strong>
|
44 | * </p>
|
45 | *
|
46 | * @param {ModelManager} modelManager - The ModelManager for this instance
|
47 | * @param {ClassDeclaration} classDeclaration - The class declaration for this instance.
|
48 | * @param {string} ns - The namespace this instance.
|
49 | * @param {string} type - The type this instance.
|
50 | * @param {ResourceValidator} resourceValidator - The validator to use for this instance
|
51 | * @private
|
52 | */
|
53 | constructor(modelManager, classDeclaration, ns, type, resourceValidator) {
|
54 | super(modelManager, classDeclaration, ns, type);
|
55 | this.$validator = resourceValidator;
|
56 | }
|
57 |
|
58 | /**
|
59 | * Sets a property, validating that it does not violate the model
|
60 | * @param {string} propName - the name of the field
|
61 | * @param {string} value - the value of the property
|
62 | * @throws {Error} if the value is not compatible with the model definition for the field
|
63 | */
|
64 | setPropertyValue(propName, value) {
|
65 | let classDeclaration = this.getClassDeclaration();
|
66 | let field = classDeclaration.getProperty(propName);
|
67 |
|
68 | if (!field) {
|
69 | throw new Error('Trying to set field ' +
|
70 | propName + ' which is not declared in the model.');
|
71 | }
|
72 | // else {
|
73 | // this.log( 'Validating field ' + field + ' with data ' + value );
|
74 | // }
|
75 |
|
76 | const parameters = {};
|
77 | parameters.stack = new TypedStack(value);
|
78 | parameters.modelManager = this.getModelManager();
|
79 | parameters.rootResourceIdentifier = 'undefined';
|
80 | field.accept(this.$validator, parameters);
|
81 | super.setPropertyValue(propName,value);
|
82 | }
|
83 |
|
84 | /**
|
85 | * Adds an array property value, validating that it does not violate the model
|
86 | * @param {string} propName - the name of the field
|
87 | * @param {string} value - the value of the property
|
88 | * @throws {Error} if the value is not compatible with the model definition for the field
|
89 | */
|
90 | addArrayValue(propName, value) {
|
91 | let classDeclaration = this.getClassDeclaration();
|
92 | let field = classDeclaration.getProperty(propName);
|
93 |
|
94 | if (!field) {
|
95 | throw new Error('Trying to set field ' +
|
96 | propName + ' which is not declared in the model.');
|
97 | }
|
98 |
|
99 | if (!field.isArray()) {
|
100 | throw new Error('Trying to add array item ' +
|
101 | propName + ' which is not declared as an array in the model.');
|
102 | }
|
103 |
|
104 | const parameters = {};
|
105 | let newArray = [];
|
106 | if(this[propName]) {
|
107 | newArray = this[propName].slice(0);
|
108 | }
|
109 | newArray.push(value);
|
110 | parameters.stack = new TypedStack(newArray);
|
111 | parameters.modelManager = this.getModelManager();
|
112 | parameters.rootResourceIdentifier = 'undefined';
|
113 | field.accept(this.$validator, parameters);
|
114 | super.addArrayValue(propName, value);
|
115 | }
|
116 |
|
117 | /**
|
118 | * Validates the instance against its model.
|
119 | *
|
120 | * @throws {Error} - if the instance if invalid with respect to the model
|
121 | */
|
122 | validate() {
|
123 | const classDeclaration = this.getClassDeclaration();
|
124 | const parameters = {};
|
125 | parameters.stack = new TypedStack(this);
|
126 | parameters.modelManager = this.getModelManager();
|
127 | parameters.rootResourceIdentifier = 'undefined';
|
128 | classDeclaration.accept(this.$validator, parameters);
|
129 | }
|
130 | }
|
131 |
|
132 | module.exports = ValidatedConcept;
|