You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2008/03/11 16:21:44 UTC
svn commit: r635972 - in /incubator/sling/trunk:
api/src/main/java/org/apache/sling/api/scripting/SlingScript.java
scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java
Author: cziegeler
Date: Tue Mar 11 08:21:38 2008
New Revision: 635972
URL: http://svn.apache.org/viewvc?rev=635972&view=rev
Log:
SLING-320: Allow method calls in a script; this implementation is not optimal yet, it uses the javax.script.Invocable interface if the script engine supports it; otherwise it tries to generate a javascript like method call.
Modified:
incubator/sling/trunk/api/src/main/java/org/apache/sling/api/scripting/SlingScript.java
incubator/sling/trunk/scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java
Modified: incubator/sling/trunk/api/src/main/java/org/apache/sling/api/scripting/SlingScript.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/api/src/main/java/org/apache/sling/api/scripting/SlingScript.java?rev=635972&r1=635971&r2=635972&view=diff
==============================================================================
--- incubator/sling/trunk/api/src/main/java/org/apache/sling/api/scripting/SlingScript.java (original)
+++ incubator/sling/trunk/api/src/main/java/org/apache/sling/api/scripting/SlingScript.java Tue Mar 11 08:21:38 2008
@@ -53,4 +53,20 @@
*/
Object eval(SlingBindings props);
+ /**
+ * Evaluates this script using the bound variables as global variables to
+ * the script and then calls the given method with the arguments.
+ *
+ * @param props The {@link SlingBindings} providing the bound variables for
+ * evaluating the script. Any bound variables must conform to the
+ * requirements of the {@link SlingBindings} predefined variables
+ * set.
+ * @param name The name of the method to call.
+ * @param args The arguments for the method call.
+ * @return The value returned by the method from the script.
+ * @throws ScriptEvaluationException If an error occurrs executing the
+ * script or preparing the script execution. The cause of the
+ * evaluation execption is available as the exception cause.
+ */
+ Object call(SlingBindings props, String method, Object... args);
}
Modified: incubator/sling/trunk/scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java?rev=635972&r1=635971&r2=635972&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java (original)
+++ incubator/sling/trunk/scripting/resolver/src/main/java/org/apache/sling/scripting/resolver/impl/DefaultSlingScript.java Tue Mar 11 08:21:38 2008
@@ -32,7 +32,9 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
+import java.io.StringReader;
import java.io.Writer;
+import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
@@ -40,6 +42,7 @@
import javax.jcr.Node;
import javax.script.Bindings;
+import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -100,8 +103,17 @@
* @throws ScriptEvaluationException
*/
public Object eval(SlingBindings props) {
+ return this.call(props, null);
+ }
- String scriptName = getScriptResource().getPath();
+ // ---------- Servlet interface --------------------------------------------
+
+ /**
+ * @see org.apache.sling.api.scripting.SlingScript#call(org.apache.sling.api.scripting.SlingBindings, java.lang.String, java.lang.Object[])
+ * @throws ScriptEvaluationException
+ */
+ public Object call(SlingBindings props, String method, Object... args) {
+ final String scriptName = getScriptResource().getPath();
Bindings bindings = null;
try {
@@ -114,10 +126,21 @@
ctx.setErrorWriter(new LogWriter((Logger) bindings.get(LOG)));
Reader reader = getScriptReader();
+ if ( method != null && !(this.scriptEngine instanceof Invocable)) {
+ reader = getWrapperReader(reader, method, args);
+ }
// evaluate the script
final Object result = scriptEngine.eval(reader, ctx);
+ // call method - if supplied and script engine supports direct invocation
+ if ( method != null && (this.scriptEngine instanceof Invocable)) {
+ try {
+ ((Invocable)scriptEngine).invokeFunction(method, Arrays.asList(args).toArray());
+ } catch (NoSuchMethodException e) {
+ throw new ScriptEvaluationException(scriptName, "Method " + method + " not found in script.", e);
+ }
+ }
// optionall flush the output channel
Object flushObject = bindings.get(SlingBindings.FLUSH);
if (flushObject instanceof Boolean && (Boolean) flushObject) {
@@ -146,8 +169,6 @@
}
}
- // ---------- Servlet interface --------------------------------------------
-
public void init(ServletConfig servletConfig) {
if (servletConfig != null) {
Dictionary<String, String> params = new Hashtable<String, String>();
@@ -250,6 +271,66 @@
// converting the stream data using UTF-8 encoding, which is
// the default encoding used
return new BufferedReader(new InputStreamReader(input, encoding));
+ }
+
+ private Reader getWrapperReader(final Reader scriptReader, final String method, final Object... args) {
+ final StringBuffer buffer = new StringBuffer(method);
+ buffer.append('(');
+ for(Object o : args) {
+ buffer.append('"');
+ buffer.append(o);
+ buffer.append('"');
+ }
+ buffer.append(')');
+ final String msg = buffer.toString();
+ return new Reader() {
+
+ protected boolean doAppend = false;
+
+ protected StringReader methodReader = new StringReader(msg);
+ /**
+ * @see java.io.Reader#close()
+ */
+ public void close() throws IOException {
+ scriptReader.close();
+ }
+
+ @Override
+ public int read(char[] cbuf, int start, int len) throws IOException {
+ if ( doAppend ) {
+ return methodReader.read(cbuf, start, len);
+ }
+ int readLen = scriptReader.read(cbuf, start, len);
+ if ( readLen == -1 ) {
+ doAppend = true;
+ return this.read(cbuf, start, len);
+ }
+ return readLen;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if ( doAppend ) {
+ return methodReader.read();
+ }
+ int value = scriptReader.read();
+ if ( value == -1 ) {
+ doAppend = true;
+ return methodReader.read();
+ }
+ return value;
+ }
+
+ @Override
+ public int read(char[] cbuf) throws IOException {
+ return this.read(cbuf, 0, cbuf.length);
+ }
+
+ @Override
+ public boolean ready() throws IOException {
+ return scriptReader.ready();
+ }
+ };
}
private Bindings verifySlingBindings(String scriptName,