UNPKG

5.2 kBJavaScriptView Raw
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
17const slash = require('slash');
18const fsPath = require('path');
19
20const Parser = require('@accordproject/concerto-cto').Parser;
21const ModelManager = require('@accordproject/concerto-core').ModelManager;
22const ModelFile = require('@accordproject/concerto-core').ModelFile;
23const Builtin = require('./builtin');
24
25const processModelFiles = (modelFiles) => {
26 let models = [];
27 modelFiles.forEach(function (file) {
28 // ignore the system namespace when creating an archive
29 if (file.isSystemModelFile()) {
30 return;
31 }
32 let fileName = file.getName();
33 if (fileName === 'UNKNOWN' || !fileName) {
34 fileName = file.getNamespace() + '.cto';
35 } else {
36 fileName = fsPath.basename(fileName);
37 }
38 models.push({ 'name' : fileName, 'namespace': file.getNamespace(), 'content' : file.definitions });
39 });
40 return models;
41};
42
43/**
44 * Accord Project Model Manager. Bootstraps the ModelManager with system files.
45 * @class
46 * @public
47 * @abstract
48 * @memberof module:ergo-compiler
49 */
50class APModelManager extends ModelManager {
51
52 /**
53 */
54 constructor() {
55 super();
56 this.addCTOModel(Builtin.TimeModel, '@models.accordproject.org.time@0.2.0.cto');
57 this.addCTOModel(Builtin.MoneyModel, '@models.accordproject.org.accordproject.money@0.2.0.cto');
58 this.addCTOModel(Builtin.ContractModel, '@models.accordproject.org.accordproject.contract.cto');
59 this.addCTOModel(Builtin.RuntimeModel, '@models.accordproject.org.accordproject.runtime.cto');
60 this.addCTOModel(Builtin.OptionsModel, '@org.accordproject.ergo.options.cto');
61 this.validateModelFiles();
62 this.builtInNamespaces = this.getNamespaces();
63 }
64
65 /**
66 * Gets all the CTO models
67 * @return {Array<{name:string, content:string}>} the name and content of each CTO file
68 */
69 getModels() {
70 return processModelFiles(this.getModelFiles());
71 }
72
73 /**
74 * Adds a model file (as a string) to the TemplateLogic.
75 * @param {string} modelFileContent - The model file content as a string
76 * @param {string} fileName - an optional file name to associate with the model file
77 */
78 addAPModelFile(modelFileContent, fileName) {
79 const name = slash(fileName);
80 const ast = Parser.parse(modelFileContent, fileName);
81 const modelFile = new ModelFile(this, ast, modelFileContent, name);
82 if (!this.builtInNamespaces.includes(modelFile.getNamespace())) {
83 this.addModelFile(modelFile,modelFileContent,name,true);
84 }
85 }
86
87 /**
88 * Add a set of model files to the TemplateLogic
89 * @param {string[]} modelFiles - An array of Composer files as
90 * strings.
91 * @param {string[]} [modelFileNames] - An optional array of file names to
92 * associate with the model files
93 * @param {boolean} offline - do not update external models
94 */
95 async addAPModelFiles(modelFiles, modelFileNames, offline) {
96 modelFiles.map((modelFileContent, index) => {
97 const modelFileName = modelFileNames[index];
98 this.addAPModelFile(modelFileContent, modelFileName);
99 });
100 if (offline) {
101 this.validateModelFiles();
102 return [];
103 } else {
104 const externalModelFiles = await this.updateExternalModels();
105 return processModelFiles(externalModelFiles);
106 }
107 }
108
109 /**
110 * Update of a given model
111 * @param {string} content - the model content
112 * @param {string} name - the model name
113 */
114 updateModel(content, name) {
115 const currentModels = this.getModelFiles();
116 // Is this a new model?
117 if (!currentModels.some(x => x.getName() === name)) {
118 this.addCTOModel(content, name);
119 } else {
120 const previousModelFile =
121 (currentModels.filter(x => x.getName() === name))[0];
122 const previousContent = previousModelFile.getDefinitions();
123 if (content !== previousContent) {
124 const previousNamespace = previousModelFile.getNamespace();
125 const ast = Parser.parse(content, name);
126 const newNamespace = new ModelFile(this, ast, content, name).getNamespace();
127 if (previousNamespace === newNamespace) {
128 this.updateModelFile(content, name, true);
129 } else {
130 this.deleteModelFile(previousNamespace);
131 this.addCTOModel(content, name, true);
132 }
133 }
134 }
135 }
136}
137
138module.exports = APModelManager;
\No newline at end of file