OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/eos/zephyr
[eos/zephyr.git] / server / class / Eos.js
1 <<<<<<< HEAD
2 /**
3  *
4  * Class variables
5  */
6
7 =======
8 /** * * Class variables */
9 >>>>>>> 6b2b2b88511733893d2c6e7848c389abfcd53ba6
10 // include all Eos command's info.
11 // For seaching with O(n), the object key name is command name.
12 var db = require('./DB.js').instance;
13 var commandList = require(__dirname + '/../../user-specific-files/OptionControlFile/command_list.json');
14 var ocfReference = {};
15
16 commandList.forEach(function(c) {
17     ocfReference[c.name] = require(__dirname + '/../../user-specific-files/OptionControlFile/commands/' + c.name);
18 });
19 var spawn = require('child_process').spawn;
20
21
22 function hasOneProperty(options) {
23     return new Promise(function(resolve, reject) {
24         if(options.length === 0) {
25             var errorMsg = 'At least one option is required.';
26             throw new Error(errorMsg);
27         } else {
28             resolve();
29         }
30     });
31 }
32
33 function matchOption(options, ocf) {
34     return new Promise(function(resolve, reject) {
35         var ok = {};
36         var notIncludingRequiredOptions = [];
37         options.forEach(function(o) {
38             ok[o.name] = o.arguments;
39         });
40         ocf.forEach(function(o) {
41             if(o.optionProperties && !ok[o.option]) {
42                 notIncludingRequiredOptions.push(o.option);
43             }
44         });
45
46         // check whether all required option exist
47         if(notIncludingRequiredOptions.length > 0) {
48             var errorMsg = 'Option ' + notIncludingRequiredOptions.toString() + ' are required';
49             reject(new Error(errorMsg));
50         } else {
51             resolve();
52         }
53     });
54 }
55
56 function validArgumentsNumber(options, ocfObj) {
57     return new Promise(function(resolve, reject) {
58         options.forEach(function(o) {
59             // option number
60             var expectNum = ocfObj[o.name].optionNumber;
61             var actualNum = o.arguments.length;
62             if(expectNum !== actualNum) {
63                 reject(new Error('Invalid arguments number'));
64             }
65         });
66         resolve();
67     });
68 };
69
70 function validArgumentsType(options, ocfObj, workspace) {
71     return new Promise(function(resolve, reject) {
72         options.forEach(function(o) {
73             o.arguments.forEach(function(arg,i) {
74                 // argType
75                 var formType = ocfObj[o.name].arg[i].formType
76                 if(formType === 'select') { // This argument is filename
77                     var exist = workspace.indexOf(arg) > -1;
78                     if(!exist) {
79                         reject(new Error(arg + ' doesn\'t exist.'));
80                     }
81                 } else {
82                     var expectType = formType === 'text' ? 'string' : 'number';
83                     var actualType = typeof arg;
84                     if(expectType !== actualType) {
85                         reject(new Error('argType is invalid'));
86                     }
87                 }
88             });
89         });
90         resolve();
91     });
92 }
93
94 function validOutfileName(options, ocfObj, workspace) {
95     return new Promise(function(resolve, reject) {
96         // output file Regexp
97         var outRegExp = /out|append/;
98
99         options.forEach(function(o) {
100             o.arguments.forEach(function(arg,i) {
101                 // outFile name
102                 if(outRegExp.test(ocfObj[o.name].arg[i].argType)) {
103                     if(workspace.indexOf(o.arguments[i]) > -1) {
104                         reject(new Error('Invalid outfile name.'));
105                     }
106                 }
107             });
108         });
109         resolve();
110     });
111 }
112
113 /**
114  * validate
115  * コマンドとオプションのバリデーション
116  * @param command
117  * @param params
118  * @returns {valid: boolean, message: string}
119  */
120 function validate(command, options, workspaceId) {
121     return new Promise(function(resolve, reject) {
122
123         var ocf;
124         if(ocfReference[command]) {
125             ocf = ocfReference[command];
126         } else {
127             var errorMsg = 'Command name is invalid';
128             reject(new Error(errorMsg));
129         }
130
131         var ocfObj = {};
132         ocf.forEach(function(o) {
133             ocfObj[o.option] = o;
134         });
135
136         var optionsObj = {};
137         if(Array.isArray(options)) {
138             options.forEach(function(o) {
139                 if(o.name && o.arguments) {
140                     if(Array.isArray(o.arguments)) {
141                         optionsObj[o.name] = o.arguments;
142                     } else {
143                         var errorMsg = 'Each "arguments" properties needs to be Array';
144                         reject(new Error(errorMsg));
145                     }
146                 } else {
147                     var errorMsg = 'Options need to include Object which have properties "name" and "arguments"';
148                     reject(new Error(errorMsg));
149                 }
150             });
151         } else {
152             var errorMsg = 'Options need to be Array';
153             reject(new Error(errorMsg));
154         }
155
156         getFiles(workspaceId)
157         .then(function(workspace) {
158
159             // validate function
160             var promises = [];
161             promises.push(hasOneProperty(options));
162             promises.push(matchOption(options, ocf));
163             promises.push(validArgumentsNumber(options, ocfObj));
164             promises.push(validArgumentsType(options, ocfObj, workspace));
165             promises.push(validOutfileName(options, ocfObj, workspace));
166
167             // do validation
168             return Promise.all(promises)
169         })
170         .catch(function(error) {
171             reject(error);
172         })
173         .then(function(r) {
174             resolve();
175         })
176     });
177 }
178
179 /**
180  * toExecString
181  *
182  * @param command
183  * @param options
184  * @returns {string}
185  */
186 function toExecString(command, options, workspaceId) {
187     var ocf = ocfReference[command]; // Array
188     var finalOptions = {};
189 <<<<<<< HEAD
190 =======
191     //var execStr = '/Users/hiratakengo/Eos/bin/X86MAC64/'+command + ' ';
192 >>>>>>> 6b2b2b88511733893d2c6e7848c389abfcd53ba6
193     var execStr = command + ' ';
194     var ocfObj = {};
195     ocf.forEach(function(o) {
196         ocfObj[o.option] = o;
197     });
198
199
200     if(workspaceId === "1f83f620-c1ed-11e5-9657-7942989daa00") { // root
201         var root = __dirname + '/../../user-specific-files/workspace/';
202     }
203
204     // set default parameters
205     ocf.forEach(function(o) {
206         o.arg.forEach(function(arg) {
207             if(!(arg.initialValue === "") && arg.initialValue) {
208                 if(!(finalOptions[o.option])) {
209                     finalOptions[o.option] = [];
210                     finalOptions[o.option].push(arg.initialValue);
211                 } else {
212                     finalOptions[o.option].push(arg.initialValue);
213                 }
214             }
215         });
216     });
217
218     // set user setting parameters
219     options.forEach(function(o) {
220         var s = [];
221         var outRegExp = /out|append/;
222         o.arguments.forEach(function(arg, i) {
223             if(ocfObj[o.name].arg[i].formType === 'select' || outRegExp.test(ocfObj[o.name].arg[i].argType)) {
224                 s.push(root+arg);
225             } else {
226                 s.push(arg);
227             }
228         });
229         finalOptions[o.name] = s;
230     });
231
232     // set execution string
233     Object.keys(finalOptions).forEach(function(key) {
234         execStr += key + ' ';
235         finalOptions[key].forEach(function(arg) {
236             execStr += arg + ' ';
237         });
238     });
239
240     // remove last blank
241     execStr = execStr.slice(0,execStr.length-1);
242
243     return execStr;
244 }
245
246 /**
247  * toExecArray
248  *
249  * @param {fileId}
250  * @returns {string}
251  */
252 function toExecArray(command, options, workspaceId) {
253     return new Promise(function(resolve, reject) {
254         var ocf = ocfReference[command]; // Array
255         var finalOptions = {};
256         var ocfObj = {};
257         ocf.forEach(function(o) {
258             ocfObj[o.option] = o;
259         });
260
261         // set default parameters
262         ocf.forEach(function(o) {
263             o.arg.forEach(function(arg) {
264                 if(!(arg.initialValue === "") && arg.initialValue) {
265                     if(!(finalOptions[o.option])) {
266                         finalOptions[o.option] = [];
267                         finalOptions[o.option].push(arg.initialValue);
268                     } else {
269                         finalOptions[o.option].push(arg.initialValue);
270                     }
271                 }
272             });
273         });
274
275         getUUIDs(workspaceId)
276         .then(function(uuids) {
277             // set user setting parameters
278             options.forEach(function(o) {
279                 var s = [];
280                 var outRegExp = /out|append/;
281                 o.arguments.forEach(function(arg, i) {
282                     if(ocfObj[o.name].arg[i].formType === 'select') {
283 <<<<<<< HEAD
284                         s.push(uuids[arg]);
285                         //s.push(arg);
286                         console.log('input:' + uuids[arg]);
287 =======
288                         //s.push(uuids[arg]);
289                         s.push(arg);
290 >>>>>>> 6b2b2b88511733893d2c6e7848c389abfcd53ba6
291                     } else {
292                         s.push(arg);
293                     }
294                 });
295                 finalOptions[o.name] = s;
296             });
297             var array = Object.keys(finalOptions).reduce(function(a,b) {
298                 a.push(b);
299                 finalOptions[b].forEach(function(v) {
300                     a.push(v);
301                 });
302                 return a;
303             },[]);
304             resolve(array);
305         });
306     });
307 }
308
309 /**
310  * execute
311  *
312  * @param command
313  * @param params
314  * @returns {object}
315  */
316 function execute(command, optionsArray) {
317     return new Promise(function(resolve, reject) {
318         var workspace;
319         if(process.env.NODE_ENV === 'debug') {
320             workspace = __dirname + '/../../user-specific-files/workspace.debug';
321         } else {
322 <<<<<<< HEAD
323             workspace = __dirname + '/../../user-specific-files/workspace';
324 =======
325             workspace = _dirname + '/../../user-specific-files/workspace';
326 >>>>>>> 6b2b2b88511733893d2c6e7848c389abfcd53ba6
327         }
328
329         var config = {
330             cwd: workspace
331         };
332 <<<<<<< HEAD
333         var runner = spawn(command,optionsArray,config);
334         //var runner = spawn(command,optionsArray,'/');
335         console.log('spawn');
336 =======
337         //var runner = spawn('/Users/hiratakengo/Eos/bin/X86MAC64/'+command,optionsArray,config);
338         var runner = spawn(command,optionsArray,config);
339         //var runner = spawn(command,optionsArray);
340         //commandRet    = spawn('ls', ['-lh', '/usr']);
341         //commandRet    = spawn(command, ['-h']);
342
343         var commandRet = runner;
344
345         commandRet.stdout.on('data', function (data) {
346           console.log('stdout: ' + data);
347         });
348
349         commandRet.stderr.on('data', function (data) {
350           console.log('stderr: ' + data);
351         });
352 >>>>>>> 6b2b2b88511733893d2c6e7848c389abfcd53ba6
353
354         runner.on('close', function() {
355             resolve();
356         });
357     });
358 }
359
360 /**
361  * getFiles
362  * @param fileId
363  * @returns {promise} resolve(Array)
364  */
365 function getFiles(fileId) {
366     return new Promise(function(resolve, reject) {
367         if(process.env.NODE_ENV === 'test') {
368             resolve(['file1.txt', 'file2.txt']);
369         } else {
370             db.getFiles(fileId)
371             .then(function(r) {
372                 var workspace = r.map(function(f) { return f.name });
373                 resolve(workspace);
374             });
375         }
376     });
377 }
378
379 /**
380  * getUUID
381  * @param fileId
382  * @returns {object} key: filename, value: uuid
383  */
384 function getUUIDs(fileId) {
385     return new Promise(function(resolve) {
386         db.getFiles(fileId)
387         .then(function(r) {
388             var uuids = {};
389             r.forEach(function(v) {
390                 uuids[v.dataValues.name] = v.dataValues.fileId;
391             });
392             resolve(uuids);
393         });
394     });
395 }
396
397 /**
398  * Eosコマンドをエミュレートするクラス
399  * @varructor
400  * @returns {object}
401  * function execute(command, params) {
402  */
403 var eos = {
404     validate: validate,
405     toExecString: toExecString,
406     execute: execute,
407     getFiles: getFiles,
408     getUUIDs: getUUIDs,
409     toExecArray: toExecArray
410 }
411
412 module.exports = { instance: eos };