From a40e527938d76ba71f211da7e327adb50384ba69 Mon Sep 17 00:00:00 2001 From: lresende Date: Wed, 11 Nov 2009 23:26:33 +0000 Subject: Moving 1.x tags git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835157 13f79535-47bb-0310-9956-ffa450edef68 --- .../context/SCAParentApplicationContext.java | 190 +++++++++++++++++++ .../spring/runtime/context/SpringContextTie.java | 207 +++++++++++++++++++++ .../runtime/context/SpringImplementationStub.java | 129 +++++++++++++ 3 files changed, 526 insertions(+) create mode 100644 sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java create mode 100644 sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java create mode 100644 sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java (limited to 'sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime') diff --git a/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java new file mode 100644 index 0000000000..b93874a9f3 --- /dev/null +++ b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java @@ -0,0 +1,190 @@ +/* + * 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.runtime.context; + +import java.io.IOException; +import java.util.Locale; +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.NoSuchMessageException; +import org.springframework.core.io.Resource; + +/** + * A Spring ParentApplicationContext for a given Spring Implementation + * + * The Parent application context is responsible for handling those entities within a Spring + * application context that actually belong to SCA rather than to Spring. The principal things + * are Properties and References. These may be present either through explicit + * and elements in the application context or they may be implicit through + * unresolved Spring bean elements. In either case, it is the Parent application + * context that must provide Spring beans that correspond to the property or reference, as derived + * from the SCA composite in which the Spring application context is an implementation. + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +class SCAParentApplicationContext implements ApplicationContext { + + // The Spring implementation for which this is the parent application context + private SpringImplementationStub implementation; + + private static final String[] EMPTY_ARRAY = new String[0]; + + public SCAParentApplicationContext(SpringImplementationStub implementation) { + this.implementation = implementation; + } // end constructor + + public Object getBean(String name) throws BeansException { + return getBean(name, (Class) null); + } + + /** + * 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) throws BeansException { + return implementation.getBean(name, requiredType); + } // end method getBean( String, Class ) + + public Object getBean(String name, Object[] args) throws BeansException { + return getBean(name, ((Class)null)); + } + + public boolean containsBean(String name) { + // TODO + System.out.println("Spring parent context - containsBean called for name: " + name); + return false; + } + + public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + // TODO + return false; + } + + public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException { + throw new UnsupportedOperationException(); + } + + public Class getType(String name) throws NoSuchBeanDefinitionException { + return null; + } + + public String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return EMPTY_ARRAY; + } + + public ApplicationContext getParent() { + return null; + } + + public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException { + return null; + } + + public String getId() { + return this.toString(); + } + + public String getDisplayName() { + return implementation.getURI(); + } + + public long getStartupDate() { + return 0; + } + + public boolean containsBeanDefinition(String beanName) { + return false; + } + + public int getBeanDefinitionCount() { + return 0; + } + + public String[] getBeanDefinitionNames() { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type) { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) { + return new String[0]; + } + + public Map getBeansOfType(Class type) throws BeansException { + return null; + } + + public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException { + return null; + } + + public boolean isPrototype(String theString) { + return false; + } + + public BeanFactory getParentBeanFactory() { + return null; + } + + public boolean containsLocalBean(String name) { + return false; + } + + public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { + return null; + } + + public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { + return null; + } + + public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { + return null; + } + + public void publishEvent(ApplicationEvent event) { + + } + + public Resource[] getResources(String locationPattern) throws IOException { + return new Resource[0]; + } + + public Resource getResource(String location) { + return null; + } + + public ClassLoader getClassLoader() { + // REVIEW: this is almost certainly flawed, but it's not clear how the SCA runtime's + // resource loading mechanism is exposed right now. + return this.getClass().getClassLoader(); + } +} diff --git a/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java new file mode 100644 index 0000000000..6e8f1e8df4 --- /dev/null +++ b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java @@ -0,0 +1,207 @@ +/* + * 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.runtime.context; + +import java.net.URL; +import java.util.Iterator; +import java.util.List; + +import org.apache.tuscany.sca.implementation.spring.processor.ComponentNameAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.ComponentStub; +import org.apache.tuscany.sca.implementation.spring.processor.ConstructorAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.InitDestroyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.PropertyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.PropertyValueStub; +import org.apache.tuscany.sca.implementation.spring.processor.ReferenceAnnotationProcessor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.ConstructorArgumentValues; +import org.springframework.beans.factory.config.TypedStringValue; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.UrlResource; +import org.springframework.core.SpringVersion; + +/** + * This is the runtime side tie for the corresponding tuscany 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 SpringContextStub class + * in the implementation-spring module for what the stub does. + */ +public class SpringContextTie { + + private AbstractApplicationContext springContext; + private SpringImplementationStub implementation; + private boolean isAnnotationSupported; + private String versionSupported; + private boolean isMultipleContextSupport; + + // TUSCANY-3128 + // extension of the generic application context just to force the classloader + // on the bean factory to stay set to the contribution classloader + // instead of being set back to the application classloader + private class LocalGenericApplicationContext extends GenericApplicationContext{ + + ClassLoader classloader = null; + + public LocalGenericApplicationContext(DefaultListableBeanFactory beanFactory, + ApplicationContext parent, + ClassLoader classloader) { + super(beanFactory, parent); + this.classloader = classloader; + } + + @Override + protected void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) { + beanFactory.setBeanClassLoader(classloader); + } + } + + public SpringContextTie(SpringImplementationStub implementation, URL resource, boolean annotationSupport, String versionSupported, boolean multipleContextSupport) throws Exception { + this.implementation = implementation; + this.isAnnotationSupported = annotationSupport; + this.versionSupported = versionSupported; + this.isMultipleContextSupport = multipleContextSupport; + if (! this.versionSupported.equals("ANY")) { + if ((SpringVersion.getVersion()!= null) && (! SpringVersion.getVersion().equals(versionSupported))) + throw new RuntimeException("Unsupported version: Use only Spring Framework Version " + versionSupported); + } + SCAParentApplicationContext scaParentContext = new SCAParentApplicationContext(implementation); + springContext = createApplicationContext(scaParentContext, resource); + } + + public void start() { + // Do refresh here to ensure that Spring Beans are not touched before + // the SCA config process is complete... + springContext.refresh(); + springContext.start(); + } + + public void close() { + springContext.close(); + if (springContext instanceof GenericApplicationContext) { + springContext.stop(); + } + } + + /** + * Create appropriate ApplicationContext by reading the bean definitions. + */ + private AbstractApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext, URL resource) { + + XmlBeanFactory beanFactory = new XmlBeanFactory(new UrlResource(resource)); + beanFactory.setBeanClassLoader(implementation.getClassLoader()); + AbstractApplicationContext appContext = null; + + if (isMultipleContextSupport) { + for (String bean : beanFactory.getBeanDefinitionNames()) { + String beanClassName = (beanFactory.getType(bean)).getName(); + // Using FileSystemXmlApplicationContext is not supported, as the + // SCA runtime does not support paths relative to current VM working directory. + /*if (beanClassName.indexOf(".FileSystemXmlApplicationContext") != -1) { + throw new RuntimeException("Usage of FileSystemXmlApplicationContext Bean is not supported"); + }*/ + + if (beanClassName.indexOf(".ClassPathXmlApplicationContext") != -1) { + BeanDefinition beanDef = beanFactory.getBeanDefinition(bean); + String[] configLocations = null; + List conArgs = + beanDef.getConstructorArgumentValues().getGenericArgumentValues(); + for (ConstructorArgumentValues.ValueHolder conArg : conArgs) { + if (conArg.getValue() instanceof TypedStringValue) { + TypedStringValue value = (TypedStringValue) conArg.getValue(); + if (value.getValue().indexOf(".xml") != -1) + configLocations = new String[]{value.getValue()}; + } + if (conArg.getValue() instanceof ManagedList) { + Iterator itml = ((ManagedList)conArg.getValue()).iterator(); + StringBuffer values = new StringBuffer(); + while (itml.hasNext()) { + TypedStringValue next = (TypedStringValue)itml.next(); + if (next.getValue().indexOf(".xml") != -1) { + values.append(implementation.getClassLoader().getResource(next.getValue()).toString()); + values.append("~"); + } + } + configLocations = (values.toString()).split("~"); + } + } + + appContext = new ClassPathXmlApplicationContext(configLocations, true, scaParentContext); + if (isAnnotationSupported) + includeAnnotationProcessors(appContext.getBeanFactory()); + return appContext; + } + } + } + + // use the generic application context as default + if (isAnnotationSupported) + { + includeAnnotationProcessors(beanFactory); + } + + appContext = new LocalGenericApplicationContext(beanFactory, + scaParentContext, + implementation.getClassLoader()); + return appContext; + } + + public Object getBean(String id) throws BeansException { + return springContext.getBean(id); + } + + /** + * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean + */ + private void includeAnnotationProcessors(ConfigurableListableBeanFactory beanFactory) { + + // Processor to deal with @Init and @Destroy SCA Annotations + BeanPostProcessor initDestroyProcessor = new InitDestroyAnnotationProcessor(); + beanFactory.addBeanPostProcessor(initDestroyProcessor); + + // Processor to deal with @Reference SCA Annotations + ComponentStub component = new ComponentStub(implementation.getComponentTie()); + BeanPostProcessor referenceProcessor = new ReferenceAnnotationProcessor(component); + beanFactory.addBeanPostProcessor(referenceProcessor); + + // Processor to deal with @Property SCA Annotations + PropertyValueStub pvs = new PropertyValueStub(implementation.getPropertyValueTie()); + BeanPostProcessor propertyProcessor = new PropertyAnnotationProcessor(pvs); + beanFactory.addBeanPostProcessor(propertyProcessor); + + // Processor to deal with @ComponentName SCA Annotations + BeanPostProcessor componentNameProcessor = new ComponentNameAnnotationProcessor(implementation.getComponentName()); + beanFactory.addBeanPostProcessor(componentNameProcessor); + + // Processor to deal with @Constructor SCA Annotations + BeanPostProcessor constructorProcessor = new ConstructorAnnotationProcessor(); + beanFactory.addBeanPostProcessor(constructorProcessor); + } + +} diff --git a/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java new file mode 100644 index 0000000000..b123be8b5c --- /dev/null +++ b/sca-java-1.x/tags/1.5.1-RC4/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java @@ -0,0 +1,129 @@ +/* + * 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.runtime.context; + +import java.lang.reflect.Method; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; + +/** + * This is the runtime side stub for the corresponding Tuscany-side stub class. + * It enables the Spring 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 SpringImplementationTie class + * in the implementation-spring module for what the tie does. + */ +public class SpringImplementationStub { + + Object tie; + Method getURI; + Method getBean; + Method getComponentName; + Method getComponentTie; + Method getPropertyValueTie; + Method getClassLoader; + + public SpringImplementationStub(Object tie) { + this.tie = tie; + Class tieClass = tie.getClass(); + try { + getURI = tieClass.getMethod("getURI", new Class[]{}); + getBean = tieClass.getMethod("getBean", new Class[]{String.class, Class.class}); + getComponentName = tieClass.getMethod("getComponentName"); + getComponentTie = tieClass.getMethod("getComponentTie"); + getPropertyValueTie = tieClass.getMethod("getPropertyValueTie"); + getClassLoader = tieClass.getMethod("getClassLoader"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public String getURI() { + try { + + return (String)getURI.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 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) throws BeansException { + try { + + Object bean = getBean.invoke(tie, new Object[] {name, requiredType}); + if (bean == null) { + throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name); + } + return bean; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public String getComponentName() { + try { + + return (String)getComponentName.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getComponentTie() { + try { + + return getComponentTie.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getPropertyValueTie() { + try { + + return getPropertyValueTie.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ClassLoader getClassLoader() { + try { + + return (ClassLoader) getClassLoader.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} -- cgit v1.2.3