blob: f9516e0fd26083f5753ae38d09d59f7a8f380779 [file] [log] [blame]
orion.Framework = function () {
this._installOrderBundles = [];
this._resolveOrderBundles = [];
this._exports = {};
this._requiredBundles = {};
this._properties = {};
this._currentBundleId = 0;
this._loader = new orion.ModuleLoader(this);
};
orion.Framework.prototype = {
getBundles : function() {
return this._installOrderBundles.slice();
},
getProperty : function(name) {
return this._properties[name];
},
setProperty : function(name, value) {
this._properties[name] = value;
},
installBundle : function(location, headers) {
if (location === undefined)
throw "location cannot be undefined";
if (location === null)
throw "location cannot be null";
var bundle = new orion.Bundle(this, this._currentBundleId, location, headers);
for ( var i = 0; i < this._installOrderBundles.length; i++) {
if (bundle.equals(this._installOrderBundles[i]))
return this._installOrderBundles[i];
}
this._installOrderBundles[this._currentBundleId] = bundle;
this._currentBundleId++;
return bundle;
},
refresh : function() {
var uninstalledBundleFound = false;
var resolvedBundles = this._resolveOrderBundles.slice();
var i = 0;
var bundle = null;
var newInstallOrderBundles = [];
for (i = 0; i < this._installOrderBundles.length; i++) {
bundle = this._installOrderBundles[i];
if (bundle.getState() !== orion.Bundle.UNINSTALLED) {
newInstallOrderBundles.push(bundle);
}
}
this._installOrderBundles = newInstallOrderBundles;
for (i = 0; i < resolvedBundles.length; i++) {
bundle = resolvedBundles[i];
if (bundle.getState() === orion.Bundle.UNINSTALLED) {
uninstalledBundleFound = true;
}
if (uninstalledBundleFound) {
this._unresolveBundle(bundle);
}
}
if (uninstalledBundleFound) {
var newResolveOrderBundles = [];
for (i = 0; i < this._resolveOrderBundles.length; i++) {
bundle = this._resolveOrderBundles[i];
if (bundle.getState() === orion.Bundle.RESOLVED || bundle.getState() === orion.Bundle.ACTIVE) {
newResolveOrderBundles.push(bundle);
}
}
this._resolveOrderBundles = newResolveOrderBundles;
this.resolve();
}
},
resolve : function() {
var unresolvedBundles = [];
var i = 0;
for (i = 0; i < this._installOrderBundles.length; i++) {
var bundle = this._installOrderBundles[i];
if (bundle.getState() === orion.Bundle.INSTALLED)
unresolvedBundles.push(bundle);
}
var resolvedBundles = [];
var resolvedBundle = null;
while (unresolvedBundles.length !== 0) {
resolvedBundle = this._stepResolver(unresolvedBundles);
if (resolvedBundle !== null)
resolvedBundles.push(resolvedBundle);
else
break;
}
},
shutdown : function() {
var reversed = this._installOrderBundles.slice().reverse();
for ( var i = 0; i < reversed.length; i++) {
var bundle = reversed[i];
bundle.uninstall();
}
this.refresh();
},
_getBundleContext : function(bundle) {
return new orion.BundleContext(bundle, this);
},
_stepResolver : function(unresolvedBundles) {
for (var i = 0; i < unresolvedBundles.length; i++) {
var bundle = unresolvedBundles[i];
if (this._resolveBundle(bundle)) {
this._resolveOrderBundles.push(bundle);
unresolvedBundles.splice(i,1);
return bundle;
}
}
return null;
},
_resolveBundle: function(bundle) {
if (bundle._isSingleton() && this._requiredBundles[bundle.getName()])
return false;
if (this._wire(bundle)) {
bundle._resolve();
this._addExports(bundle);
this._addRequiredBundle(bundle);
return true;
}
this._unwire(bundle);
return false;
},
_wire : function(bundle) {
var imports = bundle._getImports();
for (var i = 0; i < imports.length; i++) {
var jsImport = imports[i];
var name = jsImport.getName();
var candidates = this._exports[name];
var satisfied = false;
if (candidates) {
for (var j = 0; j < candidates.length; j++) {
var candidate = candidates[j];
satisfied = jsImport.wire(candidate);
if (satisfied)
break;
}
}
if (!satisfied && !jsImport.isOptional())
return false;
}
return true;
},
_addExports : function(bundle) {
var exports = bundle._getExports();
for (var i = 0; i < exports.length; i++) {
var jsExport = exports[i];
var name = jsExport.getName();
var namedExports = this._exports[name];
if (!namedExports) {
namedExports = [];
this._exports[name] = namedExports;
}
namedExports.push(jsExport);
namedExports.sort(orion.Framework._exportsComparator);
}
},
_addRequiredBundle : function(bundle) {
var name = bundle.getName();
var namedBundles = this._requiredBundles[name];
if (! namedBundles) {
namedBundles = [];
this._requiredBundles[name]= namedBundles;
}
namedBundles.push(bundle);
namedBundles.sort(orion.Framework._requireBundlesComparator);
},
_unresolveBundle : function(bundle) {
this._removeExports(bundle);
this._removeRequiredBunde(bundle);
bundle._unresolve();
this._unwire(bundle);
},
_removeExports : function(bundle) {
var exports = bundle._getExports();
for ( var i = 0; i < exports.length; i++) {
var jsExport = exports[i];
var name = jsExport.getName();
var namedExports = this._exports[name];
if (!namedExports)
continue;
for ( var j = 0; j < namedExports.length; j++) {
if (namedExports[j] === jsExport) {
namedExports.splice(j, 1);
break;
}
}
if (namedExports.length === 0)
delete this._exports[name];
}
},
_removeRequiredBunde : function(bundle) {
var name = bundle.getName();
var namedBundles = this._requiredBundles[name];
if (!namedBundles)
return;
for ( var i = 0; i < namedBundles.length; i++) {
if (namedBundles[i] === bundle) {
namedBundles.splice(i, 1);
break;
}
}
if (namedBundles.length === 0)
delete this._requiredBundles[name];
},
_unwire : function(bundle) {
var imports = bundle._getImports();
for ( var i = 0; i < imports.length; i++) {
var jsImport = imports[i];
jsImport.unwire();
}
}
};
orion.Framework._exportsComparator = function(export0, export1) {
// order switched for descending order
var result = export1.getVersion().compareTo(export0.getVersion());
if (result == 0)
result = export0.getBundleId() - export1.getBundleId();
return result;
};
orion.Framework._requireBundlesComparator = function(bundle0, bundle1) {
// order switched for descending order
var result = bundle1.getVersion().compareTo(bundle0.getVersion());
if (result == 0)
result = bundle0.getBundleId() - bundle1.getBundleId();
return result;
};
orion.Framework._fetch = function(location){
if (typeof XMLHttpRequest != "undefined") {
var request = new XMLHttpRequest();
request.open("GET", location, false);
request.send();
return request.responseText;
}
var url = new java.net.URL(location);
var reader = new java.io.InputStreamReader(url.openStream());
var stringWriter = new java.io.StringWriter();
var buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024);
var charsRead;
try {
while ((charsRead = reader.read(buffer, 0, 1024)) != -1) {
stringWriter.write(buffer, 0, charsRead);
}
} finally {
reader.close;
stringWriter.close();
}
return stringWriter.toString();
};
orion.Framework._eval = function(script){
// done to give global scope when evaling
return eval(script);
};