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/ant/container.rhino/src |
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/ant/container.rhino/src')
13 files changed, 971 insertions, 0 deletions
diff --git a/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/JavaScriptImplementationLoader.java b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/JavaScriptImplementationLoader.java new file mode 100644 index 0000000000..74ecda04ab --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/JavaScriptImplementationLoader.java @@ -0,0 +1,81 @@ +/* + * 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.rhino; + +import static org.osoa.sca.Version.XML_NAMESPACE_1_0; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.container.easy.EasyImplementation; +import org.apache.tuscany.container.easy.EasyImplementationLoader; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.osoa.sca.annotations.Constructor; + +/** + * Loader for handling implementation.script elements. + * + * <implementation.script script="path/foo.py" class="myclass"> + * + */ +public class JavaScriptImplementationLoader extends EasyImplementationLoader { + + private static final QName IMPLEMENTATION_SCRIPT = new QName(XML_NAMESPACE_1_0, "implementation.js"); + + @Constructor( { "registry" }) + public JavaScriptImplementationLoader(@Autowire LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return IMPLEMENTATION_SCRIPT; + } + + @Override + public EasyImplementation load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + String scriptName = reader.getAttributeValue(null, "script"); + if (scriptName == null) { + throw new MissingResourceException("implementation element has no 'script' attribute"); + } + + String className = reader.getAttributeValue(null, "class"); + + LoaderUtil.skipToEndElement(reader); + + ClassLoader cl = deploymentContext.getClassLoader(); + String scriptSource = loadSource(cl, scriptName); + + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory(scriptName, className, scriptSource, cl); + + EasyImplementation implementation = new EasyImplementation(); + implementation.setResourceName(scriptName); + implementation.setScriptInstanceFactory(instanceFactory); + + registry.loadComponentType(parent, implementation, deploymentContext); + + return implementation; + } +} diff --git a/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoFunctionInvoker.java b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoFunctionInvoker.java new file mode 100644 index 0000000000..3b0e132d94 --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoFunctionInvoker.java @@ -0,0 +1,88 @@ +/* + * 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.rhino; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.Wrapper; + +/** + * 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; + + } + finally { + Context.exit(); + } + } + + protected Object[] toJavaScript(Object[] arg, Scriptable scope, Context cx) throws RuntimeException { + Object[] jsArgs; + if (arg == null) { + jsArgs = new Object[0]; + } 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) { + Object response; + if (Context.getUndefinedValue().equals(o)) { + response = null; + } 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; + } + +} diff --git a/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstance.java b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstance.java new file mode 100644 index 0000000000..66e76855d6 --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstance.java @@ -0,0 +1,103 @@ +/* + * 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.rhino; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.tuscany.container.easy.EasyInstance; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.UniqueTag; + +/** + * An invokeable instance of a JavaScript script. + */ +public class RhinoScriptInstance implements EasyInstance { + + private Scriptable scriptScope; + + private Scriptable instanceScope; + + private Map<String, Class> responseClasses; + + public RhinoScriptInstance(Scriptable scriptScope, Scriptable instanceScope, Map<String, Object> context, Map<String, Class> responseClasses) { + this.scriptScope = scriptScope; + this.instanceScope = instanceScope; + this.responseClasses = responseClasses; + if (this.responseClasses == null) { + this.responseClasses = new HashMap<String, Class>(); + } + addContexts(instanceScope, context); + } + + public Object invokeTarget(String operationName, Object[] args) throws InvocationTargetException { + RhinoFunctionInvoker invoker = createRhinoFunctionInvoker(operationName); + return invoker.invoke(args); + } + + + public RhinoFunctionInvoker createRhinoFunctionInvoker(String functionName) { + Function function = getFunction(functionName); + Class responseClass = responseClasses.get(functionName); + RhinoFunctionInvoker invoker = new RhinoFunctionInvoker(instanceScope, function, responseClass); + return invoker; + } + + /** + * Add the context to the scope. This will make the objects available to a script by using the name it was added with. + */ + protected void addContexts(Scriptable scope, Map contexts) { + if (contexts != null) { + Context.enter(); + try { + for (Iterator i = contexts.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + Object value = contexts.get(name); + if (value != null) { + scope.put(name, scope, Context.toObject(value, scope)); + } + } + } finally { + Context.exit(); + } + } + } + + /** + * Get the Rhino Function object for the named script function + */ + protected Function getFunction(String functionName) { + + Object handleObj = scriptScope.get(functionName, instanceScope); + if (UniqueTag.NOT_FOUND.equals(handleObj)) { + // Bit of a hack so E4X scripts don't need to define a function for every operation + handleObj = scriptScope.get("process", instanceScope); + } + if (!(handleObj instanceof Function)) { + throw new RuntimeException("script function '" + functionName + "' is undefined or not a function"); + } + + return (Function) handleObj; + } + +} diff --git a/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceFactory.java b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceFactory.java new file mode 100644 index 0000000000..ea55669696 --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceFactory.java @@ -0,0 +1,145 @@ +/* + * 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.rhino; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.container.easy.EasyInstanceFactory; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ContextFactory; +import org.mozilla.javascript.ImporterTopLevel; +import org.mozilla.javascript.Script; +import org.mozilla.javascript.Scriptable; + +/** + * A RhinoScript represents a compiled JavaScript script + */ +public class RhinoScriptInstanceFactory extends EasyInstanceFactory<RhinoScriptInstance> { + + protected String scriptSource; + + protected Scriptable scriptScope; + + protected Map<String, Class> responseClasses; + + private String className; + + /* + * Enable dynamic scopes so a script can be used concurrently with a global shared scope and individual execution scopes. See + * http://www.mozilla.org/rhino/scopes.html + */ + private static class MyFactory extends ContextFactory { + protected boolean hasFeature(Context cx, int featureIndex) { + if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) { + return true; + } + return super.hasFeature(cx, featureIndex); + } + } + + static { + ContextFactory.initGlobal(new MyFactory()); + } + + public RhinoScriptInstanceFactory(String resourceName, String className, String scriptSource, ClassLoader classLoader) { + super(resourceName, classLoader); + this.className = className; + this.scriptSource = scriptSource; + this.responseClasses = new HashMap<String, Class>(); + initScriptScope(resourceName, scriptSource, null, classLoader); + } + + @Override + public RhinoScriptInstance createInstance(List<Class> services, Map<String, Object> context) { + // TODO services should really be on the constructor of this class, not on this method + // and the responseClasses done in the constructor/init + Scriptable instanceScope = createInstanceScope(context); + RhinoScriptInstance rsi = new RhinoScriptInstance(scriptScope, instanceScope, context, getResponseClasses(services)); + return rsi; + } + + /** + * Initialize the Rhino Scope for this script instance + */ + public Scriptable createInstanceScope(Map<String, Object> context) { + Context cx = Context.enter(); + try { + + Scriptable instanceScope = cx.newObject(scriptScope); + instanceScope.setPrototype(scriptScope); + instanceScope.setParentScope(null); + + addContexts(instanceScope, context); + + return instanceScope; + + } finally { + Context.exit(); + } + } + + /** + * Create a Rhino scope and compile the script into it + */ + public void initScriptScope(String fileName, String scriptCode, Map context, ClassLoader cl) { + Context cx = Context.enter(); + try { + if (cl != null) { + // TODO: broken with the way the tuscany launcher now uses class loaders + // cx.setApplicationClassLoader(cl); + } + this.scriptScope = new ImporterTopLevel(cx, true); + Script compiledScript = cx.compileString(scriptCode, fileName, 1, null); + compiledScript.exec(cx, scriptScope); + addContexts(scriptScope, context); + + } finally { + Context.exit(); + } + } + + /** + * Add the context to the scope. This will make the objects available to a script by using the name it was added with. + */ + protected void addContexts(Scriptable scope, Map contexts) { + if (contexts != null) { + for (Iterator i = contexts.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + Object value = contexts.get(name); + if (value != null) { + scope.put(name, scope, Context.toObject(value, scope)); + } + } + } + } + + /** + * Set the Java type of a response value. JavaScript is dynamically typed so Rhino cannot always work out what the intended Java type of a + * response should be, for example should the statement "return 42" be a Java int, or Integer or Double etc. When Rhino can't determine the type + * it will default to returning a String, using this method enables overriding the Rhino default to use a specific Java type. + */ + public void setResponseClass(String functionName, Class responseClasses) { + this.responseClasses.put(functionName, responseClasses); + } + +} diff --git a/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/default.scdl b/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..61311036a8 --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/default.scdl @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- + JavaScript configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT" + + name="org.apache.tuscany.container.rhino.RhinoImplementation"> + + <component name="rhino.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.rhino.JavaScriptImplementationLoader"/> + </component> + + <component name="rhino.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.easy.EasyComponentTypeLoader"/> + </component> + + <component name="rhino.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.easy.EasyComponentBuilder"/> + </component> + +</composite> diff --git a/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/script.system.scdl b/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/script.system.scdl new file mode 100644 index 0000000000..766374863c --- /dev/null +++ b/sandbox/ant/container.rhino/src/main/resources/META-INF/sca/script.system.scdl @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- + JavaScript configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT" + + name="org.apache.tuscany.container.script.ScriptImplementation"> + + <component name="rhino.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.rhino.JavaScriptImplementationLoader"/> + </component> + + <component name="rhino.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.easy.EasyComponentTypeLoader"/> + </component> + + <component name="rhino.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.easy.EasyComponentBuilder"/> + </component> + +</composite> diff --git a/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoFunctionInvokerTestCase.java b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoFunctionInvokerTestCase.java new file mode 100644 index 0000000000..132c602028 --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoFunctionInvokerTestCase.java @@ -0,0 +1,160 @@ +/* + * 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.rhino; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.rhino.mock.Foo; + +/** + * Tests for the RhinoFunctionInvoker + */ +public class RhinoFunctionInvokerTestCase extends TestCase { + + public RhinoFunctionInvokerTestCase() { + } + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testNoArgsInvoke() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getPetra() {return 'petra';}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, null); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getPetra"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(null)); + } + + public void testOneArgInvoke() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getS(s) {return s;}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, null); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getS"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(new Object[] { "petra" })); + } + + public void testMultiArgsInvoke() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function concat(x, y) {return x + y}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("concat"); + assertNotNull(invoker); + assertEquals("petrasue", invoker.invoke(new Object[] { "petra", "sue" })); + } + + public void testNoResponseInvoke() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getNull() {}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getNull"); + assertNotNull(invoker); + assertEquals(null, invoker.invoke(new Object[0])); + } + + public void testNullResponseInvoke() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getNull() {return null;}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getNull"); + assertNotNull(invoker); + assertEquals(null, invoker.invoke(new Object[0])); + } + + public void testResponseTypeDefaultString() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getTrue() {return true;}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getTrue"); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertTrue(o instanceof String); + assertEquals("true", o); + } + + public void testResponseTypeBoolean() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getTrue() {return true;}", getClass().getClassLoader()); + instanceFactory.setResponseClass("getTrue", Boolean.class); + List<Class> services = new ArrayList<Class>(); + services.add(TestTypes.class); + RhinoScriptInstance instance = instanceFactory.createInstance(services, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getTrue"); + assertNotNull(invoker); + assertTrue((Boolean) invoker.invoke(new Object[0])); + } + + interface TestTypes { + Boolean getTrue(); + String[] getAs(); + Boolean[] getBs(); + } + + public void testResponseTypeStringArray() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getAs() {var as = new Array(1);as[0]='petra';return as;}", getClass().getClassLoader()); + instanceFactory.setResponseClass("getAs", new String[0].getClass()); + List<Class> services = new ArrayList<Class>(); + services.add(TestTypes.class); + RhinoScriptInstance instance = instanceFactory.createInstance(services, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getAs"); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertNotNull(o); + assertTrue(o.getClass().isArray()); + assertEquals("petra", ((Object[]) o)[0]); + } + + public void testResponseTypeBooleanArray() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getBs() {var bs = new Array(1);bs[0]=true;return bs;}", getClass().getClassLoader()); + instanceFactory.setResponseClass("getBs", new Boolean[0].getClass()); + List<Class> services = new ArrayList<Class>(); + services.add(TestTypes.class); + RhinoScriptInstance instance = instanceFactory.createInstance(services, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getBs"); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertNotNull(o); + assertTrue(o.getClass().isArray()); + assertTrue(((Boolean[]) o)[0]); + } + + public void testRequestCustomType() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, "function getFooS(foo) {return foo.getS();}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getFooS"); + assertNotNull(invoker); + + Foo foo = new Foo(); + foo.setS("petra"); + Object o = invoker.invoke(new Object[] { foo }); + assertEquals(foo.getS(), o); + } + + public void testResponseCustomType() { + RhinoScriptInstanceFactory instanceFactory = new RhinoScriptInstanceFactory("foo", null, + "importClass(Packages.org.apache.tuscany.container.rhino.mock.Foo);function getFoo(s) {var foo = new Foo(); foo.setS(s);return foo;}", getClass().getClassLoader()); + RhinoScriptInstance instance = instanceFactory.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getFoo"); + assertNotNull(invoker); + + Object o = invoker.invoke(new Object[] { "petra" }); + assertNotNull(o); + assertEquals("petra", ((Foo) o).getS()); + } + +} diff --git a/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceTestCase.java b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceTestCase.java new file mode 100644 index 0000000000..54e0d41b40 --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceTestCase.java @@ -0,0 +1,52 @@ +/* + * 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.rhino; + +import java.util.HashMap; + +import junit.framework.TestCase; + +/** + * Tests for the RhinoScriptInstance + */ +public class RhinoScriptInstanceTestCase extends TestCase { + + public RhinoScriptInstanceTestCase() { + + } + + protected void setUp() throws Exception { + super.setUp(); + } + +// public void testInvokeFunction() { +// RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null, "function getPetra() {return 'petra';}", getClass().getClassLoader()); +// RhinoScriptInstance instance = rhinoScript.createInstance(new HashMap<String, Object>()); +// assertEquals("petra", instance.invokeFunction("getPetra", new Object[0])); +// } + + public void testCreateRhinoFunctionInvoker() { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null, "function getPetra() {return 'petra';}", getClass().getClassLoader()); + RhinoScriptInstance instance = rhinoScript.createInstance(null, new HashMap<String, Object>()); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getPetra"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(new Object[0])); + } + +} diff --git a/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptTestCase.java b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptTestCase.java new file mode 100644 index 0000000000..5c6b012832 --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptTestCase.java @@ -0,0 +1,85 @@ +/* + * 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.rhino; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.container.rhino.RhinoFunctionInvokerTestCase.TestTypes; + +import junit.framework.TestCase; + +/** + * Tests for the RhinoScript + */ +public class RhinoScriptTestCase extends TestCase { + + public RhinoScriptTestCase() { + + } + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testSimpleConstructor() throws InvocationTargetException { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null,"function getPetra() {return 'petra';}", getClass().getClassLoader()); + RhinoScriptInstance instance = rhinoScript.createInstance(null, new HashMap<String, Object>()); + assertEquals("petra", instance.invokeTarget("getPetra", new Object[0])); + } + + public void testCreateInstance() { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null,"function getPetra() {return 'petra';}", getClass().getClassLoader()); + RhinoScriptInstance instance = rhinoScript.createInstance(null, new HashMap<String, Object>()); + assertNotNull(instance); + } + + public void testCreateInstanceWithContext() throws InvocationTargetException { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null,"function getName() {return name;}", getClass().getClassLoader()); + Map<String, Object> contexts = new HashMap<String, Object>(); + contexts.put("name", "petra"); + RhinoScriptInstance instance = rhinoScript.createInstance(null, contexts); + assertEquals("petra", instance.invokeTarget("getName", new Object[0])); + } + + public void testDefaultResponseType() throws InvocationTargetException { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null,"function getX() {return 42;}", getClass().getClassLoader()); + RhinoScriptInstance instance = rhinoScript.createInstance(null, new HashMap<String, Object>()); + assertEquals("42", instance.invokeTarget("getX", new Object[0])); + } + + public void testSetResponseType() throws InvocationTargetException { + RhinoScriptInstanceFactory rhinoScript = new RhinoScriptInstanceFactory("foo", null,"function getX() {return 42;}", getClass().getClassLoader()); + rhinoScript.setResponseClass("getX", Integer.class); + List<Class> services = new ArrayList<Class>(); + services.add(TypeTest.class); + RhinoScriptInstance instance = rhinoScript.createInstance(services, new HashMap<String, Object>()); + Object x = instance.invokeTarget("getX", new Object[0]); + assertTrue(x instanceof Integer); + assertEquals(new Integer(42), x); + } + + interface TypeTest { + Integer getX(); + } + +} diff --git a/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/ScriptImplementationLoaderTestCase.java b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/ScriptImplementationLoaderTestCase.java new file mode 100644 index 0000000000..14ba71e86c --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/ScriptImplementationLoaderTestCase.java @@ -0,0 +1,133 @@ +/* + * 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.rhino; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.osoa.sca.Version.XML_NAMESPACE_1_0; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.rhino.JavaScriptImplementationLoader; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; + +/** + * + */ +public class ScriptImplementationLoaderTestCase extends TestCase { + private CompositeComponent parent; + + private XMLStreamReader reader; + + private DeploymentContext deploymentContext; + + private ClassLoader classLoader; + + private LoaderRegistry registry; + + private JavaScriptImplementationLoader loader; + + public void testLoadNoScriptAttribute() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn(null); + replay(reader); + replay(deploymentContext); + + try { + loader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + // ok + } + verify(reader); + verify(deploymentContext); + } + + public void testLoad() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn("foo.mock"); + expect(reader.getAttributeValue(null, "class")).andReturn(null); + expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + JavaScriptImplementationLoader mockLoader = new JavaScriptImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.mock", resource); + return "var bar;"; + } + }; + mockLoader.load(parent, reader, deploymentContext); + verify(reader); + verify(deploymentContext); + } + + public void testLoadNoScriptPresent() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn("foo.py"); + expect(reader.getAttributeValue(null, "class")).andReturn(null); + expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + JavaScriptImplementationLoader mockLoader = new JavaScriptImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.py", resource); + throw new MissingResourceException(resource); + } + }; + try { + mockLoader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + assertEquals("foo.py", e.getMessage()); + } + verify(reader); + verify(deploymentContext); + } + + public void testGetXMLType() throws LoaderException { + assertEquals(XML_NAMESPACE_1_0, loader.getXMLType().getNamespaceURI()); + assertEquals("implementation.js", loader.getXMLType().getLocalPart()); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + loader = new JavaScriptImplementationLoader(registry); + + parent = createMock(CompositeComponent.class); + reader = createMock(XMLStreamReader.class); + deploymentContext = createMock(DeploymentContext.class); + classLoader = createMock(ClassLoader.class); + } +} diff --git a/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/mock/Foo.java b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/mock/Foo.java new file mode 100644 index 0000000000..ee5b0d6db1 --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/mock/Foo.java @@ -0,0 +1,34 @@ +/* + * 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.rhino.mock; + +public class Foo { + private String s; + + public Foo() { + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } +} diff --git a/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.componentType b/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.componentType new file mode 100644 index 0000000000..9c37e1cb3e --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.componentType @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="ASCII"?>
+
+<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <service name="HelloWorldService">
+ <interface.java interface="not.used"/>
+ </service>
+
+</componentType>
diff --git a/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.mock b/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.mock new file mode 100644 index 0000000000..b6fc4c620b --- /dev/null +++ b/sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.mock @@ -0,0 +1 @@ +hello
\ No newline at end of file |