summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:13:23 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:13:23 +0000
commit6d0e93c68d3aeaeb4bb6d96ac0460eec40ef786e (patch)
treea956ed510e14a5509b8ef49fae42cfd439629825 /sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src
parent3ac2d800d840f03618fc364090d786effde84b1f (diff)
Moving 1.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835143 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src')
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java92
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java34
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java120
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java119
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java43
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java43
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java150
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java45
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java87
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java110
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl40
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java77
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java37
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java102
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java90
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java79
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java189
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java27
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java25
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl28
-rw-r--r--sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy1
21 files changed, 1538 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java
new file mode 100644
index 0000000000..f761122847
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+
+/**
+ * Responsible for performing a non-blocking dispatch on a Groovy component implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class AsyncGroovyInvoker extends GroovyInvoker {
+
+ private InboundWire wire;
+ private AsyncMonitor monitor;
+ private WorkContext workContext;
+ private Object target;
+
+ /**
+ * Creates a new invoker
+ *
+ * @param operation the operation the invoker is associated with
+ * @param wire
+ * @param component the target component
+ * @param monitor the monitor to pass events to
+ * @param workContext
+ */
+ public AsyncGroovyInvoker(String operation,
+ InboundWire wire,
+ GroovyAtomicComponent component,
+ AsyncMonitor monitor,
+ WorkContext workContext) {
+ super(operation, component);
+ this.wire = wire;
+ this.monitor = monitor;
+ this.workContext = workContext;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object messageId = msg.getMessageId();
+ wire.addMapping(messageId, msg.getFromAddress());
+ workContext.setCurrentMessageId(null);
+ workContext.setCurrentCorrelationId(messageId);
+ invokeTarget(msg.getBody());
+ // async so no return value
+ return null;
+ } catch (Throwable e) {
+ // FIXME need to log exceptions
+ monitor.executionError(e);
+ return null;
+ }
+ }
+
+ public AsyncGroovyInvoker clone() throws CloneNotSupportedException {
+ return (AsyncGroovyInvoker) super.clone();
+ }
+
+ /**
+ * Resolves the target service instance or returns a cached one
+ */
+ protected Object getInstance() throws TargetException {
+ if (!cacheable) {
+ return component.getTargetInstance();
+ } else {
+ if (target == null) {
+ target = component.getTargetInstance();
+ }
+ return target;
+ }
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java
new file mode 100644
index 0000000000..4da5538990
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+/**
+ * A monitor used to log events during non-blocking invocations
+ * <p/>
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public interface AsyncMonitor {
+
+ /**
+ * Logs an exception thrown during an invocation
+ */
+ void executionError(Throwable e);
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java
new file mode 100644
index 0000000000..b0ed18382f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import groovy.lang.GroovyObject;
+
+/**
+ * The Groovy atomic component implementation. Groovy implementations may be "scripts" or classes.
+ */
+public class GroovyAtomicComponent extends AtomicComponentExtension {
+ private final Class<? extends GroovyObject> groovyClass;
+ private final List<Class<?>> services;
+ //FIXME properties should move up to AtomicComponentExtension
+ private final Map<String, ObjectFactory> properties;
+ private AsyncMonitor monitor;
+
+ public GroovyAtomicComponent(GroovyConfiguration configuration, AsyncMonitor monitor) {
+ super(configuration.getName(),
+ configuration.getParent(),
+ configuration.getScopeContainer(),
+ configuration.getWireService(),
+ configuration.getWorkContext(),
+ null, configuration.getInitLevel());
+
+ this.groovyClass = configuration.getGroovyClass();
+ this.services = Collections.unmodifiableList(configuration.getServices());
+ this.properties = new HashMap<String, ObjectFactory>();
+ assert groovyClass != null;
+ this.monitor = monitor;
+ }
+
+ public List<Class<?>> getServiceInterfaces() {
+ return services;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation) {
+ return new GroovyInvoker(operation.getName(), this);
+ }
+
+ public TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation) {
+ return new AsyncGroovyInvoker(operation.getName(), wire, this, monitor, workContext);
+ }
+
+ public Object createInstance() throws ObjectCreationException {
+ GroovyObject instance;
+ try {
+ instance = groovyClass.newInstance();
+ } catch (IllegalAccessException e) {
+ throw new ObjectCreationException(e);
+ } catch (InstantiationException e) {
+ throw new ObjectCreationException(e);
+ }
+
+ // inject properties
+ for (Map.Entry<String, ObjectFactory> property : properties.entrySet()) {
+ instance.setProperty(property.getKey(), property.getValue().getInstance());
+ }
+
+ // inject references
+ for (List<OutboundWire> referenceWires : getOutboundWires().values()) {
+ for (OutboundWire wire : referenceWires) {
+ instance.setProperty(wire.getReferenceName(), wireService.createProxy(wire));
+ }
+ }
+ return instance;
+ }
+
+ public GroovyObject getTargetInstance() throws TargetException {
+ return (GroovyObject) scopeContainer.getInstance(this);
+ }
+
+ public Object getServiceInstance() throws TargetException {
+ //TODO this should return a default service from a wire
+ return scopeContainer.getInstance(this);
+ }
+
+ public Object getServiceInstance(String service) throws TargetException {
+ InboundWire wire = getInboundWire(service);
+ if (wire == null) {
+ TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message
+ e.setIdentifier(service);
+ throw e;
+ }
+ return wireService.createProxy(wire);
+ }
+
+ public void addPropertyFactory(String name, ObjectFactory<?> factory) {
+ properties.put(name, factory);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java
new file mode 100644
index 0000000000..4e99b888da
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentBuilderExtension;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+/**
+ * Extension point for creating {@link GroovyAtomicComponent}s from an assembly configuration
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class GroovyComponentBuilder extends ComponentBuilderExtension<GroovyImplementation> {
+
+ protected Class<GroovyImplementation> getImplementationType() {
+ return GroovyImplementation.class;
+ }
+
+ public Component build(CompositeComponent parent,
+ ComponentDefinition<GroovyImplementation> componentDefinition,
+ DeploymentContext deploymentContext)
+ throws BuilderConfigException {
+
+ String name = componentDefinition.getName();
+ GroovyImplementation implementation = componentDefinition.getImplementation();
+ GroovyComponentType componentType = implementation.getComponentType();
+
+ int initLevel = componentType.getInitLevel();
+
+ // get list of services provided by this component
+ Collection<ServiceDefinition> collection = componentType.getServices().values();
+ List<Class<?>> services = new ArrayList<Class<?>>(collection.size());
+ for (ServiceDefinition serviceDefinition : collection) {
+ services.add(serviceDefinition.getServiceContract().getInterfaceClass());
+ }
+
+ // get the Groovy classloader for this deployment component
+ GroovyClassLoader groovyClassLoader = (GroovyClassLoader) deploymentContext.getExtension("groovy.classloader");
+ if (groovyClassLoader == null) {
+ groovyClassLoader = new GroovyClassLoader(deploymentContext.getClassLoader());
+ deploymentContext.putExtension("groovy.classloader", groovyClassLoader);
+ }
+
+ // create the implementation class for the script
+ Class<? extends GroovyObject> groovyClass;
+ try {
+ String script = implementation.getScript();
+ // REVIEW JFM can we cache the class?
+ groovyClass = groovyClassLoader.parseClass(script);
+ } catch (CompilationFailedException e) {
+ BuilderConfigException bce = new BuilderConfigException(e);
+ bce.setIdentifier(name);
+ throw bce;
+ }
+ // TODO deal with init and destroy
+
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName(name);
+ configuration.setGroovyClass(groovyClass);
+ configuration.setParent(parent);
+ // get the scope container for this component's scope
+ Scope scope = componentType.getLifecycleScope();
+ if (Scope.MODULE == scope) {
+ configuration.setScopeContainer(deploymentContext.getModuleScope());
+ } else {
+ configuration.setScopeContainer(scopeRegistry.getScopeContainer(scope));
+ }
+
+
+ configuration.setWireService(wireService);
+ configuration.setWorkContext(workContext);
+ configuration.setInitLevel(initLevel);
+ configuration.setServices(services);
+ GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null);
+
+ // handle properties
+ for (Property<?> property : componentType.getProperties().values()) {
+ ObjectFactory<?> factory = property.getDefaultValueFactory();
+ if (factory != null) {
+ component.addPropertyFactory(property.getName(), factory);
+ }
+ }
+ return component;
+ }
+
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java
new file mode 100644
index 0000000000..bd54371fd7
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.ReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * Model object representing a Groovy component type
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class GroovyComponentType extends ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> {
+ private Scope lifecycleScope;
+
+ public Scope getLifecycleScope() {
+ return lifecycleScope;
+ }
+
+ public void setLifecycleScope(Scope lifecycleScope) {
+ this.lifecycleScope = lifecycleScope;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java
new file mode 100644
index 0000000000..6da7840fdb
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class GroovyComponentTypeLoader extends ComponentTypeLoaderExtension<GroovyImplementation> {
+ protected Class<GroovyImplementation> getImplementationClass() {
+ return GroovyImplementation.class;
+ }
+
+ public void load(CompositeComponent parent, GroovyImplementation implementation, DeploymentContext context)
+ throws LoaderException {
+ GroovyComponentType componentType = new GroovyComponentType();
+ // for now, default to module
+ componentType.setLifecycleScope(Scope.MODULE);
+ implementation.setComponentType(componentType);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java
new file mode 100644
index 0000000000..b9ede2d034
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.WireService;
+
+import groovy.lang.GroovyObject;
+
+/**
+ * Encapsulates confuration for a Groovy-based atomic component
+ *
+ * @version $Rev$ $Date$
+ */
+public class GroovyConfiguration {
+
+ private CompositeComponent parent;
+ private ScopeContainer scopeContainer;
+ private int initLevel;
+ private Map<String, Member> referenceSites = new HashMap<String, Member>();
+ private Map<String, Member> propertySites = new HashMap<String, Member>();
+ private Map<String, Member> callbackSites = new HashMap<String, Member>();
+ private List<Class<?>> serviceInterfaces = new ArrayList<Class<?>>();
+ private WireService wireService;
+ private WorkContext workContext;
+ private String name;
+ private Class<? extends GroovyObject> groovyClass;
+ private List<Class<?>> services;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Class<? extends GroovyObject> getGroovyClass() {
+ return groovyClass;
+ }
+
+ public void setGroovyClass(Class<? extends GroovyObject> groovyClass) {
+ this.groovyClass = groovyClass;
+ }
+
+ public CompositeComponent getParent() {
+ return parent;
+ }
+
+ public void setParent(CompositeComponent parent) {
+ this.parent = parent;
+ }
+
+ public ScopeContainer getScopeContainer() {
+ return scopeContainer;
+ }
+
+ public void setScopeContainer(ScopeContainer scopeContainer) {
+ this.scopeContainer = scopeContainer;
+ }
+
+ public List<Class<?>> getServiceInterfaces() {
+ return serviceInterfaces;
+ }
+
+ public void addServiceInterface(Class<?> serviceInterface) {
+ serviceInterfaces.add(serviceInterface);
+ }
+
+ public int getInitLevel() {
+ return initLevel;
+ }
+
+ public void setInitLevel(int initLevel) {
+ this.initLevel = initLevel;
+ }
+
+ public List<Class<?>> getServices() {
+ return services;
+ }
+
+ public void setServices(List<Class<?>> services) {
+ this.services = services;
+ }
+
+ public Map<String, Member> getReferenceSite() {
+ return referenceSites;
+ }
+
+ public void addReferenceSite(String name, Member member) {
+ referenceSites.put(name, member);
+ }
+
+ public Map<String, Member> getCallbackSite() {
+ return callbackSites;
+ }
+
+ public void addCallbackSite(String name, Member member) {
+ callbackSites.put(name, member);
+ }
+
+ public Map<String, Member> getPropertySites() {
+ return propertySites;
+ }
+
+ public void addPropertySite(String name, Member member) {
+ propertySites.put(name, member);
+ }
+
+ public WireService getWireService() {
+ return wireService;
+ }
+
+ public void setWireService(WireService wireService) {
+ this.wireService = wireService;
+ }
+
+ public WorkContext getWorkContext() {
+ return workContext;
+ }
+
+ public void setWorkContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java
new file mode 100644
index 0000000000..96b4a3bc2d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import org.apache.tuscany.spi.model.AtomicImplementation;
+
+/**
+ * Model object for a Groovy implementation.
+ */
+public class GroovyImplementation extends AtomicImplementation<GroovyComponentType> {
+
+ //the Groovy source to be executed
+ private String script;
+
+ /**
+ * Returns the Groovy source to be executed.
+ */
+ public String getScript() {
+ return script;
+ }
+
+ /**
+ * Sets the Groovy source to be executed.
+ */
+ public void setScript(String script) {
+ this.script = script;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java
new file mode 100644
index 0000000000..b6fdbbb0b6
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import groovy.lang.GroovyObject;
+
+/**
+ * Dispatches to a Groovy implementation instance
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class GroovyInvoker implements TargetInvoker, Cloneable {
+
+ protected GroovyAtomicComponent component;
+ protected String operation;
+ protected boolean cacheable;
+
+ public GroovyInvoker(String operation, GroovyAtomicComponent context) {
+ this.component = context;
+ this.operation = operation;
+ }
+
+ public boolean isCacheable() {
+ return cacheable;
+ }
+
+ public void setCacheable(boolean cacheable) {
+ this.cacheable = cacheable;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ /**
+ * Dispatches to the the target.
+ */
+ public Object invokeTarget(final Object payload) throws InvocationTargetException {
+ GroovyObject target = component.getTargetInstance();
+ Object[] args = (Object[]) payload;
+ try {
+ return target.invokeMethod(operation, args);
+ } catch (Exception ex) {
+ throw new InvocationTargetException(ex);
+ }
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody());
+ msg.setBody(resp);
+ } catch (InvocationTargetException e) {
+ msg.setBodyWithFault(e.getCause());
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public GroovyInvoker clone() throws CloneNotSupportedException {
+ return (GroovyInvoker) super.clone();
+ }
+
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java
new file mode 100644
index 0000000000..da93abbd9d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.MissingResourceException;
+
+/**
+ * Loader for handling <groovy:implementation> elements.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ImplementationLoader extends LoaderExtension<GroovyImplementation> {
+ private static final QName IMPLEMENTATION_GROOVY =
+ new QName("http://incubator.apache.org/tuscany/xmlns/container/groovy/1.0-incubator-M2", "implementation.groovy");
+
+ public ImplementationLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return IMPLEMENTATION_GROOVY;
+ }
+
+ public GroovyImplementation load(CompositeComponent parent,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ String script = reader.getAttributeValue(null, "script");
+ if (script == null) {
+ throw new MissingResourceException("No script supplied");
+ }
+ String source = loadSource(deploymentContext.getClassLoader(), script);
+
+ LoaderUtil.skipToEndElement(reader);
+
+ GroovyImplementation implementation = new GroovyImplementation();
+ implementation.setScript(source);
+ // no component type support
+ //registry.loadComponentType(parent, implementation, deploymentContext);
+ return implementation;
+ }
+
+ protected String loadSource(ClassLoader cl, String resource) throws LoaderException {
+ URL url = cl.getResource(resource);
+ if (url == null) {
+ throw new MissingResourceException(resource);
+ }
+ InputStream is;
+ try {
+ is = url.openStream();
+ } catch (IOException e) {
+ MissingResourceException mre = new MissingResourceException(resource, e);
+ mre.setIdentifier(resource);
+ throw mre;
+ }
+ try {
+ Reader reader = new InputStreamReader(is, "UTF-8");
+ char[] buffer = new char[1024];
+ StringBuilder source = new StringBuilder();
+ int count;
+ while ((count = reader.read(buffer)) > 0) {
+ source.append(buffer, 0, count);
+ }
+ return source.toString();
+ } catch (IOException e) {
+ LoaderException le = new LoaderException(e);
+ le.setIdentifier(resource);
+ throw le;
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl
new file mode 100644
index 0000000000..24fbfd5e25
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ -->
+<!--
+ JavaScript configuration for the launcher environment.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2"
+
+ name="groovy.extension">
+
+ <component name="GroovyLoader">
+ <system:implementation.system class="org.apache.tuscany.container.groovy.ImplementationLoader"/>
+ </component>
+
+ <component name="GroovyComponentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.container.groovy.GroovyComponentTypeLoader"/>
+ </component>
+
+ <component name="GroovyBuilder">
+ <system:implementation.system class="org.apache.tuscany.container.groovy.GroovyComponentBuilder"/>
+ </component>
+
+</composite> \ No newline at end of file
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java
new file mode 100644
index 0000000000..a27bb25484
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+
+import groovy.lang.GroovyObject;
+import junit.framework.TestCase;
+import org.apache.tuscany.container.groovy.mock.AsyncTarget;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AsyncInvokerTestCase extends TestCase {
+
+ public void testInvoke() throws Exception {
+ GroovyObject instance = createMock(GroovyObject.class);
+ expect(instance.invokeMethod("invoke", null)).andReturn(null).once();
+ replay(instance);
+ GroovyAtomicComponent component = EasyMock.createMock(GroovyAtomicComponent.class);
+ expect(component.getTargetInstance()).andReturn(instance);
+ EasyMock.replay(component);
+ AsyncMonitor monitor = createMock(AsyncMonitor.class);
+ replay(monitor);
+
+ WorkScheduler scheduler = createMock(WorkScheduler.class);
+ scheduler.scheduleWork(isA(Runnable.class));
+ expectLastCall().andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ Runnable runnable = (Runnable) getCurrentArguments()[0];
+ runnable.run();
+ return null;
+ }
+ });
+ replay(scheduler);
+ WorkContext context = createMock(WorkContext.class);
+ Method method = AsyncTarget.class.getMethod("invoke");
+ method.setAccessible(true);
+ InboundWire wire = createMock(InboundWire.class);
+ AsyncGroovyInvoker invoker = new AsyncGroovyInvoker("invoke", wire, component, monitor, context);
+ Message msg = new MessageImpl();
+ invoker.invoke(msg);
+ verify(instance);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java
new file mode 100644
index 0000000000..bfff4bdef7
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class GroovyComponentTypeLoaderTestCase extends TestCase {
+
+ public void testLoad() throws Exception {
+ GroovyComponentTypeLoader loader = new GroovyComponentTypeLoader();
+ GroovyImplementation impl = new GroovyImplementation();
+ loader.load(null, impl, null);
+ GroovyComponentType type = impl.getComponentType();
+ assertEquals(Scope.MODULE, type.getLifecycleScope());
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java
new file mode 100644
index 0000000000..2af0611757
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.MissingResourceException;
+
+import junit.framework.TestCase;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ImplementationLoaderTestCase extends TestCase {
+ private CompositeComponent parent;
+ private XMLStreamReader reader;
+ private DeploymentContext deploymentContext;
+ private ClassLoader classLoader;
+ private LoaderRegistry registry;
+ private ImplementationLoader loader;
+
+ public void testNoScriptAttribute() throws LoaderException, XMLStreamException {
+ expect(reader.getAttributeValue(null, "script")).andReturn(null);
+ replay(reader);
+ replay(deploymentContext);
+
+ try {
+ loader.load(parent, reader, deploymentContext);
+ fail();
+ } catch (MissingResourceException e) {
+ // ok
+ }
+ verify(reader);
+ verify(deploymentContext);
+ }
+
+ public void testNoScriptPresent() throws LoaderException, XMLStreamException {
+ expect(reader.getAttributeValue(null, "script")).andReturn("foo.groovy");
+ expect(deploymentContext.getClassLoader()).andReturn(classLoader);
+
+ replay(reader);
+ replay(deploymentContext);
+
+ ImplementationLoader mockLoader = new ImplementationLoader(registry) {
+ protected String loadSource(ClassLoader cl, String resource) throws LoaderException {
+ assertSame(classLoader, cl);
+ assertEquals("foo.groovy", resource);
+ throw new MissingResourceException(resource);
+ }
+ };
+ try {
+ mockLoader.load(parent, reader, deploymentContext);
+ fail();
+ } catch (MissingResourceException e) {
+ assertEquals("foo.groovy", e.getMessage());
+ }
+ verify(reader);
+ verify(deploymentContext);
+ }
+
+ public void testLoadScript() throws LoaderException {
+ String script = loader.loadSource(getClass().getClassLoader(),
+ "org/apache/tuscany/container/groovy/mock/TestScript.groovy");
+ assertEquals("Test Script", script);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ loader = new ImplementationLoader(registry);
+
+ parent = createMock(CompositeComponent.class);
+ reader = createMock(XMLStreamReader.class);
+ deploymentContext = createMock(DeploymentContext.class);
+ classLoader = createMock(ClassLoader.class);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java
new file mode 100644
index 0000000000..9b828db7eb
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+import junit.framework.TestCase;
+import org.apache.tuscany.container.groovy.mock.Greeting;
+import static org.apache.tuscany.test.ArtifactFactory.createWireService;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import org.easymock.IAnswer;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class PropertyTestCase extends TestCase {
+
+ private static final String SCRIPT = "import org.apache.tuscany.container.groovy.mock.Greeting;"
+ + "class Foo implements Greeting{"
+ + " String property;"
+ + " public String greet(String name){"
+ + " return property; "
+ + " }"
+ + "}";
+
+ private ScopeContainer scopeContainer;
+ private Class<? extends GroovyObject> implClass;
+
+ /**
+ * Tests injecting a simple property type on a Groovy implementation instance
+ */
+ public void testPropertyInjection() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Greeting.class);
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName("source");
+ configuration.setGroovyClass(implClass);
+ configuration.setServices(services);
+ configuration.setScopeContainer(scopeContainer);
+ configuration.setWireService(createWireService());
+ GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null);
+ ObjectFactory<?> factory = createMock(ObjectFactory.class);
+ expect((String) factory.getInstance()).andReturn("bar");
+ replay(factory);
+ component.addPropertyFactory("property", factory);
+ Greeting greeting = (Greeting) component.getServiceInstance();
+ assertEquals("bar", greeting.greet("foo"));
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader());
+ implClass = cl.parseClass(SCRIPT);
+ scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return ((AtomicComponent) getCurrentArguments()[0]).createInstance();
+ }
+ });
+ replay(scopeContainer);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java
new file mode 100644
index 0000000000..f0ae7deb33
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+import junit.framework.TestCase;
+import org.apache.tuscany.container.groovy.mock.Greeting;
+import static org.apache.tuscany.test.ArtifactFactory.createWireService;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import org.easymock.IAnswer;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class ScriptInvokeTestCase extends TestCase {
+
+ private static final String SCRIPT = "def greet(name) { return name }";
+
+ private Class<? extends GroovyObject> implClass;
+ private ScopeContainer scopeContainer;
+
+ /**
+ * Tests the invocation of a Groovy "script" as opposed to a class
+ */
+ public void testBasicScriptInvocation() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Greeting.class);
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName("source");
+ configuration.setGroovyClass(implClass);
+ configuration.setServices(services);
+ configuration.setScopeContainer(scopeContainer);
+ configuration.setWireService(createWireService());
+ GroovyAtomicComponent context = new GroovyAtomicComponent(configuration, null);
+ GroovyObject object = (GroovyObject) context.getServiceInstance();
+ assertEquals("foo", object.invokeMethod("greet", "foo"));
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader());
+ implClass = cl.parseClass(SCRIPT);
+ scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return ((AtomicComponent) getCurrentArguments()[0]).createInstance();
+ }
+ });
+ replay(scopeContainer);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java
new file mode 100644
index 0000000000..79f37f514c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+import junit.framework.TestCase;
+import org.apache.tuscany.container.groovy.mock.Greeting;
+import static org.apache.tuscany.test.ArtifactFactory.createInboundWire;
+import static org.apache.tuscany.test.ArtifactFactory.createOutboundWire;
+import static org.apache.tuscany.test.ArtifactFactory.createWireService;
+import static org.apache.tuscany.test.ArtifactFactory.terminateWire;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reportMatcher;
+import static org.easymock.EasyMock.verify;
+import org.easymock.IAnswer;
+import org.easymock.IArgumentMatcher;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class WireTestCase extends TestCase {
+
+ private static final String SCRIPT = "import org.apache.tuscany.container.groovy.mock.Greeting;"
+ + "class Foo implements Greeting{"
+ + " Greeting wire;"
+ + " "
+ + " void setWire(Greeting ref){"
+ + " wire = ref;"
+ + " };"
+ + " "
+ + " String greet(String name){"
+ + " return wire.greet(name); "
+ + " };"
+ + "}";
+
+ private static final String SCRIPT2 = "import org.apache.tuscany.container.groovy.mock.Greeting;"
+ + "class Foo implements Greeting{"
+ + " public String greet(String name){"
+ + " return name; "
+ + " }"
+ + "}";
+
+ private Class<? extends GroovyObject> implClass1;
+ private Class<? extends GroovyObject> implClass2;
+ private ScopeContainer scopeContainer;
+
+ /**
+ * Tests a basic invocation down a source wire
+ */
+ public void testReferenceWireInvocation() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Greeting.class);
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName("source");
+ configuration.setGroovyClass(implClass1);
+ configuration.setServices(services);
+ configuration.setScopeContainer(scopeContainer);
+ configuration.setWireService(createWireService());
+ GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null);
+ OutboundWire wire = createOutboundWire("wire", Greeting.class);
+ terminateWire(wire);
+
+ TargetInvoker invoker = createMock(TargetInvoker.class);
+ expect(invoker.isCacheable()).andReturn(false);
+ Message response = new MessageImpl();
+ response.setBody("foo");
+ expect(invoker.invoke(eqMessage())).andReturn(response);
+ replay(invoker);
+
+ for (OutboundInvocationChain chain : wire.getInvocationChains().values()) {
+ chain.setTargetInvoker(invoker);
+ }
+ component.addOutboundWire(wire);
+ Greeting greeting = (Greeting) component.getServiceInstance();
+ assertEquals("foo", greeting.greet("foo"));
+ verify(invoker);
+ }
+
+ // todo this could be generalized and moved to test module
+ public static Message eqMessage() {
+ reportMatcher(new IArgumentMatcher() {
+ public boolean matches(Object object) {
+ if (!(object instanceof Message)) {
+ return false;
+ }
+ final Message msg = (Message) object;
+ Object[] body = (Object[]) msg.getBody();
+ return "foo".equals(body[0]);
+ }
+
+ public void appendTo(StringBuffer stringBuffer) {
+ }
+ });
+ return null;
+ }
+
+
+ /**
+ * Tests a basic invocation to a target
+ */
+ public void testTargetInvocation() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Greeting.class);
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName("source");
+ configuration.setGroovyClass(implClass2);
+ configuration.setServices(services);
+ configuration.setScopeContainer(scopeContainer);
+ configuration.setWireService(createWireService());
+ GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null);
+ Operation<Type> operation = new Operation<Type>("greet", null, null, null, false, null);
+ TargetInvoker invoker = component.createTargetInvoker(null, operation);
+ assertEquals("foo", invoker.invokeTarget(new String[]{"foo"}));
+ }
+
+
+ /**
+ * Tests a basic invocation down a target wire
+ */
+ public void testTargetWireInvocation() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Greeting.class);
+ GroovyConfiguration configuration = new GroovyConfiguration();
+ configuration.setName("source");
+ configuration.setGroovyClass(implClass2);
+ configuration.setServices(services);
+ configuration.setScopeContainer(scopeContainer);
+ configuration.setWireService(createWireService());
+ GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null);
+ InboundWire wire = createInboundWire("Greeting", Greeting.class);
+ terminateWire(wire);
+ for (InboundInvocationChain chain : wire.getInvocationChains().values()) {
+ chain.setTargetInvoker(component.createTargetInvoker(null, chain.getOperation()));
+ }
+ component.addInboundWire(wire);
+ Greeting greeting = (Greeting) component.getServiceInstance("Greeting");
+ assertEquals("foo", greeting.greet("foo"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader());
+ implClass1 = cl.parseClass(SCRIPT);
+ implClass2 = cl.parseClass(SCRIPT2);
+ scopeContainer = createMock(ScopeContainer.class);
+ expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return ((AtomicComponent) getCurrentArguments()[0]).createInstance();
+ }
+ });
+ replay(scopeContainer);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java
new file mode 100644
index 0000000000..8918c3dfd5
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy.mock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AsyncTarget {
+
+ void invoke();
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java
new file mode 100644
index 0000000000..b975491f16
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.groovy.mock;
+
+public interface Greeting {
+
+ String setWire(Greeting ref);
+ String greet(String name);
+}
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl
new file mode 100644
index 0000000000..2a04ae7a6c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ -->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:groovy="http://incubator.apache.org/tuscany/xmlns/container/groovy/1.0-incubator-M2"
+ name="groovy.test">
+
+ <component name="Greeting">
+ <groovy:implementation.groovy script="Foo.groovy"/>
+ </component>
+
+</composite>
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy
new file mode 100644
index 0000000000..f0b0a3a9d4
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy
@@ -0,0 +1 @@
+Test Script \ No newline at end of file