Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80680 views
1
/*
2
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
3
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4
*/
5
6
var util = require('util'),
7
path = require('path'),
8
fs = require('fs'),
9
abbrev = require('abbrev');
10
11
function Factory(kind, dir, allowAbbreviations) {
12
this.kind = kind;
13
this.dir = dir;
14
this.allowAbbreviations = allowAbbreviations;
15
this.classMap = {};
16
this.abbreviations = null;
17
}
18
19
Factory.prototype = {
20
21
knownTypes: function () {
22
var keys = Object.keys(this.classMap);
23
keys.sort();
24
return keys;
25
},
26
27
resolve: function (abbreviatedType) {
28
if (!this.abbreviations) {
29
this.abbreviations = abbrev(this.knownTypes());
30
}
31
return this.abbreviations[abbreviatedType];
32
},
33
34
register: function (constructor) {
35
var type = constructor.TYPE;
36
if (!type) { throw new Error('Could not register ' + this.kind + ' constructor [no TYPE property]: ' + util.inspect(constructor)); }
37
this.classMap[type] = constructor;
38
this.abbreviations = null;
39
},
40
41
create: function (type, opts) {
42
var allowAbbrev = this.allowAbbreviations,
43
realType = allowAbbrev ? this.resolve(type) : type,
44
Cons;
45
46
Cons = realType ? this.classMap[realType] : null;
47
if (!Cons) { throw new Error('Invalid ' + this.kind + ' [' + type + '], allowed values are ' + this.knownTypes().join(', ')); }
48
return new Cons(opts);
49
},
50
51
loadStandard: function (dir) {
52
var that = this;
53
fs.readdirSync(dir).forEach(function (file) {
54
if (file !== 'index.js' && file.indexOf('.js') === file.length - 3) {
55
try {
56
that.register(require(path.resolve(dir, file)));
57
} catch (ex) {
58
console.error(ex.message);
59
console.error(ex.stack);
60
throw new Error('Could not register ' + that.kind + ' from file ' + file);
61
}
62
}
63
});
64
},
65
66
bindClassMethods: function (Cons) {
67
var tmpKind = this.kind.charAt(0).toUpperCase() + this.kind.substring(1), //ucfirst
68
allowAbbrev = this.allowAbbreviations;
69
70
Cons.mix = Factory.mix;
71
Cons.register = this.register.bind(this);
72
Cons.create = this.create.bind(this);
73
Cons.loadAll = this.loadStandard.bind(this, this.dir);
74
Cons['get' + tmpKind + 'List'] = this.knownTypes.bind(this);
75
if (allowAbbrev) {
76
Cons['resolve' + tmpKind + 'Name'] = this.resolve.bind(this);
77
}
78
}
79
};
80
81
Factory.mix = function (cons, proto) {
82
Object.keys(proto).forEach(function (key) {
83
cons.prototype[key] = proto[key];
84
});
85
};
86
87
module.exports = Factory;
88
89
90