Subversion Repositories pub

Compare Revisions

No changes between revisions

Ignore whitespace Rev 56 → Rev 57

/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/Sandbox.java
0,0 → 1,92
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Public methods provided by the sandbox.
* Note that all methods in this interface imply a call to {@link #execute}.
*/
public interface Sandbox extends RuntimeHooks, SandboxProperties {
 
/**
* @see #createDelayedImplementation(Class, boolean)
* @deprecated (TEMPORARILY) Until the API stabilizes,
* {@link #createDelayedImplementation(Class, String)} is the only
* secure variant.
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass) throws PluginExecutionException;
 
/**
* Creates an implementation of an interface from JS code
* @param interfaceClass Class of the interface to implement
* @param allowPartialImplementation If true, the implementation would be used
* even if incomplete (note that calling an unimplemented method will produce
* an exception)
* @return The implementation
* @throws net.outlyer.plugins.sandboxing.PluginExecutionException
* @deprecated (TEMPORARILY) Until the API stabilizes,
* {@link #createDelayedImplementation(Class, String)} is the only
* secure variant.
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass,
boolean allowPartialImplementation)
throws PluginExecutionException;
 
/**
* @see #createDelayedImplementation(Class, boolean)
* @param fallbackObject If not null incomplete implementations are allowed and
* calls to undefined methods will be passed to this object
* @deprecated (TEMPORARILY) Until the API stabilizes,
* {@link #createDelayedImplementation(Class, String)} is the only
* secure variant.
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass,
final T fallbackObject)
throws PluginExecutionException;
 
/**
* Creates an implementation of an interface from a JS object
* containing the interface's methods.
* @param interfaceClass Interface to implement
* @param objectName Name of the JS object implementing the interface
* @return The implementation
* @throws net.outlyer.plugins.PluginExecutionException
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass, final String objectName) throws PluginExecutionException;
 
/**
* Run the script
*/
void execute() throws PluginExecutionException;
 
/**
* Obtains object containing the plugin object
* @see #getPluginName
* @return Plugin object associated to this sandbox
*/
BasePluginObject getPluginObject() throws PluginExecutionException;
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginExecutionException.java
0,0 → 1,49
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* PluginException produced when an execution failed.
*/
public class PluginExecutionException extends PluginException {
 
public PluginExecutionException(Throwable cause) {
super(cause);
}
 
public PluginExecutionException(String message, Throwable cause) {
super(message, cause);
}
 
public PluginExecutionException(String message) {
super(message);
}
 
public PluginExecutionException() {
}
 
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/SandboxAccessorImpl.java
0,0 → 1,49
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.util.concurrent.Callable;
 
/**
* {@see SandboxAccessor}
*/
public abstract class SandboxAccessorImpl implements SandboxAccessor {
public Callable<Sandbox> _getSandbox;
protected final Sandbox getSandbox() {
if (null == _getSandbox) {
throw new IllegalStateException(getClass()+" hasn't been correctly initialised");
}
try {
return _getSandbox.call();
}
catch (final Exception e) {
throw new IllegalStateException("getSandbox produced an exception, which is not expected!");
}
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginEnvironmentImpl.java
0,0 → 1,250
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.IOException;
import java.io.LineNumberReader;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
/**
* Default implementation of a PluginEnvironment.
*/
final class PluginEnvironmentImpl extends PluginEnvironment {
static class UnsupportedAPIException extends PluginException {
public UnsupportedAPIException(int providedApi) {
super("Plugin has unsupported API ("+providedApi+")");
}
}
static class UnsupportedTypeException extends PluginException {
public UnsupportedTypeException(String pluginType) {
super("Plugin has unsupported type ("+pluginType+")");
}
}
private final Map<String, Object> exportedObjects;
private BasePluginObject pluginObject;
private StringBuilder boilerPlate;
private List<String> acceptedTypes = null;
private int maxApi=API.REVISION;
// Since these lines are evaluated they'll be executed twice
// so the lower the number the better to reduce unexpected side effects
int linesToCheckForSupport = 1;
 
static final String EXPORTED_SANDBOX_VARIABLE = "$net.outlyer.runtime.sandbox";
{
exportedObjects = new HashMap();
pluginObject = null;
boilerPlate = new StringBuilder();
}
private void enableSandboxAccess(final String name, final SandboxAccessor sa) {
try {
Field f = sa.getClass().getField("_getSandbox");
}
catch (final NoSuchFieldException e) {
throw new IllegalArgumentException("object " + name + " must comply " +
"with the contract of SandboxAccessor");
}
 
final String callback = name + "._getSandbox";
 
boilerPlate.append(callback).append("=function() {")
.append(" return ")
.append(EXPORTED_SANDBOX_VARIABLE).append(";\n};");
 
}
/**
* {@inheritDoc}
*/
public void exportGlobalObject(final String name, final Object object) {
if (null == name) {
throw new IllegalArgumentException("Can't export an object with" +
"a null name");
}
if (name.equals("plugin")) {
throw new IllegalArgumentException("Can't export an object named " +
"plugin, use setPluginObject() instead");
}
exportedObjects.put(name, object);
if (object instanceof SandboxAccessor) {
enableSandboxAccess(name, (SandboxAccessor)object);
}
}
/**
* {@inheritDoc}
*/
public void setPluginObject(BasePluginObject pObject) {
pluginObject = pObject;
}
PluginProperties checkForSupport(final URI uri) throws PluginException {
final ScriptEngine rhino = new ScriptEngineManager().getEngineByName("rhino");
 
try {
// Define a Plugin object with a field named type
rhino.eval("var plugin={ type: null, apiVersion: null };");
}
catch (ScriptException e) {
assert false;
throw new IllegalStateException("Unknown error encountered");
}
 
// First of all check the script for support
Object type = null, name = null;
Object apiVersion = null;
// Try to eval each line, since it executes in a sandbox this is
// *relatively* safe
String line;
try {
final LineNumberReader script = new LineNumberReader(new PluginReader(uri));
try {
while ((null == type || null == apiVersion || null == name) &&
(null != (line = script.readLine())) &&
script.getLineNumber() < linesToCheckForSupport) {
try {
rhino.eval(line);
// Note that undefined doesn't convert to null!
if (null == type) {
rhino.eval("$_1_$ = (undefined===plugin.type)?null:plugin.type;");
type = rhino.get("$_1_$");
}
if (null == apiVersion) {
rhino.eval("$_1_$ = (undefined===plugin.apiVersion)?null:plugin.apiVersion;");
apiVersion = rhino.get("$_1_$");
}
if (null == name) {
rhino.eval("$_1_$ = (undefined===plugin.name)?null:plugin.name;");
name = rhino.get("$_1_$");
}
}
catch (final ScriptException e) {
// Exceptions are to be expected since none of the guaranteed
// plugin tools are provided in this context they'll try to
// access unexisting objects
}
}
}
finally {
script.close();
}
}
catch (final IOException e) {
throw new PluginExecutionException("Failed while reading plugin: " + e.getMessage(), e);
}
 
if (null == type) {
type = "";
}
if (null == apiVersion) {
apiVersion = 0;
}
// name can be null
final PluginProperties pp = new PluginProperties();
 
try {
pp.apiVersion = Double.valueOf(apiVersion.toString()).intValue();
pp.type = type.toString();
pp.name = (null != name) ? name.toString(): null;
}
catch (final NumberFormatException e) {
throw new PluginException("Incorrect value for apiVersion provided, must be integer");
}
if (null != acceptedTypes) {
if (!acceptedTypes.contains(pp.type)) {
throw new UnsupportedTypeException(pp.type);
}
}
if (pp.apiVersion > maxApi) {
throw new UnsupportedAPIException(pp.apiVersion);
}
return pp;
}
 
/**
* {@inheritDoc}
*/
public Sandbox createSandbox(final URI forUri) throws PluginException {
final ScriptEngine rhino = new ScriptEngineManager().getEngineByName("rhino");
final PluginProperties pp = checkForSupport(forUri);
 
if (null == pluginObject) {
pluginObject = new PluginObject();
}
 
try {
final PluginObject po = (PluginObject) pluginObject.clone();
 
final Bindings bindings = rhino.createBindings();
 
for (final String objectName : exportedObjects.keySet()) {
bindings.put(objectName, exportedObjects.get(objectName));
}
bindings.put("plugin", po);
enableSandboxAccess("plugin", po);
 
return new SandboxImpl(forUri, bindings, pp, boilerPlate.toString());
}
catch (final CloneNotSupportedException e) {
assert false;
throw new IllegalStateException("Incorrect implementation");
}
}
 
/**
* {@inheritDoc}
*/
public void setAcceptedTypes(final String ... pluginTypes) {
if (null != pluginTypes) {
for (final String type : pluginTypes) {
if (null == type) {
throw new IllegalArgumentException("The set of plugin types" +
" must be either null, or a set of non-null values");
}
}
}
acceptedTypes = Arrays.asList(pluginTypes);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/Shell.java
0,0 → 1,70
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.File;
import net.outlyer.plugins.utils.*;
 
/**
* Sample shell for tests, files passed as arguments will be loaded and
* executed.
*/
public final class Shell {
public static void main(String...args) {
if (args.length == 0) {
System.err.printf("Usage: java [...] %s [file1.js [file2.js [...]]]\n",
Shell.class.getName());
System.exit(1);
}
final PluginEnvironment pe = PluginEnvironment.create();
pe.exportGlobalObject("input", new Input());
pe.exportGlobalObject("out", new Output());
pe.exportGlobalObject("err", new Output(System.err));
pe.exportGlobalObject("hooks", new Hooks());
// Generally either UI or GUI should be used but not both
// since GUI falls-back to UI if appropriate (so the ui object
// will use the "best" implementation)
pe.exportGlobalObject("ui", new GUI());
pe.exportGlobalObject("gui", new GUI());
pe.exportGlobalObject("cui", new UI()); // cui stands for Console UI
final PluginObject po = new PluginObject();
pe.setPluginObject(po);
for (final String path : args) {
try {
final Sandbox sandbox = pe.createSandbox(new File(path).toURI());
sandbox.execute();
}
catch (final PluginException e) {
System.err.printf("Exception while running plugin %s: %s\n",
path, e.getLocalizedMessage());
System.exit(2);
}
}
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/API.java
0,0 → 1,60
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* API versioning
*/
public final class API {
// Release will be REVISION.(IMPLEMENTATION-1) i.e.
// for REVISION=1 and IMPLEMENTATION=1, release would be 1.0
 
/**
* API Revision.
* Newer revisions might break backwards compatibility (see
* {@link #MIN_SUPPORTED_REVISION}).
*/
public static final int REVISION = 1;
 
/**
* Implementation of the API revision.
* Different implementations of an API are guaranteed to maintain
* the API unchanged.
* @see #REVISION
*/
public static final int IMPLEMENTATION = 1;
 
/**
* Minimum API revision supported by this implementation.
* For future use.
* In principle a new API should provide support for previous revisions,
* in case it doesn't, this constant will hold the lower supported API.
* @see #REVISION
* @pre MIN_SUPPORTED_REVISION &lt;= REVISION
*/
public static final int MIN_SUPPORTED_REVISION = 1;
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/SandboxProperties.java
0,0 → 1,56
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.net.URI;
 
/**
* Provides access to some properties of a sandbox
* @see Sandbox
*/
public interface SandboxProperties {
/**
* Obtains the number of this execution (each time the script is executed
* this value is increases by one)
* @return Execution number
*/
public int getExecution();
 
/**
* Obtains the URI/file name from which this sandbox was created.
* @return Script file name
*/
public URI loadedFrom();
 
/**
* Obtains the name of the script of this sandbox
* @return Plugin name
* @see #loadedFrom
*/
public String getPluginName();
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginProperties.java
0,0 → 1,38
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Common properties of the plugin object. All of them
* take sane defaults.
*/
public class PluginProperties extends SandboxAccessorImpl {
public int apiVersion = 1;
public String type;
public String name;
public Object properties; // FIXME: To be defined
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginException.java
0,0 → 1,49
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Base exception
*/
public class PluginException extends Exception {
 
public PluginException(Throwable cause) {
super(cause);
}
 
public PluginException(String message, Throwable cause) {
super(message, cause);
}
 
public PluginException(String message) {
super(message);
}
 
public PluginException() {
}
 
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/SandboxImpl.java
0,0 → 1,320
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import net.outlyer.plugins.Sandbox;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import net.outlyer.plugins.BasePluginObject;
import net.outlyer.plugins.PluginProperties;
 
/**
* Implementation of the Sandbox interface
*/
class SandboxImpl implements Sandbox {
private final Bindings bindings;
private final URI pluginUri;
private static int nextUniqueVarNum;
private Map<String, Collection<Runnable>> hooks;
private final String boilerPlate;
private int execution = 0;
private final PluginProperties properties;
private static final String END_KEY = "e";
 
static {
nextUniqueVarNum = (int) (1193 * (1+Math.random()));
}
{
hooks = new HashMap<String, Collection<Runnable>>();
hooks.put(END_KEY, new LinkedList<Runnable>());
}
protected SandboxImpl(final URI plugin, final Bindings bs, final PluginProperties pp) {
this(plugin, bs, pp, null);
}
protected SandboxImpl(final URI plugin, final Bindings bs,
final PluginProperties pp, final String boilerPlate) {
bindings = bs;
pluginUri = plugin;
this.boilerPlate = boilerPlate;
properties = pp;
}
public void addEndHook(Runnable r) {
hooks.get(END_KEY).add(r);
}
 
/**
* Namespace for variables used by the enviroment
*/
private static String namespace() {
return "$net.outlyer.runtime";
}
 
/**
* Creates a unique variable name.
*/
private static String uniqueVarName() {
return new StringBuilder("$_").append(nextUniqueVarNum+=1193).append("_$").toString();
}
 
/**
* Creates a unique variable name including namespace
* @see #namespace
* @see #uniqueVarName
*/
private static String uniqueFQVarName() {
return new StringBuilder(namespace()).append(".")
.append(uniqueVarName()).toString();
}
private static ScriptEngine getEngine() {
return new ScriptEngineManager().getEngineByName("rhino");
}
private ScriptEngine execute(boolean appendText, String text, final Map<String,Object> extraBindings)
throws PluginExecutionException {
final ScriptEngine rhino = getEngine();
// First, export in the global namespace the reference to this
// sandbox. This variable isn't meant to be used directly, it's only
// set to refer to it from the boilerplate code (AFAIK there's no
// way to add a binding with a FQ name).
// TODO: Can a fully qualified name be bound directly?
final String globalSanboxVarName = uniqueVarName();
bindings.put(globalSanboxVarName, this);
if (null != extraBindings) {
for (final String key : extraBindings.keySet()) {
bindings.put(key, extraBindings.get(key));
}
}
// Will contain some biolerplate code used to provide access
// to the runtime wrapped-environment
final StringBuilder runtime = new StringBuilder();
// $net.outlyer.runtime.sandbox Contains a reference to this object
// Implementation note: PluginEnvironment.EXPORTED_SANDBOX_VARIABLE should have the same name
// TODO: ? $net.outlyer.runtime.pluginEnvironment
runtime.append("var $net = {\n")
.append(" outlyer : {\n")
.append(" runtime : {\n")
.append(" sandbox : ").append(globalSanboxVarName).append("\n")
.append(" }\n")
.append(" }\n")
.append("};\n");
 
try {
rhino.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
 
execution++;
if (null != boilerPlate) {
rhino.eval(boilerPlate);
}
// Create the $net.outlyer.runtime pseudo-namespace...
rhino.eval(runtime.toString());
 
rhino.eval(new PluginReader(pluginUri));
if (appendText) {
rhino.eval(text);
}
// Execute any end hooks
for (final Runnable hook : hooks.get(END_KEY)) {
hook.run();
}
}
catch (final IOException e) {
throw new PluginExecutionException("I/O Error: " + e.getMessage(), e);
}
catch (final ScriptException e) {
throw new PluginExecutionException("Script exception: " + e.getMessage(), e);
}
return rhino;
}
public void execute() throws PluginExecutionException {
execute(false, null, null);
}
 
public <T> T createDelayedImplementation(final Class<T> c,
final String objectName)
throws PluginExecutionException {
System.err.println("createDelayedImple");
final String varImpl = uniqueVarName();
 
final StringBuilder code = new StringBuilder();
 
code.append("var ").append(objectName).append(" = {\n");
for (final Method method : c.getMethods()) {
if (method.getDeclaringClass() != c) {
continue;
}
code.append(method.getName()).append(": null,");
}
code.append("};\n");
 
code.append(varImpl).append(" = new ")
.append(c.getCanonicalName()).append("(").append(objectName).append(");");
System.err.println(code.toString());
 
final ScriptEngine rhino = execute(true, code.toString(), null);
 
assert (c.isInstance(rhino.get(varImpl)));
return (T) rhino.get(varImpl);
}
 
public <T> T createDelayedImplementation(final Class<T> c)
throws PluginExecutionException {
return createDelayedImplementation(c, false);
}
 
public <T> T createDelayedImplementation(final Class<T> c, boolean allowPartial)
throws PluginExecutionException {
return createDelayedImplementation(c, null, allowPartial);
}
 
public <T> T createDelayedImplementation(final Class<T> interfaceClass,
final T fallbackObject)
throws PluginExecutionException {
if (null == fallbackObject) {
throw new IllegalArgumentException("Can't use a null fallback object");
}
return createDelayedImplementation(interfaceClass, fallbackObject, true);
}
 
private <T> T createDelayedImplementation(final Class<T> c,
final T fallback,
boolean allowPartial)
throws PluginExecutionException {
final StringBuilder hack = new StringBuilder();
 
final String var = uniqueFQVarName();
// Apparently only global namespace objects can be retrieved with get()
// so to simplify retrieval a global variable is used
final String varImpl = uniqueVarName();
 
hack.append(var).append("={\n");
 
final StringBuilder script = new StringBuilder();
 
final String varFallback = uniqueVarName();
 
for (final Method m : c.getMethods()) {
if (m.getDeclaringClass() != c) {
continue;
}
 
final String implFuncName = c.getSimpleName()+"_"+m.getName();
if (allowPartial) {
// This makes undefined functions to be mapped to undefined
// variables (otherwise the interface instantation would fail)
// Apparently defining a var with the same name as a function
// produces no error, while checking for an undefined
// variable/method does fail.
// FIXME: Might be cleaner by handling "undefined"
script.append("var ").append(implFuncName).append(";\n");
if (null != fallback) {
script.append("if (!").append(implFuncName).append(")\n\t")
.append(implFuncName).append("=")
.append(varFallback).append(".").append(m.getName())
.append("\n");
}
// script.append("if (!").append(implFuncName).append(") ")
// .append(implFuncName).append("=null;\n");
}
hack.append("\t").append(m.getName()).append(" : ").append(implFuncName).append(",\n");
}
hack.append("};\nvar ")
.append(varImpl).append("=new ")
.append(c.getCanonicalName()).append("(").append(var).append(");");
script.append(hack.toString());
final HashMap<String, Object> bn = new HashMap();
bn.put(varFallback, fallback);
 
if (null != fallback) {
script.append("\n// " + bn.get(varFallback).getClass());
}
//System.err.println(script.toString());
 
final ScriptEngine rhino = execute(true, script.toString(), bn);
assert (c.isInstance(rhino.get(varImpl)));
return (T) rhino.get(varImpl);
}
 
public BasePluginObject getPluginObject() throws PluginExecutionException {
execute();
assert bindings.get("plugin") instanceof BasePluginObject;
return (BasePluginObject) bindings.get("plugin");
}
public int getExecution() {
return execution;
}
 
/**
* {@inheritDoc}
*/
public String getPluginName() {
if (null == properties.name) {
return new File(loadedFrom().getPath()).getName(); // FIXME: <= Is this safe?
}
return properties.name;
}
 
/**
* {@inheritDoc}
*/
public URI loadedFrom() {
return pluginUri.normalize(); // FIXME: Return a copy
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/BasePluginObject.java
0,0 → 1,39
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Simplest object to be exported as "plugin"
* @see PluginObject
*/
public class BasePluginObject extends PluginProperties implements SandboxAccessor, Cloneable {
public int version = 0;
 
@Override public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/UI.java
0,0 → 1,66
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.File;
 
/**
* User Interface-related methods.
*/
public class UI {
/**
* Prompt the user for a string
* @param question Question to ask
* @return String written by the user
*/
public String prompt(final String question) {
System.err.printf("%s: ", question);
return new Input().readline();
}
 
/**
* Prompts the user for an existent file path.
* If the provided path is empty the result will be null, otherwise
* the prompt will be repeated until a valid file is provided.
* @param message Message to display
* @return User-provided file or null if none
*/
public File promptForFile(final String message) {
do {
final Input in = new Input();
System.err.printf("%s: ", message);
final String path = in.readline();
if (path.isEmpty()) {
return null;
}
final File file = new File(path);
if (file.isFile()) {
return file;
}
} while (true);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/Input.java
0,0 → 1,58
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
/**
* Provides a simplified wrapper for input.
*/
public class Input {
 
private final InputStream in;
 
public Input() {
this(System.in);
}
public Input(final InputStream is) {
in = is;
}
public String readline() {
final BufferedReader br = new BufferedReader(new InputStreamReader(in));
try {
return br.readLine();
}
catch (final IOException e) {
return null;
}
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/Output.java
0,0 → 1,66
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.PrintStream;
 
/**
* Provides a simplified wrapper for output.
*/
public class Output {
 
private final PrintStream ps;
public Output() {
this(System.out);
}
public Output(final PrintStream ps) {
this.ps = ps;
}
public void println() {
ps.println();
}
public void println(final String s) {
ps.println(s);
}
 
/**
* Note that varargs can't be used transparently from JS
* @param sfmt
* @param args
*/
public void printf(final String sfmt, final Object [] args) {
ps.printf(sfmt, args);
}
public void printf(final String s) {
ps.printf("%s", s);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/Hooks.java
0,0 → 1,39
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import net.outlyer.plugins.SandboxAccessorImpl;
 
/**
* Provides hooks to points in time during execution.
*/
public class Hooks extends SandboxAccessorImpl {
// Due to Rhino's magic passing a JS function() is enough
public void atexit(Runnable callback) {
getSandbox().addEndHook(callback);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/GUI.java
0,0 → 1,64
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.awt.GraphicsEnvironment;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
 
/**
* User Interface-related methods with <b>optional</b> GUI support.
* In a headless environment will fall back to {@link net.outlyer.plugins.utils.UI}
* methods.
*/
public class GUI extends UI {
 
/**
* {@inheritDoc}
*/
@Override public String prompt(final String question) {
if (GraphicsEnvironment.isHeadless()) {
return super.prompt(question);
}
return JOptionPane.showInputDialog(question);
}
 
/**
* {@inheritDoc}
*/
@Override public File promptForFile(final String title) {
if (GraphicsEnvironment.isHeadless()) {
return super.promptForFile(title);
}
final JFileChooser fc = new JFileChooser();
fc.setMultiSelectionEnabled(false);
fc.setDialogTitle(title);
fc.showOpenDialog(null);
return fc.getSelectedFile();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/utils/package-info.java
0,0 → 1,33
/**
* This package provides some common functionality that might often be
* wanted to be exported as global objects.
* {@see net.outlyer.plugins.sandboxing.PluginEnvironment#exportGlobalObject}.
*/
 
// $Id$
 
package net.outlyer.plugins.utils;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/SandboxAccessor.java
0,0 → 1,43
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Optional interface for exported objects (see
* {@link net.outlyer.plugins.sandboxing.PluginEnvironment#exportGlobalObject}),
* it enables exported objects to retrieve the sandbox object in which they're
* being executed.
*
* Implementors must contain a field exactly:
*
* public Callable<Sandbox> _getSandbox = null;
*
* The convenience default implementation, {@link SandboxAccessorImpl} can
* be used as a base class if that's possible, to hide such requirement.
*/
public interface SandboxAccessor {
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginReader.java
0,0 → 1,79
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
 
/**
* java.io.Reader for plugins, tries to abstract the plugin location (file or jar)
*/
class PluginReader extends Reader {
 
private final Reader readerImpl;
 
PluginReader(final URI uri) throws IOException {
super();
assert null != uri;
 
try {
if (uri.getScheme().equals("file")) {
readerImpl = new FileReader(new File(uri));
}
else {
final String path = uri.getSchemeSpecificPart().split("!")[1];
final InputStream is = getClass().getResourceAsStream(path);
if (null == is) {
throw new IOException("Failed to get resource for " + uri);
}
readerImpl = new InputStreamReader(is);
}
// TODO: Add exception for other schemes
}
catch (final FileNotFoundException e) {
throw new IOException("Can\'t read input " + uri);
}
}
 
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return readerImpl.read(cbuf, off, len);
}
 
@Override
public void close() throws IOException {
readerImpl.close();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginLocator.java
0,0 → 1,368
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
 
/**
* Simplifies seeking plugins and abstracts their location (whether they're
* in a directory or inside a jar file).
*/
public class PluginLocator {
 
private final List<URI> paths;
private final Library library;
private static final FileFilter jsFileFilter;
private boolean scanned = false;
private final PluginEnvironment environment;
static {
jsFileFilter = new FileFilter() {
public boolean accept(final File pathname) {
return pathname.isFile() && pathname.canRead() &&
pathname.getName().endsWith(".js");
}
};
}
private static class Library {
// FIXME: Do something more elegant...
private final HashMap<String, List<Sandbox>> byType;
private final HashMap<String, Sandbox> byFilename; // FIXME: Not really unique
private final HashMap<String, Sandbox> byName;
private final HashSet<Sandbox> unique;
{
byType = new HashMap<String, List<Sandbox>>();
byFilename = new HashMap<String, Sandbox>();
byName = new HashMap<String, Sandbox>();
unique = new HashSet<Sandbox>();
}
void add(final String fileName, final BasePluginObject bpo, final Sandbox sbox) {
byName.put(bpo.name, sbox);
byFilename.put(fileName, sbox);
if (byType.get(bpo.type) == null) {
byType.put(bpo.type, new LinkedList<Sandbox>());
}
byType.get(bpo.type).add(sbox);
unique.add(sbox);
}
void drop() {
byType.clear();
byFilename.clear();
byName.clear();
unique.clear();
}
}
{
paths = new LinkedList<URI>();
library = new Library();
}
public PluginLocator(final PluginEnvironment pe, final URI...searchPaths) {
if (null == searchPaths) {
throw new IllegalArgumentException("Can't initialise PluginLocator with no search path");
}
for (final URI path : searchPaths) {
addSearchPath(path);
}
environment = pe;
}
public void addSearchPath(final URI path) {
if (null == path) {
throw new IllegalArgumentException("Can't have a null path in the search paths");
}
 
if (path.getScheme().equals("file")) {
final File file = new File(path.normalize()).getAbsoluteFile();
if (file.exists() && file.isDirectory() && file.canRead()) {
paths.add(file.toURI().normalize());
}
}
else if (path.getScheme().equals("jar")) {
final URI normalized = path.normalize();
if (!normalized.getSchemeSpecificPart().endsWith("/")) {
throw new IllegalArgumentException("Jar file entries must" +
" represent directories");
}
// TODO: Check for existence (Class.getResource())
paths.add(normalized);
}
else {
throw new IllegalArgumentException("Only directories or jar directories are accepted");
}
}
public Sandbox getFirst(final String type, final String name, final String fileName) {
if (null == type && null == name && null == fileName) {
throw new IllegalArgumentException("At least one of type, name or fileName must be non-null");
}
if (!scanned) {
throw new IllegalStateException("Can't retrieve before scanning");
}
final Set<Sandbox> sf = new HashSet<Sandbox>(),
sn = new HashSet<Sandbox>(),
st = new HashSet<Sandbox>();
// All keys are optional but if one of them is not null and yields no
// results then getFirst yields no result
if (null != fileName) {
final Sandbox s = library.byFilename.get(fileName);
if (null == s) {
return null;
}
sf.add(s);
}
if (null != name) {
final Sandbox s = library.byName.get(name);
if (null == s) {
return null;
}
sn.add(s);
}
if (null != type) {
final Collection<Sandbox> byType = library.byType.get(type);
if (byType.isEmpty()) {
return null;
}
st.addAll(byType);
}
Set<Sandbox> inters;
 
if (null != fileName) {
inters = sf;
 
if (null != name) {
assert ! sn.isEmpty();
inters.retainAll(sn);
}
if (!inters.isEmpty() && null != type) {
assert ! st.isEmpty();
inters.retainAll(st);
}
}
else if (null != name) {
assert null == fileName && sf.isEmpty();
inters = sn;
if (null != type) {
assert ! st.isEmpty();
sn.retainAll(st);
}
}
else {
assert null != type && ! st.isEmpty();
assert null == name && sn.isEmpty();
assert null == fileName && sf.isEmpty();
 
inters = st;
}
if (inters.isEmpty()) {
return null;
}
 
return inters.iterator().next();
}
public Collection<Sandbox> getAll(final String type, final String name, final String fileName) {
if (null == type && null == name && null == fileName) {
throw new IllegalArgumentException("At least one of type, name or fileName must be non-null");
}
if (!scanned) {
throw new IllegalStateException("Can't retrieve before scanning");
}
final Set<Sandbox> set = new HashSet<Sandbox>();
if (null != fileName) {
final Sandbox s = library.byFilename.get(fileName);
if (null != s) {
set.add(s);
}
}
if (null != name) {
final Sandbox s = library.byName.get(name);
if (null != s) {
set.add(s);
}
}
if (null != type) {
final Collection<Sandbox> sbox = library.byType.get(type);
if (null != sbox) {
set.addAll(sbox);
}
}
return Collections.unmodifiableSet(set);
}
public void scan() {
if (scanned) {
return;
}
if (paths.size() == 0) { // Nothing to scan
scanned = true;
return;
}
 
for (final URI uri : paths) {
if (uri.getScheme().equals("file")) {
final File dir = new File(uri);
checkDirConsistency(dir);
scan(dir);
}
else {
assert uri.getScheme().equals("jar");
scan(uri);
}
}
 
scanned = true;
}
 
/**
* Scan over a directory
* @param dir Directory to scan
*/
private void scan(final File dir) {
assert dir.isDirectory() && dir.canRead();
for (final File candidateFile : dir.listFiles(jsFileFilter)) {
final URI fileURI = candidateFile.toURI();
try {
final Sandbox sb = environment.createSandbox(fileURI);
final BasePluginObject bpo = sb.getPluginObject();
if (bpo.name == null) {
bpo.name = candidateFile.getName();
}
library.add(candidateFile.getName(), bpo, sb);
}
catch (final Exception e) {
continue;
}
}
}
 
/**
* Scan over a directory inside a jar file
* @param jarUri Directory to scan
* @return LIst of plugins in directory <code>jarUri</code>
*/
private void scan(final URI jarUri) {
assert jarUri.getScheme().equals("jar");
 
try {
final JarURLConnection conn = (JarURLConnection) jarUri.toURL().openConnection();
assert null != conn.getEntryName();
final Enumeration<JarEntry> entries = conn.getJarFile().entries();
final String[] jarURIElements =jarUri.getSchemeSpecificPart().split("!");
assert jarURIElements.length == 2;
final String jarFile = jarURIElements[0]; // = file:....jar
final String root = jarURIElements[1]; // = /path
while (entries.hasMoreElements()) {
final JarEntry je = entries.nextElement();
 
final String url = "/"+je.getName();
if (url.startsWith(root) && !je.isDirectory()) {
// Accepted URI
 
try {
final URI pluginUri = new URI("jar:"+jarFile+"!"+url);
 
final Sandbox sb = environment.createSandbox(pluginUri);
final BasePluginObject bpo = sb.getPluginObject();
final String fileName = new File(jarURIElements[1]).getName();
if (bpo.name == null) {
bpo.name = fileName;
}
library.add(fileName, bpo, sb);
}
catch (final Exception e) {
continue;
}
}
}
}
catch (IOException e) {
throw new IllegalStateException("Error reading jar file");
}
}
 
/**
* Throws an unchecked exception if something that, on construction, was
* a valid directory, is not anymore.
* @param dir Directory to check
* @throws java.lang.IllegalStateException If the <em>directory</em> is
* no longer a directory or can't be accessed or has ceased to exist.
*/
private static void checkDirConsistency(final File dir)
throws IllegalStateException {
if (!dir.exists() || !dir.isDirectory() || !dir.canRead()) {
throw new IllegalStateException("Permissions of " + dir +
" modified while running");
}
}
public Collection<Sandbox> list() {
scan();
return Collections.unmodifiableCollection(library.unique);
}
public int foundPlugins() {
scan();
return library.unique.size();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginEnvironment.java
0,0 → 1,74
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.net.URI;
 
/**
* Provides the environment for {@link net.outlyer.plugins.Sandbox}es.
*/
public abstract class PluginEnvironment {
/**
* Creates a sandbox associated to the script found in uri
* @param uri Plugin uri
* @return Sandbox associated to uri
* @throws net.outlyer.plugins.PluginException
*/
abstract public Sandbox createSandbox(final URI uri) throws PluginException;
 
/**
* Makes an object accessible from the plugin.
* Note the object will be shared amongst any sandboxes created after
* the exporting it.
* @param name Name with which to access the object
* @param object Object to export
*/
abstract public void exportGlobalObject(final String name, final Object object);
 
/**
* Restricts the set of supported plugins to the ones with the given plugin
* type (by default no restriction is applied).
* @see PluginProperties#type
* @param pluginTypes Set of types to allow; use null to allow all types
*/
abstract public void setAcceptedTypes(final String... pluginTypes);
 
/**
* 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.
* <br />
* <b>Note</b> that, unlike for other objects, plugin objects aren't
* shared amongst sandboxes, a clone of the one provided will be used.
* @param pluginObject Object to export, set to null to use a default one.
*/
abstract public void setPluginObject(final BasePluginObject pluginObject);
 
public static PluginEnvironment create() {
return new PluginEnvironmentImpl();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/PluginObject.java
0,0 → 1,58
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
import java.util.LinkedList;
import java.util.List;
 
/**
* Default plugin object, adds a "features" field intended to describe
* the plugin features, and execution() which provides the number of times
* the script has been executed.
*/
public class PluginObject extends BasePluginObject {
public List features;
 
{
features = new LinkedList();
}
public int execution() {
return getSandbox().getExecution();
}
 
@Override public Object clone() throws CloneNotSupportedException {
PluginObject po = (PluginObject) super.clone();
po.features = new LinkedList();
po.features.addAll(this.features);
return po;
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/src/net/outlyer/plugins/RuntimeHooks.java
0,0 → 1,37
package net.outlyer.plugins;
 
/*
* Copyright (c) 2008, Toni Corvera. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// $Id$
 
/**
* Provides hooks to the execution
*/
public interface RuntimeHooks {
/**
* Adds a callback to be executed after the script is finished
*/
void addEndHook(final Runnable r);
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/debian/changelog
0,0 → 1,6
pluggablejs (0.0build28-upstream.0) experimental; urgency=low
 
* Initial public release.
 
-- Toni Corvera <outlyer@gmail.com> Sun, 29 Jun 2008 02:00:42 +0200
 
/pluggablejs/tags/1.0build28/debian/rules
0,0 → 1,98
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
 
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
 
 
 
 
CFLAGS = -Wall -g
 
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
 
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
 
touch configure-stamp
 
 
build: build-stamp
 
build-stamp: configure-stamp
dh_testdir
 
# Add here commands to compile the package.
$(MAKE)
#docbook-to-man debian/libpluggablejs-java.sgml > libpluggablejs-java.1
 
touch $@
 
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
 
# Add here commands to clean up after the build process.
-$(MAKE) clean
 
dh_clean
 
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
 
# Add here commands to install the package into debian/libpluggablejs-java.
$(MAKE) DESTDIR=$(CURDIR)/debian/libpluggablejs-java prefix=/usr install
 
 
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
 
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_installexamples
# dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_python
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
 
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/pluggablejs/tags/1.0build28/debian/copyright
0,0 → 1,42
This package was debianized by Toni Corvera <outlyer@gmail.com> on
Thu, 26 Jun 2008 02:54:11 +0200.
 
It was downloaded from <url://example.com>
 
Upstream Author(s):
 
<put author's name and email here>
<likewise for another author>
 
Copyright:
 
<Copyright (C) YYYY Name OfAuthor>
<likewise for another author>
 
License:
 
Redistribution and use in source and binary forms, with or without
modification, are permitted under the terms of the BSD License.
 
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
 
On Debian systems, the complete text of the BSD License can be
found in `/usr/share/common-licenses/BSD'.
 
 
The Debian packaging is (C) 2008, Toni Corvera <outlyer@gmail.com> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
 
 
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.
/pluggablejs/tags/1.0build28/debian/docs
--- tags/1.0build28/debian/README (nonexistent)
+++ tags/1.0build28/debian/README (revision 57)
@@ -0,0 +1,6 @@
+The Debian Package libpluggablejs-java
+----------------------------
+
+Comments regarding the Package
+
+ -- Toni Corvera <outlyer@gmail.com> Thu, 26 Jun 2008 02:54:11 +0200
/pluggablejs/tags/1.0build28/debian/README.Debian
0,0 → 1,6
libpluggablejs-java for Debian
------------------------------
 
<possible notes regarding this package - if none, delete this file>
 
-- Toni Corvera <outlyer@gmail.com> Thu, 26 Jun 2008 02:54:11 +0200
/pluggablejs/tags/1.0build28/debian/control
0,0 → 1,16
Source: pluggablejs
Section: contrib/libs
Priority: extra
Maintainer: Toni Corvera <outlyer@gmail.com>
Build-Depends: debhelper (>= 5), ant
Standards-Version: 3.7.2
 
Package: libpluggablejs-java
Architecture: all
Homepage: http://p.outlyer.net/pluggablejs
Depends: java6-runtime-headless
Description: Simple framework for JavaScript-Java plugging
This package provides a simplistic approach to support plugins in Java
loaded from JavaScript code.
.
See the upstream site.
/pluggablejs/tags/1.0build28/debian/dirs
0,0 → 1,0
usr/bin
/pluggablejs/tags/1.0build28/debian/compat
0,0 → 1,0
5
/pluggablejs/tags/1.0build28/samples/zeroer.js
0,0 → 1,63
 
// This file is put in the public domain
//
// $Id$
 
var FILE_SIZE_LIMIT = -1;
var BUFFER_SIZE = 1024 * 1024;
var DEFAULT_FILE_NAME = "zeroes";
 
java.lang.System.err.println("Disk Zero Filler v0.2");
 
var DiskZeroFiller = {
zero: null,
wipe: null,
commonFill: null
};
DiskZeroFiller.commonFill = function(filename, buffer) {
// try
var fos = new java.io.FileOutputStream(filename, false);
 
java.lang.System.err.println();
var written = 0;
var ignore = BUFFER_SIZE * 3;
 
var reference = new java.io.File(".");
var free;
while (ignore < (free = reference.getUsableSpace())) {
// Must use this form to not be ambiguous
fos.write(buffer.array(), 0, buffer.array().length);
written += buffer.array().length;
 
java.lang.System.err.printf("\r%d w %d f // %.2fMiB w %.2fMiB",
new Array(
new java.lang.Long(written), new java.lang.Long(free),
written / 1024.0 / 1024.0,
free / 1024.0 / 1024.0
)
);
}
java.lang.System.err.println();
 
fos.close();
};
 
DiskZeroFiller.zero = function(filename) {
var buffer = java.nio.ByteBuffer.allocate(BUFFER_SIZE);
java.util.Arrays.fill(buffer.array(), new java.lang.Byte(0));
this.commonFill(filename, buffer);
};
 
DiskZeroFiller.wipe = function(filename) {
var buffer = java.nio.ByteBuffer.allocate(BUFFER_SIZE);
java.util.Arrays.fill(buffer.array(), new java.lang.Byte(0));
for (var i=0; i<BUFFER_SIZE; i+=2) {
buffer.array()[i] = new java.lang.Byte(127);
}
this.commonFill(filename, buffer);
};
 
DiskZeroFiller.zero("zeroes");
//DiskZeroFiller.wipe("wipe");
 
// vim:set ts=4 et ai: //
Property changes:
Added: svn:executable
+*
\ No newline at end of property
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/samples/RhinoRun.java
0,0 → 1,54
 
// This file is put in the Public Domain, originally published
// at <http://p.outlyer.net./javacode/>
// $Id$
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
/**
* This is a wrapper around the rhino script engine, it will load a file
* and try to eval() its contents.
*
* Usage: RhinoRun [inputfile.js] [inputfile2.js]
*/
public class RhinoRun {
public static void main(String...args) {
if (args.length == 0) {
System.err.printf("Usage: java [...] %s [file1.js [file2.js [...]]]\n",
RhinoRun.class.getName());
System.exit(1);
}
 
final ScriptEngine rhino = new ScriptEngineManager().getEngineByName("rhino");
 
for (final String path : args) {
try {
final File file = new File(path);
if (!file.isFile() || !file.canRead()) {
throw new FileNotFoundException("Failed to access " + path);
}
rhino.eval(new BufferedReader(new FileReader(file)));
}
catch (final FileNotFoundException e) {
System.err.println("Error: " + e.getMessage());
if (System.getProperty("debug", "0").equals("1")) {
e.printStackTrace(System.err);
}
}
catch (final ScriptException e) {
System.err.println("Error: " + e.getMessage());
if (System.getProperty("debug", "0").equals("1")) {
e.printStackTrace(System.err);
}
}
}
}
}
 
// vim:set ts=4 et ai: //
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/samples/ui.js
0,0 → 1,8
 
var file = ui.promptForFile("Choose an appropriate executable");
 
err.println("Chosen file: "+file);
 
if (!file.canExecute()) {
err.println("Not a valid executable");
}
/pluggablejs/tags/1.0build28/samples/sandbox.js
0,0 → 1,30
 
var api = {
createPE: function() {
var pe = net.outlyer.plugins.PluginEnvironment.create();
pe.exportGlobalObject("input", input);
pe.exportGlobalObject("out", out);
pe.exportGlobalObject("err", err);
return pe;
},
 
createSandbox: function(uri) {
return api.createPE().createSandbox(uri);
},
};
 
var sb = api.createSandbox(new java.io.File("sandboxed-sandbox.js").toURI());
 
sb.execute();
 
/*
do {
var line = ui.prompt("%> ");
if (null == line || line.isEmpty()) {
break;
}
}
while (true);
*/
 
// vim:set ts=4 et ai: //
/pluggablejs/tags/1.0build28/samples/prefs.js
0,0 → 1,17
 
var prefs = java.utils.prefs;
 
var p = java.util.prefs.Preferences.userRoot();
 
var shell = new net.outlyer.plugins.Shell();
 
var k = java.util.prefs.Preferences.userNodeForPackage(shell.getClass());
 
err.println("user root: " + p);
err.println("pkg root: " + k);
 
k.put("SampleKey", "sampleValue");
k.sync();
err.println("Read: " + k.get("SampleKey", "none set"));
k.remove("SampleKey");
k.sync();
/pluggablejs/tags/1.0build28/samples/sandboxed-sandbox.js
0,0 → 1,3
 
err.println("I'm a sandbox inside a sandbox");
 
/pluggablejs/tags/1.0build28/Makefile
0,0 → 1,26
 
prefix:=/usr/local
DESTDIR:=
JAR=dist/pluggablejs.jar
 
bindir=$(DESTDIR)/$(prefix)/bin
 
all:
ant compile.downstream
 
$(JAR):
ant dist.downstream
 
clean:
ant clean
 
install: $(JAR)
mkdir -p $(DESTDIR)/$(prefix)/share/java $(bindir)/
install -m644 -o0 -g0 $(JAR) $(DESTDIR)/$(prefix)/share/java/
cat pjsh.sh | sed 's\^prefix=.*$$\prefix=$(prefix)\g' > $(bindir)/pjsh
chmod 755 $(bindir)/pjsh
-chown root.root $(bindir)/pjsh
 
uninstall:
$(RM) $(DESTDIR)/$(prefix)/share/java/`basename "$(JAR)"`
-rmdir -p $(DESTDIR)/$(prefix)/share/java
/pluggablejs/tags/1.0build28/build.num
0,0 → 1,3
#Build Number for ANT. Do not edit!
#Fri Jun 27 22:16:02 CEST 2008
build.number=28
/pluggablejs/tags/1.0build28/pjsh.sh
0,0 → 1,6
#!/bin/sh
 
prefix=/usr/local
JAR="$prefix/pluggablejs.jar"
 
java -cp "$JAR" net.outlyer.plugins.Shell $@
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/pjsh.cmd
0,0 → 1,11
@echo off
REM $Id$
 
setlocal
 
set prefix=.
set JAR=%prefix%\pluggablejs.jar
 
java -cp "%JAR%" net.outlyer.plugins.Shell %*
 
endlocal
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/tags/1.0build28/build.xml
0,0 → 1,69
<?xml version="1.0" encoding="utf-8"?>
 
<project name="pluggablejs" default="dist" basedir=".">
<description>Pluggable JS framework</description>
 
<property name="src" location="src"/>
<property name="build" location="obj"/>
<property name="dist" location="dist"/>
<property name="release" location="release"/>
<property name="depends" location="lib"/>
 
<property name="version" value="1.0"/>
 
<target name="init">
<!-- Create timestamp, sets TODAY (full, human), DSTAMP (yyyymmdd) and
TSTAMP (hhmm) -->
<tstamp/>
<!-- Build directory structure -->
<mkdir dir="${build}" />
</target>
 
<target name="compile.real" depends="init" description="Source compilation">
<!-- from ${src} to ${build} -->
<javac srcdir="${src}" destdir="${build}" />
</target>
 
<target name="compile" depends="compile.real">
<!-- Build finished, update number -->
<buildnumber file="build.num"/>
</target>
 
<target name="compile.downstream" depends="compile.real"
description="Compilation without build number increase">
<!-- Forge build number, buildnumber must be called to have
${build.number} defined -->
<copy file="build.num" tofile="build.number" />
<buildnumber file="build.number" />
<delete file="build.number" />
</target>
 
<target name="dist.real" description="Generate the distribution">
<mkdir dir="${dist}/"/>
 
<jar jarfile="${dist}/pluggablejs.jar" basedir="${build}">
<!-- <classpath refid="${third.party.libs}" /> -->
<manifest>
<attribute name="X-COMMENT" value="Standard build" />
<attribute name="Build-Date" value="${TODAY}"/>
<!-- Package.getImplementationVersion() -->
<attribute name="Implementation-Version"
value="${version}-build${build.number}" />
<!--
<attribute name="Class-Path" value="${manifest.classpath}" />
-->
</manifest>
</jar>
<jar destfile="${dist}/pluggablejs-src.jar" basedir="${src}"/>
</target>
 
<target name="dist.downstream" depends="compile.downstream, dist.real" />
<target name="dist" depends="compile, dist.real" />
 
<target name="clean" description="Clean up">
<delete dir="${build}" />
<delete dir="${dist}" />
<delete dir="${release}" />
</target>
</project>
<!-- vim:set ts=4 et noai: -->
/pluggablejs/tags/1.0build28
Property changes:
Added: svn:mergeinfo
Merged /pluggablejs/branches/1.0build27:r52
Merged /pluggablejs/branches/1.0build28:r55
/pluggablejs/branches/1.0build28/debian/copyright
File deleted
/pluggablejs/branches/1.0build28/debian/rules
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/pluggablejs/branches/1.0build28/debian/README
File deleted
/pluggablejs/branches/1.0build28/debian/README.Debian
File deleted
/pluggablejs/branches/1.0build28/debian/control
File deleted
/pluggablejs/branches/1.0build28/debian/dirs
File deleted
/pluggablejs/branches/1.0build28/debian/compat
File deleted
/pluggablejs/branches/1.0build28/debian/changelog
File deleted
/pluggablejs/branches/1.0build28/samples/zeroer.js
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/samples/RhinoRun.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/samples/ui.js
File deleted
/pluggablejs/branches/1.0build28/samples/sandbox.js
File deleted
/pluggablejs/branches/1.0build28/samples/prefs.js
File deleted
/pluggablejs/branches/1.0build28/samples/sandboxed-sandbox.js
File deleted
/pluggablejs/branches/1.0build28/pjsh.cmd
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginReader.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/SandboxAccessor.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginLocator.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginEnvironment.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginObject.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/RuntimeHooks.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/Sandbox.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginExecutionException.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/SandboxAccessorImpl.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginEnvironmentImpl.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/Shell.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/API.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/SandboxProperties.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginProperties.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/PluginException.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/SandboxImpl.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/BasePluginObject.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/GUI.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/package-info.java
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/UI.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/Input.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/Output.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/src/net/outlyer/plugins/utils/Hooks.java
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/pjsh.sh
File deleted
Property changes:
Deleted: svn:keywords
-Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.0build28/Makefile
File deleted
/pluggablejs/branches/1.0build28/build.num
File deleted
/pluggablejs/branches/1.0build28/build.xml
File deleted
/pluggablejs/branches/1.0build28
Property changes:
Deleted: svn:mergeinfo
Reverse-merged /pluggablejs/branches/1.0build27:r52