Subversion Repositories pub

Compare Revisions

No changes between revisions

Ignore whitespace Rev 66 → Rev 67

/pluggablejs/branches/1.1.1build36/build.num
0,0 → 1,3
#Build Number for ANT. Do not edit!
#Sat Jul 05 15:58:10 CEST 2008
build.number=36
/pluggablejs/branches/1.1.1build36/build.xml
0,0 → 1,70
<?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.1.1"/>
<property name="jarbasename" value="pluggablejs-${version}build" /><!-- followed by build.number, can't resolve yet -->
 
<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}/${jarbasename}${build.number}.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}/${jarbasename}${build.number}-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/branches/1.1.1build36/debian/changelog
0,0 → 1,18
pluggablejs (1.1.1build36-upstream.0) experimental; urgency=low
 
* New release.
 
-- Toni Corvera <outlyer@gmail.com> Sat, 05 Jul 2008 15:58:16 +0200
 
pluggablejs (1.1.0build33-upstream.0) experimental; urgency=low
 
* New release.
 
-- Toni Corvera <outlyer@gmail.com> Tue, 01 Jul 2008 02:20:32 +0200
 
pluggablejs (1.0build29-upstream.0) experimental; urgency=low
 
* Initial public release.
 
-- Toni Corvera <outlyer@gmail.com> Sun, 29 Jun 2008 04:31:28 +0200
 
/pluggablejs/branches/1.1.1build36/debian/README.Debian
0,0 → 1,7
libpluggablejs-java for Debian
------------------------------
 
This is debian package created from the upstream source, it might
not follow the Debian policy correctly.
 
-- Toni Corvera <outlyer@gmail.com> Thu, 26 Jun 2008 02:54:11 +0200
/pluggablejs/branches/1.1.1build36/debian/docs
0,0 → 1,2
pjsh.cmd
 
/pluggablejs/branches/1.1.1build36/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 ChangeLog
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/branches/1.1.1build36/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/branches/1.1.1build36/debian/README
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/branches/1.1.1build36/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/branches/1.1.1build36/debian/dirs
0,0 → 1,0
usr/bin
/pluggablejs/branches/1.1.1build36/debian/compat
0,0 → 1,0
5
/pluggablejs/branches/1.1.1build36/ChangeLog
0,0 → 1,55
1.1.1build36: 2008-07-05
* Re-fixed including from within jar
* General bugfixes
+ Released
 
1.1.1build35: not a release
* Fixed loading of plugins from within jar
* Fixed including (lang.include()) files from within jar
* Added code injection to Sandbox while executing (SandboxAccessor's can
benefit from this)
* Made PluginProperties public again, otherwise it couldn't be modified
from JS
* Made PluginReader public
* Simplified plugin's properties retrieval (plugin identification over
the first line)
 
 
1.1.1build34: not a release
* Bumped revision number
* Renamed the $net object to $net_outlyer to be less intrusive
* Interactive shell prints the result of each line (optionally and on by default)
* Cleaner use of internal variables, there's no longer a need to
reserve any variable name / namespace beyond $net_outlyer
* lang.array() family of methods to create Java arrays
* lang.var_dump() to help in debugging
* (optional) lang.for_each() as alternative to "for each"
 
1.1.0build33: 2008-07-01
* Sandbox can be created with no associated file (only boilerPlate code
will be issued)
* Shell supports interactive mode
* Scripts have access to the PluginEnvironment
($net.outlyer.runtime.pluginEnvironment)
* Sandbox allows access to the ScriptEngine in use
* LanguageExtensions (eval and include)
* More opaque hierarchies where appropriate
* Output.print()
* PluginObject.features as a Set instead of a List
+ Released
 
