diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-21 07:55:20 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-21 07:55:20 +0000 |
commit | 36436b71b9977d6b5940cb6285d5335708ef9bfa (patch) | |
tree | b218a104f180c67690a6ae2ad097cd9306a8f203 /sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany | |
parent | d5be76c0b31df9b5d203295b146b13d2205243de (diff) |
Moving 1.x tags
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@882851 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/tags/java-stable-20060304/sca/container.js/src/main/java/org/apache/tuscany')
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 + } + } +} |