diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java')
-rw-r--r-- | sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java b/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java new file mode 100644 index 0000000000..b2064f9110 --- /dev/null +++ b/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.container.javascript.rhino; + +import java.io.ByteArrayInputStream; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.om.util.StAXUtils; +import org.apache.xmlbeans.XmlObject; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Wrapper; +import org.mozilla.javascript.xml.XMLObject; + +/** + * An invoker for a specific function in a JavaScript script + */ +public class RhinoFunctionInvoker { + + private Scriptable instanceScope; + + private Function function; + + private Class responseClass; + + public RhinoFunctionInvoker(Scriptable instanceScope, Function function, Class responseClass) { + this.instanceScope = instanceScope; + this.function = function; + this.responseClass = responseClass; + } + + public Object invoke(Object[] args) { + Context cx = Context.enter(); + try { + + Object[] jsArgs = toJavaScript(args, instanceScope, cx); + Object jsResponse = function.call(cx, instanceScope, instanceScope, jsArgs); + Object response = fromJavaScript(jsResponse); + return response; + + } catch ( Exception e ) { + throw new RuntimeException(e); + } + finally { + Context.exit(); + } + } + + protected Object[] toJavaScript(Object[] arg, Scriptable scope, Context cx) throws RuntimeException { + Object[] jsArgs; + if (arg == null) { + jsArgs = new Object[0]; + } else if (arg.length == 1 && arg[0] instanceof OMElement) { + try { + XmlObject xmlObject = XmlObject.Factory.parse(arg[0].toString()); + Object jsXML = cx.getWrapFactory().wrap(cx, scope, xmlObject, XmlObject.class); + jsArgs = new Object[] { cx.newObject(scope, "XML", new Object[] { jsXML }) }; + } catch ( Exception e ) { + throw new RuntimeException(e); + } + } else if (arg.length == 1 && arg[0] instanceof XmlObject) { + Object jsXML = cx.getWrapFactory().wrap(cx, scope, (XmlObject)arg[0], XmlObject.class); + jsArgs = new Object[] { cx.newObject(scope, "XML", new Object[] { jsXML }) }; + } else { + jsArgs = new Object[arg.length]; + for (int i = 0; i < jsArgs.length; i++) { + jsArgs[i] = Context.toObject(arg[i], scope); + } + } + + return jsArgs; + } + + protected Object fromJavaScript(Object o) throws Exception { + Object response; + if (Context.getUndefinedValue().equals(o)) { + response = null; + } else if (o instanceof XMLObject) { + // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost??? + Scriptable jsXML = (Scriptable) ScriptableObject.callMethod((Scriptable) o, "copy", new Object[0]); + Wrapper wrapper = (Wrapper) ScriptableObject.callMethod(jsXML, "getXmlObject", new Object[0]); + response = wrapper.unwrap(); + + XMLStreamReader xmlReader = + StAXUtils.createXMLStreamReader(new ByteArrayInputStream(response.toString().getBytes())); + StAXOMBuilder staxOMBuilder = new StAXOMBuilder(OMAbstractFactory.getOMFactory(), xmlReader); + response = staxOMBuilder.getDocumentElement(); + + } else if (o instanceof Wrapper) { + response = ((Wrapper) o).unwrap(); + } else { + if (responseClass != null) { + response = Context.jsToJava(o, responseClass); + } else { + response = Context.jsToJava(o, String.class); + } + } + return response; + } + +} |