From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- sandbox/ant/container.python/NOTICE.txt | 14 +++ sandbox/ant/container.python/pom.xml | 78 +++++++++++++ .../tuscany/container/python/PythonComponent.java | 113 +++++++++++++++++++ .../container/python/PythonComponentBuilder.java | 74 +++++++++++++ .../container/python/PythonComponentType.java | 61 ++++++++++ .../python/PythonComponentTypeLoader.java | 76 +++++++++++++ .../container/python/PythonImplementation.java | 37 +++++++ .../python/PythonImplementationLoader.java | 123 +++++++++++++++++++++ .../tuscany/container/python/PythonInvoker.java | 54 +++++++++ .../tuscany/container/python/PythonScript.java | 116 +++++++++++++++++++ .../src/main/resources/META-INF/sca/py.system.scdl | 40 +++++++ .../container/python/HelloWorldService.java | 25 +++++ .../python/PythonComponentBuilderTestCase.java | 23 ++++ .../container/python/PythonComponentTestCase.java | 94 ++++++++++++++++ .../python/PythonComponentTypeLoaderTestCase.java | 87 +++++++++++++++ .../python/PythonComponentTypeTestCase.java | 36 ++++++ .../python/PythonImplementationLoaderTestCase.java | 110 ++++++++++++++++++ .../python/PythonImplementationTestCase.java | 33 ++++++ .../container/python/PythonInvokerTestCase.java | 62 +++++++++++ .../container/python/PythonScriptTestCase.java | 82 ++++++++++++++ .../python/function/HelloWorldTestCase.java | 46 ++++++++ .../container/python/PythonScriptTestCase.py | 6 + .../python/function/HelloWorld.componentType | 9 ++ .../container/python/function/helloworld.py | 6 + .../container/python/function/helloworld.scdl | 29 +++++ 25 files changed, 1434 insertions(+) create mode 100644 sandbox/ant/container.python/NOTICE.txt create mode 100644 sandbox/ant/container.python/pom.xml create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponent.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentBuilder.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentType.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentTypeLoader.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementation.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementationLoader.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonInvoker.java create mode 100644 sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonScript.java create mode 100644 sandbox/ant/container.python/src/main/resources/META-INF/sca/py.system.scdl create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/HelloWorldService.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentBuilderTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeLoaderTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationLoaderTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonInvokerTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonScriptTestCase.java create mode 100644 sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/function/HelloWorldTestCase.java create mode 100644 sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/PythonScriptTestCase.py create mode 100644 sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/HelloWorld.componentType create mode 100644 sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.py create mode 100644 sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.scdl (limited to 'sandbox/ant/container.python') diff --git a/sandbox/ant/container.python/NOTICE.txt b/sandbox/ant/container.python/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/sandbox/ant/container.python/NOTICE.txt @@ -0,0 +1,14 @@ +${pom.name} +Copyright (c) 2005 - 2006 The Apache Software Foundation + +Apache Tuscany is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is +required of all newly accepted projects until a further review indicates that +the infrastructure, communications, and decision making process have stabilized +in a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the ASF. + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/sandbox/ant/container.python/pom.xml b/sandbox/ant/container.python/pom.xml new file mode 100644 index 0000000000..1b31cab18b --- /dev/null +++ b/sandbox/ant/container.python/pom.xml @@ -0,0 +1,78 @@ + + + + + + org.apache.tuscany.containers + containers + 1.0-SNAPSHOT + + + 4.0.0 + tuscany-python + Apache Tuscany Python Container + Apache Tuscany Python Container + + + + ant + http://people.apache.org/~antelder/maven2 + + true + + + + + + + + org.apache.tuscany + core + ${sca.version} + compile + + + + jython + jython + 2.2a1 + compile + + + + org.apache.tuscany + test + ${sca.version} + test + + + + org.easymock + easymock + + + + org.easymock + easymockclassextension + + + + + diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponent.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponent.java new file mode 100644 index 0000000000..4376c48b82 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponent.java @@ -0,0 +1,113 @@ +/* + * 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.python; + +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.AtomicComponentExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireService; + +/** + * A component implementation for the Python language. + */ +public class PythonComponent extends AtomicComponentExtension { + + private final List> services; + + private final Map properties; + + private PythonScript rhinoScript; + + public PythonComponent(String name, PythonScript rhinoScript, List> services, CompositeComponent parent, ScopeContainer scopeContainer, + WireService wireService, WorkContext workContext) { + + super(name, parent, scopeContainer, wireService, workContext, null, 0); + + this.rhinoScript = rhinoScript; + this.services = services; + this.scope = scopeContainer.getScope(); + this.properties = new HashMap(); + } + + public Object createInstance() throws ObjectCreationException { + + Map context = new HashMap(getProperties()); + + for (List referenceWires : getOutboundWires().values()) { + for (OutboundWire wire : referenceWires) { + Object wireProxy = wireService.createProxy(wire); + context.put(wire.getReferenceName(), wireProxy); + } + } + + Object instance = rhinoScript.createInstance(context); + + return instance; + } + + public TargetInvoker createTargetInvoker(String serviceName, Operation operation) { + Method[] methods = operation.getServiceContract().getInterfaceClass().getMethods(); + Method method = findMethod(operation, methods); + return new PythonInvoker(method, this); + } + + // TODO: move all the following up to AtomicComponentExtension? + + public List> getServiceInterfaces() { + return services; + } + + public Map getProperties() { + return properties; + } + + public Object getTargetInstance() throws TargetException { + return scopeContainer.getInstance(this); + } + + public Object getServiceInstance() throws TargetException { + return getServiceInstance(null); + } + + @SuppressWarnings("unchecked") + public Object getServiceInstance(String service) throws TargetException { + InboundWire wire = getInboundWire(service); + if (wire == null) { + TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message + e.setIdentifier(service); + throw e; + } + return wireService.createProxy(wire); + } + +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentBuilder.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentBuilder.java new file mode 100644 index 0000000000..d460f77bc6 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentBuilder.java @@ -0,0 +1,74 @@ +/* + * 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.python; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Extension point for creating {@link PythonComponent}s from an assembly configuration + */ +public class PythonComponentBuilder extends ComponentBuilderExtension { + + public PythonComponentBuilder() { + } + + protected Class getImplementationType() { + return PythonImplementation.class; + } + + @SuppressWarnings("unchecked") + public Component build(CompositeComponent parent, ComponentDefinition componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException { + + String name = componentDefinition.getName(); + PythonImplementation implementation = componentDefinition.getImplementation(); + PythonComponentType componentType = implementation.getComponentType(); + + // get list of services provided by this component + Collection collection = componentType.getServices().values(); + List> services = new ArrayList>(collection.size()); + for (ServiceDefinition serviceDefinition : collection) { + services.add(serviceDefinition.getServiceContract().getInterfaceClass()); + } + + // TODO: have ComponentBuilderExtension pass ScopeContainer in on build method? + ScopeContainer scopeContainer; + Scope scope = componentType.getLifecycleScope(); + if (Scope.MODULE == scope) { + scopeContainer = deploymentContext.getModuleScope(); + } else { + scopeContainer = scopeRegistry.getScopeContainer(scope); + } + + return new PythonComponent(name, implementation.getJythonScript(), services, parent, scopeContainer, wireService, workContext); + } + +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentType.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentType.java new file mode 100644 index 0000000000..640ff297c5 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentType.java @@ -0,0 +1,61 @@ +/* + * 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.python; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * A componentType for Python components + * TODO: really need a generic componentType that supports scope and lifecycle + */ +public class PythonComponentType extends ComponentType> { + + private Scope lifecycleScope = Scope.MODULE; + + public PythonComponentType() { + } + + @SuppressWarnings("unchecked") + public PythonComponentType(ComponentType ct) { + // TODO: A bit hacky but this is so the non-python .componentType XML side file can be used for now + setInitLevel(ct.getInitLevel()); + for (Object property : ct.getProperties().values()) { + add((Property) property); + } + for (Object reference : ct.getReferences().values()) { + add((ReferenceDefinition) reference); + } + for (Object service : ct.getServices().values()) { + add((ServiceDefinition) service); + } + } + + public Scope getLifecycleScope() { + return lifecycleScope; + } + + public void setLifecycleScope(Scope lifecycleScope) { + this.lifecycleScope = lifecycleScope; + } + +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentTypeLoader.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentTypeLoader.java new file mode 100644 index 0000000000..1f1456594e --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonComponentTypeLoader.java @@ -0,0 +1,76 @@ +/* + * 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.python; + +import java.net.URL; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.ComponentType; + +/** + * ComponentType loader for Python components + */ +public class PythonComponentTypeLoader extends ComponentTypeLoaderExtension { + + public PythonComponentTypeLoader() { + } + + @Override + protected Class getImplementationClass() { + return PythonImplementation.class; + } + + protected String getResourceName(PythonImplementation implementation) { + return implementation.getJythonScript().getModuleName(); + } + + // TODO: must be possible to move all the following up in to ComponentTypeLoaderExtension + + public void load(CompositeComponent parent, PythonImplementation implementation, DeploymentContext deploymentContext) throws LoaderException { + String sideFile = getSideFileName(implementation); + URL resource = implementation.getJythonScript().getClassLoader().getResource(sideFile); + PythonComponentType componentType; + if (resource == null) { + throw new IllegalArgumentException("missing .componentType side file: " + sideFile); + // TODO: or else implement intospection + } else { + componentType = loadFromSidefile(resource, deploymentContext); + } + implementation.setComponentType(componentType); + } + + protected PythonComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException { + ComponentType ct = loaderRegistry.load(null, url, ComponentType.class, deploymentContext); + PythonComponentType pythonComponentType = new PythonComponentType(ct); + return pythonComponentType; + } + + protected String getSideFileName(PythonImplementation implementation) { + String baseName = getResourceName(implementation); + int lastDot = baseName.lastIndexOf('.'); + if (lastDot != -1) { + baseName = baseName.substring(0, lastDot); + } + return baseName + ".componentType"; + } + +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementation.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementation.java new file mode 100644 index 0000000000..df35801e88 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementation.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.python; + +import org.apache.tuscany.spi.model.AtomicImplementation; + +/** + * Model object for a Python implementation. + */ +public class PythonImplementation extends AtomicImplementation { + + private PythonScript pythonScript; + + public PythonScript getJythonScript() { + return pythonScript; + } + + public void setPythonScript(PythonScript pythonScript) { + this.pythonScript = pythonScript; + } +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementationLoader.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementationLoader.java new file mode 100644 index 0000000000..61a6cbd4b6 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonImplementationLoader.java @@ -0,0 +1,123 @@ +/* + * 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.python; + +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; +import org.osoa.sca.annotations.Constructor; + +/** + * Loader for handling python elements. + * + * + * + */ +public class PythonImplementationLoader extends LoaderExtension { + + private static final QName IMPLEMENTATION_PYTHON = new QName("http://tuscany.apache.org/xmlns/python/1.0", "implementation.python"); + + @Constructor( { "registry" }) + public PythonImplementationLoader(@Autowire LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return IMPLEMENTATION_PYTHON; + } + + public PythonImplementation load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + String moduleName = reader.getAttributeValue(null, "module"); + if (moduleName == null) { + throw new MissingResourceException("implementation element has no module attribute"); + } + + String className = reader.getAttributeValue(null, "class"); + + LoaderUtil.skipToEndElement(reader); + + PythonImplementation implementation = new PythonImplementation(); + + ClassLoader cl = deploymentContext.getClassLoader(); + String pythonSource = loadSource(cl, moduleName); + + PythonScript pythonScript = new PythonScript(moduleName, className, pythonSource, cl); + implementation.setPythonScript(pythonScript); + + registry.loadComponentType(parent, implementation, deploymentContext); + + Class iface = implementation.getComponentType().getServices().values().iterator().next().getServiceContract().getInterfaceClass(); + // TODO: service interfaces should be on PythonScript constructor but loadComponentType requires the script name to work out the sidefile name + pythonScript.setServiceInterface(iface); + + 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/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonInvoker.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonInvoker.java new file mode 100644 index 0000000000..62f7a6c847 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonInvoker.java @@ -0,0 +1,54 @@ +/* + * 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.python; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.extension.TargetInvokerExtension; + +/** + * Dispatches to a PythonScript implementation instance + * + * @version $$Rev$$ $$Date$$ + */ +public class PythonInvoker extends TargetInvokerExtension { + + private PythonComponent context; + + private Method method; + + public PythonInvoker(Method method, PythonComponent context) { + this.method = method; + this.context = context; + } + + /** + * Invokes a function on a script instance + */ + public Object invokeTarget(final Object payload) throws InvocationTargetException { + Object target = context.getTargetInstance(); + try { + return method.invoke(target, (Object[]) payload); + } catch (Exception e) { + throw new InvocationTargetException(e); + } + } + +} diff --git a/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonScript.java b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonScript.java new file mode 100644 index 0000000000..1eab532582 --- /dev/null +++ b/sandbox/ant/container.python/src/main/java/org/apache/tuscany/container/python/PythonScript.java @@ -0,0 +1,116 @@ +/* + * 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.python; + +import java.util.Map; + +import org.python.core.Py; +import org.python.core.PyObject; +import org.python.core.PySystemState; +import org.python.util.PythonInterpreter; + +/** + * JythonScript represents a compiled Jython script + */ +public class PythonScript { + + protected String moduleName; + + protected String className; + + protected String script; + + protected Class iface; + + protected ClassLoader classLoader; + + private PyObject pythonClass; + + /** + * Create a new RhinoInvoker. + * + * @param scriptName + * the name of the script. Can be anything, only used in messages to identify the script + * @param script + * the complete script + * @param context + * name-value pairs that are added in to the scope where the script is compiled. May be null. The value objects are made available to + * the script by using a variable with the name. + * @param classLoader + * the ClassLoader Rhino should use to locate any user Java classes used in the script + */ + public PythonScript(String moduleName, String className, String script, ClassLoader classLoader) { + this.moduleName = moduleName; + this.className = className; + this.script = script; + this.classLoader = classLoader; + + } + + private void initScript(String moduleName, String className, String script) { + PythonInterpreter interpreter = new PythonInterpreter(); + PySystemState sys = Py.getSystemState(); + PySystemState.add_package(iface.getPackage().getName(), null); + sys.setClassLoader(classLoader); + interpreter.exec(script); + + pythonClass = interpreter.get(className); + if (pythonClass == null) { + throw new RuntimeException("No callable (class or function) " + "named " + className + " in " + moduleName); + } + } + + /** + * Create a new invokeable instance of the script + * + * @param context + * objects to add to scope of the script instance + * @return a RhinoScriptInstance + */ + public Object createInstance(Map context) { + initScript(moduleName, className, script); + + PyObject instance = pythonClass.__call__(); + Object o = instance.__tojava__(iface); + if (o == Py.NoConversion) { + throw new RuntimeException("The value from " + className + " must extend " + iface.getName()); + } + return o; + } + + public String getModuleName() { + return moduleName; + } + + public String getClassName() { + return className; + } + + public String getScript() { + return script; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public void setServiceInterface(Class iface) { + this.iface = iface; + } +} diff --git a/sandbox/ant/container.python/src/main/resources/META-INF/sca/py.system.scdl b/sandbox/ant/container.python/src/main/resources/META-INF/sca/py.system.scdl new file mode 100644 index 0000000000..e124d8677d --- /dev/null +++ b/sandbox/ant/container.python/src/main/resources/META-INF/sca/py.system.scdl @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/HelloWorldService.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/HelloWorldService.java new file mode 100644 index 0000000000..50ba1c3695 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/HelloWorldService.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.python; + +public interface HelloWorldService { + + String sayHello(String s); + +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentBuilderTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentBuilderTestCase.java new file mode 100644 index 0000000000..86e77920dc --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentBuilderTestCase.java @@ -0,0 +1,23 @@ +package org.apache.tuscany.container.python; + +import junit.framework.TestCase; + +public class PythonComponentBuilderTestCase extends TestCase { + + public void testGetImplementationType() { + PythonComponentBuilder builder = new PythonComponentBuilder(); + assertEquals(PythonImplementation.class, builder.getImplementationType()); + } + + public void testBuild() { +// PythonComponentBuilder builder = new PythonComponentBuilder(); +// CompositeComponent parent = createMock(CompositeComponent.class); +// Component component = builder.build(parent, componentDefinition, deploymentContext); +// assertNotNull(component); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTestCase.java new file mode 100644 index 0000000000..3a1f6081ba --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTestCase.java @@ -0,0 +1,94 @@ +package org.apache.tuscany.container.python; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.easymock.IAnswer; + +public class PythonComponentTestCase extends TestCase { + + private ScopeContainer scopeContainer; + + @SuppressWarnings("unchecked") + public void testCreateTargetInvoker() { + PythonComponent pc = new PythonComponent(null,null,null, null, scopeContainer, null, null); + + Operation operation = new Operation("hashCode", null,null,null,false,null); + ServiceContract contract = new ServiceContract(List.class){}; + operation.setServiceContract(contract); + TargetInvoker invoker = pc.createTargetInvoker("hashCode", operation); + + assertNotNull(invoker); + } + + @SuppressWarnings("unchecked") + public void testCreateInstance() throws IOException { + PythonComponent pc = new PythonComponent(null,createPythonScript(),null, null, scopeContainer, null, null); + Object o = pc.createInstance(); + assertNotNull(o); + } + + @SuppressWarnings("unchecked") + public void testGetServiceInstance() { + PythonComponent pc = new PythonComponent(null,null,null, null, scopeContainer, null, null); + try { + pc.getServiceInstance(); + fail(); + } catch (TargetException e) { + // expected + } + } + + @SuppressWarnings("unchecked") + public void testGetproperties() { + PythonComponent pc = new PythonComponent(null,null,null, null, scopeContainer, null, null); + assertNotNull(pc.getProperties()); + } + + @SuppressWarnings("unchecked") + public void testGetServiceInterfaces() { + List services = new ArrayList(); + PythonComponent pc = new PythonComponent(null,null,services, null, scopeContainer, null,null); + assertEquals(services, pc.getServiceInterfaces()); + } + + @Override + @SuppressWarnings("unchecked") + protected void setUp() { + this.scopeContainer = createMock(ScopeContainer.class); + expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return Scope.MODULE; + } + }); + } + + public PythonScript createPythonScript() throws IOException { + URL scriptURL = getClass().getResource("PythonScriptTestCase.py"); + InputStream is = scriptURL.openStream(); + StringBuilder sb = new StringBuilder(); + int i = 0; + while ((i = is.read()) != -1) { + sb.append((char) i); + } + is.close(); + String script = sb.toString(); + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + pythonScript.setServiceInterface(HelloWorldService.class); + return pythonScript; + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeLoaderTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeLoaderTestCase.java new file mode 100644 index 0000000000..73a6e9b849 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeLoaderTestCase.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.python; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.xml.stream.XMLStreamException; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.loader.LoaderException; + +/** + * + */ +public class PythonComponentTypeLoaderTestCase extends TestCase { + + private String script; + + public void testGetSideFileName() { + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + PythonComponentTypeLoader loader = new PythonComponentTypeLoader(); + PythonImplementation implementation = new PythonImplementation(); + implementation.setPythonScript(pythonScript); + assertEquals("PythonScriptTestCase.componentType", loader.getSideFileName(implementation)); + } + + public void testLoadFromSideFile() throws MalformedURLException, LoaderException, XMLStreamException { +// PythonComponentTypeLoader loader = new PythonComponentTypeLoader(); +// LoaderRegistry loaderRegistry = createMock(LoaderRegistry.class); +// expect(loaderRegistry.load(isA(CompositeComponent.class),isA(URL.class),isA(Class.class),isA(DeploymentContext.class))).andStubAnswer(new IAnswer() { +// public Object answer() throws Throwable { +// return new ComponentType(); +// } +// }); +// loader.setLoaderRegistry(loaderRegistry); +// +// URL url = new URL("http://foo"); +// DeploymentContext deploymentContext = createMock(DeploymentContext.class); +// loader.loadFromSidefile(url, deploymentContext); + } + + public void testGetImplementationClass() { + PythonComponentTypeLoader loader = new PythonComponentTypeLoader(); + assertEquals(PythonImplementation.class, loader.getImplementationClass()); + } + + public void testGetResourceName() { + PythonComponentTypeLoader loader = new PythonComponentTypeLoader(); + PythonImplementation implementation = new PythonImplementation(); + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + implementation.setPythonScript(pythonScript); + assertEquals("PythonScriptTestCase", loader.getResourceName(implementation)); + } + + @Override + public void setUp() throws IOException { + URL scriptURL = getClass().getResource("PythonScriptTestCase.py"); + InputStream is = scriptURL.openStream(); + StringBuilder sb = new StringBuilder(); + int i = 0; + while ((i = is.read()) != -1) { + sb.append((char) i); + } + is.close(); + script = sb.toString(); + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeTestCase.java new file mode 100644 index 0000000000..3ae4b73e60 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonComponentTypeTestCase.java @@ -0,0 +1,36 @@ +package org.apache.tuscany.container.python; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +public class PythonComponentTypeTestCase extends TestCase { + + public void testLifecycleScope() { + PythonComponentType ct = new PythonComponentType(); + assertEquals(Scope.MODULE, ct.getLifecycleScope()); + ct.setLifecycleScope(Scope.COMPOSITE); + assertEquals(Scope.COMPOSITE, ct.getLifecycleScope()); + } + + @SuppressWarnings("unchecked") + public void testComponentTypeConstructor() { + ComponentType ct = new ComponentType(); + Property property = new Property(); + ct.add(property); + ReferenceDefinition reference = new ReferenceDefinition(); + ct.add(reference); + ServiceDefinition service = new ServiceDefinition(); + ct.add(service); + + PythonComponentType pct = new PythonComponentType(ct); + + assertEquals(property, pct.getProperties().values().iterator().next()); + assertEquals(reference, pct.getReferences().values().iterator().next()); + assertEquals(service, pct.getServices().values().iterator().next()); + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationLoaderTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationLoaderTestCase.java new file mode 100644 index 0000000000..f84d217334 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationLoaderTestCase.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.python; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; + +/** + * + */ +public class PythonImplementationLoaderTestCase extends TestCase { + private CompositeComponent parent; + + private XMLStreamReader reader; + + private DeploymentContext deploymentContext; + + private ClassLoader classLoader; + + private LoaderRegistry registry; + + private PythonImplementationLoader loader; + + public void testNoModuleAttribute() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "module")).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, "module")).andReturn("foo.py"); + expect(reader.getAttributeValue(null, "class")).andReturn(null); + expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + PythonImplementationLoader mockLoader = new PythonImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.py", resource); + throw new MissingResourceException(resource); + } + }; + try { + mockLoader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + assertEquals("foo.py", e.getMessage()); + } + verify(reader); + verify(deploymentContext); + } + + public void testLoadScript() throws LoaderException { + String script = loader.loadSource(getClass().getClassLoader(), "org/apache/tuscany/container/python/PythonScriptTestCase.py"); + assertTrue(script.startsWith("from org.apache.tuscany.container.python")); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + loader = new PythonImplementationLoader(registry); + + parent = createMock(CompositeComponent.class); + reader = createMock(XMLStreamReader.class); + deploymentContext = createMock(DeploymentContext.class); + classLoader = createMock(ClassLoader.class); + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationTestCase.java new file mode 100644 index 0000000000..a2af619795 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonImplementationTestCase.java @@ -0,0 +1,33 @@ +package org.apache.tuscany.container.python; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import junit.framework.TestCase; + +public class PythonImplementationTestCase extends TestCase { + + private PythonScript pythonScript; + + public void testGetPythonScript() { + PythonImplementation impl = new PythonImplementation(); + impl.setPythonScript(pythonScript); + assertEquals(pythonScript, impl.getJythonScript()); + } + + public void setUp() throws IOException { + URL scriptURL = getClass().getResource("PythonScriptTestCase.py"); + assert scriptURL != null; + InputStream is = scriptURL.openStream(); + StringBuilder sb = new StringBuilder(); + int i = 0; + while ((i = is.read()) != -1) { + sb.append((char) i); + } + is.close(); + String script = sb.toString(); + pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + } + +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonInvokerTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonInvokerTestCase.java new file mode 100644 index 0000000000..03a9151a47 --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonInvokerTestCase.java @@ -0,0 +1,62 @@ +package org.apache.tuscany.container.python; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.model.Scope; +import org.easymock.IAnswer; + +public class PythonInvokerTestCase extends TestCase { + + private PythonComponent context; + + private Method method; + + private ScopeContainer scopeContainer; + + public void testInvokeTarget() throws InvocationTargetException { + PythonInvoker invoker = new PythonInvoker(method, context); + Object o = invoker.invokeTarget(new Object[] { "petra" }); + assertEquals("hello petra", o); + } + + public void testInvokeTargetException() throws InvocationTargetException, SecurityException, NoSuchMethodException { + PythonInvoker invoker = new PythonInvoker(method, context); + try { + invoker.invokeTarget(null); + fail(); + } catch (InvocationTargetException e) { + // expected + } + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + + scopeContainer = createMock(ScopeContainer.class); + expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return "hello "; + } + }); + expect(scopeContainer.getScope()).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return Scope.MODULE; + } + }); + replay(scopeContainer); + + context = new PythonComponent(null, null, null, null, scopeContainer, null, null); + method = String.class.getDeclaredMethod("concat", new Class[] { String.class }); + } +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonScriptTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonScriptTestCase.java new file mode 100644 index 0000000000..560b623e9a --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/PythonScriptTestCase.java @@ -0,0 +1,82 @@ +/* + * 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.python; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import junit.framework.TestCase; + +public class PythonScriptTestCase extends TestCase { + + protected String script; + + public void testCreateInstance() { + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + pythonScript.setServiceInterface(HelloWorldService.class); + HelloWorldService helloworld = (HelloWorldService) pythonScript.createInstance(null); + + assertEquals("Hello petra", helloworld.sayHello("petra")); + } + + public void testCreateInstanceBadIface() { + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + pythonScript.setServiceInterface(String.class); + try { + pythonScript.createInstance(null); + fail(); + } catch (RuntimeException e) { + // expected + } + } + + public void testCreateInstanceBadClassName() { + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "badClass", script, null); + pythonScript.setServiceInterface(String.class); + try { + pythonScript.createInstance(null); + assertTrue("expecting bad class exception", false); + } catch (RuntimeException e) { + // expected + } + } + + public void testGetters() { + PythonScript pythonScript = new PythonScript("PythonScriptTestCase", "hello", script, null); + assertEquals(null, pythonScript.getClassLoader()); + assertEquals("hello", pythonScript.getClassName()); + assertEquals(script, pythonScript.getScript()); + } + + @Override + public void setUp() throws IOException { + URL scriptURL = getClass().getResource("PythonScriptTestCase.py"); + InputStream is = scriptURL.openStream(); + StringBuilder sb = new StringBuilder(); + int i = 0; + while ((i = is.read()) != -1) { + sb.append((char) i); + } + is.close(); + script = sb.toString(); + + } + +} diff --git a/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/function/HelloWorldTestCase.java b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/function/HelloWorldTestCase.java new file mode 100644 index 0000000000..38f15adafd --- /dev/null +++ b/sandbox/ant/container.python/src/test/java/org/apache/tuscany/container/python/function/HelloWorldTestCase.java @@ -0,0 +1,46 @@ +/* + * 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.python.function; + + +import org.apache.tuscany.container.python.HelloWorldService; +import org.apache.tuscany.test.SCATestCase; +import org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +/** + * This shows how to test the HelloWorld service component. + */ +public class HelloWorldTestCase extends SCATestCase { + + private HelloWorldService helloWorldService; + + protected void setUp() throws Exception { + addExtension("PythonContainer", getClass().getClassLoader().getResource("META-INF/sca/py.system.scdl")); + setApplicationSCDL("org/apache/tuscany/container/python/function/helloworld.scdl"); + super.setUp(); + + CompositeContext context = CurrentCompositeContext.getContext(); + helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldComponent"); + } + + public void testHelloWorld() throws Exception { + assertEquals(helloWorldService.sayHello("petra"), "Hello petra"); + } +} diff --git a/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/PythonScriptTestCase.py b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/PythonScriptTestCase.py new file mode 100644 index 0000000000..5ce69aca61 --- /dev/null +++ b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/PythonScriptTestCase.py @@ -0,0 +1,6 @@ +from org.apache.tuscany.container.python import HelloWorldService + +class hello(HelloWorldService): + + def sayHello(self, val1): + return "Hello " + val1 diff --git a/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/HelloWorld.componentType b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/HelloWorld.componentType new file mode 100644 index 0000000000..432c9badc0 --- /dev/null +++ b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/HelloWorld.componentType @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.py b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.py new file mode 100644 index 0000000000..5ce69aca61 --- /dev/null +++ b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.py @@ -0,0 +1,6 @@ +from org.apache.tuscany.container.python import HelloWorldService + +class hello(HelloWorldService): + + def sayHello(self, val1): + return "Hello " + val1 diff --git a/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.scdl b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.scdl new file mode 100644 index 0000000000..97461b3ae3 --- /dev/null +++ b/sandbox/ant/container.python/src/test/resources/org/apache/tuscany/container/python/function/helloworld.scdl @@ -0,0 +1,29 @@ + + + + + + + + + -- cgit v1.2.3