OSDN Git Service

[TEST] eos.toExecString()
[eos/zephyr.git] / server / class / Eos.js
1
2 /**
3  * Eosコマンドをエミュレートするクラス 
4  * @varructor
5  * @returns {object}
6  * function execute(command, params) {
7  */
8 var eos = {
9     validate: validate,
10     toExecString: toExecString,
11     execute: execute,
12     getFiles: getFiles
13 }
14
15
16 /**
17  *
18  * Class variables
19  */
20
21 // include all Eos command's info.
22 // For seaching with O(n), the object key name is command name.
23 var db = require('./DB.js').instance;
24 var commandList = require(__dirname + '/../../user-specific-files/OptionControlFile/command_list.json');
25 var ocfReference = {};
26
27 commandList.forEach(function(c) {
28     ocfReference[c.name] = require(__dirname + '/../../user-specific-files/OptionControlFile/commands/' + c.name);
29 });
30
31
32 // for unit test
33
34
35 /**
36  *
37  * Class variables
38  */
39
40 function hasOneProperty(options) {
41     return new Promise(function(resolve, reject) {
42         if(options.length === 0) {
43             var errorMsg = 'At least one option is required.';
44             throw new Error(errorMsg);
45         } else {
46             resolve();
47         }
48     });
49 }
50
51 function matchOption(options, ocf) {
52     return new Promise(function(resolve, reject) {
53         var ok = {};
54         var notIncludingRequiredOptions = [];
55         options.forEach(function(o) { 
56             ok[o.name] = o.arguments;
57         });
58         ocf.forEach(function(o) {
59             if(o.optionProperties && !ok[o.option]) {
60                 notIncludingRequiredOptions.push(o.option);
61             }
62         });
63
64         // check whether all required option exist 
65         if(notIncludingRequiredOptions.length > 0) {
66             var errorMsg = 'Option ' + notIncludingRequiredOptions.toString() + ' are required';
67             reject(new Error(errorMsg));
68         } else {
69             resolve();
70         }
71     });
72 }
73
74 function validArgumentsNumber(options, ocfObj) {
75     return new Promise(function(resolve, reject) {
76         options.forEach(function(o) {
77             // option number
78             var expectNum = ocfObj[o.name].optionNumber;
79             var actualNum = o.arguments.length;
80             if(expectNum !== actualNum) {
81                 reject(new Error('Invalid arguments number'));
82             }
83         });
84         resolve();
85     });
86 };
87
88 function validArgumentsType(options, ocfObj, workspace) {
89     return new Promise(function(resolve, reject) {
90         options.forEach(function(o) {
91             o.arguments.forEach(function(arg,i) {
92                 // argType
93                 var formType = ocfObj[o.name].arg[i].formType
94                 if(formType === 'select') { // This argument is filename
95                     var exist = workspace.indexOf(arg) > -1;
96                     if(!exist) {
97                         reject(new Error(arg + ' doesn\'t exist.'));
98                     }
99                 } else {
100                     var expectType = formType === 'text' ? 'string' : 'number';
101                     var actualType = typeof arg;
102                     if(expectType !== actualType) {
103                         reject(new Error('argType is invalid'));
104                     }
105                 }
106             });
107         });
108         resolve();
109     });
110 }
111
112 function validOutfileName(options, ocfObj, workspace) {
113     return new Promise(function(resolve, reject) {
114         // output file Regexp
115         var outRegExp = /out|append/;
116
117         options.forEach(function(o) {
118             o.arguments.forEach(function(arg,i) {
119                 // outFile name
120                 if(outRegExp.test(ocfObj[o.name].arg[i].argType)) {
121                     if(workspace.indexOf(o.arguments[i]) > -1) {
122                         reject(new Error('Invalid outfile name.'));
123                     }
124                 }
125             });
126         });
127         resolve();
128     });
129 }
130
131 /**
132  * validate 
133  * コマンドとオプションのバリデーション
134  * @param command
135  * @param params
136  * @returns {valid: boolean, message: string}
137  */
138 function validate(command, options, workspaceId) {
139     return new Promise(function(resolve, reject) {
140
141         var ocf;
142         if(ocfReference[command]) {
143             ocf = ocfReference[command];
144         } else {
145             var errorMsg = 'Command name is invalid';
146             reject(new Error(errorMsg));
147         }
148
149         var ocfObj = {};
150         ocf.forEach(function(o) {
151             ocfObj[o.option] = o;
152         });
153
154         var optionsObj = {};
155         if(Array.isArray(options)) {
156             options.forEach(function(o) {
157                 if(o.name && o.arguments) {
158                     if(Array.isArray(o.arguments)) {
159                         optionsObj[o.name] = o.arguments;
160                     } else {
161                         var errorMsg = 'Each "arguments" properties needs to be Array';
162                         reject(new Error(errorMsg));
163                     }
164                 } else {
165                     var errorMsg = 'Options need to include Object which have properties "name" and "arguments"';
166                     reject(new Error(errorMsg));
167                 }
168             });
169         } else {
170             var errorMsg = 'Options need to be Array';
171             reject(new Error(errorMsg));
172         }
173
174         getFiles(workspaceId)
175         .then(function(workspace) {
176
177             // validate function
178             var promises = [];
179             promises.push(hasOneProperty(options));
180             promises.push(matchOption(options, ocf));
181             promises.push(validArgumentsNumber(options, ocfObj));
182             promises.push(validArgumentsType(options, ocfObj, workspace));
183             promises.push(validOutfileName(options, ocfObj, workspace));
184
185             // do validation
186             return Promise.all(promises)
187         })
188         .catch(function(error) {
189             reject(error);
190         })
191         .then(function(r) {
192             resolve();
193         })
194     });
195 }
196
197 /**
198  * toExecString
199  *
200  * @param command
201  * @param options
202  * @returns {string}
203  */
204 function toExecString(command, options, workspaceId) {
205     var ocf = ocfReference[command]; // Array
206     var finalOptions = {};
207     var execStr = command + ' ';
208     var ocfObj = {};
209     ocf.forEach(function(o) {
210         ocfObj[o.option] = o;
211     });
212
213
214     if(workspaceId === "1f83f620-c1ed-11e5-9657-7942989daa00") { // root
215         var root = __dirname + '/../../user-specific-files/workspace/';
216     }
217
218     // set default parameters
219     ocf.forEach(function(o) {
220         o.arg.forEach(function(arg) {
221             if(!(arg.initialValue === "") && arg.initialValue) {
222                 if(!(finalOptions[o.option])) {
223                     finalOptions[o.option] = [];
224                     finalOptions[o.option].push(arg.initialValue);
225                 } else {
226                     finalOptions[o.option].push(arg.initialValue);
227                 }
228             }
229         });
230     });
231
232     // set user setting parameters
233     options.forEach(function(o) {
234         var s = [];
235         var outRegExp = /out|append/;
236         o.arguments.forEach(function(arg, i) {
237             if(ocfObj[o.name].arg[i].formType === 'select' || outRegExp.test(ocfObj[o.name].arg[i].argType)) {
238                 s.push(root+arg);
239             } else {
240                 s.push(arg);
241             }
242         });
243         finalOptions[o.name] = s;
244     });
245
246     // set execution string
247     Object.keys(finalOptions).forEach(function(key) {
248         execStr += key + ' ';
249         finalOptions[key].forEach(function(arg) {
250             execStr += arg + ' ';
251         });
252     });
253
254     // remove last blank
255     execStr = execStr.slice(0,execStr.length-1);
256
257     return execStr;
258 }
259
260
261 /**
262  * execute
263  *
264  * @param command
265  * @param params
266  * @returns {object}
267  */
268 function execute(command, options) {
269     var result = validate(command, options);
270     if(!result.hasDone) {
271     } else {
272         var str = toExecString(command, options);
273     }
274 }
275
276 /**
277  * getFiles
278  * @param fileId
279  * @returns {promise} resolve(Array)
280  */
281 function getFiles(fileId) {
282     return new Promise(function(resolve, reject) {
283         if(process.env.NODE_ENV === 'test') {
284             resolve(['file1.txt', 'file2.txt']);
285         } else {
286             db.getFiles(fileId)
287             .then(function(r) {
288                 var workspace = r.map(function(f) { return f.name });
289                 resolve(workspace);
290             });
291         }
292     });
293 }
294
295 module.exports = { instance: eos };