1.1.0build32: not a release
* Removed the deprecated versions of Sandbox.createDelayedImplementation()
* Cleaner boilerplate code, less intrusive variables created
* Debug mode (prints eval'ed code to stderr), by setting -Ddebug=1
* Corrected/refined SandboxAccessor's specs
* PluginEnvironment.exportGlobalObject -> PluginEnvironment.exportObject
* +PluginEnvironment.exportPackage
* Use of eval() to retrieve objects instead of get() (cleaner
boilerplate, no need for extra variables to retrieve objects)
* Removed extra enableSandboxAccess'es for the plugin object
* Redefined versioning meaning
 
1.0build29: 2008-06-29
* Initial public pre-release
+ Released
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/Shell.java
0,0 → 1,182
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 javax.script.ScriptEngine;
import javax.script.ScriptException;
import net.outlyer.plugins.utils.*;
 
import static net.outlyer.plugins.Internal.getInternalObjectFieldName;
 
/**
* Sample shell for tests, or scripts.
* Files passed as arguments will be loaded and executed.
*/
public final class Shell {
 
public static void interactive(final PluginEnvironment pe) {
try {
final Sandbox sandbox = pe.createSandbox(null);
final ScriptEngine rhino = ((SandboxImpl) sandbox).executeAndGetEngine();
 
final Input in = new Input();
final Output out = new Output();
System.err.printf("pluggablejsShell v%d.%d.%d\n", API.VERSION, API.MIN_SUPPORTED_VERSION, API.REVISION);
final boolean isWin = System.getProperty("os.name").toLowerCase().startsWith("windows");
// apparently windows doesn't get EOF until enter is pressed
System.err.printf(" use EOF (%s) or break (CTRL+C) to exit\n", (isWin) ? "CTRL+Z,Enter" : "CTRL+D");
 
// This object is used as a template to identify JavaScript arrays;
// since the sun.org.mozilla.javascript package is forbidden a more
// direct check can't be used
Object jsArray;
// This is the name of the internal function used to dump
// javascript arrays
final String arrayDumpFn = getInternalObjectFieldName("shell.arrayDump");
try {
// undocumented features: when
// $net_outlyer.runtime.internal.shell.autoEOL is true an extra println() is
// issued after each eval
// and when
// $net_outlyer.runtime.internal.shell.inspect is true the result
// of each line is automatically printed
// arrayDump is used internally to print JavaScript arrays
rhino.eval(getInternalObjectFieldName("shell")+" = { " +
" autoEOL: false, inspect: true, arrayDump: null };");
jsArray = rhino.eval("new Array()");
 
// Define the arrayDump internal function
rhino.eval(arrayDumpFn+
" = function(arr) {\n" +
" if (0==arr.length) { java.lang.System.out.println('[]'); return; }\n"+
" var s = new String('[');" +
" for (var i=0;i<arr.length;++i) {\n" +
" s += arr[i]+',';\n" +
" }\n" +
" java.lang.System.out.println(s.substring(0,s.length-1)+']');\n" +
"};");
}
catch (final ScriptException e) {
e.printStackTrace();
throw new IllegalStateException("Failed to initialise interactive shell");
}
while (true) {
out.print("pjsh% : ");
final String line = in.readline();
if (null == line) {
break;
}
if (line.isEmpty()) {
continue;
}
try {
final Object result = rhino.eval(line);
final boolean eol = (Boolean) rhino.eval(getInternalObjectFieldName("shell.autoEOL"));
if (eol) {
out.println();
}
final boolean insp = (Boolean) rhino.eval(getInternalObjectFieldName("shell.inspect"));
if (insp) {
if (null==result) {
out.println("null");
}
else if (result.getClass() == jsArray.getClass()) { // JavaScript array
// Store...
Internal.setInternalValue(rhino, "result", result);
// Dump
rhino.eval(String.format("%s(%s);",
arrayDumpFn,
getInternalObjectFieldName("get")+"('result')"));
Internal.setInternalValue(rhino, "result", null);
}
else {
out.println(result.toString());
}
}
}
catch (final ScriptException e) {
System.err.println("//[E] Error: " + e.getMessage());
}
}
// EOF
System.exit(0);
}
catch (final PluginException e) {
System.err.printf("Exception while running on-the-fly " +
"interpreted script", e.getLocalizedMessage());
System.exit(5);
}
}
 
public static void main(String... args) {
if (args.length == 0) {
System.err.printf("Usage: \n" +
" java [...] %s <file1.js [file2.js [...]]>\n" +
" or\n" +
" java [...] %1$s <-i|--interactive>\n",
Shell.class.getName());
System.exit(1);
}
 
final PluginEnvironment pe = new PluginEnvironment();
pe.exportObject("input", new Input());
pe.exportObject("out", new Output());
pe.exportObject("err", new Output(System.err));
pe.exportObject("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.exportObject("ui", new GUI());
pe.exportObject("gui", new GUI());
pe.exportObject("cui", new UI()); // cui stands for Console UI
pe.exportObject("lang", new RedundantLanguageExtensions());
final PluginObject po = new PluginObject();
pe.setPluginObject(po);
 
if (args.length == 1 && (args[0].equals("-i") || args[0].equals("--interactive"))) {
interactive(pe);
assert false;
}
 
// Non-interactive mode
 
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/branches/1.1.1build36/src/net/outlyer/plugins/PluginProperties.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$
 
/**
* Common properties of the plugin object. All of them
* take sane defaults.
*/
// Can't be package-protected or its fields won't be modifiable from
// js code!
// This limitation appears to apply only to fields, not methods
public class PluginProperties extends SandboxAccessorImpl {
 
// This class isn't meant to be used outside of this package, but must be
// public (see comment above)
PluginProperties(){}
/**
* pluggablejs Api Version against which this plugin was written.
* Default: 1
* @see API#VERSION
*/
public int apiVersion = 1;
 
/**
* Type of this plugin, application-specific.
* Default: "" (no type)
* @see PluginLocator#getAll()
* @see PluginLocator#getFirst()
*/
public String type;
 
/**
* Name of this plugin.
* Default: same as filename (including extension but not path)
* @see PluginLocator#getAll()
* @see PluginLocator#getFirst()
*/
public String name;
 
/**
* @deprecated The use of this field is yet to be defined
*/
public Object properties; // FIXME: To be defined
 
@Override public String toString() {
return String.format("PluginProperties{ name=%s, type=%s, apiVersion=%d }",
name, type, apiVersion);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/Internal.java
0,0 → 1,122
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 javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
 
/**
* This class provides centralised access to features used internally.
*/
class Internal {
 
/**
* The reserved object is the only concrete variable name reserved
* in the global namespace.
* @return $net_outlyer
*/
static String getReservedObjectName() {
return "$net_outlyer";
}
/**
* Gets the name of the runtime object
* @return
*/
static String getRuntimeObjectName() {
return getReservedObjectName()+".runtime";
}
 
/**
* Gets the name of the internal object.
* Fields of this object provide access to internal features.
*/
static String getInternalObjectName() {
return getRuntimeObjectName()+".internal";
}
 
static String getInternalObjectFieldName(final String fieldName) {
return getInternalObjectName()+"."+fieldName;
}
private static String mapName = "$_";
static String getInternalInitialisation() {
// Commented-out is the the closer-to-Java version
return String.format("= {\n" +
// " %2$s: new java.util.HashMap(),\n" +
" %2$s: {},\n" +
" set: function(n,v) {\n"+
// " %1$s.put(n,v);\n" +
" %1$s[n] = v;\n" +
" return v;\n" +
" },\n" +
" get: function(n) {\n" +
// " return %1$s.get(n);\n" +
" return %1$s[n];\n" +
" }\n"+
"};",
getInternalObjectFieldName(mapName),
mapName);
}
 
static void setInternalValue(final ScriptEngine e,
final String name,
final Object value) throws ScriptException {
assert null != e;
assert null != name;
// final Map map = (Map) e.eval(getInternalObjectFieldName(mapName));
// map.put(name, value);
try {
assert e instanceof Invocable;
final Invocable ie = (Invocable) e;
ie.invokeMethod(e.eval(getInternalObjectName()), "set", name, value);
}
catch (final NoSuchMethodException x) {
throw new ScriptException("Internal error while storing " +
"internal variable: "+x.getMessage());
}
}
 
static Object getInternalValue(final ScriptEngine e,
final String name) throws ScriptException {
assert null != e;
assert null != name;
// final Map map = (Map) e.eval(getInternalObjectFieldName(mapName));
// return map.get(name);
try {
assert e instanceof Invocable;
final Invocable ie = (Invocable) e;
return ie.invokeMethod(e.eval(getInternalObjectName()), name);
}
catch (final NoSuchMethodException x) {
throw new ScriptException("Internal error while accessing " +
"internal variable: "+x.getMessage());
}
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/utils/LanguageExtensions.java
0,0 → 1,172
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.lang.reflect.Array;
import java.util.Arrays;
import net.outlyer.plugins.SandboxAccessor;
 
/**
* Extra facilities found in other languages or more complete
* versions of available facilities.
* Recommended name: lang
*/
public class LanguageExtensions extends LanguageExtensions_V1
implements SandboxAccessor {
 
public final int interfaceRevision;
 
public LanguageExtensions() {
this(2);
}
protected LanguageExtensions(int revision) {
interfaceRevision = revision;
}
 
// The array() family is mostly redundant since rhino translates
// automatically as required from JavaScript arrays to Java arrays
// but there are some edge-cases in which they might be desirable
/**
* Create an array of the same class as the provided object.
* @param tplt Template for the array, must be non-null and non-Void
* @param size Size of the array to create (can be 0)
* @since {@link #interfaceRevision} 2
*/
public <T> T[] array(final T tplt, int size) {
if (null == tplt || Void.class == tplt.getClass()) {
return null;
}
return (T[]) Array.newInstance(tplt.getClass(), size);
}
 
/**
* Create an array of the provided class.
* @param c Class of the array elements, must be non-null and different from Void.class
* @param size Size of the array (can be 0)
* @since {@link #interfaceRevision} 2
*/
public <T> T[] array(final Class<T> c, int size) {
return (T[]) Array.newInstance(c, size);
}
 
/**
* Create an array and copy a set of elements to it.
* Note that a JavaScript array will produce a java.lang.Object array
* @param size Size of the array to create (if less than
* <code>initValues.length</code>, will use
* <code>initValues.length</code> instead) (i.e., use 0 to
* get the same size as initValues)
* @param initValues Initial values to put in the array
* @since {@link #interfaceRevision} 2
*/
public <T> T[] array(final T[] initValues, int size) {
if (null == initValues) {
return null;
}
final T[] a = Arrays.copyOf(initValues, Math.max(size, initValues.length));
if (null == a) {
return null;
}
for (int i=0; i<initValues.length; ++i) {
a[i] = initValues[i];
}
return a;
}
 
/**
* Shorthand form, allows getting a Java array from a JavaScript array.
* @param initValues
* @since {@link #interfaceRevision} 2
*/
public <T> T[] array(final T[] initValues) {
return array(initValues, initValues.length);
}
 
public void var_dump(final Object obj) {
System.out.println(var_dump_(obj));
}
 
private String var_dump_(final Object obj) {
final StringBuilder sb = new StringBuilder();
if (null == obj) {
sb.append("null");
}
else if (obj.getClass() == String.class) {
sb.append("String(").append(((String)obj).length())
.append(") \"").append(obj).append("\"");
}
else if (Number.class.isInstance(obj)) {
final Class c = obj.getClass();
String v;
if (c == Double.class) { // Most probable
v = String.format("double(%f)", (Double)obj);
}
else if (c == Float.class) {
v = String.format("float(%f)", (Float)obj);
}
else if (c == Long.class) {
v = String.format("long(%d)", (Long)obj);
}
else if (c == Integer.class) {
v = String.format("int(%d)", (Integer)obj);
}
else if (c == Short.class) {
v = String.format("short(%d)", (Short)obj);
}
else if (c == Byte.class) {
v = String.format("byte(%d)", (Byte)obj);
}
else {
v = String.format("%s(%f)", c.getSimpleName(),
((Number)obj).doubleValue());
}
sb.append(v);
}
else if (obj.getClass().isArray()) {
sb.append("array(").append(java.lang.reflect.Array.getLength(obj))
.append(") {\n");
/*
for (final Object elem : java.util.Arrays.asList(obj)) {
sb.append(var_dump_(elem));
}
*/
int len = java.lang.reflect.Array.getLength(obj);
for (int i=0; i<len; ++i) {
sb.append(" [").append(i).append("]=>\n ")
.append(var_dump_(java.lang.reflect.Array.get(obj, i)))
.append("\n");
}
sb.append("}");
}
else {
sb.append(obj);
}
return sb.toString();
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/utils/RedundantLanguageExtensions.java
0,0 → 1,80
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.util.Arrays;
import net.outlyer.plugins.Functor;
 
/**
* Language extensions provided already by JavaScript.
* Versions here provide alternative syntax or semantics to the builtin
* versions, based on other languages.
* <br />
* In general {@link LanguageExtensions} will be preferable over this class.
* @since {@link net.outlyer.plugins.API#REVISION} 1
* @since {@link #interfaceRevision} 2
*/
public class RedundantLanguageExtensions extends LanguageExtensions {
 
public RedundantLanguageExtensions() {
super(2);
}
 
/**
* Apply a function to each element of an iterable collection.
* Note JavaScript 1.6 DOES have a "for each" loop
* ({@link http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Statements:for_each...in})
* @see #for_each(Object[], Functor)
* @param c Collection to which to apply
* @param f Function to apply
* @since {@link #interfaceRevision} 2
*/
public <T> void for_each(final Iterable<T> c, final Functor<Object, T> f) {
for (final T elem : c) {
f.apply(elem);
}
}
/**
* Apply a function to each element of an array
* A JavaScript function can be used transparently as a functor, e.g.:
* <br />
* <code>var arr = lang.array(new Array(1, 2, 3));<br />
* lang.for_each(arr, function(x) { err.println("Element: "+x); });</code>>
* Will produce:
* <pre>Element: 1<br />Element: 2<br />Element: 3</pre>
* @param a Array to which to apply
* @param f Function to apply
* @since {@link #interfaceRevision} 2
*/
public <T> void for_each(final T[] a, final Functor<Object, T> f) {
if (null == a || null == f) {
return; // FIXME: Error handling
}
for_each(Arrays.asList(a), f);
}
}
Property changes:
Added: svn:keyword
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/utils/LanguageExtensions_V1.java
0,0 → 1,117
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;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.script.ScriptException;
import net.outlyer.plugins.PluginException;
import net.outlyer.plugins.PluginReader;
import net.outlyer.plugins.Sandbox;
import net.outlyer.plugins.SandboxAccessorImpl;
 
/**
* Initial version of LanguageExtensions.
* @see LanguageExtensions
*/
class LanguageExtensions_V1 extends SandboxAccessorImpl {
/**
* ScriptEngine's eval.
* The built-in eval() appears to be less-powerful, in general they're
* equivalent, but if the eval'ed string is obtainer from input
* <code>eval()</code> appears to ignore it, while
* <code>LanguageExtensions.eval()</code> does eval it.
* @param code Code to evaluate
* @return Eval's result
*/
public Object eval(final String code) {
try {
return getSandbox().getCurrentEngine().eval(code);
}
catch (final ScriptException e) {
// FIXME: Handle better
System.err.println("Exception: " + e.getMessage());
}
return null;
}
 
/**
* Load an external file
* @deprecated Not yet stabilised
*/
public Object include(final String path) { // TODO: Support jar URIs
try {
if (path.startsWith("file:/") || path.startsWith("jar:file:/")) {
return include(new URI(path));
}
final File f = new File(path);
if (f.isAbsolute()) {
return include(f.toURI());
}
// Get a reasonable path
final Sandbox s = getSandbox();
final URI callerUri = s.loadedFrom();
// This isn't very elegant but works (in most cases?)...
final String c = callerUri.toString();
final int idx = callerUri.toString().lastIndexOf('/');
final URI reqUri = new URI(c.substring(0, idx)+"/"+path).normalize();
return include(reqUri);
}
catch (final URISyntaxException e) {
e.printStackTrace();
}
return null;
}
 
public Object include(final URI uri) {
if (null == uri) {
// TODO: Handle better
return null;
}
if (null == uri.getScheme() ||
(!"file".equals(uri.getScheme()) && !"jar".equals(uri.getScheme()))) {
throw new IllegalArgumentException("Only file and jar-contained files can be included");
}
 
try {
return getSandbox().inject(new PluginReader(uri));
}
catch (final IOException e) {
// FIXME: Handle better
System.err.println("Failed to read " + uri);
}
catch (final PluginException e) {
// FIXME: Handle better
System.err.println("Exception: " + e.getMessage());
}
return null;
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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.PluginEnvironment#exportObject}.
*/
 
// $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/branches/1.1.1build36/src/net/outlyer/plugins/utils/Output.java
0,0 → 1,73
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;
}
 
// Note rhino already provides print() and println() in the global
// namespace
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) {
print(s);
}
 
public void print(final String s) {
ps.print(s);
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/src/net/outlyer/plugins/SandboxImpl.java
0,0 → 1,384
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$
 
// Related reference:
// http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/
 
import java.io.IOException;
import java.io.Reader;
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;
 
/**
* 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 transient ScriptEngine currentEngine = null;
private static final String END_KEY = "e";
private static final boolean debug;
private final PluginEnvironment pE;
private static class ExecResult {
final ScriptEngine rhino;
final Object evalResult;
ExecResult(final ScriptEngine rhino_, final Object evalResult_) {
rhino = rhino_;
evalResult = evalResult_;
}
}
 
static {
nextUniqueVarNum = (int) (1193 * (1+Math.random()));
debug = System.getProperty("debug", "0").equals("1");
}
{
hooks = new HashMap<String, Collection<Runnable>>();
hooks.put(END_KEY, new LinkedList<Runnable>());
}
protected SandboxImpl(final PluginEnvironment pe, final URI plugin,
final Bindings bs, final PluginProperties pp) {
this(pe, plugin, bs, pp, null);
}
protected SandboxImpl(final PluginEnvironment pe, final URI plugin,
final Bindings bs,
final PluginProperties pp, final String boilerPlate) {
bindings = bs;
pluginUri = plugin; // if null => sandbox without file
this.boilerPlate = boilerPlate;
properties = pp;
pE = pe;
}
public void addEndHook(Runnable r) {
hooks.get(END_KEY).add(r);
}
 
/**
* 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 Internal.getInternalObjectFieldName(uniqueVarName());
}
 
/**
* Gets an engine.
* If the system property "debug" is set to "1" the returned engine
* will dump extra information to the console
* @return New engine
*/
private static ScriptEngine getEngine() {
final ScriptEngine se = new ScriptEngineManager().getEngineByName("rhino");
if (debug) {
return new EngineSink(se);
}
return se;
}
 
private ExecResult execute(final String prependText,
final String appendText,
final Map<String,Object> extraBindings)
throws PluginExecutionException {
final ScriptEngine rhino = getEngine();
currentEngine = rhino;
if (null != extraBindings) {
bindings.putAll(extraBindings);
}
 
Object result = null;
try {
rhino.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
 
execution++;
if (null != boilerPlate) {
rhino.eval(boilerPlate);
}
 
// $net.outlyer.runtime.sandbox Contains a reference to this object
// Implementation note: PluginEnvironment.EXPORTED_SANDBOX_VARIABLE
// should have the same name
final NamespaceContainer.$Net_Outlyer $nspc = new NamespaceContainer.$Net_Outlyer(pE, this);
assert this == $nspc.runtime.sandbox;
rhino.put(Internal.getReservedObjectName(), $nspc);
// ....internal can be used to store random internal data, it's
// a dynamic object so that fields can be created as needed
rhino.eval(Internal.getInternalObjectName()+Internal.getInternalInitialisation());
 
if (null != prependText) {
rhino.eval(prependText);
}
if (null != pluginUri) {
result = rhino.eval(new PluginReader(pluginUri));
}
else {
result = null;
}
if (null != appendText) {
rhino.eval(appendText);
}
// 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);
}
finally {
currentEngine = null;
}
return new ExecResult(rhino, result);
}
public void execute() throws PluginExecutionException {
execute(null, null, null);
}
ScriptEngine executeAndGetEngine() throws PluginExecutionException {
return execute(null, null, null).rhino;
}
 
public <T> T createDelayedImplementation(final Class<T> c,
final String objectName)
throws PluginExecutionException {
if (null == c) {
throw new IllegalArgumentException("Can't instantiate null");
}
if (!c.isInterface()) {
throw new IllegalArgumentException("Can only create delayed " +
"implementations for interfaces");
}
if (null == objectName) {
throw new IllegalArgumentException("Implementor's name can't be null");
}
final StringBuilder preCode = new StringBuilder();
 
if (debug) {
preCode.append("// Forward declaration for delayed implementation:\n");
}
preCode.append("var ").append(objectName).append(" = {\n");
for (final Method method : c.getMethods()) {
if (method.getDeclaringClass() == Object.class) { // Implement everything, including hierarchies
continue;
}
preCode.append(method.getName()).append(": null,\n");
}
preCode.append("};\n");
 
final ScriptEngine rhino = execute(preCode.toString(), null, null).rhino;
 
try {
final StringBuilder retriever = new StringBuilder();
retriever.append("new ")
.append(c.getCanonicalName()).append("(").append(objectName).append(");");
if (debug) {
retriever.append("// <== Actual delayed implementation creation");
}
 
// Could be safely instantiated before actually being assigned IF
// plugins were required to define their methods with
// objectName.methodName = function() {} ...
// but would file with
// objectName = { methodName: function() {}, ... }
// Creating the instance as postCode does the job for both
 
try {
currentEngine = rhino;
// eval() returns the value of the last evaluated line/command
assert (c.isInstance(rhino.eval(retriever.toString())));
return (T) rhino.eval(retriever.toString());
}
finally {
currentEngine = null;
}
}
catch (final ScriptException e) {
throw new PluginExecutionException("Failed to create the delayed " +
"implementation instance: " + e.getMessage(), e);
}
}
 
/**
* {@inheritDoc}
*/
public <T> T createDelayedImplementation(final Class<T> c,
final Map<Method, String> map)
throws PluginExecutionException {
if (null == c) {
throw new IllegalArgumentException("Can't instantiate null");
}
if (!c.isInterface()) {
throw new IllegalArgumentException("Can only create delayed " +
"implementations for interfaces");
}
if (null == map || map.isEmpty()) {
throw new IllegalArgumentException("No mappings; creating a delayed " +
"implementation with no mappings " +
"is equivalent to creating" +
"the object from Java");
}
 
final StringBuffer preCode = new StringBuffer();
final String var = uniqueFQVarName();
preCode.append(var).append(" = {\n");
for (final Method method : map.keySet()) {
preCode.append(method.getName()).append(": ")
.append(map.get(method))
.append("\n,\n");
}
preCode.append("};\n");
final ScriptEngine rhino = execute(preCode.toString(), null, null).rhino;
try {
final StringBuilder retriever = new StringBuilder();
retriever.append("new ")
.append(c.getCanonicalName()).append("(").append(var).append(");");
if (debug) {
retriever.append("// <== Actual delayed implementation creation");
}
 
// Could be safely instantiated before actually being assigned IF
// plugins were required to define their methods with
// objectName.methodName = function() {} ...
// but would file with
// objectName = { methodName: function() {}, ... }
// Creating the instance as postCode does the job for both
 
try {
currentEngine = rhino;
// eval() returns the value of the last evaluated line/command
assert (c.isInstance(rhino.eval(retriever.toString())));
return (T) rhino.eval(retriever.toString());
}
finally {
currentEngine = null;
}
}
catch (final ScriptException e) {
throw new PluginExecutionException("Failed to create the delayed " +
"implementation instance: " + e.getMessage(), e);
}
}
 
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) {
final String[] elements = loadedFrom().toString().split("/");
return elements[elements.length-1];
}
return properties.name;
}
 
/**
* {@inheritDoc}
*/
public URI loadedFrom() {
return pluginUri.normalize(); // FIXME: Return a copy
}
 
public ScriptEngine getCurrentEngine() {
return currentEngine;
}
 
/**
* {@inheritDoc}
*/
public Object inject(final Reader code) throws IllegalStateException, PluginException {
synchronized (currentEngine) { // Probably not needed
if (null == currentEngine) {
throw new IllegalStateException("Can only inject code while a sandbox is executing");
}
try {
return currentEngine.eval(code);
}
catch (final ScriptException e) {
throw new PluginException("Failed to inject code: " + e.getMessage(), e);
}
}
}
 
@Override public String toString() {
return "Sandbox("+getClass().getSimpleName()+")["+loadedFrom()+"]";
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/PluginReader.java
0,0 → 1,82
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).
* Generally users of the library may only need such functionality in case
* some needs be fed to an existing sandbox (e.g.
* {@link net.outlyer.plugins.utils.LanguageExtensions_v1#include}).
*/
public class PluginReader extends Reader {
 
private final Reader readerImpl;
 
public 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/branches/1.1.1build36/src/net/outlyer/plugins/PluginLocator.java
0,0 → 1,376
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.net.URISyntaxException;
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 PluginProperties pp, final Sandbox sbox) {
byName.put(pp.name, sbox);
byFilename.put(fileName, sbox);
if (byType.get(pp.type) == null) {
byType.put(pp.type, new LinkedList<Sandbox>());
}
byType.get(pp.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 PluginProperties pp = PluginEnvironment.fetchPluginProperties(fileURI);
if (null == pp) {
continue;
}
if (null == pp.name) {
pp.name = candidateFile.getName();
}
library.add(candidateFile.getName(), pp, sb);
}
catch (final PluginException 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 PluginProperties pp = PluginEnvironment.fetchPluginProperties(pluginUri);
// JarEntry's getName() returns the full path
final String fileName = new File(je.getName()).getName();
if (pp.name == null) {
pp.name = fileName;
}
library.add(fileName, pp, sb);
}
catch (final PluginException e) {
continue;
}
catch (final URISyntaxException e) {
assert false;
throw new IllegalStateException("Unexpected malformed " +
"jar URI, implementation error (?)");
}
}
}
}
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/branches/1.1.1build36/src/net/outlyer/plugins/PluginEnvironment.java
0,0 → 1,350
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;
 
/**
* Provides the environment for {@link net.outlyer.plugins.Sandbox}es.
*/
public class 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.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;
 
{
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 ")
.append(Internal.getRuntimeObjectName())
.append(".sandbox; });\n");
}
 
////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////
 
/**
* Creates a sandbox associated to the script found in uri
* @param uri Plugin uri
* @return Sandbox associated to uri
* @throws net.outlyer.plugins.PluginException
*/
public Sandbox createSandbox(final URI forUri) throws PluginException {
final ScriptEngine rhino = new ScriptEngineManager().getEngineByName("rhino");
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();
}
 
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(this, forUri, bindings, pp, boilerPlate.toString());
}
catch (final CloneNotSupportedException e) {
assert false;
throw new IllegalStateException("Incorrect implementation");
}
}
 
/**
* 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
* @throws IllegalArgumentException If name is <code>null</code>
* @throws IllegalArgumentException If name is "<code>plugin</code>" (use
* {@link #setPluginObject()} instead).
*/
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");
}
exportedObjects.put(name, object);
if (object instanceof SandboxAccessor) {
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.
* <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.
*/
public void setPluginObject(BasePluginObject pObject) {
pluginObject = pObject;
}
 
/**
* 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
*/
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);
}
 
////////////////////////////////////////////////////////
// Non-public interface
////////////////////////////////////////////////////////
 
/**
* Makes a {@link SanboxAccessor}'s field <code>getSandbox</code>
* be evaluable as a <code>Callable&lt;Sandbox&gt;</code>, i.e.,
* from Java it will be possible to use:<br />
* <pre>
* Sandbox sb = ( (Callable&lt;Sandbox&gt;) 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("sandboxGetter");
}
catch (final NoSuchFieldException e) {
throw new IllegalArgumentException("object " + name + " must comply " +
"with the contract of SandboxAccessor");
}
 
boilerPlate.append(name).append(".sandboxGetter=new java.util.concurrent.Callable(function() {")
.append(" return ")
.append(Internal.getRuntimeObjectName())
.append(".sandbox").append("; });\n");
}
PluginProperties checkForSupport(final URI uri) throws PluginException {
assert null != uri;
 
final PluginProperties pp = fetchPluginProperties(uri);
if (null == pp) {
throw new PluginExecutionException("Failed while inspecting plugin "+uri);
}
 
if (null != acceptedTypes) {
if (!acceptedTypes.contains(pp.type)) {
throw new UnsupportedTypeException(pp.type);
}
}
if (pp.apiVersion > maxApi) {
throw new UnsupportedAPIException(pp.apiVersion);
}
return pp;
}
 
// TODO: ? Possibly cache this, so that the first line is only eval'ed
// once more than the # of executions
static PluginProperties fetchPluginProperties(final URI uri) {
assert null != uri;
 
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, name: 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);
// XXX: Note that undefined doesn't convert to null, is this safe?
if (null == type) {
type = rhino.eval("plugin.type;");
}
if (null == apiVersion) {
apiVersion = rhino.eval("plugin.apiVersion;");
}
if (null == name) {
name = rhino.eval("plugin.name;");
}
}
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) {
// XXX: Evil silent failure
return null;
}
 
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) {
// XXX: Evil silent failure
return null;
}
return pp;
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/Sandbox.java
0,0 → 1,114
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.lang.reflect.Method;
import java.util.Map;
import javax.script.ScriptEngine;
 
/**
* Public methods provided by the sandbox.
*/
// Note that all methods defined directly in this interface imply a call to {@link #execute}.
public interface Sandbox extends RuntimeHooks, SandboxProperties, Sandbox_R1 {
/**
* Creates an implementation of an interface from a JS object
* containing the interface's methods.
* <br />
* <b>Note</b>: Implies a call to {@link #execute()}.
* @param interfaceClass Interface to implement
* @param objectName Name of the JS object implementing the interface
* @return The implementation
* @throws net.outlyer.plugins.PluginExecutionException
* @see #createDelayedImplementation(Class,Map)
* @see #execute()
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass,
final String objectName)
throws PluginExecutionException;
 
/**
* Creates an implementation of an interface from inline JS code.
* This variant allows more flexibility (e.g. the implementation might
* be split among objects, map to global functions or fallback to other
* object if unimplemented).
* Note the mapped code should be evaluable as a JS function AND
* it shouldn't end in a semicolon, e.g.:
* <br />
* Valid:
* <pre>
* function() { return SomeValue; }
* </pre>
* <pre>
* // myFunc() is a function defined somewhere in the code
* myFunc
* </pre>
* <br />
* Not valid:
* <pre>
* function() { return SomeValue; };
* </pre>
* <pre>
* SomeValue
* </pre>
* <br />
* Where possible {@link #createDelayedImplementation(Class,String)} is
* a much cleaner option.
* <br />
* <b>Note</b>: Implies a call to {@link #execute()}.
* @param interfaceClass
* @param methodToCodeMap
* @return
* @throws net.outlyer.plugins.PluginExecutionException
* @see #createDelayedImplementation(Class,String)
*/
<T> T createDelayedImplementation(final Class<T> interfaceClass,
final Map<Method, String> methodToCodeMap)
throws PluginExecutionException;
 
/**
* Run the script
*/
void execute() throws PluginExecutionException;
 
/**
* Obtains a reference to the engine currently in use, if any.
* If called during an execution it will return the current engine, from calling
* outside will return null.
* @return Current ScriptEngine
*/
ScriptEngine getCurrentEngine();
 
/**
* Obtains object containing the plugin object
* <br />
* <b>Note</b>: Implies a call to {@link #execute()}.
* @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/branches/1.1.1build36/src/net/outlyer/plugins/Sandbox_R1.java
0,0 → 1,45
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.Reader;
 
/**
* Methods added to {@link Sandbox} in the first revision.
* @since {@link net.outlyer.plugins.API#REVISION} 1
*/
interface Sandbox_R1 {
/**
* Adds code to the code currently executing.
* @param code Source of code to add
* @return Evaluation result
* @throws java.lang.IllegalStateException If not currently running
* @throws net.outlyer.plugins.PluginException If the code failed to be injected
* @since {@link net.outlyer.plugins.API#REVISION} 1
*/
public Object inject(final Reader code) throws IllegalStateException, PluginException;
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/API.java
0,0 → 1,77
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.
*
* Versioning is inspired by libtool's rules
* {@link http://www.gnu.org/software/libtool/manual.html#Versioning}, i.e.
* <pre>
* API version = "current"
* API revision = "revision"
* API min_supported_revision = "current" - "age"
* </pre>
*
* Release numbers are meaningful and composed like:
* <code>Version.MinSupported.Revision.build#</code>,
* so, e.g. release 2.3.0 won't valid since MinSupported can't be
* greater than version.
*/
public final class API {
/**
* API Version.
* Newer versions might break backwards compatibility.
*/
public static final int VERSION = 1;
 
/**
* Revision of the API Version.
* A newer revision might add features but not change the meaning of
* existing ones neither remove any of them.
* @see #VERSION
*/
public static final int REVISION = 1;
 
/**
* Number of previous Versions supported.
* For future use.
* {@see #VERSION}
* {@see #MIN_SUPPORTED_VERSION}
*/
public static final int AGE = 0;
/**
* Minimum API version 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 #VERSION
* @pre MIN_SUPPORTED_VERSION &lt;= VERSION
*/
public static final int MIN_SUPPORTED_VERSION = VERSION - AGE;
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/Functor.java
0,0 → 1,50
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$
 
/**
* Basically a wrapper inspired by {@link java.util.concurrent.Callable}
* and {@link java.lang.Runnable}.
* Allows exported methods to explicitly declare a parameter as a
* function to be applied to an object.
* <br />
* Defines a single method, {@link #apply}.
* <br />
* Due to Rhino's code adaptations, passing a JavaScript function
* where a {@link Functor} is expected works transparently, e.g.:
* <code>lang.for_each(arr, function() { ... });</code>
* @see net.outlyer.plugins.utils.LanguageExtensions
* @see net.outlyer.plugins.utils.LanguageExtensions#for_each(Object[], Functor)
*
* @since {@link API#REVISION} 1
*/
public interface Functor<ResultType, ParamType> {
/**
* Apply the function to object p and return a ResultType object.
*/
ResultType apply(final ParamType p);
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/NamespaceContainer.java
0,0 → 1,54
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 the hierarchy exported to JavaScript as $net.outlyer.runtime.
*/
class NamespaceContainer {
public static class Runtime {
public final Sandbox sandbox;
public final PluginEnvironment pluginEnvironment;
public Object internal = null;
private Runtime(final PluginEnvironment pe, final Sandbox sandbox_) {
sandbox = sandbox_;
pluginEnvironment = pe;
}
}
 
/**
* This object is published as $net_outlyer
*/
public static class $Net_Outlyer {
public final Runtime runtime;
$Net_Outlyer(final PluginEnvironment pe, final Sandbox sandbox) {
runtime = new Runtime(pe, sandbox);
}
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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 properties of a sandbox
* @see Sandbox
*/
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/branches/1.1.1build36/src/net/outlyer/plugins/SandboxAccessor.java
0,0 → 1,59
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 like
* <pre>
* public Object sandboxGetter = null;
* </pre>
*
* sandboxGetter MUST be public, it can be of class Object or
* Callable&lt;Sandbox&gt;, but shouldn't be used directly, instead, if required,
* use SandboxAccessorImpl#getSandbox(SandboxAccessor) to retrieve it's
* value, or inherit from SandboxAccessorImpl to be able to use
* SandboxAccessorImpl#getSandbox().
* <br />
* Implementation notes: It will be dynamically initialised, no user
* initialisation is required.
*
* The convenience default implementation, {@link SandboxAccessorImpl} can
* be used as a base class if that's possible, to hide such requirement.
*/
public interface SandboxAccessor {
/**
* Obtains the associated sanbdox.
* Implementors can use {@link SandboxAccessor#getSandbox(SandboxAccessor)}.
* @return The sandbox
*/
public Sandbox getSandbox();
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/package-info.java
0,0 → 1,32
/**
* This package contains the classes used to load JavaScript-based plugins.
* See {@link http://p.outlyer.net./pluggablejs/}
*/
 
// $Id$
 
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.
*/
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/PluginObject.java
0,0 → 1,69
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.HashSet;
import java.util.Set;
 
/**
* 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 {
/**
* Plugins can describe which features they provide by adding
* elements to this field. Possible values are application-specific.
* Default: empty
* @see #properties
*/
public Set<String> features;
 
{
features = new HashSet<String>();
}
 
/**
* Obtains the number of the current execution
* @return Current execution number
* @see Sandbox#getExecution()
*/
public int execution() {
return getSandbox().getExecution();
}
 
/**
* {@inheritDoc}
*/
@Override public Object clone() throws CloneNotSupportedException {
final PluginObject po = (PluginObject) super.clone();
po.features = new HashSet<String>(this.features);
return po;
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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 some points in the execution process.
*/
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/branches/1.1.1build36/src/net/outlyer/plugins/EngineSink.java
0,0 → 1,118
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.PrintStream;
import java.io.Reader;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
 
/**
* Intercepts ScriptEngine's methods and dumps their information to console.
* @see SandboxImpl#getEngine
*/
class EngineSink implements ScriptEngine {
private final ScriptEngine e;
private final PrintStream s;
{
s = System.err;
}
public EngineSink(final ScriptEngine actualEngine) {
e = actualEngine;
}
 
public Object eval(String script, ScriptContext context) throws ScriptException {
return e.eval(script, context);
}
 
public Object eval(Reader reader, ScriptContext context) throws ScriptException {
return e.eval(reader, context);
}
 
public Object eval(String script) throws ScriptException {
s.printf("//[D] eval(String):\n%s//[EOS]\n", script);
return e.eval(script);
}
 
public Object eval(Reader reader) throws ScriptException {
return e.eval(reader);
}
 
public Object eval(String script, Bindings n) throws ScriptException {
return e.eval(script, n);
}
 
public Object eval(Reader reader, Bindings n) throws ScriptException {
return e.eval(reader, n);
}
 
public void put(String key, Object value) {
s.printf("//[D] put('%s', %s)\n", key, value);
e.put(key, value);
}
 
public Object get(String key) {
return e.get(key);
}
 
public Bindings getBindings(int scope) {
return e.getBindings(scope);
}
 
public void setBindings(Bindings bindings, int scope) {
s.printf("//[D] setBindings() scope=%s:\n",
(scope==ScriptContext.ENGINE_SCOPE) ? "ENGINE_SCOPE" : "GLOBAL_SCOPE");
for (final String key : bindings.keySet()) {
s.printf(" %s=%s\n", key, bindings.get(key));
}
s.println("//[EOL]");
e.setBindings(bindings, scope);
}
 
public Bindings createBindings() {
return e.createBindings();
}
 
public ScriptContext getContext() {
return e.getContext();
}
 
public void setContext(ScriptContext context) {
e.setContext(context);
}
 
public ScriptEngineFactory getFactory() {
throw new UnsupportedOperationException("Not supported yet.");
}
 
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/src/net/outlyer/plugins/SandboxAccessorImpl.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.lang.reflect.Field;
import java.util.concurrent.Callable;
 
/**
* Default implementation of a {@see SandboxAccessor}.
*/
public abstract class SandboxAccessorImpl implements SandboxAccessor {
public Object sandboxGetter;
 
public static Sandbox getSandbox(final SandboxAccessor sa) {
try {
// Retrieve the field...
final Field gS = sa.getClass().getField("sandboxGetter");
// Evaluate as a callable
return ((Callable<Sandbox>)gS.get(sa)).call();
}
catch (final NoSuchFieldException e) {
throw new IllegalStateException(sa.getClass()+" hasn't been correctly initialised", e);
}
catch (final Exception e) {
throw new IllegalStateException("getSandbox produced an exception ("+
e.getClass().getSimpleName()+"),"+
"for object "+sa+" which is not expected!: " +
e.getMessage(), e);
}
}
 
public final Sandbox getSandbox() {
if (null == sandboxGetter) {
throw new IllegalStateException(getClass()+" hasn't been correctly initialised");
}
try {
return ((Callable<Sandbox>)sandboxGetter).call();
}
catch (final Exception e) {
throw new IllegalStateException("sandboxGetter produced an " +
"exception, which is not expected!");
}
 
}
}
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/Makefile
0,0 → 1,32
# $Id$
 
prefix:=/usr/local
DESTDIR:=
 
buildnum=$(shell grep 'build.number' build.num | cut -d'=' -f2)
version=$(shell grep '<property name="version"' build.xml | sed -r 's/.*value="([^"]*)".*/\1/')
jarbasename=pluggablejs-$(version)build$(buildnum).jar
 
bindir=$(DESTDIR)/$(prefix)/bin
 
all:
ant compile.downstream
 
dist/$(jarbasename):
ant dist.downstream
 
clean:
ant clean
 
install: dist/$(jarbasename)
test 0 -eq `id -u` # Must be root (or use fakeroot)
mkdir -p $(DESTDIR)/$(prefix)/share/java $(bindir)/
install -m644 -o0 -g0 dist/$(jarbasename) $(DESTDIR)/$(prefix)/share/java/
cd $(DESTDIR)/$(prefix)/share/java && ln -s $(jarbasename) pluggablejs.jar
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/$(jarbasename)
-rmdir -p $(DESTDIR)/$(prefix)/share/java
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/TODO
0,0 → 1,2
 
? Rename $net to $net_outlyer_runtime to be less intrusive
/pluggablejs/branches/1.1.1build36/samples/langext.js
0,0 → 1,31
 
println("Language extensions samples");
 
println("|> Inclusion of langext-included.js, composition of ");
println("|> an object from different files");
 
function method1_implementation() {
println("This method is defined in langext.js");
}
 
var method2_implementation = null;
 
// If method2 was defined this way it will fail, it needs to be
// defined as with method3
var obj = {
method1: method1_implementation,
method2: method2_implementation,
method3: function() {
method3_implementation();
}
};
 
lang.include("langext-included.js");
 
// ... instead, it can be defined now though
obj.method2 = method2_implementation;
 
println("|> calling of methods defined elsewhere:");
obj.method1();
obj.method2();
obj.method3();
/pluggablejs/branches/1.1.1build36/samples/interactive-call.js
0,0 → 1,2
 
net.outlyer.plugins.Shell.interactive($net.outlyer.runtime.pluginEnvironment);
/pluggablejs/branches/1.1.1build36/samples/langext-included.js
0,0 → 1,9
 
println("|< langext-included.js loaded");
 
method2_implementation = function() {
println("This method is defined in langext-included.js");
}
 
method3_implementation = method2_implementation;
 
/pluggablejs/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/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/branches/1.1.1build36/samples/sandboxed-sandbox.js
0,0 → 1,3
 
err.println("I'm a sandbox inside a sandbox");
 
/pluggablejs/branches/1.1.1build36/pjsh.sh
0,0 → 1,7
#!/bin/sh
 
prefix=/usr/local
installpath="$prefix/share/java"
JAR="$installpath/pluggablejs.jar"
 
java -cp "$JAR" net.outlyer.plugins.Shell $@
Property changes:
Added: svn:keywords
+Rev Id Date
\ No newline at end of property
/pluggablejs/branches/1.1.1build36/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/branches/1.1.1build36
Property changes:
Added: svn:mergeinfo
Merged /pluggablejs/branches/1.0build27:r52
Merged /pluggablejs/branches/1.0build28:r55
Merged /pluggablejs/branches/1.0build29:r58
Merged /pluggablejs/branches/1.1.0build33:r61
Merged /pluggablejs/branches/1.1.1build34:r64