| orion.Bundle = function(framework, bundleData) { |
| this._framework = framework; |
| this._bundleData = bundleData; |
| this._name = null; |
| this._version = null; |
| this._singleton = false; |
| this._imports = []; |
| this._requires = []; |
| this._exports = []; |
| this._resources = {}; |
| this._globals = []; |
| this._markedStarted = false; |
| this._state = orion.Bundle.INSTALLED; |
| this._scope = {}; |
| this._bundleContext = null; |
| this._activator = null; |
| this._script = null; |
| |
| var headers = bundleData.getHeaders(); |
| this._parseName(headers.name); |
| this._parseVersion(headers.version); |
| this._parseSingleton(headers.singleton); |
| this._parseImports(headers.imports); |
| this._parseExports(headers.exports); |
| this._parseRequires(headers.requires); |
| this._parseResources(headers.resources); |
| this._parsePath(headers.path); |
| this._parseGlobals(headers.globals); |
| }; |
| |
| orion.Bundle.UNINSTALLED = 1; |
| orion.Bundle.INSTALLED = 2; |
| orion.Bundle.RESOLVED = 4; |
| orion.Bundle.STARTING = 8; |
| orion.Bundle.STOPPING = 16; |
| orion.Bundle.ACTIVE = 32; |
| |
| orion.Bundle.prototype = { |
| getName : function() { |
| return this._name; |
| }, |
| getVersion : function() { |
| return this._version; |
| }, |
| getBundleId : function() { |
| return this._bundleData.getBundleId(); |
| }, |
| getLocation : function() { |
| return this._bundleData.getLocation(); |
| }, |
| getHeaders : function() { |
| return this._bundleData.getHeaders(); |
| }, |
| getState : function() { |
| return this._state; |
| }, |
| getEntry : function(path) { |
| if (!path || !path instanceof String || !this._resources[path]) |
| return null; |
| |
| return this.getLocation() + path; |
| }, |
| getResource : function(path) { |
| if (!path || !path instanceof String) |
| return null; |
| |
| var i = 0; |
| var resource; |
| for (i = 0; i < this._imports.length; i++) { |
| var jsImport = this._imports[i]; |
| var jsExport = jsImport.getWiredExport(); |
| if (!jsExport) |
| continue; // optional |
| var name = jsExport.getName(); |
| if (name.charAt(0) != "/") |
| continue; // not a resource |
| if (path.indexOf(name)==0) { |
| resource = jsExport.getExportingBundle().getEntry(path); |
| if (resource) |
| return resource; |
| } |
| } |
| |
| // process requires |
| for (i = 0; i < this._requires.length; i++) { |
| var jsRequire = this._requires[i]; |
| var wiredBundle = jsRequire.getWiredBundle(); |
| if (!wiredBundle) { |
| continue; //optional |
| } |
| var wiredBundleExports = wiredBundle._getExports(); |
| for (var j=0; j < wiredBundleExports.length; j++) { |
| jsExport = wiredBundleExports[j]; |
| var name = jsExport.getName(); |
| if (name.charAt(0) != "/") |
| continue; // not a resource |
| if (path.indexOf(name)==0) { |
| resource = jsExport.getExportingBundle().getEntry(path); |
| if (resource) |
| return resource; |
| } |
| } |
| } |
| return this.getEntry(path); |
| }, |
| equals : function(other) { |
| if (this === other) |
| return true; |
| |
| if (!other instanceof orion.Bundle) |
| return false; |
| |
| if (this._name !== other._name) |
| return false; |
| if (this._version === null) { |
| if (other._version !== null) |
| return false; |
| } else if (!this._version.equals(other._version)) |
| return false; |
| return true; |
| }, |
| uninstall : function() { |
| this._state = orion.Bundle.UNINSTALLED; |
| }, |
| start : function() { |
| this._markedStarted = true; |
| if (this._state !== orion.Bundle.RESOLVED) |
| return; |
| |
| this._state = orion.Bundle.STARTING; |
| this._bundleContext = this._framework._getBundleContext(this); |
| this._activator = this._createActivatorInstance(); |
| if (this._activator) { |
| this._activator.start(this._bundleContext); |
| } |
| this._state = orion.Bundle.ACTIVE; |
| }, |
| stop : function() { |
| markedStarted = false; |
| if (this._state !== orion.Bundle.ACTIVE) |
| return; |
| |
| this._state = orion.Bundle.STOPPING; |
| if (this._activator) { |
| this._activator.stop(this._bundleContext); |
| } |
| this._state = orion.Bundle.RESOLVED; |
| }, |
| load : function(name) { |
| var value = this._scope; |
| if (value === null || value === undefined) { |
| return undefined; |
| } |
| var names = name.split("."); |
| for ( var i = 0; i < names.length; i++) { |
| if (value === null || value === undefined) { |
| return undefined; |
| } |
| value = value[names[i]]; |
| } |
| return value; |
| }, |
| _isSingleton : function() { |
| return this._singleton; |
| }, |
| _isMarkedStarted : function() { |
| return this._markedStarted; |
| }, |
| _getImports : function() { |
| return this._imports; |
| }, |
| _getExports : function() { |
| return this._exports; |
| }, |
| _getRequires : function() { |
| return this._requires; |
| }, |
| _createActivatorInstance : function() { |
| var activatorName = this.getHeaders().activator; |
| if (activatorName === null || activatorName === undefined) |
| return null; |
| |
| var activatorFunction = this.load(activatorName); |
| if (typeof activatorFunction !== "function") |
| throw "" + activatorName + " is not a function."; |
| return new activatorFunction(); |
| }, |
| _resolve : function() { |
| if (this._state != orion.Bundle.INSTALLED) |
| return; |
| |
| var namedExports = {}; |
| var jsExport = null; |
| var i = 0; |
| // process imports (first) |
| for (i = 0; i < this._imports.length; i++) { |
| var jsImport = this._imports[i]; |
| var jsExport = jsImport.getWiredExport(); |
| if (!jsExport) |
| continue; // optional |
| var name = jsExport.getName(); |
| if (name.charAt(0) == "/") |
| continue; // resource |
| if (!namedExports.hasOwnProperty(name)) |
| namedExports[name] = jsImport.getWiredExport(); |
| } |
| |
| // process requires |
| for (i = 0; i < this._requires.length; i++) { |
| var jsRequire = this._requires[i]; |
| var wiredBundle = jsRequire.getWiredBundle(); |
| if (!wiredBundle) { |
| continue; //optional |
| } |
| var wiredBundleExports = wiredBundle._getExports(); |
| for (var j=0; j < wiredBundleExports.length; j++) { |
| jsExport = wiredBundleExports[j]; |
| var name = jsExport.getName(); |
| if (name.charAt(0) == "/") |
| continue; // resource |
| if (!namedExports.hasOwnProperty(name)) |
| namedExports[name] = jsImport.getWiredExport(); |
| } |
| } |
| |
| var names = []; |
| var exportName = null; |
| for (exportName in namedExports) { |
| if (namedExports.hasOwnProperty(exportName)) |
| names.push(exportName); |
| } |
| |
| // this sorts the set of names we'll be importing alphabetically and |
| // perhaps more importantly will allow us to create the shorter/parent dotted entries first |
| names.sort(); |
| |
| var importScope = {}; |
| for (i = 0; i < names.length; i++) { |
| exportName = names[i]; |
| jsExport = namedExports[exportName]; |
| jsExport.addToScope(importScope); |
| } |
| |
| this._evalScript(importScope); |
| this._state = orion.Bundle.RESOLVED; |
| }, |
| _evalScript : function(importScope) { |
| var parameterNames = ["getResource"]; |
| var that = this; |
| var boundGetResource = function(path) { |
| return that.getResource(path); |
| }; |
| var parameterValues = [boundGetResource]; |
| var parameterName = null; |
| for (parameterName in importScope) { |
| if (importScope.hasOwnProperty(parameterName)) { |
| parameterNames.push(parameterName); |
| parameterValues.push(importScope[parameterName]); |
| } |
| } |
| |
| var exportNames = []; |
| for (var i = 0; i < this._exports.length; i++) { |
| var exportName = this._exports[i].getName(); |
| if (exportName.charAt(0) == "/") |
| continue; // resource |
| var dotIndex = exportName.indexOf("."); |
| if (dotIndex !== -1) |
| exportName = exportName.substring(0,dotIndex); |
| |
| if (! exportNames.hasOwnProperty(exportName)) { |
| exportNames[exportName] = true; |
| exportNames.push(exportName + ":" + exportName); |
| } |
| } |
| |
| var parameterStatement = parameterNames.join(","); |
| var returnStatement = "\n\nreturn {" + exportNames.join(",") + "};"; |
| |
| var finalScript = this._script + returnStatement; |
| // var load = new Function(parameterStatement, finalScript); |
| var load = orion.Framework._eval("(function("+parameterStatement+") {\n" + finalScript + "\n})//@ sourceURL=" + this.getLocation()); |
| this._scope = load.apply(null, parameterValues); |
| }, |
| _unresolve : function() { |
| if (this._state == orion.Bundle.ACTIVE) { |
| this.stop(); |
| markedStarted = true; |
| } |
| this._scope = null; |
| |
| if (this._state == orion.Bundle.RESOLVED) |
| this._state = orion.Bundle.INSTALLED; |
| }, |
| _parseName : function(header) { |
| this._name = header; |
| }, |
| _parseSingleton : function(header) { |
| if (typeof header == "boolean") |
| this._singleton = header; |
| }, |
| _parseVersion : function(header) { |
| this._version = orion.Version.parseVersion(header); |
| }, |
| _parseGlobals : function(header) { |
| if (!header) |
| return; |
| |
| for ( var i = 0; i < header.length; i++) { |
| if (header[i]) { |
| this._globals.push(header[i]); |
| } |
| } |
| }, |
| _parseResources : function(header) { |
| if (!header) |
| return; |
| |
| for ( var i = 0; i < header.length; i++) { |
| if (header[i]) { |
| this._resources[header[i]] = true; |
| } |
| } |
| }, |
| _parseRequires : function(header) { |
| if (!header) |
| return; |
| |
| for ( var i = 0; i < header.length; i++) { |
| var jsRequire = new orion.Require(header[i]); |
| if (jsRequire !== null) |
| this._requires.push(jsRequire); |
| } |
| }, |
| _parseExports : function(header) { |
| if (!header) |
| return; |
| |
| for ( var i = 0; i < header.length; i++) { |
| var jsExport = new orion.Export(header[i], this); |
| if (jsExport !== null) |
| this._exports.push(jsExport); |
| } |
| }, |
| _parseImports : function(header) { |
| if (!header) |
| return; |
| |
| for ( var i = 0; i < header.length; i++) { |
| var jsImport = new orion.Import(header[i]); |
| if (jsImport !== null) |
| this._imports.push(jsImport); |
| } |
| }, |
| _parsePath : function(header) { |
| if (!header) { |
| this._script = this._bundleData.getHeaders().script || ""; |
| return; |
| } |
| var scripts = []; |
| for ( var i = 0; i < header.length; i++) { |
| var path = header[i]; |
| if (path === ".") { |
| scripts[i] = this._bundleData.getHeaders().script || ""; |
| } else { |
| var scriptURL = this.getResource(path); |
| scripts[i] = orion.Framework._fetch(scriptURL); |
| } |
| } |
| this._script = scripts.join("\n\n"); |
| } |
| }; |