Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / di / lib / injector.js
1 var Module = require('./module');
2 var autoAnnotate = require('./annotation').parse;
3
4
5 var Injector = function(modules, parent) {
6   parent = parent || {
7     get: function(name) {
8       currentlyResolving.push(name);
9       throw error('No provider for "' + name + '"!');
10     }
11   };
12
13   var currentlyResolving = [];
14   var providers = this._providers = Object.create(parent._providers || null);
15   var instances = this._instances = Object.create(null);
16
17   instances.injector = this;
18
19   var error = function(msg) {
20     var stack = currentlyResolving.join(' -> ');
21     currentlyResolving.length = 0;
22     return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg);
23   };
24
25   var get = function(name) {
26     if (!providers[name] && name.indexOf('.') !== -1) {
27       var parts = name.split('.');
28       var pivot = get(parts.shift());
29
30       while(parts.length) {
31         pivot = pivot[parts.shift()];
32       }
33
34       return pivot;
35     }
36
37     if (Object.hasOwnProperty.call(instances, name)) {
38       return instances[name];
39     }
40
41     if (Object.hasOwnProperty.call(providers, name)) {
42       if (currentlyResolving.indexOf(name) !== -1) {
43         currentlyResolving.push(name);
44         throw error('Can not resolve circular dependency!');
45       }
46
47       currentlyResolving.push(name);
48       instances[name] = providers[name][0](providers[name][1]);
49       currentlyResolving.pop();
50
51       return instances[name];
52     }
53
54     return parent.get(name);
55   };
56
57   var instantiate = function(Type) {
58     var instance = Object.create(Type.prototype);
59     var returned = invoke(Type, instance);
60
61     return typeof returned === 'object' ? returned : instance;
62   };
63
64   var invoke = function(fn, context) {
65     if (typeof fn !== 'function') {
66       throw error('Can not invoke "' + fn + '". Expected a function!');
67     }
68
69     var inject = fn.$inject && fn.$inject || autoAnnotate(fn);
70     var dependencies = inject.map(function(dep) {
71       return get(dep);
72     });
73
74     // TODO(vojta): optimize without apply
75     return fn.apply(context, dependencies);
76   };
77
78   var createChild = function(modules, providersFromParent) {
79     if (providersFromParent && providersFromParent.length) {
80       var fromParentModule = Object.create(null);
81
82       providersFromParent.forEach(function(name) {
83         if (!providers[name]) {
84           throw new Error('No provider for "' + name + '". Can not use provider from the parent!');
85         }
86
87         fromParentModule[name] = [providers[name][2], providers[name][1]];
88       });
89
90       modules.unshift(fromParentModule);
91     }
92
93     return new Injector(modules, this);
94   };
95
96   var factoryMap = {
97     factory: invoke,
98     type: instantiate,
99     value: function(value) {
100       return value;
101     }
102   };
103
104   modules.forEach(function(module) {
105     // TODO(vojta): handle wrong inputs (modules)
106     if (module instanceof Module) {
107       module.forEach(function(provider) {
108         var name = provider[0];
109         var type = provider[1];
110         var value = provider[2];
111
112         providers[name] = [factoryMap[type], value, type];
113       });
114     } else if (typeof module === 'object') {
115       Object.keys(module).forEach(function(name) {
116         var type = module[name][0];
117         var value = module[name][1];
118
119         providers[name] = [factoryMap[type], value, type];
120       });
121     }
122   });
123
124   // public API
125   this.get = get;
126   this.invoke = invoke;
127   this.instantiate = instantiate;
128   this.createChild = createChild;
129 };
130
131 module.exports = Injector;