summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org')
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptAssemblyFactory.java28
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptImplementation.java34
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptAssemblyFactoryImpl.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptImplementationImpl.java116
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptComponentContextBuilder.java217
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptTargetWireBuilder.java75
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/config/JavaScriptComponentRuntimeConfiguration.java101
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/context/JavaScriptComponentContext.java161
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/loader/JavaScriptSCDLModelLoader.java77
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoScript.java298
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoTargetInvoker.java81
11 files changed, 1221 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptAssemblyFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptAssemblyFactory.java
new file mode 100644
index 0000000000..0072bcdaa1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptAssemblyFactory.java
@@ -0,0 +1,28 @@
+/**
+ *
+ * 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.js.assembly;
+
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+
+public interface JavaScriptAssemblyFactory extends AssemblyFactory {
+
+ /**
+ * Returns a new object of class '<em>JavaScript Implementation</em>'.
+ */
+ JavaScriptImplementation createJavaScriptImplementation();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptImplementation.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptImplementation.java
new file mode 100644
index 0000000000..6edaf2b60a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/JavaScriptImplementation.java
@@ -0,0 +1,34 @@
+/**
+ *
+ * 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.js.assembly;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+
+/**
+ * A representation of a JavaScript component implementation type
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaScriptImplementation extends ComponentImplementation {
+
+ public ResourceLoader getResourceLoader();
+
+ public String getScriptFile();
+
+ public void setScriptFile(String fn);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptAssemblyFactoryImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptAssemblyFactoryImpl.java
new file mode 100644
index 0000000000..21930d22ec
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptAssemblyFactoryImpl.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * 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.js.assembly.impl;
+
+import org.apache.tuscany.container.js.assembly.JavaScriptAssemblyFactory;
+import org.apache.tuscany.container.js.assembly.JavaScriptImplementation;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+
+public class JavaScriptAssemblyFactoryImpl extends AssemblyFactoryImpl implements JavaScriptAssemblyFactory {
+
+ public JavaScriptAssemblyFactoryImpl() {
+ super();
+ }
+
+ public JavaScriptImplementation createJavaScriptImplementation() {
+ return new JavaScriptImplementationImpl();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptImplementationImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptImplementationImpl.java
new file mode 100644
index 0000000000..c6b58a25c6
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/assembly/impl/JavaScriptImplementationImpl.java
@@ -0,0 +1,116 @@
+package org.apache.tuscany.container.js.assembly.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.container.js.assembly.JavaScriptImplementation;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.ComponentType;
+import org.apache.tuscany.model.assembly.ModelInitException;
+import org.apache.tuscany.model.assembly.impl.ComponentImplementationImpl;
+
+/**
+ * Default implementation of a JavScript component implementation type
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaScriptImplementationImpl extends ComponentImplementationImpl implements JavaScriptImplementation {
+
+ private ResourceLoader resourceLoader;
+
+ public JavaScriptImplementationImpl() {
+ super();
+ }
+
+ public ResourceLoader getResourceLoader() {
+ return null;
+ }
+
+ public void initialize(AssemblyModelContext modelContext) throws ModelInitException {
+ if (isInitialized()) {
+ return;
+ }
+ this.resourceLoader = modelContext.getApplicationResourceLoader();
+ if(resourceLoader == null){
+ throw new ModelInitException("No resource loader set on model context");
+ }
+ getScriptFile();
+
+ // Initialize the component type
+ ComponentType componentType = getComponentType();
+ if (componentType == null) {
+ try {
+ componentType = createComponentType(modelContext);
+ } catch (IOException e) {
+ throw new ModelInitException("Error retrieving component type file",e);
+ }
+ setComponentType(componentType);
+ }
+
+ super.initialize(modelContext);
+
+ }
+
+ String script;
+
+ public String getScriptFile() {
+ return script;
+ }
+
+ public void setScriptFile(String fn) {
+ script = fn;
+ }
+
+ private String scriptCode;
+
+ public String getScript() throws ModelInitException {
+ if (scriptCode != null) {
+ return scriptCode;
+ }
+ try {
+ URL url = resourceLoader.getResource(getScriptFile());
+ if (url == null) {
+ ModelInitException ce = new ModelInitException("Script not found");
+ ce.setIdentifier(getScriptFile());
+ throw ce;
+ }
+ InputStream inputStream = url.openStream();
+ try {
+ StringBuffer sb = new StringBuffer();
+ int n = 0;
+ while ((n = inputStream.read()) != -1) {
+ sb.append((char) n);
+ }
+ scriptCode = sb.toString();
+ return scriptCode;
+ } finally {
+ inputStream.close();
+ }
+ } catch (IOException e) {
+ ModelInitException ce = new ModelInitException("Error reading script file",e);
+ ce.setIdentifier(getScriptFile());
+ throw ce;
+ }
+ }
+
+ /**
+ * Create the component type
+ *
+ * @param modelContext
+ * @param implementationClass
+ */
+ private ComponentType createComponentType(AssemblyModelContext modelContext) throws IOException{
+ String prefix = script.substring(0,script.lastIndexOf('.'));
+ URL componentTypeFile = resourceLoader.getResource(prefix + ".componentType");
+ if (componentTypeFile != null) {
+ return modelContext.getAssemblyLoader().loadComponentType(componentTypeFile.toString());
+ } else {
+ // TODO we could introspect the JavaScript source
+ return modelContext.getAssemblyFactory().createComponentType();
+ }
+ }
+
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptComponentContextBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptComponentContextBuilder.java
new file mode 100644
index 0000000000..37ec68942a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptComponentContextBuilder.java
@@ -0,0 +1,217 @@
+/**
+ *
+ * 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.js.builder;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.container.js.assembly.JavaScriptImplementation;
+import org.apache.tuscany.container.js.assembly.impl.JavaScriptImplementationImpl;
+import org.apache.tuscany.container.js.config.JavaScriptComponentRuntimeConfiguration;
+import org.apache.tuscany.container.js.rhino.RhinoScript;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.MethodHashMap;
+import org.apache.tuscany.core.invocation.ProxyConfiguration;
+import org.apache.tuscany.core.invocation.impl.InvokerInterceptor;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactoryFactory;
+import org.apache.tuscany.core.message.MessageFactory;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+import org.apache.tuscany.model.assembly.ConfiguredReference;
+import org.apache.tuscany.model.assembly.ConfiguredService;
+import org.apache.tuscany.model.assembly.ModelInitException;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.Service;
+import org.apache.tuscany.model.assembly.ServiceContract;
+import org.apache.tuscany.model.assembly.SimpleComponent;
+import org.osoa.sca.annotations.Init;
+
+/**
+ * Builds {@link org.apache.tuscany.container.js.config.JavaScriptComponentRuntimeConfiguration}s from a JavaScript
+ * component type
+ *
+ * @version $Rev$ $Date$
+ */
+@org.osoa.sca.annotations.Scope("MODULE")
+public class JavaScriptComponentContextBuilder implements RuntimeConfigurationBuilder<AggregateContext> {
+
+ private ProxyFactoryFactory factory;
+ private MessageFactory msgFactory;
+ private RuntimeConfigurationBuilder referenceBuilder;
+ private RuntimeContext runtimeContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public JavaScriptComponentContextBuilder() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ @Init(eager = true)
+ public void init() {
+ runtimeContext.addBuilder(this);
+ }
+
+ /**
+ * @param runtimeContext The runtimeContext to set.
+ */
+ @Autowire
+ public void setRuntimeContext(RuntimeContext runtimeContext) {
+ this.runtimeContext = runtimeContext;
+ }
+
+ /**
+ * Sets the factory used to construct proxies implmementing the business interface required by a reference
+ */
+ @Autowire
+ public void setProxyFactoryFactory(ProxyFactoryFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * Sets the factory used to construct invocation messages
+ */
+ @Autowire
+ public void setMessageFactory(MessageFactory msgFactory) {
+ this.msgFactory = msgFactory;
+ }
+
+ /**
+ * Sets a builder responsible for creating source-side and target-side invocation chains for a reference. The
+ * reference builder may be hierarchical, containing other child reference builders that operate on specific
+ * metadata used to construct and invocation chain.
+ *
+ * @see org.apache.tuscany.core.builder.impl.HierarchicalBuilder
+ */
+ public void setReferenceBuilder(RuntimeConfigurationBuilder builder) {
+ this.referenceBuilder = builder;
+ }
+
+ public void build(AssemblyModelObject modelObject, AggregateContext context) throws BuilderException {
+ if (modelObject instanceof SimpleComponent) {
+ SimpleComponent component = (SimpleComponent) modelObject;
+ ComponentImplementation impl = component.getComponentImplementation();
+ if (impl instanceof JavaScriptImplementation) {
+ Scope scope = ((JavaScriptImplementation) impl).getComponentType().getServices().get(0).getServiceContract()
+ .getScope();
+ Map<String, Class> services = new HashMap();
+ for (Service service : ((JavaScriptImplementation) impl).getComponentType().getServices()) {
+ services.put(service.getName(), service.getServiceContract().getInterface());
+ }
+ Map<String, Object> properties = new HashMap();
+ // TODO support properties
+ String script = null;
+ if (impl instanceof JavaScriptImplementationImpl) { // fixme
+ try {
+ script = ((JavaScriptImplementationImpl) impl).getScript();
+ } catch (ModelInitException e) {
+ throw new BuilderConfigException(e);
+ }
+ }
+
+ RhinoScript invoker = createRhinoInvoker(component.getName(), script, properties);
+ JavaScriptComponentRuntimeConfiguration config = new JavaScriptComponentRuntimeConfiguration(component.getName(),
+ scope, services, properties, invoker);
+
+ // create target-side invocation chains for each service offered by the implementation
+ for (ConfiguredService configuredService : component.getConfiguredServices()) {
+ Service service = configuredService.getService();
+ ServiceContract contract = service.getServiceContract();
+ Map<Method, InvocationConfiguration> iConfigMap = new MethodHashMap();
+ ProxyFactory proxyFactory = factory.createProxyFactory();
+ for (Method method : contract.getInterface().getMethods()) {
+ InvocationConfiguration iConfig = new InvocationConfiguration(method);
+ iConfigMap.put(method, iConfig);
+ }
+ QualifiedName qName = new QualifiedName(component.getName() + QualifiedName.NAME_SEPARATOR + service.getName());
+ ProxyConfiguration pConfiguration = new ProxyConfiguration(qName, iConfigMap, contract.getInterface().getClassLoader(), msgFactory);
+ proxyFactory.setBusinessInterface(contract.getInterface());
+ proxyFactory.setProxyConfiguration(pConfiguration);
+ configuredService.setProxyFactory(proxyFactory);
+ if (referenceBuilder != null) {
+ // invoke the reference builder to handle target-side metadata
+ referenceBuilder.build(configuredService, context);
+ }
+ // add tail interceptor
+ for (InvocationConfiguration iConfig : (Collection<InvocationConfiguration>) iConfigMap.values()) {
+ iConfig.addTargetInterceptor(new InvokerInterceptor());
+ }
+ config.addTargetProxyFactory(service.getName(), proxyFactory);
+ }
+
+ // handle references
+ List<ConfiguredReference> configuredReferences = component.getConfiguredReferences();
+ if (configuredReferences != null) {
+ for (ConfiguredReference reference : configuredReferences) {
+ ProxyFactory proxyFactory = factory.createProxyFactory();
+ ServiceContract interfaze = reference.getReference().getServiceContract();
+ Map<Method, InvocationConfiguration> iConfigMap = new MethodHashMap();
+ for (Method method : interfaze.getInterface().getMethods()) {
+ InvocationConfiguration iConfig = new InvocationConfiguration(method);
+ iConfigMap.put(method, iConfig);
+ }
+ String targetCompName = reference.getTargetConfiguredServices().get(0).getAggregatePart().getName();
+ String targetSerivceName = reference.getTargetConfiguredServices().get(0).getService().getName();
+
+ QualifiedName qName = new QualifiedName(targetCompName + "/" + targetSerivceName);
+
+ // QualifiedName qName = new QualifiedName(reference.getPart().getName() + "/"
+ // + reference.getPort().getName());
+ ProxyConfiguration pConfiguration = new ProxyConfiguration(qName, iConfigMap, interfaze.getInterface().getClassLoader(), msgFactory);
+ proxyFactory.setBusinessInterface(interfaze.getInterface());
+ proxyFactory.setProxyConfiguration(pConfiguration);
+ reference.setProxyFactory(proxyFactory);
+ if (referenceBuilder != null) {
+ // invoke the reference builder to handle metadata associated with the reference
+ referenceBuilder.build(reference, context);
+ }
+ config.addSourceProxyFactory(reference.getReference().getName(), proxyFactory);
+ }
+ }
+ component.getComponentImplementation().setRuntimeConfiguration(config);
+ }
+ }
+ }
+
+ /**
+ * Creates a representation of the JavaScript implementation script that is used to perform invocations
+ *
+ * @param name
+ * @param script the Script source
+ * @param properties configured properties for the component
+ * @return
+ */
+ private RhinoScript createRhinoInvoker(String name, String script, Map properties) {
+ RhinoScript ri = new RhinoScript(name, script, properties);
+ return ri;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptTargetWireBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptTargetWireBuilder.java
new file mode 100644
index 0000000000..74433db823
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/builder/JavaScriptTargetWireBuilder.java
@@ -0,0 +1,75 @@
+package org.apache.tuscany.container.js.builder;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.container.js.config.JavaScriptComponentRuntimeConfiguration;
+import org.apache.tuscany.container.js.rhino.RhinoTargetInvoker;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.WireBuilder;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.osoa.sca.annotations.Init;
+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 implements WireBuilder {
+
+ private RuntimeContext runtimeContext;
+
+ @Autowire
+ public void setRuntimeContext(RuntimeContext context) {
+ runtimeContext = context;
+ }
+
+ public JavaScriptTargetWireBuilder() {
+ }
+
+ @Init(eager=true)
+ public void init() {
+ runtimeContext.addBuilder(this);
+ }
+
+ public void connect(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (!(JavaScriptComponentRuntimeConfiguration.class.isAssignableFrom(targetType))) {
+ return;
+ }
+ for (InvocationConfiguration sourceInvocationConfig : sourceFactory.getProxyConfiguration().getInvocationConfigurations()
+ .values()) {
+ Method method = sourceInvocationConfig.getMethod();
+ RhinoTargetInvoker invoker = new RhinoTargetInvoker(sourceFactory.getProxyConfiguration().getTargetName()
+ .getPartName(), method.getName(), targetScopeContext);
+ if (downScope) {
+ // the source scope is shorter than the target, so the invoker can cache the target instance
+ // invoker.setCacheable(true);
+ } else {
+ // invoker.setCacheable(false);
+ }
+ sourceInvocationConfig.setTargetInvoker(invoker);
+ }
+ }
+
+ public void completeTargetChain(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext)
+ throws BuilderConfigException {
+ if (!(JavaScriptComponentRuntimeConfiguration.class.isAssignableFrom(targetType))) {
+ return;
+ }
+ for (InvocationConfiguration targetInvocationConfig : targetFactory.getProxyConfiguration().getInvocationConfigurations()
+ .values()) {
+ Method method = targetInvocationConfig.getMethod();
+ RhinoTargetInvoker invoker = new RhinoTargetInvoker(targetFactory.getProxyConfiguration().getTargetName()
+ .getPartName(), method.getName(), targetScopeContext);
+ targetInvocationConfig.setTargetInvoker(invoker);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/config/JavaScriptComponentRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/config/JavaScriptComponentRuntimeConfiguration.java
new file mode 100644
index 0000000000..b24f98f32a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/config/JavaScriptComponentRuntimeConfiguration.java
@@ -0,0 +1,101 @@
+/**
+ *
+ * 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.js.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.container.js.context.JavaScriptComponentContext;
+import org.apache.tuscany.container.js.rhino.RhinoScript;
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Creates instance contexts for JavaScript component types
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaScriptComponentRuntimeConfiguration implements RuntimeConfiguration<SimpleComponentContext> {
+
+ private Scope scope;
+
+ private String name;
+
+ private Map<String, Class> services;
+
+ private Map<String, Object> properties;
+
+ private RhinoScript invoker;
+
+ public JavaScriptComponentRuntimeConfiguration(String name, Scope scope, Map<String, Class> services,
+ Map<String, Object> properties, RhinoScript invoker) {
+ this.name = name;
+ this.scope = scope;
+ this.services = services;
+ this.properties = properties;
+ this.invoker = invoker;
+ }
+
+ public SimpleComponentContext createInstanceContext() throws ContextCreationException {
+ return new JavaScriptComponentContext(name, services, properties, sourceProxyFactories, targetProxyFactories, invoker
+ .copy());
+ }
+
+ public Scope getScope() {
+ return scope;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private Map<String, ProxyFactory> targetProxyFactories = new HashMap<String, ProxyFactory>();
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory) {
+ targetProxyFactories.put(serviceName, factory);
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ return targetProxyFactories.get(serviceName);
+ }
+
+ public Map<String, ProxyFactory> getTargetProxyFactories() {
+ return targetProxyFactories;
+ }
+
+ private Map<String, ProxyFactory> sourceProxyFactories = new HashMap<String, ProxyFactory>();
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory factory) {
+ sourceProxyFactories.put(referenceName, factory);
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ return sourceProxyFactories.get(referenceName);
+ }
+
+ public Map<String, ProxyFactory> getSourceProxyFactories() {
+ return sourceProxyFactories;
+ }
+
+ public void prepare() {
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/context/JavaScriptComponentContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/context/JavaScriptComponentContext.java
new file mode 100644
index 0000000000..8a4db7eb44
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/context/JavaScriptComponentContext.java
@@ -0,0 +1,161 @@
+/**
+ *
+ * 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.js.context;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.tuscany.container.js.rhino.RhinoScript;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+public class JavaScriptComponentContext extends AbstractContext implements SimpleComponentContext {
+
+ private Map<String, Class> services;
+
+ private RhinoScript rhinoInvoker;
+
+ private Map<String, Object> properties;
+
+ private Map<String, ProxyFactory> sourceProxyFactories;
+
+ private Map<String, ProxyFactory> targetProxyFactories;
+
+ private Object instance;
+
+ public JavaScriptComponentContext(String name, Map<String, Class> services, Map<String, Object> properties,
+ Map<String, ProxyFactory> sourceProxyFactories, Map<String, ProxyFactory> targetProxyFactories, RhinoScript invoker) {
+ super(name);
+ assert (services != null) : "No service interface mapping specified";
+ assert (properties != null) : "No properties specified";
+ this.services = services;
+ this.properties = properties;
+ this.rhinoInvoker = invoker;
+ this.sourceProxyFactories = sourceProxyFactories;
+ this.targetProxyFactories = targetProxyFactories;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public synchronized Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ String portName=qName.getPortName();
+ ProxyFactory 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 });
+ notifyListeners(notify);
+ return proxy;
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException("Error returning target", e);
+ e.setIdentifier(qName.getPortName());
+ e.addContextName(getName());
+ throw te;
+ }
+ }
+
+ public Object getImplementationInstance() throws TargetException {
+ return getImplementationInstance(true);
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ rhinoInvoker.updateScriptScope(properties); // create prop values
+ return rhinoInvoker;
+ }
+
+// private Object createProxy(Class[] ifaces) throws ProxyCreationException {
+// // final RhinoInvoker rhinoInvoker = implementation.getRhinoInvoker().copy();
+// rhinoInvoker.updateScriptScope(properties); // create prop values
+// final Map refs = createInvocationContext();
+// InvocationHandler ih = new InvocationHandler() {
+// public Object invoke(Object proxy, Method method, Object[] args) {
+// return rhinoInvoker.invoke(method.getName(), args, method.getReturnType(), refs);
+// // return rhinoInvoker.invoke(method.getName(), args, method.getReturnType(),createInvocationContext());
+// }
+// };
+// return Proxy.newProxyInstance(ifaces[0].getClassLoader(), ifaces, ih);
+// }
+
+ private void notifyListeners(boolean notify) {
+ if (notify) {
+ for (Iterator iter = contextListener.iterator(); iter.hasNext();) {
+ LifecycleEventListener listener = (LifecycleEventListener) iter.next();
+ listener.onInstanceCreate(this);
+ }
+ }
+ }
+
+ /**
+ * Creates a map containing any properties and their values
+ */
+ // private Map createPropertyValues() {
+ // Map<String,Object> context = new HashMap<String,Object>();
+ // List<ConfiguredProperty> configuredProperties = component.getConfiguredProperties();
+ // if (configuredProperties != null) {
+ // for (ConfiguredProperty property : configuredProperties) {
+ // context.put(property.getProperty().getName(), property.getValue());
+ // }
+ // }
+ // return context;
+ // }
+ /**
+ * Creates a map containing any ServiceReferences
+ */
+ private Map createInvocationContext() throws ProxyCreationException {
+ Map<String, Object> context = new HashMap<String, Object>();
+ for (Map.Entry<String, ProxyFactory> entry : sourceProxyFactories.entrySet()) {
+ context.put(entry.getKey(), entry.getValue().createProxy());
+ }
+ return context;
+ }
+
+ public boolean isEagerInit() {
+ return false;
+ }
+
+ public boolean isDestroyable() {
+ return false;
+ }
+
+ public void start() throws CoreRuntimeException {
+ }
+
+ public void stop() throws CoreRuntimeException {
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/loader/JavaScriptSCDLModelLoader.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/loader/JavaScriptSCDLModelLoader.java
new file mode 100644
index 0000000000..ed7d267c89
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/loader/JavaScriptSCDLModelLoader.java
@@ -0,0 +1,77 @@
+package org.apache.tuscany.container.js.loader;
+
+import org.apache.tuscany.container.js.assembly.JavaScriptAssemblyFactory;
+import org.apache.tuscany.container.js.assembly.JavaScriptImplementation;
+import org.apache.tuscany.container.js.assembly.impl.JavaScriptAssemblyFactoryImpl;
+import org.apache.tuscany.container.js.scdl.ScdlFactory;
+import org.apache.tuscany.container.js.scdl.impl.ScdlPackageImpl;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.loader.SCDLModelLoaderRegistry;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+import org.apache.tuscany.sdo.util.SDOUtil;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Reference;
+
+/**
+ * Populates the assembly model from an SCDL model
+ */
+@org.osoa.sca.annotations.Scope("MODULE")
+public class JavaScriptSCDLModelLoader implements SCDLModelLoader {
+
+ private RuntimeContext runtimeContext;
+ private SCDLModelLoaderRegistry loaderRegistry;
+ private JavaScriptAssemblyFactory jsFactory;
+
+ static {
+ // Register the JavaScript SCDL model
+ SDOUtil.registerStaticTypes(ScdlFactory.class);
+ }
+
+ /**
+ * @param runtimeContext The runtimeContext to set.
+ */
+ @Autowire
+ public void setRuntimeContext(RuntimeContext runtimeContext) {
+ this.runtimeContext = runtimeContext;
+ }
+
+// @Reference
+ public void setLoaderRegistry(SCDLModelLoaderRegistry registry) {
+ this.loaderRegistry = registry;
+ }
+
+ @Init(eager=true)
+ public void init() {
+ runtimeContext.addLoader(this);
+// loaderRegistry.registerLoader(this);
+ }
+
+ @Destroy
+ public void destroy() {
+// loaderRegistry.unregisterLoader(this);
+ }
+
+ /**
+ * Constructs a new JavaSCDLModelLoader.
+ */
+ public JavaScriptSCDLModelLoader() {
+ this.jsFactory=new JavaScriptAssemblyFactoryImpl();
+ }
+
+ /**
+ * @see org.apache.tuscany.model.scdl.loader.SCDLModelLoader#load(org.apache.tuscany.model.assembly.AssemblyModelContext, java.lang.Object)
+ */
+ public AssemblyModelObject load(AssemblyModelContext modelContext, Object object) {
+ if (object instanceof org.apache.tuscany.container.js.scdl.JavaScriptImplementation) {
+ org.apache.tuscany.container.js.scdl.JavaScriptImplementation scdlImplementation=(org.apache.tuscany.container.js.scdl.JavaScriptImplementation)object;
+ JavaScriptImplementation implementation=jsFactory.createJavaScriptImplementation();
+ implementation.setScriptFile(scdlImplementation.getScriptFile());
+ return implementation;
+ } else
+ return null;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoScript.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoScript.java
new file mode 100644
index 0000000000..4ddee12fe4
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoScript.java
@@ -0,0 +1,298 @@
+/**
+ *
+ * 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.js.rhino;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ContextFactory;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.Wrapper;
+
+/**
+ * Represents, and is responsible for dispatching to, a JavaScript artifact in Rhino
+ */
+public class RhinoScript {
+
+ private String scriptName;
+
+ private String script;
+
+ private Scriptable scriptScope;
+
+ private Scriptable sharedScope;
+
+ /*
+ * 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 TODO: need to review how ths fits in with Tuscany scopes
+ */
+ 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 RhinoInvoker.
+ *
+ * @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);
+ }
+
+ /**
+ * 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.
+ */
+ public RhinoScript(String scriptName, String script, Map context) {
+ this.scriptName = scriptName;
+ this.script = script;
+ initScriptScope(scriptName, script, context);
+ initSharedScope();
+ }
+
+ /**
+ * Construct a RhinoInvoker from another RhinoInvoker object. This uses the original script scope so the script
+ * doesn't need to be recompiled.
+ */
+ protected RhinoScript(String scriptName, String script, Scriptable scriptScope) {
+ this.scriptName = scriptName;
+ this.script = script;
+ this.scriptScope = scriptScope;
+ initSharedScope();
+ }
+
+ /**
+ * Invoke a script function
+ *
+ * @param functionName the name of the function to invoke.
+ * @param arg arguments to the function, may be a single object or an array of objects.
+ * @return the function return value.
+ */
+ public Object invoke(String functionName, Object args) {
+ return invoke(functionName, args, null, null);
+ }
+
+ /**
+ * Invoke a script function
+ *
+ * @param functionName the name of the function to invoke.
+ * @param arg arguments to the function, may be a single object or an array of objects.
+ * @param contexts a Map of name-value pairs which are added to the invocation Scope to enable the script to access
+ * the values by using the variable in name.
+ * @return the function return value.
+ */
+ public Object invoke(String functionName, Object args, Map contexts) {
+ return invoke(functionName, args, null, contexts);
+ }
+
+ /**
+ * Invoke a script function
+ *
+ * @param functionName the name of the function to invoke.
+ * @param arg arguments to the function, may be a single object or an array of objects.
+ * @param responseClass the desired class of the response object.
+ * @param contexts a Map of name-value pairs which are added to the invocation Scope to enable the script to access
+ * the values by using the variable in name.
+ * @return the function return value.
+ */
+ public Object invoke(String functionName, Object arg, Class responseClass, Map contexts) {
+ Context cx = Context.enter();
+ try {
+ Function function = getFunction(scriptScope, functionName);
+ Scriptable invocationScope = getInvocationScope(cx, contexts);
+ Object[] args = processArgs(arg, invocationScope);
+ Object jsResponse = function.call(cx, invocationScope, invocationScope, args);
+ Object response = processResponse(jsResponse, responseClass);
+ return response;
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Turn args to JS objects and convert any OMElement to E4X XML
+ */
+ protected Object[] processArgs(Object arg, Scriptable scope) {
+ // TODO: implement pluggable way to transform objects (eg SDO or AXIOM) to E4X XML objects
+ // if (arg instanceof OMElement) {
+ // try {
+ // arg = E4XAXIOMUtils.toScriptableObject((OMElement) arg, scope);
+ // } catch (XmlException e) {
+ // throw new RuntimeException(e);
+ // }
+ // } else if (arg instanceof MessageContext) {
+ // arg = new E4XMessageContext((MessageContext) arg, scope);
+ // }
+ Object[] args;
+ if (arg == null) {
+ args = new Object[] { null };
+ } else if (arg.getClass().isArray()) {
+ args = (Object[]) arg;
+ for (int i = 0; i < args.length; i++) {
+ args[i] = Context.toObject(args[i], scope);
+ }
+ } else {
+ args = new Object[] { Context.toObject(arg, scope) };
+ }
+ return args;
+ }
+
+ /**
+ * Unwrap and convert response
+ */
+ protected Object processResponse(Object response, Class responseClass) {
+ // TODO: implement pluggable way to transform E4X XML into specific objects (eg SDO or AXIOM)
+ // } else if (response instanceof XMLObject) {
+ // response = E4XAXIOMUtils.toOMElement((XMLObject) response);
+ if (Context.getUndefinedValue().equals(response)) {
+ response = null;
+ } else if (response instanceof Wrapper) {
+ response = ((Wrapper) response).unwrap();
+ } else {
+ if (responseClass != null) {
+ response = Context.toType(response, responseClass);
+ } else {
+ response = Context.toType(response, String.class);
+ }
+ }
+ return response;
+ }
+
+ /**
+ * Create a Rhino scope and compile the script into it
+ */
+ protected void initScriptScope(String fileName, String scriptCode, Map context) {
+ Context cx = Context.enter();
+ try {
+
+ this.scriptScope = cx.initStandardObjects(null, true);
+ Script compiledScript = cx.compileString(scriptCode, fileName, 1, null);
+ compiledScript.exec(cx, scriptScope);
+ addContexts(scriptScope, context);
+
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Initializes the shared scope
+ */
+ protected void initSharedScope() {
+ Context cx = Context.enter();
+ try {
+
+ this.sharedScope = cx.newObject(scriptScope);
+ sharedScope.setPrototype(scriptScope);
+ sharedScope.setParentScope(null);
+
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Get a Rhino scope for the function invocation. If the invocation has no context objects then this will use the
+ * shared scope otherwise a new scope is created to hold the context objects. Any new variables the executing script
+ * might define will go in the sharedScope. This new scope is just to hold the invocation specific context objects.
+ */
+ protected Scriptable getInvocationScope(Context cx, Map contexts) {
+
+ Scriptable scope;
+ if (contexts == null || contexts.size() == 0) {
+ scope = sharedScope;
+ } else {
+ scope = cx.newObject(sharedScope);
+ scope.setPrototype(sharedScope);
+ scope.setParentScope(null);
+ addContexts(scope, contexts);
+ }
+
+ return scope;
+ }
+
+ /**
+ * 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));
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the Rhino Function object for the named script function
+ */
+ protected Function getFunction(Scriptable scope, String functionName) {
+
+ Object handleObj = scope.get(functionName, scope);
+
+ if (!(handleObj instanceof Function)) {
+ throw new RuntimeException("script function '" + functionName + "' is undefined or not a function in script "
+ + scriptName);
+ }
+
+ return (Function) handleObj;
+ }
+
+ /**
+ * Make a copy of this RhinoScript object. This shares the script scope to avoid the overhead of recompiling the
+ * script, and to allow any initialization done by the script to be shared.
+ */
+ public RhinoScript copy() {
+ return new RhinoScript(scriptName, script, scriptScope);
+ }
+
+ /**
+ * Update the scope where the script is complied with new context values
+ *
+ * @param properties
+ */
+ public void updateScriptScope(Map context) {
+ Context.enter();
+ try {
+ addContexts(scriptScope, context);
+ } finally {
+ Context.exit();
+ }
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoTargetInvoker.java b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoTargetInvoker.java
new file mode 100644
index 0000000000..62cf40f333
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany/container/js/rhino/RhinoTargetInvoker.java
@@ -0,0 +1,81 @@
+package org.apache.tuscany.container.js.rhino;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.TargetInvoker;
+import org.apache.tuscany.core.message.Message;
+
+public class RhinoTargetInvoker implements TargetInvoker {
+
+ private ScopeContext container;
+
+ private QualifiedName name;
+
+ private String operation;
+
+ private RhinoScript target;
+
+ public RhinoTargetInvoker(String serviceName, String operation, ScopeContext container) {
+ assert (serviceName != null) : "No service name specified";
+ assert (container != null) : "No scope container specified";
+ assert (operation != null) : "No operation specified";
+ this.name = new QualifiedName(serviceName);
+ this.container = container;
+ this.operation = operation;
+ }
+
+ public Object invokeTarget(Object payload) throws InvocationTargetException {
+ if (cacheable) {
+ if (target == null) {
+ target = (RhinoScript) container.getContext(name.getPartName()).getImplementationInstance();
+ }
+ return target.invoke(operation, payload);
+ } else {
+ return ((RhinoScript) container.getContext(name.getPartName()).getImplementationInstance())
+ .invoke(operation, payload);
+ }
+ }
+
+ private boolean cacheable;
+
+ public boolean isCacheable() {
+ return cacheable;
+ }
+
+ public void setCacheable(boolean val) {
+ cacheable = val;
+ }
+
+ public Message invoke(Message msg) {
+ try {
+ Object resp = invokeTarget(msg.getBody());
+ msg.setBody(resp);
+ } catch (InvocationTargetException e) {
+ msg.setBody(e.getCause());
+ } catch (Throwable e) {
+ msg.setBody(e);
+ }
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+ throw new IllegalStateException("This interceptor must be the last interceptor in an interceptor chain");
+ }
+
+ public Object clone() {
+ try {
+ RhinoTargetInvoker invoker = (RhinoTargetInvoker) super.clone();
+ invoker.container = this.container;
+ invoker.cacheable = this.cacheable;
+ invoker.name = this.name;
+ invoker.operation = this.operation;
+ invoker.target = null;
+ return invoker;
+ } catch (CloneNotSupportedException e) {
+ return null; // will not happen
+ }
+ }
+}