summaryrefslogtreecommitdiffstats
path: root/sandbox/ant/container.rhino
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /sandbox/ant/container.rhino
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')
-rw-r--r--sandbox/ant/container.rhino/NOTICE.txt14
-rw-r--r--sandbox/ant/container.rhino/pom.xml68
-rw-r--r--sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/JavaScriptImplementationLoader.java81
-rw-r--r--sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoFunctionInvoker.java88
-rw-r--r--sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstance.java103
-rw-r--r--sandbox/ant/container.rhino/src/main/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceFactory.java145
-rw-r--r--sandbox/ant/container.rhino/src/main/resources/META-INF/sca/default.scdl40
-rw-r--r--sandbox/ant/container.rhino/src/main/resources/META-INF/sca/script.system.scdl40
-rw-r--r--sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoFunctionInvokerTestCase.java160
-rw-r--r--sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptInstanceTestCase.java52
-rw-r--r--sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/RhinoScriptTestCase.java85
-rw-r--r--sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/ScriptImplementationLoaderTestCase.java133
-rw-r--r--sandbox/ant/container.rhino/src/test/java/org/apache/tuscany/container/rhino/mock/Foo.java34
-rw-r--r--sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.componentType9
-rw-r--r--sandbox/ant/container.rhino/src/test/resources/org/apache/tuscany/container/script/foo.mock1
15 files changed, 1053 insertions, 0 deletions
diff --git a/sandbox/ant/container.rhino/NOTICE.txt b/sandbox/ant/container.rhino/NOTICE.txt
new file mode 100644
index 0000000000..d83ebbe236
--- /dev/null
+++ b/sandbox/ant/container.rhino/NOTICE.txt
@@ -0,0 +1,14 @@
+${pom.name}
+Copyright (c) 2005 - 2006 The Apache Software Foundation
+
+Apache Tuscany is an effort undergoing incubation at The Apache Software
+Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is
+required of all newly accepted projects until a further review indicates that
+the infrastructure, communications, and decision making process have stabilized
+in a manner consistent with other successful ASF projects. While incubation
+status is not necessarily a reflection of the completeness or stability of the
+code, it does indicate that the project has yet to be fully endorsed by the ASF.
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/ant/container.rhino/pom.xml b/sandbox/ant/container.rhino/pom.xml
new file mode 100644
index 0000000000..8c5543efc5
--- /dev/null
+++ b/sandbox/ant/container.rhino/pom.xml
@@ -0,0 +1,68 @@
+<?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.
+-->
+<project>
+
+ <parent>
+ <groupId>org.apache.tuscany.sca.services.containers</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-incubator-M2-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>tuscany-rhino</artifactId>
+ <name>Apache Tuscany Rhino JavaScript Container</name>
+ <description>Apache Tuscany Rhino JavaScript Container</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca.services.containers</groupId>
+ <artifactId>easy-container</artifactId>
+ <version>${sca.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>rhino</groupId>
+ <artifactId>js</artifactId>
+ <version>1.6R2</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>test</artifactId>
+ <version>${sca.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ </dependency>
+
+ </dependencies>
+
+</project>
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