diff options
Diffstat (limited to 'sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation')
8 files changed, 699 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java new file mode 100644 index 0000000000..b97c02d216 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java @@ -0,0 +1,41 @@ +/* + * 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.sca.implementation.spring.invocation; + +/** + * This is the Tuscany side tie for the corresponding Spring runtime side stub class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the ComponentStub class + * in the implementation-spring-runtime module for what the stub does. + */ +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class ComponentTie { + + private RuntimeComponent component; + + public ComponentTie(RuntimeComponent component) { + this.component = component; + } + + public Object getService(Class<?> type, String name) { + return component.getComponentContext().getService(type, name); + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java new file mode 100644 index 0000000000..89d14961ac --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java @@ -0,0 +1,53 @@ +/* + * 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.sca.implementation.spring.invocation; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side tie for the corresponding Spring runtime side stub class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the PropertyValueStub class + * in the implementation-spring-runtime module for what the stub does. + */ +public class PropertyValueTie { + + private RuntimeComponent component; + private JavaPropertyValueObjectFactory propertyFactory; + + public PropertyValueTie(RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { + this.component = component; + this.propertyFactory = propertyFactory; + } + + public Object getPropertyObj(Class<?> type, String name) { + List<ComponentProperty> props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + return propertyFactory.createValueFactory(prop, prop.getValue(), type).getInstance(); + } + } + return null; // property name not found + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java new file mode 100644 index 0000000000..dcb9a53a33 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java @@ -0,0 +1,134 @@ +/* + * 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.sca.implementation.spring.invocation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side stub for the corresponding runtime tie class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the SpringContextTie class + * in the implementation-spring-runtime module for what the tie does. + */ +public class SpringContextStub { + + private Object tie; + private Method startMethod; + private Method closeMethod; + private Method getBeanMethod; + + public SpringContextStub(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + + initTie(component, implementation, propertyValueObjectFactory); + + } + + private void initTie(RuntimeComponent component, + SpringImplementation implementation, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + + // TODO: what class loader to use? + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + try { + + Class<?> stubClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringImplementationStub", true, cl); + Constructor<?> stubConstructor = stubClass.getConstructor(new Class<?>[]{Object.class}); + Object stub = stubConstructor.newInstance(new SpringImplementationTie(implementation, component, propertyValueObjectFactory)); + + Class<?> tieClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringContextTie", true, cl); + Constructor<?> tieConstructor = tieClass.getConstructor(new Class<?>[]{stubClass, List.class}); + this.tie = tieConstructor.newInstance(stub, implementation.getResource()); + + this.startMethod = tieClass.getMethod("start"); + this.closeMethod = tieClass.getMethod("close"); + this.getBeanMethod = tieClass.getMethod("getBean", String.class); + + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public void start() { + try { + startMethod.invoke(tie); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public void close() { + try { + closeMethod.invoke(tie); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public Object getBean(String id) throws SpringInvocationException { + try { + + return getBeanMethod.invoke(tie, id); + + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + +}
\ No newline at end of file diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java new file mode 100644 index 0000000000..0ecd00d5a8 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java @@ -0,0 +1,85 @@ +/* + * 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.sca.implementation.spring.invocation; + +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * A provider class for runtime Spring implementation instances + * @version $Rev$ $Date$ + */ +public class SpringImplementationProvider implements ImplementationProvider { + private RuntimeComponent component; + + // A Spring application context object + private SpringContextStub springContext; + + private SpringImplementation implementation; + + private JavaPropertyValueObjectFactory propertyValueObjectFactory; + + /** + * Constructor for the provider - takes a component definition and a Spring implementation + * description + * @param component - the component in the assembly + * @param implementation - the implementation + */ + public SpringImplementationProvider(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + super(); + this.implementation = implementation; + this.component = component; + this.propertyValueObjectFactory = propertyValueObjectFactory; + + springContext = new SpringContextStub(component, implementation, proxyService, propertyValueObjectFactory); + + } // end constructor + + public Invoker createInvoker(RuntimeComponentService service, Operation operation) { + return new SpringInvoker(component, springContext, service, operation); + } + + public boolean supportsOneWayInvocation() { + return false; + } + + /** + * Start this Spring implementation instance + */ + public void start() { + springContext.start(); + } + + /** + * Stop this implementation instance + */ + public void stop() { + springContext.close(); + } + +} // end class SpringImplementationProvider diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java new file mode 100644 index 0000000000..01b458d1f5 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java @@ -0,0 +1,75 @@ +/* + * 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.sca.implementation.spring.invocation; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.databinding.impl.MediatorImpl; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * ImplementationProviderFactory for Spring implementation type + * @version $Rev$ $Date$ + * + */ +public class SpringImplementationProviderFactory implements ImplementationProviderFactory<SpringImplementation> { + + private ProxyFactory proxyFactory; + private JavaPropertyValueObjectFactory propertyFactory; + + /** + * Simple constructor + * + */ + public SpringImplementationProviderFactory(ExtensionPointRegistry extensionPoints) { + super(); + + proxyFactory = ExtensibleProxyFactory.getInstance(extensionPoints); + + // TODO: could the runtime have a default PropertyValueObjectFactory? + propertyFactory = new JavaPropertyValueObjectFactory(new MediatorImpl(extensionPoints)); + } + + /** + * Returns a SpringImplementationProvider for a given component and Spring implementation + * @param component the component for which implementation instances are required + * @param implementation the Spring implementation with details of the component + * implementation + * @return the SpringImplementationProvider for the specified component + */ + public ImplementationProvider createImplementationProvider(RuntimeComponent component, + SpringImplementation implementation) { + return new SpringImplementationProvider(component, + implementation, + proxyFactory, + propertyFactory); + } + + /** + * Returns the class of the Spring implementation + */ + public Class<SpringImplementation> getModelType() { + return SpringImplementation.class; + } +} // end class SpringImplementationProviderFactory diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java new file mode 100644 index 0000000000..6caa5207e4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java @@ -0,0 +1,147 @@ +/* + * 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.sca.implementation.spring.invocation; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side tie for the corresponding runtime stub class. + * It enables the Sping code in the runtime module to invoke methods on a + * Tuscany SpringImplementation without the Spring runtime module + * needing to know about any Tuscany classes. See the SpringImplementationStub class + * in the implementation-spring-runtime module for what the stub does. + */ +public class SpringImplementationTie { + + private SpringImplementation implementation; + private RuntimeComponent component; + private JavaPropertyValueObjectFactory propertyFactory; + + public SpringImplementationTie(SpringImplementation implementation, RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { + this.implementation = implementation; + this.component = component; + this.propertyFactory = propertyFactory; + } + + public String getURI() { + throw new IllegalStateException("Not yet impl"); + } + + public String getComponentName() { + return component.getName(); + } + /** + * Method to create a Java Bean for a Property value + * @param <B> the class type of the Bean + * @param requiredType - a Class object for the required type + * @param name - the Property name + * @return - a Bean of the specified property, with value set + */ + private <B> B getPropertyBean(Class<?> requiredType, String name) { + B propertyObject = null; + // Get the component's list of properties + List<ComponentProperty> props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + // On finding the property, create a factory for it and create a Bean using + // the factory + ObjectFactory<?> factory = propertyFactory.createValueFactory(prop, prop.getValue(), requiredType); + propertyObject = (B)factory.getInstance(); + } // end if + } // end for + + return propertyObject; + } + + /** + * Creates a proxy Bean for a reference + * @param <B> the Business interface type for the reference + * @param businessInterface - the business interface as a Class + * @param referenceName - the name of the Reference + * @return an Bean of the type defined by <B> + */ + private <B> B getService(Class<B> businessInterface, String referenceName) { + return component.getComponentContext().getService(businessInterface, referenceName); + } + + /** + * Get a Bean for a reference or for a property. + * + * @param name - the name of the Bean required + * @param requiredType - the required type of the Bean (either a Java class or a Java interface) + * @return Object - a Bean which matches the requested bean + */ + public Object getBean(String name, Class<?> requiredType) { + // The expectation is that the requested Bean is either a reference or a property + // from the Spring context + for (Reference reference : implementation.getReferences()) { + if (reference.getName().equals(name)) { + // Extract the Java interface for the reference (it can't be any other interface type + // for a Spring application context) + if (requiredType == null) { + JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface(); + requiredType = javaInterface.getJavaClass(); + } + // Create and return the proxy for the reference + return getService(requiredType, reference.getName()); + } // end if + } // end for + + // For a property, get the name and the required Java type and create a Bean + // of that type with the value inserted. + for (Property property : implementation.getProperties()) { + if (property.getName().equals(name)) { + if (requiredType == null) { + // The following code only deals with a subset of types and was superceded + // by the information from the implementation (which uses Classes as found + // in the Spring implementation itself. + //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() ); + requiredType = implementation.getPropertyClass(name); + } + return getPropertyBean(requiredType, property.getName()); + } // end if + } // end for + // TODO: NoSuchBeanException + throw new RuntimeException("Unable to find Bean with name " + name); + + } // end method getBean( String, Class ) + + public Object getComponentTie() { + return new ComponentTie(component); + } + + public Object getPropertyValueTie() { + return new PropertyValueTie(component, propertyFactory); + } + + public ClassLoader getClassLoader() { + return implementation.getClassLoader(); + } + +}
\ No newline at end of file diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java new file mode 100644 index 0000000000..6a23830aa9 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java @@ -0,0 +1,40 @@ +/* + * 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.sca.implementation.spring.invocation; + +/** + * @version $Rev$ $Date$ + */ +public class SpringInvocationException extends Exception { + + private static final long serialVersionUID = -1157790036638157513L; + + public SpringInvocationException(String msg) { + super(msg); + } + + public SpringInvocationException(Throwable e) { + super(e); + } + + public SpringInvocationException(String msg,Throwable e) { + super(msg,e); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java new file mode 100644 index 0000000000..1f9796ccc4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java @@ -0,0 +1,124 @@ +/* + * 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.sca.implementation.spring.invocation; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.sca.implementation.spring.SpringBeanElement; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * Initial implementation of a Spring bean invoker + * @version $Rev$ $Date$ + */ +public class SpringInvoker implements Invoker { + + private Method theMethod = null; + private Object bean; + private SpringBeanElement beanElement; + private boolean badInvoker = false; + + private SpringContextStub springContext; + private Operation operation; + + /** + * SpringInvoker constructor + * @param component - the Spring component to invoke + * @param service - the service to invoke + * @param operation - the operation to invoke + */ + public SpringInvoker(RuntimeComponent component, + SpringContextStub springContext, + RuntimeComponentService service, + Operation operation) { + + this.springContext = springContext; + this.operation = operation; + + // From the component and the service, identify the Spring Bean which is the target + SpringImplementation theImplementation = (SpringImplementation)component.getImplementation(); + beanElement = theImplementation.getBeanFromService(service.getService()); + + if (beanElement == null) { + badInvoker = true; + return; + } + + } // end constructor SpringInvoker + + // Lazy-load the method to avoid timing problems with the Spring Context + private void setupMethod() throws SpringInvocationException{ + try { + bean = springContext.getBean(beanElement.getId()); + Class<?> beanClass = bean.getClass(); + theMethod = JavaInterfaceUtil.findMethod(beanClass, operation); + //System.out.println("SpringInvoker - found method " + theMethod.getName() ); + } catch (NoSuchMethodException e) { + throw new SpringInvocationException(e); + } + } + + private Object doInvoke(Object payload) throws SpringInvocationException { + if (theMethod == null) + setupMethod(); + + if (badInvoker) + throw new SpringInvocationException("Spring invoker incorrectly configured"); + // Invoke the method on the Spring bean using the payload, returning the results + try { + Object ret; + + if (payload != null && !payload.getClass().isArray()) { + ret = theMethod.invoke(bean, payload); + } else { + ret = theMethod.invoke(bean, (Object[])payload); + } + return ret; + } catch (InvocationTargetException e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e.getCause()); + } catch (Exception e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e); + } + + } // end method doInvoke + + /** + * @param msg the message to invoke on the target bean + */ + public Message invoke(Message msg) { + try { + Object resp = doInvoke(msg.getBody()); + msg.setBody(resp); + } catch (SpringInvocationException e) { + msg.setFaultBody(e.getCause()); + }catch (Throwable e) { + msg.setFaultBody(e); + } + //System.out.println("Spring Invoker - invoke called"); + return msg; + } // end method invoke + +} // end class SpringInvoker |