60,7 → 60,7 |
private BasePluginObject pluginObject; |
private StringBuilder boilerPlate; |
private List<String> acceptedTypes = null; |
private int maxApi=API.REVISION; |
private int maxApi=API.VERSION; |
// Since these lines are evaluated they'll be executed twice |
// so the lower the number the better to reduce unexpected side effects |
private static int linesToCheckForSupport = 1; |
71,6 → 71,11 |
exportedObjects = new HashMap(); |
pluginObject = null; |
boilerPlate = new StringBuilder(); |
|
// plugin is guaranteed to be a SandboxAccessor, regardless of which |
// exact object it ends up mapping to, see enableSandboxAccess() |
boilerPlate.append("plugin.sandboxGetter = new java.util.concurrent.Callable(function() {") |
.append(" return $net.outlyer.runtime.sandbox; });\n"); |
} |
|
//////////////////////////////////////////////////////// |
86,7 → 91,17 |
public Sandbox createSandbox(final URI forUri) throws PluginException { |
final ScriptEngine rhino = new ScriptEngineManager().getEngineByName("rhino"); |
|
final PluginProperties pp = checkForSupport(forUri); |
PluginProperties pp; |
|
if (null != forUri) { |
pp = checkForSupport(forUri); |
} |
else { |
pp = new PluginProperties(); |
pp.apiVersion = API.VERSION; |
pp.name = "none"; |
pp.type = ""; |
} |
|
if (null == pluginObject) { |
pluginObject = new PluginObject(); |
101,9 → 116,9 |
bindings.put(objectName, exportedObjects.get(objectName)); |
} |
bindings.put("plugin", po); |
enableSandboxAccess("plugin", po); |
//enableSandboxAccess("plugin", po); |
|
return new SandboxImpl(forUri, bindings, pp, boilerPlate.toString()); |
return new SandboxImpl(this, forUri, bindings, pp, boilerPlate.toString()); |
} |
catch (final CloneNotSupportedException e) { |
assert false; |
117,12 → 132,17 |
* the exporting it. |
* @param name Name with which to access the object |
* @param object Object to export |
* @throws IllegalArgumentException If name is <code>null</code> |
* @throws IllegalArgumentException If name is "<code>plugin</code>" (use |
* {@link #setPluginObject()} instead). |
*/ |
public void exportGlobalObject(final String name, final Object object) { |
public void exportObject(final String name, final Object object) { |
if (null == name) { |
throw new IllegalArgumentException("Can't export an object with" + |
"a null name"); |
} |
// Since the plugin object rules' are special (it will be cloned) |
// being nice could (?) lead to confusion |
if (name.equals("plugin")) { |
throw new IllegalArgumentException("Can't export an object named " + |
"plugin, use setPluginObject() instead"); |
133,8 → 153,39 |
enableSandboxAccess(name, (SandboxAccessor)object); |
} |
} |
|
|
/** |
* Makes a package's contents available in the global namespace. |
* (<em>Imports</em> it into JavaScript). |
* @param pkg Package to export |
* @see #exportPackage(String) |
*/ |
public void exportPackage(final Package pkg) { |
if (null == pkg) { |
throw new IllegalArgumentException("Can't export a null package"); |
} |
|
boilerPlate.append("importPackage("+pkg.getName()+")"); |
} |
|
/** |
* Makes a package's contents available in the global namespace. |
* Like {@see #exportPackage(Package)} but exporting by name. |
* @param packageName |
* @see #exportPackage(Package) |
*/ |
public void exportPackage(final String packageName) { |
if (null == packageName) { |
throw new IllegalArgumentException("Can't export a null-named package"); |
} |
final Package pkg = Package.getPackage(packageName); |
if (null == pkg) { |
throw new IllegalArgumentException("Failed to find package "+packageName); |
} |
exportPackage(pkg); |
} |
|
/** |
* Defines the object to be exported as <code>plugin</code>. |
* The <code>plugin</code> object is the only one exported by default. |
* If none is set, a default one will be provided. |
169,9 → 220,24 |
// Non-public interface |
//////////////////////////////////////////////////////// |
|
/** |
* Makes a {@link SanboxAccessor}'s field <code>getSandbox</code> |
* be evaluable as a <code>Callable<Sandbox></code>, i.e., |
* from Java it will be possible to use:<br /> |
* <pre> |
* Sandbox sb = ( (Callable<Sandbox>) object.getSandbox ).call() |
* </pre> |
* to retrieve the sandbox, while from JavaScript it will be enough |
* with: |
* <pre> |
* var sb = object.getSandbox() |
* </pre> |
* @param name Exported object's name |
* @param sa Exported object |
*/ |
private void enableSandboxAccess(final String name, final SandboxAccessor sa) { |
try { |
Field f = sa.getClass().getField("_getSandbox"); |
Field f = sa.getClass().getField("sandboxGetter"); |
} |
catch (final NoSuchFieldException e) { |
throw new IllegalArgumentException("object " + name + " must comply " + |
178,12 → 244,9 |
"with the contract of SandboxAccessor"); |
} |
|
final String callback = name + "._getSandbox"; |
|
boilerPlate.append(callback).append("=function() {") |
.append(" return ") |
.append(EXPORTED_SANDBOX_VARIABLE).append(";\n};"); |
|
boilerPlate.append(name).append(".sandboxGetter=new java.util.concurrent.Callable(function() {") |
.append(" return ") |
.append(EXPORTED_SANDBOX_VARIABLE).append("; });\n"); |
} |
|
PluginProperties checkForSupport(final URI uri) throws PluginException { |