summaryrefslogtreecommitdiffstats
path: root/sandbox/ant/container.script
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.script
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.script')
-rw-r--r--sandbox/ant/container.script/NOTICE.txt14
-rw-r--r--sandbox/ant/container.script/doc/sca-java-container-script.xml119
-rw-r--r--sandbox/ant/container.script/pom.xml89
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptImplementationLoader.java81
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstance.java52
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstanceFactory.java94
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncInvoker.java210
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncMonitor.java31
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponent.java117
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilder.java83
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentType.java62
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoader.java71
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementation.java47
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoader.java85
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstance.java31
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactory.java71
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInvoker.java53
-rw-r--r--sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngine.java118
-rw-r--r--sandbox/ant/container.script/src/main/resources/META-INF/sca/default.scdl40
-rw-r--r--sandbox/ant/container.script/src/main/resources/META-INF/sca/script.system.scdl40
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptImplementationLoaderTestCase.java132
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceFactoryTestCase.java69
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceTestCase.java30
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/AsyncInvokerTestCase.java211
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilderTestCase.java107
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTestCase.java145
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoaderTestCase.java144
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeTestCase.java37
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoaderTestCase.java78
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationTestCase.java30
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactoryTestCase.java56
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInvokerTestCase.java64
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/AsyncTarget.java26
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/MockInstanceFactory.java30
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngineTestCase.java45
-rw-r--r--sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/mock/MockBSFEngine.java27
-rw-r--r--sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.componentType9
-rw-r--r--sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.mock1
-rw-r--r--sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.componentType9
-rw-r--r--sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.mock1
40 files changed, 2759 insertions, 0 deletions
diff --git a/sandbox/ant/container.script/NOTICE.txt b/sandbox/ant/container.script/NOTICE.txt
new file mode 100644
index 0000000000..d83ebbe236
--- /dev/null
+++ b/sandbox/ant/container.script/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.script/doc/sca-java-container-script.xml b/sandbox/ant/container.script/doc/sca-java-container-script.xml
new file mode 100644
index 0000000000..ec100de245
--- /dev/null
+++ b/sandbox/ant/container.script/doc/sca-java-container-script.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document>
+
+ <properties>
+ <title>Tuscany</title>
+ <bannertitle>Tuscany SCA Java Scripting Language Implementation</bannertitle>
+ </properties>
+
+ <body>
+
+<section name="Scripting Language Implementation">
+
+<p>
+The Tuscany Java SCA runtime has a script container allowing SCA components to be implemented with a variety of scripting languages.
+</p>
+<p>
+To use the script container you use the &lt;implementation.script&gt; element in the component SCDL. The &lt;implementation.script&gt; element has two attributes, 'script' and 'class'. The 'script' attribute is required and defines the location of the script program. The 'class' attribute is optional and enables specifying the class or prototype to be used if the script language supports such concepts.
+</p>
+<p>
+The language the script is implemented in is defined by the suffix of the script attribute value. For example, the '.js' suffix indicates a JavaScript program, or '.py' indicates a Python program. The script container uses the <a href='http://jakarta.apache.org/bsf/' target='_blank'>Apache BSF script engine</a>, so any script language supported by BSF can be used as an SCA component implementation.
+</p>
+
+<p>
+</p>
+
+<p>
+</p>
+
+<p>
+</p>
+
+<p>
+</p>
+
+<p>
+The following example shows the files necessary to implement a simple HelloWorld style SCA component using the script container and a JavaScript program.
+</p>
+
+<p>
+The composite SCDL:
+</p>
+<p>
+<table width="100%" class="ex" cellspacing="0" bgcolor="#f4f4f4">
+<tr><td>
+<pre>
+&lt;composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ name="HelloWorldComposite"&gt;
+
+ &lt;component name="HelloWorldComponent"&gt;
+ &lt;implementation.script script="HelloWorld.js"/&gt;
+ &lt;/component&gt;
+
+&lt;/composite&gt;
+</pre>
+</td></tr>
+</table>
+</p>
+
+<p>
+and the associated JavaScript program, 'HelloWorld.js':
+</p>
+<p>
+<table width="100%" class="ex" cellspacing="0" bgcolor="#f4f4f4">
+<tr><td>
+<pre>
+function sayHello(s) {
+ return "Hello " + s;
+}
+</pre>
+</td></tr>
+</table>
+</p>
+
+<p>
+This next example shows a HelloWorld program using the Ruby language, and the use of the &lt;implementation.script&gt; element 'class' attribute to specifying the class of the component implementation:
+</p>
+<p>
+The composite SCDL:
+</p>
+<p>
+<table width="100%" class="ex" cellspacing="0" bgcolor="#f4f4f4">
+<tr><td>
+<pre>
+&lt;composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ name="HelloWorldComposite"&gt;
+
+ &lt;component name="HelloWorldComponent"&gt;
+ &lt;implementation.script script="HelloWorld.rb" class="Helloworld"/&gt;
+ &lt;/component&gt;
+
+&lt;/composite&gt;
+</pre>
+</td></tr>
+</table>
+</p>
+
+<p>
+and the associated Ruby program, 'HelloWorld.rb':
+</p>
+<p>
+<table width="100%" class="ex" cellspacing="0" bgcolor="#f4f4f4">
+<tr><td>
+<pre>
+class Helloworld
+
+ def sayHello(s)
+ return "Hello to " + s + " from the Ruby World!"
+ end
+
+end
+</pre>
+</td></tr>
+</table>
+</p>
+
+
+ </section>
+ </body>
+</document>
diff --git a/sandbox/ant/container.script/pom.xml b/sandbox/ant/container.script/pom.xml
new file mode 100644
index 0000000000..337d507ea6
--- /dev/null
+++ b/sandbox/ant/container.script/pom.xml
@@ -0,0 +1,89 @@
+<?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>container-script</artifactId>
+ <name>Apache Tuscany Script Container</name>
+ <description>Apache Tuscany Script Container using BSF</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca.kernel</groupId>
+ <artifactId>tuscany-spi</artifactId>
+ <version>${sca.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>bsf</groupId>
+ <artifactId>bsf</artifactId>
+ <version>2.4.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>bsf</groupId>
+ <artifactId>bsf3</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>test</artifactId>
+ <version>${sca.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>rhino</groupId>
+ <artifactId>js</artifactId>
+ <version>1.6R2</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.script/src/main/java/org/apache/tuscany/container/script/ScriptImplementationLoader.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptImplementationLoader.java
new file mode 100644
index 0000000000..3e5d228cb5
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptImplementationLoader.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.script;
+
+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.script.helper.ScriptHelperImplementation;
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementationLoader;
+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.apache.tuscany.spi.model.ModelObject;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * Loader for handling implementation.script elements.
+ *
+ * <implementation.script script="path/foo.py" class="myclass">
+ *
+ */
+public class ScriptImplementationLoader extends ScriptHelperImplementationLoader {
+
+ private static final QName IMPLEMENTATION_SCRIPT = new QName(XML_NAMESPACE_1_0, "implementation.script");
+
+ @Constructor( { "registry" })
+ public ScriptImplementationLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return IMPLEMENTATION_SCRIPT;
+ }
+
+ public ScriptHelperImplementation load(CompositeComponent parent, ModelObject mo, 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);
+
+ ScriptInstanceFactory instanceFactory = new ScriptInstanceFactory(scriptName, className, scriptSource, cl);
+
+ ScriptHelperImplementation implementation = new ScriptHelperImplementation();
+ implementation.setResourceName(scriptName);
+ implementation.setScriptInstanceFactory(instanceFactory);
+
+ registry.loadComponentType(parent, implementation, deploymentContext);
+
+ return implementation;
+ }
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstance.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstance.java
new file mode 100644
index 0000000000..9910661f85
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstance.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.script;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.bsf.BSFEngine;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+
+/**
+ * An invokable instance of a script
+ *
+ * Basically just a wrapper around a BSF engine with an optional script class object.
+ */
+public class ScriptInstance implements ScriptHelperInstance {
+
+ protected BSFEngine bsfEngine;
+
+ protected Object clazz;
+
+ public ScriptInstance(BSFEngine bsfEngine, Object clazz) {
+ this.bsfEngine = bsfEngine;
+ this.clazz = clazz;
+ }
+
+ public Object invokeTarget(String operationName, Object[] args) throws InvocationTargetException {
+ try {
+
+ return bsfEngine.call(clazz, operationName, args);
+
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstanceFactory.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstanceFactory.java
new file mode 100644
index 0000000000..7206eb9e8f
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/ScriptInstanceFactory.java
@@ -0,0 +1,94 @@
+/*
+ * 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.script;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.bsf.BSFEngine;
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstanceFactory;
+import org.apache.tuscany.spi.ObjectCreationException;
+
+/**
+ * ScriptInstanceFactory creates ScriptInstances for a script
+ */
+public class ScriptInstanceFactory extends ScriptHelperInstanceFactory<ScriptInstance>{
+
+ private String className;
+
+ private String scriptSource;
+
+ public ScriptInstanceFactory(String resourceName, String className, String scriptSource, ClassLoader classLoader) {
+ super(resourceName, classLoader);
+ this.className = className;
+ this.scriptSource = scriptSource;
+ }
+
+ /**
+ * Create a new invokeable instance of the script
+ *
+ * @param context
+ * objects to add to scope of the script instance
+ * @return a RhinoScriptInstance
+ */
+ public ScriptInstance createInstance(List<Class> services, Map<String, Object> context) {
+ try {
+
+ //TODO: this uses a new manager and recompiles the scrip each time, may be able to optimize
+ // but need to be careful about instance scoping
+
+ BSFManager bsfManager = new BSFManager();
+ bsfManager.setClassLoader(BSFManager.class.getClassLoader());
+
+ // TODO: hack to get Ruby working with the standalone launcher
+ Thread.currentThread().setContextClassLoader(BSFManager.class.getClassLoader());
+
+ // register any context objects (SCA properties and references)
+ for (String beanName : context.keySet()) {
+ bsfManager.registerBean(beanName, context.get(beanName));
+ }
+
+ String scriptLanguage = BSFManager.getLangFromFilename(resourceName);
+ BSFEngine bsfEngine = bsfManager.loadScriptingEngine(scriptLanguage);
+ bsfEngine.exec(resourceName, 0, 0, scriptSource);
+
+ // if there's a className then get the class object
+ Object clazz = null;
+ if (className != null) {
+ // special case for Ruby which requires a .new call
+ if ("ruby".equals(scriptLanguage)) {
+ clazz = bsfEngine.eval(null, 1, 1, className + ".new");
+ } else {
+ clazz = bsfEngine.call(null, className, null);
+ }
+ }
+
+ return new ScriptInstance(bsfEngine, clazz);
+
+ } catch (BSFException e) {
+ if (e.getTargetException() != null) {
+ throw new ObjectCreationException(e.getTargetException());
+ }
+ throw new ObjectCreationException(e.getTargetException());
+ }
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncInvoker.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncInvoker.java
new file mode 100644
index 0000000000..d5cfe581ce
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncInvoker.java
@@ -0,0 +1,210 @@
+/*
+ * 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.script.helper;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.osoa.sca.CompositeContext;
+import org.osoa.sca.CurrentCompositeContext;
+import org.osoa.sca.SCA;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Responsible for performing a non-blocking dispatch on a component implementation instance
+ *
+ * TODO: Pretty much a direct copy of what the groovy container does for async
+ */
+public class AsyncInvoker extends ScriptHelperInvoker {
+
+ private static final ContextBinder BINDER = new ContextBinder();
+ private static final Message RESPONSE = new AsyncInvoker.ImmutableMessage();
+
+ private InboundWire wire;
+ private WorkScheduler workScheduler;
+ private AsyncMonitor monitor;
+ private WorkContext workContext;
+ private Object target;
+ private Object messageId;
+
+ /**
+ * Creates a new invoker
+ *
+ * @param operation the operation the invoker is associated with
+ * @param wire
+ * @param component the target component
+ * @param workScheduler the work scheduler to run the invocation
+ * @param monitor the monitor to pass events to
+ * @param workContext
+ */
+ public AsyncInvoker(String operation,
+ InboundWire wire,
+ ScriptHelperComponent component,
+ WorkScheduler workScheduler,
+ AsyncMonitor monitor,
+ WorkContext workContext) {
+ super(operation, component);
+ this.wire = wire;
+ this.workScheduler = workScheduler;
+ this.monitor = monitor;
+ this.workContext = workContext;
+ }
+
+ // Override invocation methods to defer invocation to work item
+ // Both methods return null to indicate asynchrony; result will
+ // be conveyed by callback
+ @Override
+ public Object invokeTarget(final Object payload) throws InvocationTargetException {
+ final CompositeContext currentContext = CurrentCompositeContext.getContext();
+ // Schedule the invocation of the next interceptor in a new Work instance
+ try {
+ workScheduler.scheduleWork(new Runnable() {
+ private Object currentMessageId = messageId;
+
+ public void run() {
+ workContext.setCurrentMessageId(null);
+ workContext.setCurrentCorrelationId(currentMessageId);
+ CompositeContext oldContext = CurrentCompositeContext.getContext();
+ try {
+ BINDER.setContext(currentContext);
+ // REVIEW response must be null for one-way and non-null for callback
+ AsyncInvoker.super.invokeTarget(payload);
+ } catch (Exception e) {
+ // REVIEW uncomment when it is available
+ // monitor.executionError(e);
+ e.printStackTrace();
+ } finally {
+ BINDER.setContext(oldContext);
+ }
+ }
+ });
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ return RESPONSE;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ // can't just call overriden invoke because it would bypass async
+ try {
+ messageId = msg.getMessageId();
+ wire.addMapping(messageId, msg.getFromAddress());
+ return (Message) invokeTarget(msg.getBody());
+ } catch (Throwable e) {
+ // FIXME need to log exceptions
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public AsyncInvoker clone() {
+ AsyncInvoker invoker = (AsyncInvoker) super.clone();
+ invoker.workScheduler = this.workScheduler;
+ invoker.monitor = this.monitor;
+ return invoker;
+ }
+
+ /**
+ * Resolves the target service instance or returns a cached one
+ */
+ protected Object getInstance() throws TargetException {
+ if (!isCacheable()) {
+ return component.getTargetInstance();
+ } else {
+ if (target == null) {
+ target = component.getTargetInstance();
+ }
+ return target;
+ }
+ }
+
+ protected static class ContextBinder extends SCA {
+ public void setContext(CompositeContext context) {
+ setCompositeContext(context);
+ }
+
+ public void start() {
+ throw new AssertionError();
+ }
+
+ public void stop() {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * A dummy message passed back on an invocation
+ */
+ protected static class ImmutableMessage implements Message {
+
+ public Object getBody() {
+ return null;
+ }
+
+ public void setBody(Object body) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setTargetInvoker(TargetInvoker invoker) {
+ throw new UnsupportedOperationException();
+ }
+
+ public TargetInvoker getTargetInvoker() {
+ return null;
+ }
+
+ public Object getFromAddress() {
+ return null;
+ }
+
+ public void setFromAddress(Object fromAddress) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getMessageId() {
+ return null;
+ }
+
+ public void setMessageId(Object messageId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getCorrelationId() {
+ return null;
+ }
+
+ public void setCorrelationId(Object correlationId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isFault() {
+ return false;
+ }
+
+ public void setBodyWithFault(Object fault) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncMonitor.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncMonitor.java
new file mode 100644
index 0000000000..a3aa9958c7
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/AsyncMonitor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.script.helper;
+
+/**
+ * A monitor used to log events during non-blocking invocations
+ */
+public interface AsyncMonitor {
+
+ /**
+ * Logs an exception thrown during an invocation
+ */
+ void executionError(Exception e);
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponent.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponent.java
new file mode 100644
index 0000000000..03f5da96ca
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponent.java
@@ -0,0 +1,117 @@
+/*
+ * 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.script.helper;
+
+import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * A component implementation for script languages.
+ */
+public class ScriptHelperComponent extends AtomicComponentExtension {
+
+ private final List<Class<?>> services;
+
+ private final Map<String, Object> properties;
+
+ protected ScriptHelperInstanceFactory instanceFactory;
+
+ public ScriptHelperComponent(String name, ScriptHelperInstanceFactory instanceFactory, Map<String, Object> properties, List<Class<?>> services, CompositeComponent parent, ScopeContainer scopeContainer,
+ WireService wireService, WorkContext workContext, WorkScheduler workScheduler) {
+
+ super(name, parent, scopeContainer, wireService, workContext, workScheduler, 0);
+
+ this.instanceFactory = instanceFactory;
+ this.services = services;
+ this.scope = scopeContainer.getScope();
+ this.properties = properties;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object createInstance() throws ObjectCreationException {
+
+ Map<String, Object> context = new HashMap<String, Object>(getProperties());
+
+ for (List<OutboundWire> referenceWires : getOutboundWires().values()) {
+ for (OutboundWire wire : referenceWires) {
+ Object wireProxy = wireService.createProxy(wire);
+ context.put(wire.getReferenceName(), wireProxy);
+ }
+ }
+
+ return instanceFactory.createInstance(services, context);
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation) {
+ Method[] methods = operation.getServiceContract().getInterfaceClass().getMethods();
+ Method method = findMethod(operation, methods);
+ return new ScriptHelperInvoker(method.getName(), this);
+ }
+
+ public TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation) {
+ return new AsyncInvoker(operation.getName(), wire, this, workScheduler, null, workContext);
+ }
+
+ // TODO: move all the following up to AtomicComponentExtension?
+
+ public List<Class<?>> getServiceInterfaces() {
+ return services;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public Object getTargetInstance() throws TargetException {
+ return scopeContainer.getInstance(this);
+ }
+
+ public Object getServiceInstance() throws TargetException {
+ return getServiceInstance(null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getServiceInstance(String service) throws TargetException {
+ InboundWire wire = getInboundWire(service);
+ if (wire == null) {
+ TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message
+ e.setIdentifier(service);
+ throw e;
+ }
+ return wireService.createProxy(wire);
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilder.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilder.java
new file mode 100644
index 0000000000..865827f83f
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilder.java
@@ -0,0 +1,83 @@
+/*
+ * 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.script.helper;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentBuilderExtension;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * Extension point for creating {@link ScriptComponent}s from an assembly configuration
+ */
+public class ScriptHelperComponentBuilder extends ComponentBuilderExtension<ScriptHelperImplementation> {
+
+ public ScriptHelperComponentBuilder() {
+ }
+
+ protected Class<ScriptHelperImplementation> getImplementationType() {
+ return ScriptHelperImplementation.class;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Component build(CompositeComponent parent, ComponentDefinition<ScriptHelperImplementation> componentDefinition,
+ DeploymentContext deploymentContext) throws BuilderConfigException {
+
+ String name = componentDefinition.getName();
+ ScriptHelperImplementation implementation = componentDefinition.getImplementation();
+ ScriptHelperComponentType componentType = implementation.getComponentType();
+
+ // get list of services provided by this component
+ Collection<ServiceDefinition> collection = componentType.getServices().values();
+ List<Class<?>> services = new ArrayList<Class<?>>(collection.size());
+ for (ServiceDefinition serviceDefinition : collection) {
+ services.add(serviceDefinition.getServiceContract().getInterfaceClass());
+ }
+
+ // get the properties for the component
+ Map<String, Object> properties = new HashMap<String, Object>();
+ for (PropertyValue propertyValue : componentDefinition.getPropertyValues().values()) {
+ properties.put(propertyValue.getName(), propertyValue.getValueFactory().getInstance());
+ }
+
+ // TODO: have ComponentBuilderExtension pass ScopeContainer in on build method?
+ ScopeContainer scopeContainer;
+ Scope scope = componentType.getLifecycleScope();
+ if (Scope.MODULE == scope) {
+ scopeContainer = deploymentContext.getModuleScope();
+ } else {
+ scopeContainer = scopeRegistry.getScopeContainer(scope);
+ }
+
+ return new ScriptHelperComponent(name, implementation.getScriptInstanceFactory(), properties, services, parent, scopeContainer, wireService, workContext, workScheduler);
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentType.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentType.java
new file mode 100644
index 0000000000..b7abb9f60e
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentType.java
@@ -0,0 +1,62 @@
+/*
+ * 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.script.helper;
+
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.ReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * A componentType for script components
+ * TODO: need lifecycle methods init/destroy
+ * TODO: really need a generic componentType that supports scope and lifecycle
+ */
+public class ScriptHelperComponentType extends ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> {
+
+ private Scope lifecycleScope = Scope.MODULE;
+
+ public ScriptHelperComponentType() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public ScriptHelperComponentType(ComponentType ct) {
+ // TODO: A bit hacky but this is so the generic .componentType XML side file can be used for now
+ setInitLevel(ct.getInitLevel());
+ for (Object property : ct.getProperties().values()) {
+ add((Property) property);
+ }
+ for (Object reference : ct.getReferences().values()) {
+ add((ReferenceDefinition) reference);
+ }
+ for (Object service : ct.getServices().values()) {
+ add((ServiceDefinition) service);
+ }
+ }
+
+ public Scope getLifecycleScope() {
+ return lifecycleScope;
+ }
+
+ public void setLifecycleScope(Scope lifecycleScope) {
+ this.lifecycleScope = lifecycleScope;
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoader.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoader.java
new file mode 100644
index 0000000000..2c7b1dd4e2
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoader.java
@@ -0,0 +1,71 @@
+/*
+ * 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.script.helper;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentType;
+
+/**
+ * ComponentType loader for script components
+ */
+public class ScriptHelperComponentTypeLoader extends ComponentTypeLoaderExtension<ScriptHelperImplementation> {
+
+ public ScriptHelperComponentTypeLoader() {
+ }
+
+ @Override
+ protected Class<ScriptHelperImplementation> getImplementationClass() {
+ return ScriptHelperImplementation.class;
+ }
+
+ // TODO: must be possible to move all the following up in to ComponentTypeLoaderExtension
+
+ public void load(CompositeComponent parent, ScriptHelperImplementation implementation, DeploymentContext deploymentContext) throws LoaderException {
+ String sideFile = getSideFileName(implementation.getResourceName());
+ URL resource = implementation.getScriptInstanceFactory().getClassLoader().getResource(sideFile);
+ ScriptHelperComponentType componentType;
+ if (resource == null) {
+ throw new IllegalArgumentException("missing .componentType side file: " + sideFile);
+ // TODO: or else implement introspection
+ } else {
+ componentType = loadFromSidefile(resource, deploymentContext);
+ }
+ implementation.setComponentType(componentType);
+ }
+
+ protected ScriptHelperComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException {
+ ComponentType ct = loaderRegistry.load(null, null, url, ComponentType.class, deploymentContext);
+ ScriptHelperComponentType scriptComponentType = new ScriptHelperComponentType(ct);
+ return scriptComponentType;
+ }
+
+ protected String getSideFileName(String resourceName) {
+ int lastDot = resourceName.lastIndexOf('.');
+ if (lastDot != -1) {
+ resourceName = resourceName.substring(0, lastDot);
+ }
+ return resourceName + ".componentType";
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementation.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementation.java
new file mode 100644
index 0000000000..39b867c069
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementation.java
@@ -0,0 +1,47 @@
+/*
+ * 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.script.helper;
+
+import org.apache.tuscany.spi.model.AtomicImplementation;
+
+/**
+ * Model object for a script implementation.
+ */
+public class ScriptHelperImplementation extends AtomicImplementation<ScriptHelperComponentType> {
+
+ private String resourceName;
+
+ private ScriptHelperInstanceFactory scriptInstanceFactory;
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public ScriptHelperInstanceFactory getScriptInstanceFactory() {
+ return scriptInstanceFactory;
+ }
+
+ public void setScriptInstanceFactory(ScriptHelperInstanceFactory scriptInstanceFactory) {
+ this.scriptInstanceFactory = scriptInstanceFactory;
+ }
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoader.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoader.java
new file mode 100644
index 0000000000..cda196590c
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoader.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.script.helper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+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 abstract class ScriptHelperImplementationLoader extends LoaderExtension<ScriptHelperImplementation> {
+
+ @Constructor( { "registry" })
+ public ScriptHelperImplementationLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public abstract QName getXMLType();
+
+ protected String loadSource(ClassLoader cl, String resource) throws LoaderException {
+ URL url = cl.getResource(resource);
+ if (url == null) {
+ throw new MissingResourceException(resource);
+ }
+ InputStream is;
+ try {
+ is = url.openStream();
+ } catch (IOException e) {
+ MissingResourceException mre = new MissingResourceException(resource, e);
+ mre.setIdentifier(resource);
+ throw mre;
+ }
+ try {
+ Reader reader = new InputStreamReader(is, "UTF-8");
+ char[] buffer = new char[1024];
+ StringBuilder source = new StringBuilder();
+ int count;
+ while ((count = reader.read(buffer)) > 0) {
+ source.append(buffer, 0, count);
+ }
+ return source.toString();
+ } catch (IOException e) {
+ LoaderException le = new LoaderException(e);
+ le.setIdentifier(resource);
+ throw le;
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstance.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstance.java
new file mode 100644
index 0000000000..dda5c6e27f
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstance.java
@@ -0,0 +1,31 @@
+/*
+ * 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.script.helper;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * An invokable instance of a script
+ *
+ * Basically just a wrapper around a BSF engine with an optional script class object.
+ */
+public interface ScriptHelperInstance {
+
+ public Object invokeTarget(String operationName, Object[] args) throws InvocationTargetException;
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactory.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactory.java
new file mode 100644
index 0000000000..b3b13fc1a7
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactory.java
@@ -0,0 +1,71 @@
+/*
+ * 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.script.helper;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ScriptInstanceFactory creates ScriptInstances for a script
+ */
+public abstract class ScriptHelperInstanceFactory<T extends ScriptHelperInstance> {
+
+ protected String resourceName;
+
+ protected ClassLoader classLoader;
+
+ public ScriptHelperInstanceFactory(String resourceName, ClassLoader classLoader) {
+ this.resourceName = resourceName;
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Create a new invokeable instance of the script
+ * @param services
+ *
+ * @param context
+ * objects to add to scope of the script instance
+ * @return a RhinoScriptInstance
+ * TODO: services should be on the constructor not on this method
+ */
+ public abstract T createInstance(List<Class> services, Map<String, Object> context);
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ protected Map<String, Class> getResponseClasses(List<Class> services) {
+ Map<String, Class> responseClasses = new HashMap<String, Class>();
+ if (services != null) {
+ for (Class s : services) {
+ for (Method m : s.getMethods()) {
+ responseClasses.put(m.getName(), m.getReturnType());
+ }
+ }
+ }
+ return responseClasses;
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInvoker.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInvoker.java
new file mode 100644
index 0000000000..2a8ffe855a
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/helper/ScriptHelperInvoker.java
@@ -0,0 +1,53 @@
+/*
+ * 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.script.helper;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.spi.extension.TargetInvokerExtension;
+
+/**
+ * TargetInvoker that calls a function on a ScriptInstance
+ */
+public class ScriptHelperInvoker extends TargetInvokerExtension {
+
+ protected ScriptHelperComponent component;
+
+ protected String functionName;
+
+ public ScriptHelperInvoker(String functionName, ScriptHelperComponent component) {
+ this.functionName = functionName;
+ this.component = component;
+ }
+
+ /**
+ * Invoke the function
+ */
+ public Object invokeTarget(final Object payload) throws InvocationTargetException {
+ ScriptHelperInstance target = (ScriptHelperInstance) component.getTargetInstance();
+ try {
+
+ return target.invokeTarget(functionName, (Object[]) payload);
+
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngine.java b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngine.java
new file mode 100644
index 0000000000..fab9813af4
--- /dev/null
+++ b/sandbox/ant/container.script/src/main/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngine.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed 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.script.jsr223;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.apache.bsf.BSFDeclaredBean;
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+import org.apache.bsf.util.BSFEngineImpl;
+
+/**
+ * JSR223BSFEngine enables using any available JSR-223 script engine with BSF
+ *
+ * Use the static method JSR223BSFEngine.registerAllJSR223Engines to register all
+ * the available JSR-223 engines with BSF.
+ */
+public class JSR223BSFEngine extends BSFEngineImpl {
+
+ private ScriptEngine engine;
+
+ /*
+ * @see org.apache.bsf.BSFEngine.call(Object, String, Object[])
+ */
+ public Object call(Object object, String name, Object[] args) throws BSFException {
+ if (!(engine instanceof Invocable)) {
+ throw new BSFException(BSFException.REASON_OTHER_ERROR, "JSR223Bridge Error, call not supported by engine: "
+ + engine.getContext().getAttribute(ScriptEngine.ENGINE));
+ }
+ try {
+
+ return ((Invocable) engine).call(name, object, args);
+
+ } catch (Exception e) {
+ throw new BSFException(BSFException.REASON_OTHER_ERROR, "JSR223Bridge Error: " + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /*
+ * @see org.apache.bsf.BSFEngine.call(Object, String, Object[])
+ */
+ public Object eval(String source, int lineNo, int columnNo, Object expr) throws BSFException {
+ try {
+
+ return engine.eval(expr.toString());
+
+ } catch (ScriptException e) {
+ throw new BSFException(BSFException.REASON_OTHER_ERROR, "JSR223Bridge Error: " + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /*
+ * @see org.apache.bsf.BSFEngine.declareBean(BSFDeclaredBean)
+ */
+ public void declareBean(BSFDeclaredBean bean) throws BSFException {
+ engine.getContext().setAttribute(bean.name, bean.bean, ScriptContext.ENGINE_SCOPE);
+ }
+
+ /*
+ * @see org.apache.bsf.BSFEngine.undeclareBean(BSFDeclaredBean)
+ */
+ public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
+ engine.getContext().removeAttribute(bean.name, ScriptContext.ENGINE_SCOPE);
+ }
+
+ /*
+ * @see org.apache.bsf.BSFEngine.initialize(BSFManager, String, Vector)
+ */
+ public void initialize(BSFManager mgr, String lang, Vector declaredBeans) throws BSFException {
+
+ super.initialize(mgr, lang, declaredBeans);
+
+ this.engine = new ScriptEngineManager().getEngineByName(lang);
+
+ for (Iterator it = declaredBeans.iterator(); it.hasNext();) {
+ declareBean((BSFDeclaredBean) it.next());
+ }
+
+ }
+
+ /**
+ * Register all the available JSR-223 engines with BSF.
+ *
+ * Any BSF engines for the same language will be replaced with the JSR-223 engine.
+ */
+ public static void registerAllJSR223Engines() {
+ ScriptEngineFactory[] engineFactories = new ScriptEngineManager().getEngineFactories();
+ for (int i = 0; i < engineFactories.length; i++) {
+ String[] names = engineFactories[i].getNames();
+ String[] extensions = engineFactories[i].getExtensions();
+ for (int j = 0; j < names.length; j ++) {
+ BSFManager.registerScriptingEngine(names[j], JSR223BSFEngine.class.getName(), extensions);
+ }
+ }
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/main/resources/META-INF/sca/default.scdl b/sandbox/ant/container.script/src/main/resources/META-INF/sca/default.scdl
new file mode 100644
index 0000000000..1f059bdb08
--- /dev/null
+++ b/sandbox/ant/container.script/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.script.ScriptImplementation">
+
+ <component name="script.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.container.script.ScriptImplementationLoader"/>
+ </component>
+
+ <component name="script.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.container.script.helper.ScriptHelperComponentTypeLoader"/>
+ </component>
+
+ <component name="script.componentBuilder">
+ <system:implementation.system class="org.apache.tuscany.container.script.helper.ScriptHelperComponentBuilder"/>
+ </component>
+
+</composite>
diff --git a/sandbox/ant/container.script/src/main/resources/META-INF/sca/script.system.scdl b/sandbox/ant/container.script/src/main/resources/META-INF/sca/script.system.scdl
new file mode 100644
index 0000000000..1f059bdb08
--- /dev/null
+++ b/sandbox/ant/container.script/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="script.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.container.script.ScriptImplementationLoader"/>
+ </component>
+
+ <component name="script.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.container.script.helper.ScriptHelperComponentTypeLoader"/>
+ </component>
+
+ <component name="script.componentBuilder">
+ <system:implementation.system class="org.apache.tuscany.container.script.helper.ScriptHelperComponentBuilder"/>
+ </component>
+
+</composite>
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptImplementationLoaderTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptImplementationLoaderTestCase.java
new file mode 100644
index 0000000000..6db6cf1200
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptImplementationLoaderTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * 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.script;
+
+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.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 ScriptImplementationLoader loader;
+
+ public void testLoadNoScriptAttribute() throws LoaderException, XMLStreamException {
+ expect(reader.getAttributeValue(null, "script")).andReturn(null);
+ replay(reader);
+ replay(deploymentContext);
+
+ try {
+ loader.load(parent, null, 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);
+
+ ScriptImplementationLoader mockLoader = new ScriptImplementationLoader(registry) {
+ protected String loadSource(ClassLoader cl, String resource) throws LoaderException {
+ assertSame(classLoader, cl);
+ assertEquals("foo.mock", resource);
+ return "bar";
+ }
+ };
+ mockLoader.load(parent, null, 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);
+
+ ScriptImplementationLoader mockLoader = new ScriptImplementationLoader(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, null, 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.script", loader.getXMLType().getLocalPart());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ loader = new ScriptImplementationLoader(registry);
+
+ parent = createMock(CompositeComponent.class);
+ reader = createMock(XMLStreamReader.class);
+ deploymentContext = createMock(DeploymentContext.class);
+ classLoader = createMock(ClassLoader.class);
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceFactoryTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceFactoryTestCase.java
new file mode 100644
index 0000000000..2e72de6074
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceFactoryTestCase.java
@@ -0,0 +1,69 @@
+package org.apache.tuscany.container.script;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.bsf.BSFManager;
+import org.apache.tuscany.container.script.mock.MockBSFEngine;
+import org.apache.tuscany.spi.ObjectCreationException;
+
+public class ScriptInstanceFactoryTestCase extends TestCase {
+
+ public void testCreateInstance() throws InvocationTargetException {
+ BSFManager.registerScriptingEngine("mock", MockBSFEngine.class.getName(), new String[] {"mock"});
+ ScriptInstanceFactory factory = new ScriptInstanceFactory("foo.mock", "bar", "baz", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ assertNotNull(instance.bsfEngine);
+// assertNotNull(instance.clazz);
+ }
+
+ public void testCreateInstanceNoClass() throws InvocationTargetException {
+ BSFManager.registerScriptingEngine("mock", MockBSFEngine.class.getName(), new String[] {"mock"});
+ ScriptInstanceFactory factory = new ScriptInstanceFactory("foo.mock", null, "baz", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ assertNotNull(instance.bsfEngine);
+ }
+
+ public void testCreateInstanceRuby() throws InvocationTargetException {
+ BSFManager.registerScriptingEngine("ruby", MockBSFEngine.class.getName(), new String[] {"mock"});
+ ScriptInstanceFactory factory = new ScriptInstanceFactory("foo.mock", "bar", "baz", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ assertNotNull(instance.bsfEngine);
+// assertNotNull(instance.clazz);
+ }
+
+ public void testBadCreateInstance() throws InvocationTargetException {
+ ScriptInstanceFactory factory = new ScriptInstanceFactory("foo", "bar", "baz", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ try {
+ factory.createInstance(null, context);
+ fail();
+ } catch (ObjectCreationException e) {
+ // expected
+ }
+ }
+
+ public void testGetters() throws InvocationTargetException {
+ ScriptInstanceFactory factory = new ScriptInstanceFactory("foo", "bar", "baz", getClass().getClassLoader());
+// assertEquals("foo", factory.getScriptName());
+// assertEquals("bar", factory.getClassName());
+// assertEquals("baz", factory.getScriptSource());
+ assertEquals(getClass().getClassLoader(), factory.getClassLoader());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceTestCase.java
new file mode 100644
index 0000000000..9784721b83
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/ScriptInstanceTestCase.java
@@ -0,0 +1,30 @@
+package org.apache.tuscany.container.script;
+
+import java.lang.reflect.InvocationTargetException;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.mock.MockBSFEngine;
+
+public class ScriptInstanceTestCase extends TestCase {
+
+ private ScriptInstance instance;
+
+ public void testInvokeTarget() throws InvocationTargetException {
+ assertEquals("hello:", instance.invokeTarget("hello", null));
+ }
+
+ public void testInvokeTargetException() throws InvocationTargetException {
+ try {
+ instance.invokeTarget("bang", null);
+ fail();
+ } catch (InvocationTargetException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.instance = new ScriptInstance(new MockBSFEngine(), null);
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/AsyncInvokerTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/AsyncInvokerTestCase.java
new file mode 100644
index 0000000000..9c99cf306f
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/AsyncInvokerTestCase.java
@@ -0,0 +1,211 @@
+/*
+ * 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.script.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.AsyncInvoker;
+import org.apache.tuscany.container.script.helper.AsyncMonitor;
+import org.apache.tuscany.container.script.helper.ScriptHelperComponent;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+import org.apache.tuscany.container.script.helper.AsyncInvoker.ContextBinder;
+import org.apache.tuscany.container.script.helper.AsyncInvoker.ImmutableMessage;
+import org.apache.tuscany.container.script.helper.mock.AsyncTarget;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMock;
+
+/**
+ */
+public class AsyncInvokerTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testInvoke() throws Exception {
+ ScriptHelperInstance instance = createMock(ScriptHelperInstance.class);
+ expect(instance.invokeTarget("invoke", null)).andReturn(null).once();
+ replay(instance);
+ ScriptHelperComponent component = EasyMock.createMock(ScriptHelperComponent.class);
+ expect(component.getTargetInstance()).andReturn(instance);
+ EasyMock.replay(component);
+ AsyncMonitor monitor = createMock(AsyncMonitor.class);
+ replay(monitor);
+
+ WorkScheduler scheduler = createMock(WorkScheduler.class);
+ scheduler.scheduleWork(isA(Runnable.class));
+ expectLastCall().andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ Runnable runnable = (Runnable) getCurrentArguments()[0];
+ runnable.run();
+ return null;
+ }
+ });
+ replay(scheduler);
+ WorkContext context = createMock(WorkContext.class);
+ Method method = AsyncTarget.class.getMethod("invoke");
+ method.setAccessible(true);
+ InboundWire wire = createMock(InboundWire.class);
+ AsyncInvoker invoker = new AsyncInvoker("invoke", wire, component, scheduler, monitor, context);
+ Message msg = new MessageImpl();
+ invoker.invoke(msg);
+ verify(instance);
+ }
+
+ public void testClone() {
+ AsyncInvoker invoker = new AsyncInvoker(null, null, null,null,null,null);
+ assertNotNull(invoker.clone());
+ }
+
+ public void testGetInstance() {
+ ScriptHelperComponent component = EasyMock.createMock(ScriptHelperComponent.class);
+ expect(component.getTargetInstance()).andReturn("petra");
+ EasyMock.replay(component);
+ AsyncInvoker invoker = new AsyncInvoker(null, null, component,null,null,null);
+ assertEquals("petra", invoker.getInstance());
+ }
+
+ public void testGetInstanceCacheable() {
+ ScriptHelperComponent component = EasyMock.createMock(ScriptHelperComponent.class);
+ expect(component.getTargetInstance()).andReturn("petra");
+ EasyMock.replay(component);
+ AsyncInvoker invoker = new AsyncInvoker(null, null, component,null,null,null);
+ invoker.setCacheable(true);
+ assertEquals("petra", invoker.getInstance());
+ }
+
+ public void testGetBody() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertNull(message.getBody());
+ }
+
+ public void testSetBody() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setBody(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testGetTargetInvoker() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertNull(message.getTargetInvoker());
+ }
+
+ public void testSetTargetInvoker() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setTargetInvoker(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testGetFromAddress() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertNull(message.getFromAddress());
+ }
+
+ public void testSetFromAddress() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setFromAddress(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testGetMessageId() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertNull(message.getMessageId());
+ }
+
+ public void testSetMessageId() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setMessageId(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testGetCorrelationId() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertNull(message.getCorrelationId());
+ }
+
+ public void testSetCorrelationId() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setCorrelationId(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testIsFault() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ assertFalse(message.isFault());
+ }
+
+ public void testSetBodyWithFault() {
+ ImmutableMessage message = new AsyncInvoker.ImmutableMessage();
+ try {
+ message.setBodyWithFault(null);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testContextBinder() {
+ ContextBinder contextBinder = new AsyncInvoker.ContextBinder();
+ contextBinder.setContext(null);
+ try {
+ contextBinder.start();
+ fail();
+ } catch (AssertionError e) {
+ // expected
+ }
+ try {
+ contextBinder.stop();
+ fail();
+ } catch (AssertionError e) {
+ // expected
+ }
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilderTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilderTestCase.java
new file mode 100644
index 0000000000..5b93df3d76
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentBuilderTestCase.java
@@ -0,0 +1,107 @@
+package org.apache.tuscany.container.script.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperComponentBuilder;
+import org.apache.tuscany.container.script.helper.ScriptHelperComponentType;
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementation;
+import org.apache.tuscany.core.component.scope.ModuleScopeObjectFactory;
+import org.apache.tuscany.core.component.scope.ScopeRegistryImpl;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.easymock.IAnswer;
+
+public class ScriptHelperComponentBuilderTestCase extends TestCase {
+
+ public void testGetImplementationType() {
+ ScriptHelperComponentBuilder builder = new ScriptHelperComponentBuilder();
+ assertEquals(ScriptHelperImplementation.class, builder.getImplementationType());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testBuild() {
+ ScriptHelperComponentBuilder builder = new ScriptHelperComponentBuilder();
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ scopeRegistry.registerFactory(Scope.COMPOSITE, new ModuleScopeObjectFactory(scopeRegistry));
+ builder.setScopeRegistry(scopeRegistry);
+ DeploymentContext deploymentContext = createMock(DeploymentContext.class);
+ final ScopeContainer scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.COMPOSITE;
+ }
+ });
+ expect(deploymentContext.getModuleScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return scopeContainer;
+ }
+ });
+ replay(deploymentContext);
+ ComponentDefinition<ScriptHelperImplementation> impl = new ComponentDefinition<ScriptHelperImplementation>(new ScriptHelperImplementation());
+ ScriptHelperComponentType componentType = new ScriptHelperComponentType();
+ componentType.setLifecycleScope(Scope.COMPOSITE);
+ ServiceDefinition service = new ServiceDefinition();
+ ServiceContract serviceContract = new JavaServiceContract();
+ service.setServiceContract(serviceContract);
+ componentType.add(service);
+ impl.getImplementation().setComponentType(componentType);
+
+ PropertyValue pv = new PropertyValue("foo", "", "");
+ ObjectFactory pvFactory = createMock(ObjectFactory.class);
+ expect(pvFactory.getInstance()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return null;
+ }
+ });
+ replay(pvFactory);
+ pv.setValueFactory(pvFactory);
+ impl.add(pv);
+
+ Component component = builder.build(null, impl, deploymentContext);
+ assertNotNull(component);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testBuildModuleScope() {
+ ScriptHelperComponentBuilder builder = new ScriptHelperComponentBuilder();
+ DeploymentContext deploymentContext = createMock(DeploymentContext.class);
+ final ScopeContainer scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+ expect(deploymentContext.getModuleScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return scopeContainer;
+ }
+ });
+ replay(deploymentContext);
+ ComponentDefinition<ScriptHelperImplementation> impl = new ComponentDefinition<ScriptHelperImplementation>(new ScriptHelperImplementation());
+ ScriptHelperComponentType componentType = new ScriptHelperComponentType();
+ ServiceDefinition service = new ServiceDefinition();
+ ServiceContract serviceContract = new JavaServiceContract();
+ service.setServiceContract(serviceContract);
+ componentType.add(service);
+ impl.getImplementation().setComponentType(componentType);
+ Component component = builder.build(null, impl, deploymentContext);
+ assertNotNull(component);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTestCase.java
new file mode 100644
index 0000000000..a1e300051d
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTestCase.java
@@ -0,0 +1,145 @@
+package org.apache.tuscany.container.script.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperComponent;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstanceFactory;
+import org.apache.tuscany.container.script.helper.mock.MockInstanceFactory;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.RuntimeWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+import org.easymock.IAnswer;
+
+public class ScriptHelperComponentTestCase extends TestCase {
+
+ private ScopeContainer scopeContainer;
+
+ @SuppressWarnings("unchecked")
+ public void testCreateTargetInvoker() {
+ ScriptHelperComponent component = new ScriptHelperComponent(null,null, null, null, null, scopeContainer, null, null, null);
+
+ Operation operation = new Operation("hashCode", null,null,null,false,null);
+ ServiceContract contract = new ServiceContract(List.class){};
+ operation.setServiceContract(contract);
+ TargetInvoker invoker = component.createTargetInvoker("hashCode", operation);
+
+ assertNotNull(invoker);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testCreateInstance() throws IOException {
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,createBSFEasy(), new HashMap(), null, null, scopeContainer, null, null, null);
+ Object o = pc.createInstance();
+ assertNotNull(o);
+ assertTrue(o instanceof ScriptHelperInstance);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testCreateInstanceWithRef() throws IOException {
+ WireService wireService = createMock(WireService.class);
+ expect(wireService.createProxy(isA(RuntimeWire.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,createBSFEasy(), new HashMap(), null, null, scopeContainer, wireService, null, null);
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setReferenceName("foo");
+ pc.addOutboundWire(wire);
+ Object o = pc.createInstance();
+ assertNotNull(o);
+ assertTrue(o instanceof ScriptHelperInstance);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testGetServiceInstance() {
+ WireService wireService = createMock(WireService.class);
+ expect(wireService.createProxy(isA(RuntimeWire.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return "foo";
+ }
+ });
+ replay(wireService);
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,null, null, null, null, scopeContainer, wireService, null, null);
+ InboundWire wire = new InboundWireImpl();
+ pc.addInboundWire(wire);
+ assertEquals("foo", pc.getServiceInstance());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testGetServiceInstanceFail() {
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,null, null, null, null, scopeContainer, null, null, null);
+ try {
+ pc.getServiceInstance();
+ fail();
+ } catch (TargetException e) {
+ // expected
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testGetproperties() {
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,null, new HashMap(), null, null, scopeContainer, null, null, null);
+ assertNotNull(pc.getProperties());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testGetServiceInterfaces() {
+ List services = new ArrayList();
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,null,null, services, null, scopeContainer, null, null, null);
+ assertEquals(services, pc.getServiceInterfaces());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testCreateAsyncTargetInvoker() {
+ ScriptHelperComponent pc = new ScriptHelperComponent(null,null,null, new ArrayList<Class<?>>(), null, scopeContainer, null, null, null);
+ assertNotNull(pc.createAsyncTargetInvoker(null, new Operation("foo", null,null,null)));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+ }
+
+ public ScriptHelperInstanceFactory createBSFEasy() throws IOException {
+// URL scriptURL = getClass().getResource("foo.mock");
+// InputStream is = scriptURL.openStream();
+// StringBuilder sb = new StringBuilder();
+// int i = 0;
+// while ((i = is.read()) != -1) {
+// sb.append((char) i);
+// }
+// is.close();
+// String script = sb.toString();
+ MockInstanceFactory bsfEasy = new MockInstanceFactory("foo.mock", null);
+ return bsfEasy;
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoaderTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoaderTestCase.java
new file mode 100644
index 0000000000..4686d1b9f1
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeLoaderTestCase.java
@@ -0,0 +1,144 @@
+/*
+ * 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.script.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.stream.XMLStreamException;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperComponentTypeLoader;
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementation;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstanceFactory;
+import org.apache.tuscany.container.script.helper.mock.MockInstanceFactory;
+import org.apache.tuscany.core.loader.LoaderRegistryImpl;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+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.model.ComponentType;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Scope;
+import org.easymock.IAnswer;
+
+/**
+ *
+ */
+public class ScriptHelperComponentTypeLoaderTestCase extends TestCase {
+
+ public void testGetSideFileName() {
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ assertEquals("BSFEasyTestCase.componentType", loader.getSideFileName("BSFEasyTestCase.mock"));
+ }
+
+ public void testGetSideFileNameNoDot() {
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ assertEquals("BSFEasyTestCase.componentType", loader.getSideFileName("BSFEasyTestCase"));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testLoadFromSideFile() throws MalformedURLException, LoaderException, XMLStreamException {
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ LoaderRegistry loaderRegistry = new LoaderRegistryImpl() {
+ public <MO extends ModelObject> MO load(CompositeComponent parent, ModelObject mo, URL url, Class<MO> type, DeploymentContext ctx) throws LoaderException {
+ return (MO) new ComponentType();
+ }
+ };
+ loader.setLoaderRegistry(loaderRegistry);
+ loader.loadFromSidefile(null, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testLoad() throws LoaderException {
+ ScriptHelperInstanceFactory bsfEasy = new MockInstanceFactory("org/apache/tuscany/container/script/helper/foo.mock", getClass().getClassLoader());
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ LoaderRegistry loaderRegistry = new LoaderRegistryImpl() {
+ public <MO extends ModelObject> MO load(CompositeComponent parent,
+ ModelObject mo,
+ URL url,
+ Class<MO> type,
+ DeploymentContext ctx) throws LoaderException {
+ return (MO) new ComponentType();
+ }
+ };
+ loader.setLoaderRegistry(loaderRegistry);
+ ScriptHelperImplementation implementation = new ScriptHelperImplementation();
+ implementation.setResourceName("org/apache/tuscany/container/script/helper/foo.mock");
+ implementation.setScriptInstanceFactory(bsfEasy);
+ DeploymentContext deploymentContext = createMock(DeploymentContext.class);
+ final ScopeContainer scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+ expect(deploymentContext.getModuleScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return scopeContainer;
+ }
+ });
+ replay(deploymentContext);
+ loader.load(null, implementation, deploymentContext);
+ assertNotNull(implementation.getComponentType());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testLoadMissingSideFile() throws LoaderException {
+ ScriptHelperInstanceFactory bsfEasy = new MockInstanceFactory("org/apche/tuscany/container/script/helper/foo.mock", getClass().getClassLoader());
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ ScriptHelperImplementation implementation = new ScriptHelperImplementation();
+ implementation.setResourceName("org/apache/tuscany/container/script/helper/doesntExist");
+ implementation.setScriptInstanceFactory(bsfEasy);
+ DeploymentContext deploymentContext = createMock(DeploymentContext.class);
+ final ScopeContainer scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+ expect(deploymentContext.getModuleScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return scopeContainer;
+ }
+ });
+ replay(deploymentContext);
+ try {
+ loader.load(null, implementation, deploymentContext);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testGetImplementationClass() {
+ ScriptHelperComponentTypeLoader loader = new ScriptHelperComponentTypeLoader();
+ assertEquals(ScriptHelperImplementation.class, loader.getImplementationClass());
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeTestCase.java
new file mode 100644
index 0000000000..dd29f85e44
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperComponentTypeTestCase.java
@@ -0,0 +1,37 @@
+package org.apache.tuscany.container.script.helper;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperComponentType;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.ReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+public class ScriptHelperComponentTypeTestCase extends TestCase {
+
+ public void testLifecycleScope() {
+ ScriptHelperComponentType ct = new ScriptHelperComponentType();
+ assertEquals(Scope.MODULE, ct.getLifecycleScope());
+ ct.setLifecycleScope(Scope.COMPOSITE);
+ assertEquals(Scope.COMPOSITE, ct.getLifecycleScope());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testComponentTypeConstructor() {
+ ComponentType ct = new ComponentType();
+ Property property = new Property();
+ ct.add(property);
+ ReferenceDefinition reference = new ReferenceDefinition();
+ ct.add(reference);
+ ServiceDefinition service = new ServiceDefinition();
+ ct.add(service);
+
+ ScriptHelperComponentType pct = new ScriptHelperComponentType(ct);
+
+ assertEquals(property, pct.getProperties().values().iterator().next());
+ assertEquals(reference, pct.getReferences().values().iterator().next());
+ assertEquals(service, pct.getServices().values().iterator().next());
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoaderTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoaderTestCase.java
new file mode 100644
index 0000000000..be3d4de909
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationLoaderTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * 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.script.helper;
+
+import static org.easymock.classextension.EasyMock.createMock;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementation;
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementationLoader;
+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;
+import org.apache.tuscany.spi.model.ModelObject;
+
+/**
+ *
+ */
+public class ScriptHelperImplementationLoaderTestCase extends TestCase {
+
+ private LoaderRegistry registry;
+
+ private ScriptHelperImplementationLoader loader;
+
+ public void testLoadSource() throws LoaderException {
+ String script = loader.loadSource(getClass().getClassLoader(), "org/apache/tuscany/container/script/helper/foo.mock");
+ assertTrue(script.startsWith("hello"));
+ }
+
+ public void testLoadSourceMissingResource() throws LoaderException {
+ try {
+ loader.loadSource(getClass().getClassLoader(), "doesnt.exist");
+ fail();
+ } catch (MissingResourceException e) {
+ // expected
+ }
+ }
+
+ public void testGetXMLType() throws LoaderException {
+ assertEquals("http://foo", loader.getXMLType().getNamespaceURI());
+ assertEquals("bar", loader.getXMLType().getLocalPart());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ loader = new ScriptHelperImplementationLoader(registry){
+ public QName getXMLType() {
+ return new QName("http://foo", "bar");
+ }
+// @Override
+ public ScriptHelperImplementation load(CompositeComponent arg0, ModelObject arg1, XMLStreamReader arg2, DeploymentContext arg3) throws XMLStreamException, LoaderException {
+ return null;
+ }};
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationTestCase.java
new file mode 100644
index 0000000000..f906c701f3
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperImplementationTestCase.java
@@ -0,0 +1,30 @@
+package org.apache.tuscany.container.script.helper;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperImplementation;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstanceFactory;
+import org.apache.tuscany.container.script.helper.mock.MockInstanceFactory;
+
+public class ScriptHelperImplementationTestCase extends TestCase {
+
+ private ScriptHelperInstanceFactory bsfEasy;
+
+ public void testGetBSFEasy() {
+ ScriptHelperImplementation impl = new ScriptHelperImplementation();
+ impl.setScriptInstanceFactory(bsfEasy);
+ assertEquals(bsfEasy, impl.getScriptInstanceFactory());
+ }
+
+ public void testGetResourceName() {
+ ScriptHelperImplementation impl = new ScriptHelperImplementation();
+ impl.setResourceName("foo");
+ assertEquals("foo", impl.getResourceName());
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ bsfEasy = new MockInstanceFactory("BSFEasyTestCase", null);
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactoryTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactoryTestCase.java
new file mode 100644
index 0000000000..132ea2bdfc
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInstanceFactoryTestCase.java
@@ -0,0 +1,56 @@
+package org.apache.tuscany.container.script.helper;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+import org.apache.tuscany.container.script.helper.mock.MockInstanceFactory;
+
+public class ScriptHelperInstanceFactoryTestCase extends TestCase {
+
+ public void testCreateInstance() throws InvocationTargetException {
+ MockInstanceFactory factory = new MockInstanceFactory("foo.mock", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptHelperInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ }
+
+ public void testCreateInstanceNoClass() throws InvocationTargetException {
+ MockInstanceFactory factory = new MockInstanceFactory("foo.mock", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptHelperInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ }
+
+ public void testCreateInstanceRuby() throws InvocationTargetException {
+ MockInstanceFactory factory = new MockInstanceFactory("foo.mock", getClass().getClassLoader());
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("foo", "bar");
+ ScriptHelperInstance instance = factory.createInstance(null, context);
+ assertNotNull(instance);
+ }
+
+ public void testGetters() throws InvocationTargetException {
+ MockInstanceFactory factory = new MockInstanceFactory("foo", getClass().getClassLoader());
+ assertEquals("foo", factory.getResourceName());
+ assertEquals(getClass().getClassLoader(), factory.getClassLoader());
+ }
+
+ public void testGetResponseClasses() {
+ MockInstanceFactory factory = new MockInstanceFactory("foo", getClass().getClassLoader());
+ Map<String, Class> classes = factory.getResponseClasses(Arrays.asList( new Class[]{ Runnable.class}));
+ assertEquals(1, classes.size());
+ assertEquals("run", classes.keySet().iterator().next());
+ assertEquals(void.class, classes.get("run"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInvokerTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInvokerTestCase.java
new file mode 100644
index 0000000000..6a40eae163
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/ScriptHelperInvokerTestCase.java
@@ -0,0 +1,64 @@
+package org.apache.tuscany.container.script.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+
+import java.lang.reflect.InvocationTargetException;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperComponent;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+import org.apache.tuscany.container.script.helper.ScriptHelperInvoker;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.model.Scope;
+import org.easymock.IAnswer;
+
+public class ScriptHelperInvokerTestCase extends TestCase {
+
+ private ScriptHelperComponent component;
+
+ public void testInvokeTarget() throws InvocationTargetException {
+ ScriptHelperInvoker invoker = new ScriptHelperInvoker("hello", component);
+ assertEquals("hello petra", invoker.invokeTarget(null));
+ }
+
+ public void testInvokeTargetException() throws InvocationTargetException, SecurityException, NoSuchMethodException {
+ ScriptHelperInvoker badInvoker = new ScriptHelperInvoker("bang", component);
+ try {
+ badInvoker.invokeTarget(null);
+ fail();
+ } catch (InvocationTargetException e) {
+ // expected
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ ScopeContainer scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return Scope.MODULE;
+ }
+ });
+ expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return new ScriptHelperInstance(){
+ public Object invokeTarget(String operationName, Object[] args) throws InvocationTargetException {
+ if ("bang".equals(operationName)) {
+ throw new RuntimeException("bang");
+ }
+ return "hello petra";
+ }};
+ }
+ });
+ replay(scopeContainer);
+
+ this.component = new ScriptHelperComponent(null, null, null, null, null, scopeContainer, null, null, null);
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/AsyncTarget.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/AsyncTarget.java
new file mode 100644
index 0000000000..8961f882f1
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/AsyncTarget.java
@@ -0,0 +1,26 @@
+/*
+ * 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.script.helper.mock;
+
+/**
+ */
+public interface AsyncTarget {
+
+ void invoke();
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/MockInstanceFactory.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/MockInstanceFactory.java
new file mode 100644
index 0000000000..6f90913938
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/helper/mock/MockInstanceFactory.java
@@ -0,0 +1,30 @@
+package org.apache.tuscany.container.script.helper.mock;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.container.script.helper.ScriptHelperInstance;
+import org.apache.tuscany.container.script.helper.ScriptHelperInstanceFactory;
+
+public class MockInstanceFactory extends ScriptHelperInstanceFactory<MockInstance> {
+
+ public MockInstanceFactory(String scriptName, ClassLoader classLoader) {
+ super(scriptName, classLoader);
+ }
+
+ @Override
+ public MockInstance createInstance(List<Class> services, Map<String, Object> context) {
+ return new MockInstance();
+ }
+
+}
+
+class MockInstance implements ScriptHelperInstance {
+
+ public Object invokeTarget(String operationName, Object[] args) throws InvocationTargetException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngineTestCase.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngineTestCase.java
new file mode 100644
index 0000000000..a9cc459627
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/jsr223/JSR223BSFEngineTestCase.java
@@ -0,0 +1,45 @@
+package org.apache.tuscany.container.script.jsr223;
+
+import junit.framework.TestCase;
+
+import org.apache.bsf.BSFEngine;
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+import org.mozilla.javascript.EcmaError;
+
+public class JSR223BSFEngineTestCase extends TestCase {
+
+ public void testRegisterAllJSR223Engines() throws BSFException {
+ JSR223BSFEngine.registerAllJSR223Engines();
+ BSFEngine engine = new BSFManager().loadScriptingEngine("rhino");
+ assertTrue(engine instanceof JSR223BSFEngine);
+ }
+
+ public void testDeclareBean() throws BSFException {
+ JSR223BSFEngine.registerAllJSR223Engines();
+ BSFManager manager = new BSFManager();
+ manager.declareBean("foo", "foo", String.class);
+ BSFEngine engine = manager.loadScriptingEngine("rhino");
+ assertEquals("foo", engine.eval("testDeclareBean", 0, 0, "foo"));
+ manager.undeclareBean("foo");
+ try {
+ engine.eval("testDeclareBean", 0, 0, "foo");
+ fail();
+ } catch (EcmaError e) {
+ //expected
+ }
+ }
+
+ public void testEval() throws BSFException {
+ JSR223BSFEngine.registerAllJSR223Engines();
+ BSFEngine engine = new BSFManager().loadScriptingEngine("rhino");
+ assertEquals(true, engine.eval("testDeclareBean", 0, 0, "true"));
+ }
+
+ public void testCall() throws BSFException {
+ JSR223BSFEngine.registerAllJSR223Engines();
+ BSFEngine engine = new BSFManager().loadScriptingEngine("rhino");
+ engine.eval("testDeclareBean", 0, 0, "function foo() { return true;}");
+ assertEquals(true, engine.call(null, "foo", new Object[]{}));
+ }
+}
diff --git a/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/mock/MockBSFEngine.java b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/mock/MockBSFEngine.java
new file mode 100644
index 0000000000..7c2434ea13
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/java/org/apache/tuscany/container/script/mock/MockBSFEngine.java
@@ -0,0 +1,27 @@
+package org.apache.tuscany.container.script.mock;
+
+import org.apache.bsf.BSFException;
+import org.apache.bsf.util.BSFEngineImpl;
+
+public class MockBSFEngine extends BSFEngineImpl {
+
+ public Object call(Object object, String name, Object[] args) throws BSFException {
+ if ("bang".equals(name)) {
+ throw new RuntimeException(name);
+ }
+
+ String resp = name + ":";
+ if (args != null) {
+ for (Object o : args) {
+ resp += " " + String.valueOf(o);
+ }
+ }
+ return resp;
+ }
+
+ public Object eval(String source, int lineNo, int columnNo, Object expr) throws BSFException {
+ // not used for the mock tests
+ return null;
+ }
+
+}
diff --git a/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.componentType b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.componentType
new file mode 100644
index 0000000000..9c37e1cb3e
--- /dev/null
+++ b/sandbox/ant/container.script/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.script/src/test/resources/org/apache/tuscany/container/script/foo.mock b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.mock
new file mode 100644
index 0000000000..b6fc4c620b
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/foo.mock
@@ -0,0 +1 @@
+hello \ No newline at end of file
diff --git a/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.componentType b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.componentType
new file mode 100644
index 0000000000..9c37e1cb3e
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/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.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.mock b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.mock
new file mode 100644
index 0000000000..b6fc4c620b
--- /dev/null
+++ b/sandbox/ant/container.script/src/test/resources/org/apache/tuscany/container/script/helper/foo.mock
@@ -0,0 +1 @@
+hello \ No newline at end of file