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 --- .../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 +++++++++++++++++++ 8 files changed, 654 insertions(+) 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 (limited to 'sandbox/ant/container.python/src/main/java/org/apache') 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; + } +} -- cgit v1.2.3