summaryrefslogtreecommitdiffstats
path: root/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/ant/tuscany-container-rhino/src/main/java/org/apache')
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/assembly/JavaScriptImplementation.java74
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptContextFactoryBuilder.java62
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptTargetWireBuilder.java40
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/config/JavaScriptContextFactory.java111
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/CopyOfJavaScriptComponentContext.java165
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/JavaScriptComponentContext.java144
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XInterceptor.java65
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XPolicyBuilder.java117
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/loader/JavaScriptImplementationLoader.java169
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoFunctionInvoker.java79
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScript.java194
-rw-r--r--sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScriptInstance.java82
12 files changed, 1302 insertions, 0 deletions
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/assembly/JavaScriptImplementation.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/assembly/JavaScriptImplementation.java
new file mode 100644
index 0000000000..5b570d5d41
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/assembly/JavaScriptImplementation.java
@@ -0,0 +1,74 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.assembly;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.model.assembly.impl.AtomicImplementationImpl;
+
+import commonj.sdo.helper.TypeHelper;
+
+/**
+ * Default implementation of a JavScript component implementation type
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaScriptImplementation extends AtomicImplementationImpl {
+
+ private String scriptFile;
+
+ private String script;
+
+ private ResourceLoader resourceLoader;
+
+ private TypeHelper typeHelper;
+
+ public JavaScriptImplementation() {
+ super();
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ public ResourceLoader getResourceLoader() {
+ return resourceLoader;
+ }
+
+ public TypeHelper getTypeHelper() {
+ return typeHelper;
+ }
+
+ public void setTypeHelper(TypeHelper typeHelper) {
+ this.typeHelper = typeHelper;
+ }
+
+ public String getScriptFile() {
+ return scriptFile;
+ }
+
+ public void setScriptFile(String fn) {
+ scriptFile = fn;
+ }
+
+ public String getScript() {
+ return script;
+ }
+
+ public void setScript(String script) {
+ this.script = script;
+ }
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptContextFactoryBuilder.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptContextFactoryBuilder.java
new file mode 100644
index 0000000000..4f58758a7e
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptContextFactoryBuilder.java
@@ -0,0 +1,62 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.builder;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.container.rhino.assembly.JavaScriptImplementation;
+import org.apache.tuscany.container.rhino.config.JavaScriptContextFactory;
+import org.apache.tuscany.container.rhino.rhino.RhinoScript;
+import org.apache.tuscany.core.builder.ContextFactory;
+import org.apache.tuscany.core.extension.ContextFactoryBuilderSupport;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.Service;
+
+/**
+ * Builds {@link org.apache.tuscany.container.rhino.config.JavaScriptContextFactory}s from a JavaScript component type
+ *
+ * @version $Rev$ $Date$
+ */
+@org.osoa.sca.annotations.Scope("MODULE")
+public class JavaScriptContextFactoryBuilder extends ContextFactoryBuilderSupport<JavaScriptImplementation> {
+
+ @Override
+ protected ContextFactory createContextFactory(String componentName, JavaScriptImplementation jsImplementation, Scope scope) {
+
+ String script = jsImplementation.getScript();
+
+ Map<String, Object> defaultProperties = new HashMap<String, Object>();
+ for (org.apache.tuscany.model.assembly.Property property : jsImplementation.getComponentType().getProperties()) {
+ defaultProperties.put(property.getName(), property.getDefaultValue());
+ }
+
+ ClassLoader cl = jsImplementation.getResourceLoader().getClassLoader();
+
+ RhinoScript rhinoScript = new RhinoScript(componentName, script, defaultProperties, cl);
+
+ for (Service service : jsImplementation.getComponentType().getServices()) {
+ for (Method serviceMethod : service.getServiceContract().getInterface().getMethods()) {
+ rhinoScript.setResponseClass(serviceMethod.getName(), serviceMethod.getReturnType());
+ }
+ }
+
+ return new JavaScriptContextFactory(componentName, scope, rhinoScript);
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptTargetWireBuilder.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptTargetWireBuilder.java
new file mode 100644
index 0000000000..0c45aee35e
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/builder/JavaScriptTargetWireBuilder.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.builder;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.container.rhino.config.JavaScriptContextFactory;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.extension.ComponentTargetInvoker;
+import org.apache.tuscany.core.extension.WireBuilderSupport;
+import org.apache.tuscany.core.wire.TargetInvoker;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Responsible for bridging source- and target-side invocations chains when the target type is a JavaScript implementation
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("MODULE")
+public class JavaScriptTargetWireBuilder extends WireBuilderSupport<JavaScriptContextFactory> {
+
+ protected TargetInvoker createInvoker(QualifiedName targetName, Method operation, ScopeContext context, boolean downScope) {
+ return new ComponentTargetInvoker(targetName, operation, context);
+ }
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/config/JavaScriptContextFactory.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/config/JavaScriptContextFactory.java
new file mode 100644
index 0000000000..7ea35075fc
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/config/JavaScriptContextFactory.java
@@ -0,0 +1,111 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.config;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.container.rhino.context.JavaScriptComponentContext;
+import org.apache.tuscany.container.rhino.rhino.RhinoScript;
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.ContextFactory;
+import org.apache.tuscany.core.builder.ContextResolver;
+import org.apache.tuscany.core.context.AtomicContext;
+import org.apache.tuscany.core.context.CompositeContext;
+import org.apache.tuscany.core.wire.SourceWireFactory;
+import org.apache.tuscany.core.wire.TargetWireFactory;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Creates instance contexts for JavaScript component types
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaScriptContextFactory implements ContextFactory<AtomicContext>, ContextResolver {
+
+ private Scope scope;
+
+ private String name;
+
+ private Map<String, TargetWireFactory> targetProxyFactories = new HashMap<String, TargetWireFactory>();
+
+ private List<SourceWireFactory> sourceProxyFactories = new ArrayList<SourceWireFactory>();
+
+ private Map<String, Object> properties;
+
+ private RhinoScript rhinoScript;
+
+ private CompositeContext parentContext;
+
+ public JavaScriptContextFactory(String name, Scope scope, RhinoScript rhinoScript) {
+ this.name = name;
+ this.scope = scope;
+ this.rhinoScript = rhinoScript;
+ this.properties = new HashMap<String, Object>();
+ }
+
+ public AtomicContext createContext() throws ContextCreationException {
+ return new JavaScriptComponentContext(name, properties, sourceProxyFactories, targetProxyFactories, rhinoScript);
+ }
+
+ public Scope getScope() {
+ return scope;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addProperty(String propertyName, Object value) {
+ properties.put(propertyName, value);
+ }
+
+ public void addTargetWireFactory(String serviceName, TargetWireFactory factory) {
+ targetProxyFactories.put(serviceName, factory);
+ }
+
+ public TargetWireFactory getTargetWireFactory(String serviceName) {
+ return targetProxyFactories.get(serviceName);
+ }
+
+ public Map<String, TargetWireFactory> getTargetWireFactories() {
+ return targetProxyFactories;
+ }
+
+ public void addSourceWireFactory(String referenceName, SourceWireFactory factory) {
+ sourceProxyFactories.add(factory);
+ }
+
+ public void addSourceWireFactories(String referenceName, Class referenceInterface, List<SourceWireFactory> factories, boolean multiplicity) {
+ sourceProxyFactories.addAll(factories);
+ }
+
+ public List<SourceWireFactory> getSourceWireFactories() {
+ return sourceProxyFactories;
+ }
+
+ public void prepare(CompositeContext parent) {
+ parentContext = parent;
+ }
+
+ public CompositeContext getCurrentContext() {
+ return parentContext;
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/CopyOfJavaScriptComponentContext.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/CopyOfJavaScriptComponentContext.java
new file mode 100644
index 0000000000..c4690e2170
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/CopyOfJavaScriptComponentContext.java
@@ -0,0 +1,165 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.context;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.container.rhino.rhino.RhinoScript;
+import org.apache.tuscany.container.rhino.rhino.RhinoScriptInstance;
+import org.apache.tuscany.core.context.AtomicContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.event.InstanceCreated;
+import org.apache.tuscany.core.context.impl.AbstractContext;
+import org.apache.tuscany.core.extension.ExternalServiceInvoker;
+import org.apache.tuscany.core.wire.ProxyCreationException;
+import org.apache.tuscany.core.wire.SourceWireFactory;
+import org.apache.tuscany.core.wire.TargetWireFactory;
+import org.apache.tuscany.core.wire.WireFactory;
+import org.osoa.sca.ServiceRuntimeException;
+
+public class CopyOfJavaScriptComponentContext extends AbstractContext implements AtomicContext {
+
+ private RhinoScript rhinoScript;
+
+ private Map<String, Object> properties;
+
+ private List<SourceWireFactory> sourceProxyFactories;
+
+ private Map<String, TargetWireFactory> targetProxyFactories;
+
+ public CopyOfJavaScriptComponentContext(String name, Map<String, Object> properties, List<SourceWireFactory> sourceProxyFactories,
+ Map<String, TargetWireFactory> targetProxyFactories, RhinoScript rhinoScript) {
+ super(name);
+ this.properties = properties;
+ this.rhinoScript = rhinoScript;
+ this.sourceProxyFactories = sourceProxyFactories;
+ this.targetProxyFactories = targetProxyFactories;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public void init() throws TargetException {
+ getInstance(null, false);
+ }
+
+ public void destroy() throws TargetException {
+
+ }
+
+ private synchronized Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ String portName = qName.getPortName();
+ WireFactory targetFactory;
+ if (portName != null) {
+ targetFactory = targetProxyFactories.get(portName);
+ } else {
+ // FIXME The port name is null here, either locateService needs more information (the expected interface) to
+ // select the correct port, or we need to return a factory that matches the whole set of services exposed by
+ // the component.
+ targetFactory = targetProxyFactories.values().iterator().next();
+ }
+ if (targetFactory == null) {
+ TargetException e = new TargetException("Target service not found");
+ e.setIdentifier(qName.getPortName());
+ e.addContextName(getName());
+ throw e;
+ }
+ try {
+ Object proxy = targetFactory.createProxy(); // createProxy(new Class[] { iface });
+ if (notify) {
+ publish(new InstanceCreated(this));
+ }
+ return proxy;
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException("Error returning target", e);
+ e.setIdentifier(qName.getPortName());
+ e.addContextName(getName());
+ throw te;
+ }
+ }
+
+ public Object getTargetInstance() throws TargetException {
+ Map<String, Object> contexts = createServiceReferences();
+ contexts.putAll(properties);
+
+ final RhinoScriptInstance rhinoScriptInstance = rhinoScript.createRhinoScriptInstance(contexts);
+
+ ExternalServiceInvoker esi = new ExternalServiceInvoker() {
+ public Object invoke(String methodName, Object[] args) {
+ return rhinoScriptInstance.invokeFunction(methodName, args);
+ }
+ };
+
+ return esi;
+ }
+
+ /**
+ * Creates a map containing any ServiceReferences
+ */
+ private Map<String, Object> createServiceReferences() {
+ try {
+ Map<String, Object> context = new HashMap<String, Object>();
+ for (SourceWireFactory proxyFactory : sourceProxyFactories) {
+ Object referenceProxy = createReferenceProxy(proxyFactory);
+ context.put(proxyFactory.getConfiguration().getReferenceName(), referenceProxy);
+ }
+ return context;
+ } catch (ProxyCreationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ private Object createReferenceProxy(SourceWireFactory proxyFactory) throws ProxyCreationException {
+ Object proxy = proxyFactory.createProxy();
+ Class proxyClass = proxy.getClass();
+ if (Proxy.isProxyClass(proxyClass)) {
+ Class[] ifaces = proxyClass.getInterfaces();
+ Class[] newIfaces = new Class[ifaces.length+1];
+ System.arraycopy(ifaces,0,newIfaces,0,ifaces.length);
+ newIfaces[ifaces.length] = E4XReference.class;
+ InvocationHandler ih = Proxy.getInvocationHandler(proxy);
+ proxy = Proxy.newProxyInstance(proxyClass.getClassLoader(), newIfaces, ih);
+ }
+ return proxy;
+ }
+
+ interface E4XReference {
+ public Object process(Object xml);
+ }
+
+ public boolean isEagerInit() {
+ return false;
+ }
+
+ public boolean isDestroyable() {
+ return false;
+ }
+
+ public void start() throws CoreRuntimeException {
+ }
+
+ public void stop() throws CoreRuntimeException {
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/JavaScriptComponentContext.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/JavaScriptComponentContext.java
new file mode 100644
index 0000000000..74c3bea5eb
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/context/JavaScriptComponentContext.java
@@ -0,0 +1,144 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.context;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.container.rhino.rhino.RhinoScript;
+import org.apache.tuscany.container.rhino.rhino.RhinoScriptInstance;
+import org.apache.tuscany.core.context.AtomicContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.event.InstanceCreated;
+import org.apache.tuscany.core.context.impl.AbstractContext;
+import org.apache.tuscany.core.extension.ExternalServiceInvoker;
+import org.apache.tuscany.core.wire.ProxyCreationException;
+import org.apache.tuscany.core.wire.SourceWireFactory;
+import org.apache.tuscany.core.wire.TargetWireFactory;
+import org.apache.tuscany.core.wire.WireFactory;
+import org.osoa.sca.ServiceRuntimeException;
+
+public class JavaScriptComponentContext extends AbstractContext implements AtomicContext {
+
+ private RhinoScript rhinoScript;
+
+ private Map<String, Object> properties;
+
+ private List<SourceWireFactory> sourceProxyFactories;
+
+ private Map<String, TargetWireFactory> targetProxyFactories;
+
+ public JavaScriptComponentContext(String name, Map<String, Object> properties, List<SourceWireFactory> sourceProxyFactories,
+ Map<String, TargetWireFactory> targetProxyFactories, RhinoScript rhinoScript) {
+ super(name);
+ this.properties = properties;
+ this.rhinoScript = rhinoScript;
+ this.sourceProxyFactories = sourceProxyFactories;
+ this.targetProxyFactories = targetProxyFactories;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public void init() throws TargetException {
+ getInstance(null, false);
+ }
+
+ public void destroy() throws TargetException {
+
+ }
+
+ private synchronized Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ String portName = qName.getPortName();
+ WireFactory targetFactory;
+ if (portName != null) {
+ targetFactory = targetProxyFactories.get(portName);
+ } else {
+ // FIXME The port name is null here, either locateService needs more information (the expected interface) to
+ // select the correct port, or we need to return a factory that matches the whole set of services exposed by
+ // the component.
+ targetFactory = targetProxyFactories.values().iterator().next();
+ }
+ if (targetFactory == null) {
+ TargetException e = new TargetException("Target service not found");
+ e.setIdentifier(qName.getPortName());
+ e.addContextName(getName());
+ throw e;
+ }
+ try {
+ Object proxy = targetFactory.createProxy(); // createProxy(new Class[] { iface });
+ if (notify) {
+ publish(new InstanceCreated(this));
+ }
+ return proxy;
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException("Error returning target", e);
+ e.setIdentifier(qName.getPortName());
+ e.addContextName(getName());
+ throw te;
+ }
+ }
+
+ public Object getTargetInstance() throws TargetException {
+ Map<String, Object> contexts = createServiceReferences();
+ contexts.putAll(properties);
+
+ final RhinoScriptInstance rhinoScriptInstance = rhinoScript.createRhinoScriptInstance(contexts);
+
+ ExternalServiceInvoker esi = new ExternalServiceInvoker() {
+ public Object invoke(String methodName, Object[] args) {
+ return rhinoScriptInstance.invokeFunction(methodName, args);
+ }
+ };
+
+ return esi;
+ }
+
+ /**
+ * Creates a map containing any ServiceReferences
+ */
+ private Map<String, Object> createServiceReferences() {
+ try {
+ Map<String, Object> context = new HashMap<String, Object>();
+ for (SourceWireFactory proxyFactory : sourceProxyFactories) {
+ context.put(proxyFactory.getConfiguration().getReferenceName(), proxyFactory.createProxy());
+ }
+ return context;
+ } catch (ProxyCreationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public boolean isEagerInit() {
+ return false;
+ }
+
+ public boolean isDestroyable() {
+ return false;
+ }
+
+ public void start() throws CoreRuntimeException {
+ }
+
+ public void stop() throws CoreRuntimeException {
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XInterceptor.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XInterceptor.java
new file mode 100644
index 0000000000..1031a2577c
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XInterceptor.java
@@ -0,0 +1,65 @@
+package org.apache.tuscany.container.rhino.e4x;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.core.message.Message;
+import org.apache.tuscany.core.wire.Interceptor;
+import org.apache.tuscany.core.wire.InvocationRuntimeException;
+import org.apache.tuscany.databinding.sdo.SDOXMLHelper;
+import org.apache.xmlbeans.XmlObject;
+
+import commonj.sdo.helper.TypeHelper;
+
+public class E4XInterceptor implements Interceptor {
+
+ private Interceptor next;
+
+ private QName elementQN;
+
+ private TypeHelper typeHelper;
+
+ private ClassLoader classLoader;
+
+ E4XInterceptor(QName elementQN, TypeHelper typeHelper, ClassLoader classLoader) {
+ this.elementQN = elementQN;
+ this.typeHelper = typeHelper;
+ this.classLoader = classLoader;
+ }
+
+ public Message invoke(Message message) {
+ toXmlObject(message);
+ Message responseMessage = next.invoke(message);
+ fromXmlObject(responseMessage);
+ return responseMessage;
+ }
+
+ protected void toXmlObject(Message message) {
+ Object[] body = (Object[]) message.getBody();
+ byte[] xmlBytes = SDOXMLHelper.toXMLBytes(classLoader, typeHelper, body, elementQN, true);
+ try {
+ message.setBody(new Object[] { XmlObject.Factory.parse(new ByteArrayInputStream(xmlBytes)) });
+ } catch (Exception e) {
+ throw new InvocationRuntimeException(e);
+ }
+ }
+
+ protected void fromXmlObject(Message message) {
+ Object body = message.getBody();
+ if (body instanceof XmlObject) {
+ byte[] xmlBytes = ((XmlObject) body).toString().getBytes();
+ Object[] os = SDOXMLHelper.toObjects(classLoader, typeHelper, xmlBytes, true);
+ if (os == null || os.length < 1) {
+ message.setBody(os);
+ } else {
+ message.setBody(os[0]);
+ }
+ }
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XPolicyBuilder.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XPolicyBuilder.java
new file mode 100644
index 0000000000..985a0efcc8
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/e4x/E4XPolicyBuilder.java
@@ -0,0 +1,117 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.e4x;
+
+import java.util.List;
+
+import javax.wsdl.Input;
+import javax.wsdl.Message;
+import javax.wsdl.Operation;
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.container.rhino.assembly.JavaScriptImplementation;
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.SourcePolicyBuilder;
+import org.apache.tuscany.core.builder.TargetPolicyBuilder;
+import org.apache.tuscany.core.builder.system.PolicyBuilderRegistry;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.wire.TargetInvocationConfiguration;
+import org.apache.tuscany.core.wire.WireSourceConfiguration;
+import org.apache.tuscany.core.wire.WireTargetConfiguration;
+import org.apache.tuscany.model.assembly.AtomicComponent;
+import org.apache.tuscany.model.assembly.AtomicImplementation;
+import org.apache.tuscany.model.assembly.ConfiguredReference;
+import org.apache.tuscany.model.assembly.ConfiguredService;
+import org.apache.tuscany.model.assembly.Part;
+import org.apache.tuscany.model.assembly.Service;
+import org.apache.tuscany.model.assembly.ServiceContract;
+import org.apache.tuscany.model.types.wsdl.WSDLServiceContract;
+import org.osoa.sca.annotations.Init;
+
+import commonj.sdo.helper.TypeHelper;
+
+/**
+ */
+@org.osoa.sca.annotations.Scope("MODULE")
+public class E4XPolicyBuilder implements SourcePolicyBuilder, TargetPolicyBuilder {
+
+ private PolicyBuilderRegistry builderRegistry;
+
+ public E4XPolicyBuilder() {
+ }
+
+ @Init(eager = true)
+ public void init() {
+ builderRegistry.registerSourceBuilder(this);
+ builderRegistry.registerTargetBuilder(this);
+ }
+
+ @Autowire
+ public void setBuilderRegistry(PolicyBuilderRegistry builderRegistry) {
+ this.builderRegistry = builderRegistry;
+ }
+
+ public void build(ConfiguredReference service, List<WireSourceConfiguration> wireSourceConfigurations) throws BuilderException {
+ }
+
+ public void build(ConfiguredService service, WireTargetConfiguration wireTargetConfiguration) throws BuilderException {
+ Part part = service.getPart();
+ if (part instanceof AtomicComponent) {
+ AtomicImplementation implementation = ((AtomicComponent) part).getImplementation();
+ if (implementation instanceof JavaScriptImplementation) {
+ JavaScriptImplementation javaScriptImplementation = (JavaScriptImplementation) implementation;
+ for (TargetInvocationConfiguration configuration : wireTargetConfiguration.getInvocationConfigurations().values()) {
+ TypeHelper typeHelper = javaScriptImplementation.getTypeHelper();
+ ClassLoader classLoader = javaScriptImplementation.getResourceLoader().getClassLoader();
+ String methodName = configuration.getMethod().getName();
+ QName responseQN = getElementQName(javaScriptImplementation, methodName);
+ if (responseQN != null) {
+ configuration.addInterceptor(new E4XInterceptor(responseQN, typeHelper, classLoader));
+ }
+ }
+ }
+ }
+ }
+
+ protected QName getElementQName(JavaScriptImplementation javaScriptImplementation, String methodName) {
+ for (Service service : javaScriptImplementation.getComponentType().getServices()) {
+ ServiceContract sc = service.getServiceContract();
+ if (sc instanceof WSDLServiceContract) {
+ PortType pt = ((WSDLServiceContract) sc).getPortType();
+ for (Object o : pt.getOperations()) {
+ Operation operation = (Operation) o;
+ if (methodName.equals(operation.getName())) {
+ Input input = operation.getInput();
+ if (input != null) {
+ Message message = input.getMessage();
+ if (message != null) {
+ List parts = message.getOrderedParts(null);
+ if (parts != null && parts.size() > 0) {
+ javax.wsdl.Part part = (javax.wsdl.Part) parts.get(0);
+ return part.getElementName();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/loader/JavaScriptImplementationLoader.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/loader/JavaScriptImplementationLoader.java
new file mode 100644
index 0000000000..a39537b789
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/loader/JavaScriptImplementationLoader.java
@@ -0,0 +1,169 @@
+/**
+ *
+ * Copyright 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.rhino.loader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.container.rhino.assembly.JavaScriptImplementation;
+import org.apache.tuscany.core.config.ConfigurationLoadException;
+import org.apache.tuscany.core.config.InvalidRootElementException;
+import org.apache.tuscany.core.config.MissingResourceException;
+import org.apache.tuscany.core.config.SidefileLoadException;
+import org.apache.tuscany.core.loader.LoaderContext;
+import org.apache.tuscany.core.loader.StAXElementLoader;
+import org.apache.tuscany.core.loader.StAXLoaderRegistry;
+import org.apache.tuscany.core.loader.assembly.AssemblyConstants;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.model.assembly.ComponentType;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("MODULE")
+public class JavaScriptImplementationLoader implements StAXElementLoader<JavaScriptImplementation> {
+
+ public static final QName IMPLEMENTATION_JS = new QName("http://org.apache.tuscany/xmlns/js/0.9", "implementation.js");
+
+ protected StAXLoaderRegistry registry;
+
+ private XMLInputFactory xmlFactory;
+
+ public JavaScriptImplementationLoader() {
+ // todo make this a reference to a system service
+ xmlFactory = XMLInputFactory.newInstance();
+ }
+
+ @Autowire
+ public void setRegistry(StAXLoaderRegistry registry) {
+ this.registry = registry;
+ }
+
+ @Init(eager = true)
+ public void start() {
+ registry.registerLoader(IMPLEMENTATION_JS, this);
+ }
+
+ @Destroy
+ public void stop() {
+ registry.unregisterLoader(IMPLEMENTATION_JS, this);
+ }
+
+ @SuppressWarnings("deprecation")
+ public JavaScriptImplementation load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException {
+ String scriptFile = reader.getAttributeValue(null, "scriptFile");
+ String script = loadScript(scriptFile, loaderContext.getResourceLoader());
+ ComponentType componentType = loadComponentType(scriptFile, loaderContext);
+
+ JavaScriptImplementation jsImpl = new JavaScriptImplementation();
+ jsImpl.setComponentType(componentType);
+ jsImpl.setScriptFile(scriptFile);
+ jsImpl.setScript(script);
+ jsImpl.setResourceLoader(loaderContext.getResourceLoader());
+ jsImpl.setTypeHelper(registry.getContext().getTypeHelper());
+ return jsImpl;
+ }
+
+ protected String loadScript(String scriptFile, ResourceLoader resourceLoader) throws ConfigurationLoadException {
+ URL url = resourceLoader.getResource(scriptFile);
+ if (url == null) {
+ throw new ConfigurationLoadException(scriptFile);
+ }
+ InputStream inputStream;
+ try {
+ inputStream = url.openStream();
+ } catch (IOException e) {
+ throw new ConfigurationLoadException(scriptFile, e);
+ }
+ try {
+ StringBuilder sb = new StringBuilder(1024);
+ int n;
+ while ((n = inputStream.read()) != -1) {
+ sb.append((char) n);
+ }
+ return sb.toString();
+ } catch (IOException e) {
+ throw new ConfigurationLoadException(scriptFile, e);
+ } finally {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ protected ComponentType loadComponentType(String scriptFile, LoaderContext loaderContext) throws SidefileLoadException, MissingResourceException{
+ String sidefile = scriptFile.substring(0, scriptFile.lastIndexOf('.')) + ".componentType";
+ URL componentTypeFile = loaderContext.getResourceLoader().getResource(sidefile);
+ if (componentTypeFile == null) {
+ throw new MissingResourceException(sidefile);
+ }
+
+ try {
+ XMLStreamReader reader;
+ InputStream is;
+ is = componentTypeFile.openStream();
+ try {
+ reader = xmlFactory.createXMLStreamReader(is);
+ try {
+ reader.nextTag();
+ if (!AssemblyConstants.COMPONENT_TYPE.equals(reader.getName())) {
+ InvalidRootElementException e = new InvalidRootElementException(AssemblyConstants.COMPONENT_TYPE, reader.getName());
+ e.setResourceURI(componentTypeFile.toString());
+ throw e;
+ }
+ return (ComponentType) registry.load(reader, loaderContext);
+ } finally {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ // ignore
+ }
+ }
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ } catch (IOException e) {
+ SidefileLoadException sfe = new SidefileLoadException(e.getMessage());
+ sfe.setResourceURI(componentTypeFile.toString());
+ throw sfe;
+ } catch (XMLStreamException e) {
+ SidefileLoadException sfe = new SidefileLoadException(e.getMessage());
+ sfe.setResourceURI(componentTypeFile.toString());
+ throw sfe;
+ } catch (ConfigurationLoadException e) {
+ SidefileLoadException sfe = new SidefileLoadException(e.getMessage());
+ sfe.setResourceURI(componentTypeFile.toString());
+ throw sfe;
+ }
+ }
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoFunctionInvoker.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoFunctionInvoker.java
new file mode 100644
index 0000000000..1f0321f60c
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoFunctionInvoker.java
@@ -0,0 +1,79 @@
+package org.apache.tuscany.container.rhino.rhino;
+
+import org.apache.xmlbeans.XmlObject;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Wrapper;
+import org.mozilla.javascript.xml.XMLObject;
+
+/**
+ * An invoker for a specific function in a JavaScript script
+ */
+public class RhinoFunctionInvoker {
+
+ private Scriptable instanceScope;
+
+ private Function function;
+
+ private Class responseClass;
+
+ public RhinoFunctionInvoker(Scriptable instanceScope, Function function, Class responseClass) {
+ this.instanceScope = instanceScope;
+ this.function = function;
+ this.responseClass = responseClass;
+ }
+
+ public Object invoke(Object[] args) {
+ Context cx = Context.enter();
+ try {
+
+ Object[] jsArgs = toJavaScript(args, instanceScope, cx);
+ Object jsResponse = function.call(cx, instanceScope, instanceScope, jsArgs);
+ Object response = fromJavaScript(jsResponse);
+ return response;
+
+ } finally {
+ Context.exit();
+ }
+ }
+
+ protected Object[] toJavaScript(Object[] arg, Scriptable scope, Context cx) {
+ Object[] jsArgs;
+ if (arg == null) {
+ jsArgs = new Object[0];
+ } else if (arg.length == 1 && arg[0] instanceof XmlObject) {
+ Object jsXML = cx.getWrapFactory().wrap(cx, scope, (XmlObject) arg[0], XmlObject.class);
+ jsArgs = new Object[] { cx.newObject(scope, "XML", new Object[] { jsXML }) };
+ } else {
+ jsArgs = (Object[]) arg;
+ for (int i = 0; i < jsArgs.length; i++) {
+ jsArgs[i] = Context.toObject(jsArgs[i], scope);
+ }
+ }
+ return jsArgs;
+ }
+
+ protected Object fromJavaScript(Object o) {
+ Object response;
+ if (Context.getUndefinedValue().equals(o)) {
+ response = null;
+ } else if (o instanceof XMLObject) {
+ // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost???
+ Scriptable jsXML = (Scriptable) ScriptableObject.callMethod((Scriptable) o, "copy", new Object[0]);
+ Wrapper wrapper = (Wrapper) ScriptableObject.callMethod(jsXML, "getXmlObject", new Object[0]);
+ response = wrapper.unwrap();
+ } else if (o instanceof Wrapper) {
+ response = ((Wrapper) o).unwrap();
+ } else {
+ if (responseClass != null) {
+ response = Context.jsToJava(o, responseClass);
+ } else {
+ response = Context.jsToJava(o, String.class);
+ }
+ }
+ return response;
+ }
+
+}
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScript.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScript.java
new file mode 100644
index 0000000000..dafc8b585f
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScript.java
@@ -0,0 +1,194 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.rhino.rhino;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ContextFactory;
+import org.mozilla.javascript.ImporterTopLevel;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+
+/**
+ * A RhinoScript represents a compiled JavaScript script
+ */
+public class RhinoScript {
+
+ protected String scriptName;
+
+ protected String script;
+
+ protected Scriptable scriptScope;
+
+ protected Map<String, Class> responseClasses;
+
+ /*
+ * Enable dynamic scopes so a script can be used concurrently with a global shared scope and individual execution scopes. See
+ * http://www.mozilla.org/rhino/scopes.html
+ */
+ private static class MyFactory extends ContextFactory {
+ protected boolean hasFeature(Context cx, int featureIndex) {
+ if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) {
+ return true;
+ }
+ return super.hasFeature(cx, featureIndex);
+ }
+ }
+
+ static {
+ ContextFactory.initGlobal(new MyFactory());
+ }
+
+ /**
+ * Create a new RhinoScript.
+ *
+ * @param scriptName
+ * the name of the script. Can be anything, only used in messages to identify the script
+ * @param script
+ * the complete script
+ */
+ public RhinoScript(String scriptName, String script) {
+ this(scriptName, script, (Map) null, null);
+ }
+
+ /**
+ * Create a new RhinoInvoker.
+ *
+ * @param scriptName
+ * the name of the script. Can be anything, only used in messages to identify the script
+ * @param script
+ * the complete script
+ * @param context
+ * name-value pairs that are added in to the scope where the script is compiled. May be null. The value objects are made available to
+ * the script by using a variable with the name.
+ * @param classLoader
+ * the ClassLoader Rhino should use to locate any user Java classes used in the script
+ */
+ public RhinoScript(String scriptName, String script, Map context, ClassLoader cl) {
+ this.scriptName = scriptName;
+ this.script = script;
+ this.responseClasses = new HashMap<String, Class>();
+ initScriptScope(scriptName, script, context, cl);
+ }
+
+ /**
+ * Create a new invokeable instance of the script
+ *
+ * @return a RhinoScriptInstance
+ */
+ public RhinoScriptInstance createRhinoScriptInstance() {
+ return createRhinoScriptInstance(null);
+ }
+
+ /**
+ * Create a new invokeable instance of the script
+ *
+ * @param context
+ * objects to add to scope of the script instance
+ * @return a RhinoScriptInstance
+ */
+ public RhinoScriptInstance createRhinoScriptInstance(Map<String, Object> context) {
+ Scriptable instanceScope = createInstanceScope(context);
+ RhinoScriptInstance rsi = new RhinoScriptInstance(scriptScope, instanceScope, context, responseClasses);
+ return rsi;
+ }
+
+ /**
+ * Initialize the Rhino Scope for this script instance
+ */
+ protected Scriptable createInstanceScope(Map<String, Object> context) {
+ Context cx = Context.enter();
+ try {
+
+ Scriptable instanceScope = cx.newObject(scriptScope);
+ instanceScope.setPrototype(scriptScope);
+ instanceScope.setParentScope(null);
+
+ addContexts(instanceScope, context);
+
+ return instanceScope;
+
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Create a Rhino scope and compile the script into it
+ */
+ protected void initScriptScope(String fileName, String scriptCode, Map context, ClassLoader cl) {
+ Context cx = Context.enter();
+ try {
+ if (cl != null) {
+ cx.setApplicationClassLoader(cl);
+ }
+ this.scriptScope = new ImporterTopLevel(cx, true);
+ Script compiledScript = cx.compileString(scriptCode, fileName, 1, null);
+ compiledScript.exec(cx, scriptScope);
+ addContexts(scriptScope, context);
+
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Add the context to the scope. This will make the objects available to a script by using the name it was added with.
+ */
+ protected void addContexts(Scriptable scope, Map contexts) {
+ if (contexts != null) {
+ for (Iterator i = contexts.keySet().iterator(); i.hasNext();) {
+ String name = (String) i.next();
+ Object value = contexts.get(name);
+ if (value != null) {
+ scope.put(name, scope, Context.toObject(value, scope));
+ }
+ }
+ }
+ }
+
+ public String getScript() {
+ return script;
+ }
+
+ public String getScriptName() {
+ return scriptName;
+ }
+
+ public Scriptable getScriptScope() {
+ return scriptScope;
+ }
+
+ public Map<String, Class> getResponseClasses() {
+ return responseClasses;
+ }
+
+ /**
+ * Set the Java type of a response value. JavaScript is dynamically typed so Rhino
+ * cannot always work out what the intended Java type of a response should be, for
+ * example should the statement "return 42" be a Java int, or Integer or Double etc.
+ * When Rhino can't determine the type it will default to returning a String, using
+ * this method enables overriding the Rhino default to use a specific Java type.
+ */
+ public void setResponseClass(String functionName, Class responseClasses) {
+ this.responseClasses.put(functionName, responseClasses);
+ }
+
+} \ No newline at end of file
diff --git a/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScriptInstance.java b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScriptInstance.java
new file mode 100644
index 0000000000..8f22ae30f2
--- /dev/null
+++ b/sandbox/ant/tuscany-container-rhino/src/main/java/org/apache/tuscany/container/rhino/rhino/RhinoScriptInstance.java
@@ -0,0 +1,82 @@
+package org.apache.tuscany.container.rhino.rhino;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.UniqueTag;
+
+/**
+ * An invokeable instance of a JavaScript script.
+ */
+public class RhinoScriptInstance {
+
+ private Scriptable scriptScope;
+
+ private Scriptable instanceScope;
+
+ private Map<String, Class> responseClasses;
+
+ public RhinoScriptInstance(Scriptable scriptScope, Scriptable instanceScope, Map<String, Object> context, Map<String, Class> responseClasses) {
+ this.scriptScope = scriptScope;
+ this.instanceScope = instanceScope;
+ this.responseClasses = responseClasses;
+ if (this.responseClasses == null) {
+ this.responseClasses = new HashMap<String, Class>();
+ }
+ addContexts(instanceScope, context);
+ }
+
+ public Object invokeFunction(String functionName, Object[] args) {
+ RhinoFunctionInvoker invoker = createRhinoFunctionInvoker(functionName);
+ return invoker.invoke(args);
+ }
+
+ public RhinoFunctionInvoker createRhinoFunctionInvoker(String functionName) {
+ Function function = getFunction(functionName);
+ Class responseClass = responseClasses.get(functionName);
+ RhinoFunctionInvoker invoker = new RhinoFunctionInvoker(instanceScope, function, responseClass);
+ return invoker;
+ }
+
+ /**
+ * Add the context to the scope. This will make the objects available to a script by using the name it was added with.
+ */
+ protected void addContexts(Scriptable scope, Map contexts) {
+ if (contexts != null) {
+ Context.enter();
+ try {
+ for (Iterator i = contexts.keySet().iterator(); i.hasNext();) {
+ String name = (String) i.next();
+ Object value = contexts.get(name);
+ if (value != null) {
+ scope.put(name, scope, Context.toObject(value, scope));
+ }
+ }
+ } finally {
+ Context.exit();
+ }
+ }
+ }
+
+ /**
+ * Get the Rhino Function object for the named script function
+ */
+ protected Function getFunction(String functionName) {
+
+ Object handleObj = scriptScope.get(functionName, instanceScope);
+ if (UniqueTag.NOT_FOUND.equals(handleObj)) {
+ // Bit of a hack so E4X scripts don't need to define a function for every operation
+ handleObj = scriptScope.get("process", instanceScope);
+ }
+ if (!(handleObj instanceof Function)) {
+ throw new RuntimeException("script function '" + functionName + "' is undefined or not a function");
+ }
+
+ return (Function) handleObj;
+ }
+
+}