diff options
Diffstat (limited to 'sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider')
7 files changed, 571 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java new file mode 100644 index 0000000000..5bddd8a006 --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java @@ -0,0 +1,38 @@ +/* + * 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.provider; + +/** + * Wrapper for the Component + */ +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class ComponentWrapper { + + private RuntimeComponent component; + + public ComponentWrapper(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-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java new file mode 100644 index 0000000000..eca1492081 --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java @@ -0,0 +1,50 @@ +/* + * 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.provider; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.context.PropertyValueFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * Wrapper for PropertyValue + */ +public class PropertyValueWrapper { + + private RuntimeComponent component; + private PropertyValueFactory propertyFactory; + + public PropertyValueWrapper(RuntimeComponent component, PropertyValueFactory 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.createPropertyValue(prop, type); + } + } + return null; // property name not found + } +} diff --git a/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java new file mode 100644 index 0000000000..db7831322a --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java @@ -0,0 +1,81 @@ +/* + * 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.provider; + +import org.apache.tuscany.sca.context.PropertyValueFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.spring.context.SpringContextWrapper; +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; +import org.springframework.context.ApplicationContext; + +/** + * 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 SpringContextWrapper springContext; + + /** + * 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, + SpringImplementationWrapper implementation, + ApplicationContext parentApplicationContext, + ProxyFactory proxyService, + PropertyValueFactory propertyValueObjectFactory) { + super(); + this.component = component; + + springContext = new SpringContextWrapper(implementation, implementation.getResource()); + + } // 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-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java new file mode 100644 index 0000000000..be16fb3251 --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java @@ -0,0 +1,78 @@ +/* + * 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.provider; + +import org.apache.tuscany.sca.context.PropertyValueFactory; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.implementation.spring.context.SpringApplicationContextAccessor; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.springframework.context.ApplicationContext; + +/** + * ImplementationProviderFactory for Spring implementation type + * @version $Rev$ $Date$ + * + */ +public class SpringImplementationProviderFactory implements ImplementationProviderFactory<SpringImplementation> { + private ProxyFactory proxyFactory; + private PropertyValueFactory propertyFactory; + private SpringApplicationContextAccessor contextAccessor; + + /** + * Simple constructor + * + */ + public SpringImplementationProviderFactory(ExtensionPointRegistry registry) { + super(); + UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); + contextAccessor = utilities.getUtility(SpringApplicationContextAccessor.class); + proxyFactory = ExtensibleProxyFactory.getInstance(registry); + propertyFactory = utilities.getUtility(PropertyValueFactory.class); + } + + /** + * 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) { + ApplicationContext parentApplicationContext = + (contextAccessor != null) ? contextAccessor.getParentApplicationContext() : null; + SpringImplementationWrapper tie = + new SpringImplementationWrapper(implementation, parentApplicationContext, component, propertyFactory); + return new SpringImplementationProvider(component, tie, parentApplicationContext, 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-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java new file mode 100644 index 0000000000..e5593f5eaa --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java @@ -0,0 +1,158 @@ +/* + * 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.provider; + +import java.net.URL; +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.context.PropertyValueFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.springframework.context.ApplicationContext; + +/** + * Wrapper for SpringImplementation + */ +public class SpringImplementationWrapper { + + private SpringImplementation implementation; + private ApplicationContext parentApplicationContext; + private RuntimeComponent component; + private PropertyValueFactory propertyFactory; + + public SpringImplementationWrapper(SpringImplementation implementation, + ApplicationContext parentApplicationContext, + RuntimeComponent component, + PropertyValueFactory propertyFactory) { + this.implementation = implementation; + this.component = component; + this.propertyFactory = propertyFactory; + this.parentApplicationContext = parentApplicationContext; + } + + public String getURI() { + return implementation.getURI(); + } + + public List<URL> getResource() { + return implementation.getResource(); + } + + 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 + propertyObject = (B)propertyFactory.createPropertyValue(prop, requiredType); + } // 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); + return null; + + } // end method getBean( String, Class ) + + public ComponentWrapper getComponentWrapper() { + return new ComponentWrapper(component); + } + + public PropertyValueWrapper getPropertyValueWrapper() { + return new PropertyValueWrapper(component, propertyFactory); + } + + public ClassLoader getClassLoader() { + return implementation.getClassLoader(); + } + + public ApplicationContext getParentApplicationContext() { + return parentApplicationContext; + } + +} diff --git a/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java new file mode 100644 index 0000000000..0e1d3f5b5a --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/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.provider; + +/** + * @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-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java new file mode 100644 index 0000000000..ea1d6e6755 --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta2-RC1/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java @@ -0,0 +1,126 @@ +/* + * 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.provider; + +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.implementation.spring.context.SpringContextWrapper; +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 SpringContextWrapper 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, + SpringContextWrapper 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 |