From 5d29d53c4ad74b2ec834aad00cc5273bebe6e3f4 Mon Sep 17 00:00:00 2001 From: ramkumar Date: Wed, 30 Sep 2009 10:46:20 +0000 Subject: Fixes for TUSCANY-3287: Complaince with OASIS specs git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@820238 13f79535-47bb-0310-9956-ffa450edef68 --- .../META-INF/spring/SpringHelloWorld-context.xml | 31 - .../META-INF/spring/StockQuoteService-context.xml | 36 -- .../multiple/META-INF/spring/beanRefContext.xml | 35 -- .../context/multiple/MultipleContext.composite | 9 +- .../multiple/springapp/META-INF/MANIFEST.MF | 3 + .../META-INF/spring/SpringHelloWorld-context.xml | 31 + .../META-INF/spring/StockQuoteService-context.xml | 36 ++ .../springapp/META-INF/spring/beanRefContext.xml | 34 ++ .../context/SCAGenericApplicationContext.java | 29 + .../spring/runtime/context/SpringContextTie.java | 78 +-- .../implementation/spring/SpringBeanElement.java | 36 +- .../spring/SpringConstructorArgElement.java | 15 +- .../spring/SpringImplementation.java | 6 +- .../spring/SpringImplementationConstants.java | 19 +- .../spring/SpringPropertyElement.java | 15 +- .../spring/SpringSCAReferenceElement.java | 27 + .../spring/SpringSCAServiceElement.java | 21 +- .../introspect/SpringXMLComponentTypeLoader.java | 653 +++++++++++++++------ .../spring/invocation/SpringContextStub.java | 4 +- .../spring/xml/SpringImplementationProcessor.java | 2 +- .../impl-spring-validation-messages.properties | 9 +- 21 files changed, 766 insertions(+), 363 deletions(-) delete mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/SpringHelloWorld-context.xml delete mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/StockQuoteService-context.xml delete mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/beanRefContext.xml create mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/MANIFEST.MF create mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/SpringHelloWorld-context.xml create mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/StockQuoteService-context.xml create mode 100644 java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/beanRefContext.xml create mode 100644 java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/SpringHelloWorld-context.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/SpringHelloWorld-context.xml deleted file mode 100644 index 62e4e077b6..0000000000 --- a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/SpringHelloWorld-context.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/StockQuoteService-context.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/StockQuoteService-context.xml deleted file mode 100644 index 5b1885d6b3..0000000000 --- a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/StockQuoteService-context.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/beanRefContext.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/beanRefContext.xml deleted file mode 100644 index 1bb3b2c146..0000000000 --- a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/META-INF/spring/beanRefContext.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - META-INF/spring/StockQuoteService-context.xml - META-INF/spring/SpringHelloWorld-context.xml - - - - \ No newline at end of file diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/MultipleContext.composite b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/MultipleContext.composite index 5acdc77d1a..1c4b81db33 100644 --- a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/MultipleContext.composite +++ b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/MultipleContext.composite @@ -21,15 +21,10 @@ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903" targetNamespace="http://stockquote" xmlns:hw="http://stockquote" - name="MultipleContext"> - - - - - + name="MultipleContext"> - + diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/MANIFEST.MF b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..9267f28e83 --- /dev/null +++ b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Spring-Context: META-INF/spring/beanRefContext.xml; META-INF/spring/StockQuoteService-context.xml + diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/SpringHelloWorld-context.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/SpringHelloWorld-context.xml new file mode 100644 index 0000000000..62e4e077b6 --- /dev/null +++ b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/SpringHelloWorld-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/StockQuoteService-context.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/StockQuoteService-context.xml new file mode 100644 index 0000000000..5b1885d6b3 --- /dev/null +++ b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/StockQuoteService-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/beanRefContext.xml b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/beanRefContext.xml new file mode 100644 index 0000000000..5ccc8892b6 --- /dev/null +++ b/java/sca/itest/implementation-spring/src/main/resources/context/multiple/springapp/META-INF/spring/beanRefContext.xml @@ -0,0 +1,34 @@ + + + + + + + + context/multiple/META-INF/spring/SpringHelloWorld-context.xml + + + + \ No newline at end of file diff --git a/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java b/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java new file mode 100644 index 0000000000..c1aaf1570f --- /dev/null +++ b/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java @@ -0,0 +1,29 @@ +package org.apache.tuscany.sca.implementation.spring.runtime.context; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; + +public class SCAGenericApplicationContext extends GenericApplicationContext { + + ClassLoader classloader = null; + + public SCAGenericApplicationContext(DefaultListableBeanFactory beanFactory, + ApplicationContext parent, + ClassLoader classloader) { + super(beanFactory, parent); + this.classloader = classloader; + } + + public SCAGenericApplicationContext(ApplicationContext parent, + ClassLoader classloader) { + super(parent); + this.classloader = classloader; + } + + @Override + protected void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) { + beanFactory.setBeanClassLoader(classloader); + } +} diff --git a/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java b/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java index 18517755d5..77681b600f 100644 --- a/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java +++ b/java/sca/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java @@ -20,7 +20,6 @@ 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; @@ -31,16 +30,11 @@ import org.apache.tuscany.sca.implementation.spring.processor.PropertyAnnotation 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.ManagedList; import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.UrlResource; @@ -55,7 +49,7 @@ public class SpringContextTie { private AbstractApplicationContext springContext; private SpringImplementationStub implementation; - public SpringContextTie(SpringImplementationStub implementation, URL resource) { + public SpringContextTie(SpringImplementationStub implementation, List resource) { this.implementation = implementation; SCAParentApplicationContext scaParentContext = new SCAParentApplicationContext(implementation); springContext = createApplicationContext(scaParentContext, resource); @@ -77,56 +71,30 @@ public class SpringContextTie { /** * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean */ - private AbstractApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext, URL resource) { + private AbstractApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext, List resources) { - XmlBeanFactory beanFactory = new XmlBeanFactory(new UrlResource(resource)); - beanFactory.setBeanClassLoader(implementation.getClassLoader()); - AbstractApplicationContext appContext = null; - - for (String bean : beanFactory.getBeanDefinitionNames()) { - String beanClassName = (beanFactory.getType(bean)).getName(); - if (beanClassName.indexOf(".ClassPathXmlApplicationContext") != -1 || - beanClassName.indexOf(".FileSystemXmlApplicationContext") != -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("~"); - } - } - - if (beanClassName.indexOf(".ClassPathXmlApplicationContext") != -1) { - appContext = new ClassPathXmlApplicationContext(configLocations, true, scaParentContext); - includeAnnotationProcessors(appContext.getBeanFactory()); - return appContext; - } else { - appContext = new FileSystemXmlApplicationContext(configLocations, true, scaParentContext); - includeAnnotationProcessors(appContext.getBeanFactory()); - return appContext; - } - } - } + XmlBeanFactory beanFactory = null; + AbstractApplicationContext appContext = null; + + if (resources.size() > 1) { + GenericApplicationContext appCtx = + new SCAGenericApplicationContext(scaParentContext, implementation.getClassLoader()); + XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx); + for (URL resource : resources) { + xmlReader.loadBeanDefinitions(new UrlResource(resource)); + } + xmlReader.setBeanClassLoader(implementation.getClassLoader()); + includeAnnotationProcessors(appCtx.getBeanFactory()); + return appCtx; + } - // use the generic application context as default + // use the generic application context as default + beanFactory = new XmlBeanFactory(new UrlResource(resources.get(0))); + beanFactory.setBeanClassLoader(implementation.getClassLoader()); includeAnnotationProcessors(beanFactory); - appContext = new GenericApplicationContext(beanFactory, scaParentContext); + appContext = new SCAGenericApplicationContext(beanFactory, + scaParentContext, + implementation.getClassLoader()); return appContext; } diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java index 60af3e2ad5..f64c5f9476 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java @@ -31,11 +31,13 @@ import java.util.List; public class SpringBeanElement { private String id; - private String className; + private String className = null; private boolean innerBean = false; private boolean abstractBean = false; - private boolean refParentBean = false; - private boolean reffactoryBean = false; + private boolean parentAttribute = false; + private boolean factoryBeanAttribute = false; + private boolean factoryMethodAttribute = false; + private List properties = new ArrayList(); private List constructorargs = new ArrayList(); @@ -51,6 +53,10 @@ public class SpringBeanElement { public String getId() { return id; } + + public void setId(String id) { + this.id = id; + } public List getProperties() { return properties; @@ -83,5 +89,29 @@ public class SpringBeanElement { public void setAbstractBean(boolean abstractBean) { this.abstractBean = abstractBean; } + + public boolean hasParentAttribute() { + return parentAttribute; + } + + public void setParentAttribute(boolean parentAttribute) { + this.parentAttribute = parentAttribute; + } + + public boolean hasFactoryBeanAttribute() { + return factoryBeanAttribute; + } + + public void setFactoryBeanAttribute(boolean factoryBeanAttribute) { + this.factoryBeanAttribute = factoryBeanAttribute; + } + + public boolean hasFactoryMethodAttribute() { + return factoryMethodAttribute; + } + + public void setFactoryMethodAttribute(boolean factoryMethodAttribute) { + this.factoryMethodAttribute = factoryMethodAttribute; + } } // end class SpringBeanElement diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java index 88dbaaf119..9ae1273592 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java @@ -29,14 +29,13 @@ import java.util.List; */ public class SpringConstructorArgElement { - private String ref; - private String type; + private String type; private int autoIndex = -1; private int index = -1; + private List refs = new ArrayList(); private List values = new ArrayList(); - public SpringConstructorArgElement(String ref, String type) { - this.ref = ref; + public SpringConstructorArgElement(String type) { this.type = type; } @@ -44,12 +43,12 @@ public class SpringConstructorArgElement { return this.type; } - public String getRef() { - return this.ref; + public List getRefs() { + return this.refs; } - public void setRef(String ref) { - this.ref = ref; + public void addRef(String ref) { + this.refs.add(ref); } public int getIndex() { diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java index 1a183b0543..547306d748 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java @@ -46,7 +46,7 @@ public class SpringImplementation extends ImplementationImpl implements Implemen // The location attribute which points to the Spring application-context XML file private String location; // The application-context file as a Spring Resource - private URL resource; + private List resource; private ComponentType componentType; // Mapping of Services to Beans private Hashtable serviceMap; @@ -80,11 +80,11 @@ public class SpringImplementation extends ImplementationImpl implements Implemen return; } - public void setResource(URL resource) { + public void setResource(List resource) { this.resource = resource; } - public URL getResource() { + public List getResource() { return resource; } diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java index 0bccdb369c..caae72fa90 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java @@ -30,14 +30,14 @@ public interface SpringImplementationConstants { String SPRING_NS = "http://www.springframework.org/schema/beans"; String PROPERTY = "property"; - QName SCAPROPERTY_ELEMENT = new QName(SCA_NS, PROPERTY); + QName SCA_PROPERTY_ELEMENT = new QName(SCA_NS, PROPERTY); QName PROPERTY_ELEMENT = new QName(SPRING_NS, PROPERTY); - String SERVICE = "service"; - QName SERVICE_ELEMENT = new QName(SCA_NS, SERVICE); + String SCASERVICE = "service"; + QName SCA_SERVICE_ELEMENT = new QName(SCA_NS, SCASERVICE); - String REFERENCE = "reference"; - QName REFERENCE_ELEMENT = new QName(SCA_NS, REFERENCE); + String SCAREFERENCE = "reference"; + QName SCA_REFERENCE_ELEMENT = new QName(SCA_NS, SCAREFERENCE); String BEANS = "beans"; QName BEANS_ELEMENT = new QName(SPRING_NS, BEANS); @@ -54,11 +54,20 @@ public interface SpringImplementationConstants { String LIST = "list"; QName LIST_ELEMENT = new QName(SPRING_NS, LIST); + String SET = "set"; + QName SET_ELEMENT = new QName(SPRING_NS, SET); + + String MAP = "map"; + QName MAP_ELEMENT = new QName(SPRING_NS, MAP); + String VALUE = "value"; QName VALUE_ELEMENT = new QName(SPRING_NS, VALUE); String REF = "ref"; QName REF_ELEMENT = new QName(SPRING_NS, REF); + + String ENTRY = "entry"; + QName ENTRY_ELEMENT = new QName(SPRING_NS, ENTRY); String APPLICATION_CONTEXT = "application-context.xml"; } diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java index 2a55e2c7c8..37b8ef37a6 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java @@ -30,24 +30,23 @@ import java.util.List; public class SpringPropertyElement { private String name; - private String ref; + private List refs = new ArrayList(); private List values = new ArrayList(); - public SpringPropertyElement(String name, String ref) { + public SpringPropertyElement(String name) { this.name = name; - this.ref = ref; } public String getName() { return name; } - public String getRef() { - return ref; + public List getRefs() { + return this.refs; } - public void setRef(String ref) { - this.ref = ref; + public void addRef(String ref) { + this.refs.add(ref); } public List getValues() { @@ -57,5 +56,5 @@ public class SpringPropertyElement { public void addValue(String value) { this.values.add(value); } - + } // end class SpringPropertyElement diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java index 47c87fe7fe..83eef43bd5 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java @@ -29,6 +29,9 @@ public class SpringSCAReferenceElement { private String name; private String type; + private String defaultBean; + private String requiredIntents; + private String policySets; public SpringSCAReferenceElement(String name, String type) { this.name = name; @@ -50,5 +53,29 @@ public class SpringSCAReferenceElement { public String getType() { return type; } + + public void setDefaultBean(String defaultBean) { + this.defaultBean = defaultBean; + } + + public String getDefaultBean() { + return defaultBean; + } + + public void setRequiredIntents(String requiredIntents) { + this.requiredIntents = requiredIntents; + } + + public String getRequiredIntents() { + return requiredIntents; + } + + public void setPolicySets(String policySets) { + this.policySets = policySets; + } + + public String getPolicySets() { + return policySets; + } } // end class SpringSCAReferenceElement diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java index 7362a4521c..2c83df2269 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java @@ -30,10 +30,11 @@ public class SpringSCAServiceElement { private String name; private String type; private String target; + private String requiredIntents; + private String policySets; - public SpringSCAServiceElement(String name, String type, String target) { + public SpringSCAServiceElement(String name, String target) { this.name = name; - this.type = type; this.target = target; } @@ -60,5 +61,21 @@ public class SpringSCAServiceElement { public String getTarget() { return target; } + + public void setRequiredIntents(String requiredIntents) { + this.requiredIntents = requiredIntents; + } + + public String getRequiredIntents() { + return requiredIntents; + } + + public void setPolicySets(String policySets) { + this.policySets = policySets; + } + + public String getPolicySets() { + return policySets; + } } // end class SpringSCAServiceElement diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java index 3903d4ce14..496411b2dd 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java @@ -75,6 +75,9 @@ import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; import org.apache.tuscany.sca.policy.PolicyFactory; /** @@ -90,19 +93,49 @@ public class SpringXMLComponentTypeLoader { private AssemblyFactory assemblyFactory; private JavaInterfaceFactory javaFactory; private PolicyFactory policyFactory; - + private Monitor monitor; private SpringBeanIntrospector beanIntrospector; public SpringXMLComponentTypeLoader(FactoryExtensionPoint factories, AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory, - PolicyFactory policyFactory) { + PolicyFactory policyFactory, + Monitor monitor) { super(); this.assemblyFactory = assemblyFactory; this.javaFactory = javaFactory; this.policyFactory = policyFactory; this.contributionFactory = factories.getFactory(ContributionFactory.class); this.xmlInputFactory = factories.getFactory(XMLInputFactory.class); + this.monitor = monitor; + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "impl-spring-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "impl-spring-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } } protected Class getImplementationClass() { @@ -155,24 +188,35 @@ public class SpringXMLComponentTypeLoader { List scaproperties = new ArrayList(); URL resource; - + List contextResources = new ArrayList(); String contextPath = implementation.getLocation(); - try { + try { resource = resolveLocation(resolver, contextPath); - resource = getApplicationContextResource(resource); + contextResources = getApplicationContextResource(resource); implementation.setClassLoader(new ContextClassLoader(resolver)); - implementation.setResource(resource); + implementation.setResource(contextResources); // The URI is used to uniquely identify the Implementation implementation.setURI(resource.toString()); - reader = xmlInputFactory.createXMLStreamReader(resource.openStream()); - - // System.out.println("Spring TypeLoader - starting to read context file"); - readContextDefinition(resolver, reader, contextPath, beans, services, references, scaproperties); - reader.close(); - + for (URL contextResource : contextResources) { + List appCxtBeans = new ArrayList(); + List appCxtServices = new ArrayList(); + List appCxtReferences = new ArrayList(); + List appCxtProperties = new ArrayList(); + reader = xmlInputFactory.createXMLStreamReader(contextResource.openStream()); + // Read the beans, services, references and properties for individual application context + readContextDefinition(resolver, reader, contextPath, appCxtBeans, appCxtServices, appCxtReferences, appCxtProperties); + // Validate the beans from individual application context for uniqueness + validateBeans(appCxtBeans, appCxtServices, appCxtReferences, appCxtProperties); + // Add all the validated beans to the generic list + beans.addAll(appCxtBeans); + services.addAll(appCxtServices); + references.addAll(appCxtReferences); + scaproperties.addAll(appCxtProperties); + reader.close(); + } } catch (IOException e) { throw new ContributionReadException(e); } catch (XMLStreamException e) { @@ -214,7 +258,7 @@ public class SpringXMLComponentTypeLoader { private XMLStreamReader getApplicationContextReader(ModelResolver resolver, String location) throws ContributionReadException { try { - URL resource = getApplicationContextResource(resolveLocation(resolver, location)); + URL resource = getApplicationContextResource(resolveLocation(resolver, location)).get(0); XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(resource.openStream()); return reader; @@ -256,28 +300,76 @@ public class SpringXMLComponentTypeLoader { // Read the context definition for the identified imported resource readContextDefinition(resolver, ireader, contextPath, beans, services, references, scaproperties); } - } else if (SpringImplementationConstants.SERVICE_ELEMENT.equals(qname)) { - SpringSCAServiceElement service = - new SpringSCAServiceElement(reader.getAttributeValue(null, "name"), reader - .getAttributeValue(null, "type"), reader.getAttributeValue(null, "target")); + } else if (SpringImplementationConstants.SCA_SERVICE_ELEMENT.equals(qname)) { + // The value of the @name attribute of an subelement of a + // element MUST be unique amongst the subelements of the element. + if (!services.isEmpty() && (services.contains(reader.getAttributeValue(null, "name")))) + error("ScaServiceNameNotUnique", resolver); + + SpringSCAServiceElement service = + new SpringSCAServiceElement(reader.getAttributeValue(null, "name"), + reader.getAttributeValue(null, "target")); + if (reader.getAttributeValue(null, "type") != null) + service.setType(reader.getAttributeValue(null, "type")); + if (reader.getAttributeValue(null, "requires") != null) + service.setRequiredIntents(reader.getAttributeValue(null, "requires")); + if (reader.getAttributeValue(null, "policySets") != null) + service.setPolicySets(reader.getAttributeValue(null, "policySets")); services.add(service); - } else if (SpringImplementationConstants.REFERENCE_ELEMENT.equals(qname)) { - SpringSCAReferenceElement reference = - new SpringSCAReferenceElement(reader.getAttributeValue(null, "name"), reader - .getAttributeValue(null, "type")); - references.add(reference); - } else if (SpringImplementationConstants.SCAPROPERTY_ELEMENT.equals(qname)) { - SpringSCAPropertyElement scaproperty = + } else if (SpringImplementationConstants.SCA_REFERENCE_ELEMENT.equals(qname)) { + // The value of the @name attribute of an subelement of a + // element MUST be unique amongst the @name attributes of the subelements, + // of the element. + if (!references.isEmpty() && (references.contains(reader.getAttributeValue(null, "name")))) + error("ScaReferenceNameNotUnique", resolver); + + SpringSCAReferenceElement reference = + new SpringSCAReferenceElement(reader.getAttributeValue(null, "name"), + reader.getAttributeValue(null, "type")); + if (reader.getAttributeValue(null, "default") != null) + reference.setDefaultBean(reader.getAttributeValue(null, "default")); + if (reader.getAttributeValue(null, "requires") != null) + reference.setRequiredIntents(reader.getAttributeValue(null, "requires")); + if (reader.getAttributeValue(null, "policySets") != null) + reference.setPolicySets(reader.getAttributeValue(null, "policySets")); + references.add(reference); + } else if (SpringImplementationConstants.SCA_PROPERTY_ELEMENT.equals(qname)) { + // The value of the @name attribute of an subelement of a + // element MUST be unique amongst the @name attributes of the subelements, + // of the element. + if (!scaproperties.isEmpty() && (scaproperties.contains(reader.getAttributeValue(null, "name")))) + error("ScaPropertyNameNotUnique", resolver); + + SpringSCAPropertyElement scaproperty = new SpringSCAPropertyElement(reader.getAttributeValue(null, "name"), reader .getAttributeValue(null, "type")); scaproperties.add(scaproperty); } else if (SpringImplementationConstants.BEAN_ELEMENT.equals(qname)) { - bean = new SpringBeanElement(reader.getAttributeValue(null, "id"), reader - .getAttributeValue(null, "class")); + bean = new SpringBeanElement(reader.getAttributeValue(null, "id"), + reader.getAttributeValue(null, "class")); + if (reader.getAttributeValue(null, "abstract") != null) + if (reader.getAttributeValue(null, "abstract").equals("true")) + bean.setAbstractBean(true); + if (reader.getAttributeValue(null, "parent") != null) + if (!reader.getAttributeValue(null, "parent").equals("")) + bean.setParentAttribute(true); + if (reader.getAttributeValue(null, "factory-bean") != null) + if (!reader.getAttributeValue(null, "factory-bean").equals("")) + bean.setFactoryBeanAttribute(true); + if (reader.getAttributeValue(null, "factory-method") != null) + if (!reader.getAttributeValue(null, "factory-method").equals("")) + bean.setFactoryMethodAttribute(true); + // Set the first name as bean name, when the @id attribute is absent. + if (reader.getAttributeValue(null, "id") == null) { + if (reader.getAttributeValue(null, "name") != null) { + String[] names = (reader.getAttributeValue(null, "name")).split(","); + bean.setId(names[0]); + } + } beans.add(bean); // Read the element and its child elements - readBeanDefinition(resolver, reader, contextPath, bean, beans, services, references, scaproperties); - } // end if*/ + readBeanDefinition(reader, bean, beans); + } // end if break; case END_ELEMENT: if (SpringImplementationConstants.BEANS_ELEMENT.equals(reader.getName())) { @@ -297,22 +389,16 @@ public class SpringXMLComponentTypeLoader { * Method which reads the bean definitions from Spring application-context.xml file and identifies * the defined beans, properties, services and references */ - private void readBeanDefinition(ModelResolver resolver, - XMLStreamReader reader, - String contextPath, + private void readBeanDefinition(XMLStreamReader reader, SpringBeanElement bean, - List beans, - List services, - List references, - List scaproperties) throws ContributionReadException { + List beans) throws ContributionReadException { SpringBeanElement innerbean = null; SpringPropertyElement property = null; SpringConstructorArgElement constructorArg = null; - int autoConstructorIndex = -1; - + try { - boolean completed = false; + boolean completed = false; while (!completed) { switch (reader.next()) { case START_ELEMENT: @@ -320,54 +406,47 @@ public class SpringXMLComponentTypeLoader { if (SpringImplementationConstants.BEAN_ELEMENT.equals(qname)) { innerbean = new SpringBeanElement(reader.getAttributeValue(null, "id"), reader .getAttributeValue(null, "class")); + // Set the first name as bean name, when the @id attribute is absent. + if (reader.getAttributeValue(null, "id") == null) { + if (reader.getAttributeValue(null, "name") != null) { + String[] names = (reader.getAttributeValue(null, "name")).split(","); + innerbean.setId(names[0]); + } + } innerbean.setInnerBean(true); beans.add(innerbean); - readBeanDefinition(resolver, reader, contextPath, innerbean, beans, services, references, scaproperties); + readBeanDefinition(reader, innerbean, beans); } else if (SpringImplementationConstants.PROPERTY_ELEMENT.equals(qname)) { - property = new SpringPropertyElement(reader.getAttributeValue(null, "name"), reader - .getAttributeValue(null, "ref")); + property = new SpringPropertyElement(reader.getAttributeValue(null, "name")); + if (reader.getAttributeValue(null, "ref") != null) + property.addRef(reader.getAttributeValue(null, "ref")); bean.addProperty(property); } else if (SpringImplementationConstants.CONSTRUCTORARG_ELEMENT.equals(qname)) { - constructorArg = new SpringConstructorArgElement(reader.getAttributeValue(null, "ref"), - reader.getAttributeValue(null, "type")); - autoConstructorIndex++; - constructorArg.setAutoIndex(autoConstructorIndex); + constructorArg = new SpringConstructorArgElement(reader.getAttributeValue(null, "type")); + if (reader.getAttributeValue(null, "ref") != null) + constructorArg.addRef(reader.getAttributeValue(null, "ref")); if (reader.getAttributeValue(null, "index") != null) constructorArg.setIndex((new Integer(reader.getAttributeValue(null, "index"))).intValue()); - if (reader.getAttributeValue(null, "value") != null) { - String value = reader.getAttributeValue(null, "value"); - constructorArg.addValue(value); - if ((value.indexOf(".xml") != -1)) { - if ((bean.getClassName().indexOf(".ClassPathXmlApplicationContext") != -1) || - (bean.getClassName().indexOf(".FileSystemXmlApplicationContext") != -1)) { - XMLStreamReader creader = getApplicationContextReader(resolver, value); - // Read the context definition for the constructor-arg resources - readContextDefinition(resolver, creader, contextPath, beans, services, references, scaproperties); - } - } - } + if (reader.getAttributeValue(null, "value") != null) + constructorArg.addValue(reader.getAttributeValue(null, "value")); bean.addCustructorArgs(constructorArg); } else if (SpringImplementationConstants.REF_ELEMENT.equals(qname)) { - String ref = reader.getAttributeValue(null, "bean"); + String ref = reader.getAttributeValue(null, "bean"); // Check if the parent element is a property - if (property != null) property.setRef(ref); + if (property != null) property.addRef(ref); // Check if the parent element is a constructor-arg - if (constructorArg != null) constructorArg.setRef(ref); + if (constructorArg != null) constructorArg.addRef(ref); } else if (SpringImplementationConstants.VALUE_ELEMENT.equals(qname)) { String value = reader.getElementText(); // Check if the parent element is a constructor-arg - if (constructorArg != null) { - constructorArg.addValue(value); - // Identify the XML resource specified for the constructor-arg element - if ((value.indexOf(".xml") != -1)) { - if ((bean.getClassName().indexOf(".ClassPathXmlApplicationContext") != -1) || - (bean.getClassName().indexOf(".FileSystemXmlApplicationContext") != -1)) { - XMLStreamReader creader = getApplicationContextReader(resolver, value); - // Read the context definition for the constructor-arg resources - readContextDefinition(resolver, creader, contextPath, beans, services, references, scaproperties); - } - } - } + if (constructorArg != null) constructorArg.addValue(value); + } else if (SpringImplementationConstants.LIST_ELEMENT.equals(qname) || + SpringImplementationConstants.SET_ELEMENT.equals(qname) || + SpringImplementationConstants.MAP_ELEMENT.equals(qname)) { + if (property != null) + readCollections(reader, bean, beans, property, null); + if (constructorArg != null) + readCollections(reader, bean, beans, null, constructorArg); } // end if break; case END_ELEMENT: @@ -385,6 +464,73 @@ public class SpringXMLComponentTypeLoader { throw new ContributionReadException(e); } } + + + /** + * Method which reads the collection elements from Spring application-context.xml file and identifies + * the defined beans, list, maps and sets + */ + private void readCollections(XMLStreamReader reader, + SpringBeanElement bean, + List beans, + SpringPropertyElement property, + SpringConstructorArgElement constructorArg) throws ContributionReadException { + + SpringBeanElement innerbean = null; + + try { + boolean completed = false; + while (!completed) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (SpringImplementationConstants.BEAN_ELEMENT.equals(qname)) { + innerbean = new SpringBeanElement(reader.getAttributeValue(null, "id"), reader + .getAttributeValue(null, "class")); + // Set the first name as bean name, when the @id attribute is absent. + if (reader.getAttributeValue(null, "id") == null) + if (reader.getAttributeValue(null, "name") != null) { + String[] names = (reader.getAttributeValue(null, "name")).split(","); + innerbean.setId(names[0]); + } + innerbean.setInnerBean(true); + beans.add(innerbean); + readBeanDefinition(reader, innerbean, beans); + } else if (SpringImplementationConstants.REF_ELEMENT.equals(qname)) { + String ref = reader.getAttributeValue(null, "bean"); + if (property != null) property.addRef(ref); + if (constructorArg != null) constructorArg.addRef(ref); + } else if (SpringImplementationConstants.LIST_ELEMENT.equals(qname) || + SpringImplementationConstants.SET_ELEMENT.equals(qname) || + SpringImplementationConstants.MAP_ELEMENT.equals(qname)) { + if (property != null) + readCollections(reader, innerbean, beans, property, null); + if (constructorArg != null) + readCollections(reader, innerbean, beans, null, constructorArg); + } else if (SpringImplementationConstants.ENTRY_ELEMENT.equals(qname)) { + String keyRef = reader.getAttributeValue(null, "key-ref"); + String valueRef = reader.getAttributeValue(null, "value-ref"); + if (property != null) {property.addRef(keyRef); property.addRef(valueRef);} + if (constructorArg != null) {constructorArg.addRef(keyRef); constructorArg.addRef(valueRef);} + } // end if + break; + case END_ELEMENT: + if (SpringImplementationConstants.LIST_ELEMENT.equals(reader.getName())) { + completed = true; + break; + } else if (SpringImplementationConstants.SET_ELEMENT.equals(reader.getName())) { + completed = true; + break; + } else if (SpringImplementationConstants.MAP_ELEMENT.equals(reader.getName())) { + completed = true; + break; + } // end if + } // end switch + } // end while + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + } /** * Generates the Spring implementation component type from the configuration contained in the @@ -417,12 +563,30 @@ public class SpringXMLComponentTypeLoader { SpringSCAServiceElement serviceElement = its.next(); Class interfaze = resolveClass(resolver, serviceElement.getType()); Service theService = createService(interfaze, serviceElement.getName()); + // Spring allows duplication of bean definitions in multiple context scenario, + // in such cases, the latest bean definition overrides the older ones, hence + // we will remove any older definition and use the latest. + Service duplicate = null; + for (Service service : componentType.getServices()) { + if (service.getName().equals(theService.getName())) + duplicate = service; + } + if (duplicate != null) + componentType.getServices().remove(duplicate); + componentType.getServices().add(theService); // Add this service to the Service / Bean map String beanName = serviceElement.getTarget(); for (SpringBeanElement beanElement : beans) { if (beanName.equals(beanElement.getId())) { - implementation.setBeanForService(theService, beanElement); + if (isvalidBeanForService(beanElement)) { + // add the required intents and policySets for the service + //theService.getRequiredIntents().addAll(collection); + //theService.getPolicySets().addAll(collection); + implementation.setBeanForService(theService, beanElement); + } else { + // Do we need a warning message here. + } } } // end for } // end while @@ -433,6 +597,19 @@ public class SpringXMLComponentTypeLoader { SpringSCAReferenceElement referenceElement = itr.next(); Class interfaze = resolveClass(resolver, referenceElement.getType()); Reference theReference = createReference(interfaze, referenceElement.getName()); + // Override the older bean definition with the latest ones + // for the duplicate definitions found. + Reference duplicate = null; + for (Reference reference : componentType.getReferences()) { + if (reference.getName().equals(theReference.getName())) + duplicate = reference; + } + if (duplicate != null) + componentType.getReferences().remove(duplicate); + + // add the required intents and policySets for this reference + //theReference.getRequiredIntents().addAll(collection); + //theReference.getPolicySets().addAll(collection); componentType.getReferences().add(theReference); } // end while @@ -448,6 +625,16 @@ public class SpringXMLComponentTypeLoader { // Get the Java class and then an XSD element type for the property Class propType = Class.forName(scaproperty.getType()); theProperty.setXSDType(JavaXMLMapper.getXMLType(propType)); + // Override the older bean definition with the latest ones + // for the duplicate definitions found. + Property duplicate = null; + for (Property property : componentType.getProperties()) { + if (property.getName().equals(theProperty.getName())) + duplicate = property; + } + if (duplicate != null) + componentType.getProperties().remove(duplicate); + componentType.getProperties().add(theProperty); // Remember the Java Class (ie the type) for this property implementation.setPropertyClass(theProperty.getName(), propType); @@ -462,8 +649,8 @@ public class SpringXMLComponentTypeLoader { // Loop through all the beans found while (itb.hasNext()) { SpringBeanElement beanElement = itb.next(); - // If its a innerBean, ignore it - if (beanElement.isInnerBean()) continue; + // If its not a valid bean for service, ignore it + if (!isvalidBeanForService(beanElement)) continue; // Load the Spring bean class Class beanClass = resolveClass(resolver, beanElement.getClassName()); // Introspect the bean @@ -471,6 +658,9 @@ public class SpringXMLComponentTypeLoader { new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs()); ComponentType beanComponentType = assemblyFactory.createComponentType(); javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType); + // Set the service name as bean name + for (Service componentService : beanComponentType.getServices()) + componentService.setName(beanElement.getId()); // Get the service interface defined by this Spring Bean and add to // the component type of the Spring Assembly List beanServices = beanComponentType.getServices(); @@ -505,58 +695,61 @@ public class SpringXMLComponentTypeLoader { Iterator itp = beanElement.getProperties().iterator(); while (itp.hasNext()) { SpringPropertyElement propertyElement = itp.next(); - if (propertyRefUnresolved(propertyElement.getRef(), beans, references, scaproperties)) { - // This means an unresolved reference from the spring bean... - for (Reference reference : beanReferences) { - if (propertyElement.getName().equals(reference.getName())) { - // The name of the reference in this case is the string in - // the @ref attribute of the Spring property element, NOT the - // name of the field in the Spring bean.... - reference.setName(propertyElement.getRef()); - componentType.getReferences().add(reference); - } // end if - } // end for - - // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type - for (Property scaproperty : beanProperties) { - if (propertyElement.getName().equals(scaproperty.getName())) { - // The name of the reference in this case is the string in - // the @ref attribute of the Spring property element, NOT the - // name of the field in the Spring bean.... - Class interfaze = resolveClass(resolver, (propertyMap.get(propertyElement.getName()).getType()).getName()); - Reference theReference = createReference(interfaze, propertyElement.getRef()); - implementation.setUnresolvedBeanRef(propertyElement.getRef(), theReference); - } // end if - } // end for - } // end if + for (String propertyRef : propertyElement.getRefs()) { + if (propertyRefUnresolved(propertyRef, beans, references, scaproperties)) { + // This means an unresolved reference from the spring bean... + for (Reference reference : beanReferences) { + if (propertyElement.getName().equals(reference.getName())) { + // The name of the reference in this case is the string in + // the @ref attribute of the Spring property element, NOT the + // name of the field in the Spring bean.... + reference.setName(propertyRef); + componentType.getReferences().add(reference); + } // end if + } // end for + + // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type + for (Property scaproperty : beanProperties) { + if (propertyElement.getName().equals(scaproperty.getName())) { + // The name of the reference in this case is the string in + // the @ref attribute of the Spring property element, NOT the + // name of the field in the Spring bean.... + Class interfaze = resolveClass(resolver, (propertyMap.get(propertyElement.getName()).getType()).getName()); + Reference theReference = createReference(interfaze, propertyRef); + implementation.setUnresolvedBeanRef(propertyRef, theReference); + } // end if + } // end for + } // end if + } // end for } // end while Iterator itcr = beanElement.getCustructorArgs().iterator(); while (itcr.hasNext()) { SpringConstructorArgElement conArgElement = itcr.next(); - if (propertyRefUnresolved(conArgElement.getRef(), beans, references, scaproperties)) { - for (JavaParameterImpl parameter : constructor.getParameters()) { - String paramType = parameter.getType().getName(); - Class interfaze = resolveClass(resolver, paramType); - // Create a component type reference/property if the constructor-arg element has a - // type attribute OR index attribute declared... - if ((conArgElement.getType() != null && paramType.equals(conArgElement.getType())) || - (conArgElement.getIndex() != -1 && (conArgElement.getIndex() == parameter.getIndex())) || - (conArgElement.getAutoIndex() == parameter.getIndex())) - { - if (parameter.getClassifer().getName().equals("org.osoa.sca.annotations.Reference")) { - Reference theReference = createReference(interfaze, conArgElement.getRef()); - componentType.getReferences().add(theReference); - } - if (parameter.getClassifer().getName().equals("org.osoa.sca.annotations.Property")) { - // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type - // we might need to verify with the component definition later. - Reference theReference = createReference(interfaze, conArgElement.getRef()); - implementation.setUnresolvedBeanRef(conArgElement.getRef(), theReference); - } - } - } // end for - } // end if + for (String constructorArgRef : conArgElement.getRefs()) { + if (propertyRefUnresolved(constructorArgRef, beans, references, scaproperties)) { + for (JavaParameterImpl parameter : constructor.getParameters()) { + String paramType = parameter.getType().getName(); + Class interfaze = resolveClass(resolver, paramType); + // Create a component type reference/property if the constructor-arg element has a + // type attribute OR index attribute declared... + if ((conArgElement.getType() != null && paramType.equals(conArgElement.getType())) || + (conArgElement.getIndex() != -1 && (conArgElement.getIndex() == parameter.getIndex()))) + { + if (parameter.getClassifer().getName().equals("org.osoa.sca.annotations.Reference")) { + Reference theReference = createReference(interfaze, constructorArgRef); + componentType.getReferences().add(theReference); + } + if (parameter.getClassifer().getName().equals("org.osoa.sca.annotations.Property")) { + // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type + // we might need to verify with the component definition later. + Reference theReference = createReference(interfaze, constructorArgRef); + implementation.setUnresolvedBeanRef(constructorArgRef, theReference); + } + } + } // end for + } // end if + } // end for } // end while } // end while @@ -633,25 +826,131 @@ public class SpringXMLComponentTypeLoader { return unresolved; } // end method propertyRefUnresolved - + + /** + * Validates whether the , and elements + * has unique names within the application context. + */ + private void validateBeans(List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + + // The @target attribute of a subelement of a element + // MUST have the value of the @name attribute of one of the + // subelements of the element. + Iterator its = services.iterator(); + while (its.hasNext()) { + SpringSCAServiceElement serviceElement = its.next(); + boolean targetBeanExists = false; + Iterator itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + if (serviceElement.getTarget().equals(beanElement.getId())) + targetBeanExists = true; + } + if (!targetBeanExists) + error("TargetBeanDoesNotExist", beans); + } // end while + + // The value of the @name attribute of an subelement of a + // element MUST be unique amongst the @name attributes of the + // subelements and the subelements of the element. + // AND + // The @default attribute of a subelement of a + // element MUST have the value of the @name attribute of one of the + // subelements of the element. + Iterator itr = references.iterator(); + while (itr.hasNext()) { + SpringSCAReferenceElement referenceElement = itr.next(); + boolean defaultBeanExists = true; + boolean isUniqueReferenceName = true; + Iterator itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + if (referenceElement.getDefaultBean() != null) + if (referenceElement.getDefaultBean().equals(beanElement.getId())) + defaultBeanExists = false; + if (referenceElement.getName().equals(beanElement.getId())) + isUniqueReferenceName = false; + } + Iterator itp = scaproperties.iterator(); + while (itp.hasNext()) { + SpringSCAPropertyElement propertyElement = itp.next(); + if (referenceElement.getName().equals(propertyElement.getName())) + isUniqueReferenceName = false; + } + if (!defaultBeanExists) + error("DefaultBeanDoesNotExist", beans); + if (!isUniqueReferenceName) + error("ScaReferenceNameNotUnique", beans); + } // end while + + // The value of the @name attribute of an subelement of a + // element MUST be unique amongst the @name attributes of the + // subelements and the subelements of the element. + Iterator itp = scaproperties.iterator(); + while (itp.hasNext()) { + SpringSCAPropertyElement propertyElement = itp.next(); + boolean isUniquePropertyName = true; + Iterator itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + if (propertyElement.getName().equals(beanElement.getId())) + isUniquePropertyName = false; + } + Iterator itrp = references.iterator(); + while (itrp.hasNext()) { + SpringSCAReferenceElement referenceElement = itrp.next(); + if (propertyElement.getName().equals(referenceElement.getName())) + isUniquePropertyName = false; + } + if (!isUniquePropertyName) + error("ScaPropertyNameNotUnique", beans); + } // end while + } + + /** + * Validates whether a bean definition is valid for exposing as service. + */ + private boolean isvalidBeanForService(SpringBeanElement beanElement) { + + if (beanElement.isInnerBean()) + return false; + if (beanElement.hasParentAttribute()) + return false; + if (beanElement.hasFactoryMethodAttribute()) + return false; + if (beanElement.hasFactoryBeanAttribute()) + return false; + if (beanElement.getClassName() == null) + return false; + if (beanElement.getClassName().startsWith("org.springframework")) + return false; + // return true otherwise + return true; + } + + /** * Gets hold of the application-context.xml file as a Spring resource * @param locationAttr - the location attribute from the element * @param cl - the ClassLoader for the Spring implementation */ - protected URL getApplicationContextResource(URL url) + protected List getApplicationContextResource(URL url) throws ContributionReadException { File manifestFile = null; File appXmlFile; + File appXmlFolder; File locationFile = null; - + List appCtxResources = new ArrayList(); + if (url != null) { String path = url.getPath(); locationFile = new File(path); } else { - throw new ContributionReadException( - "SpringXMLLoader getApplicationContextResource: " + "unable to find resource file " - + url); + throw new ContributionReadException("SpringXMLComponentTypeLoader getApplicationContextResource: " + + "unable to find resource file " + url); } if (locationFile.isDirectory()) { @@ -662,17 +961,27 @@ public class SpringXMLComponentTypeLoader { Attributes mainAttrs = mf.getMainAttributes(); String appCtxPath = mainAttrs.getValue("Spring-Context"); if (appCtxPath != null) { - appXmlFile = new File(locationFile, appCtxPath); - if (appXmlFile.exists()) { - return appXmlFile.toURL(); - } + String[] cxtPaths = appCtxPath.split(";"); + for (String path : cxtPaths) { + appXmlFile = new File(locationFile, path.trim()); + if (appXmlFile.exists()) { + appCtxResources.add(appXmlFile.toURI().toURL()); + } + } + return appCtxResources; } - } - // no manifest-specified Spring context, use default - appXmlFile = new File(locationFile, "META-INF" + File.separator + "spring" - + File.separator + SpringImplementationConstants.APPLICATION_CONTEXT); - if (appXmlFile.exists()) { - return appXmlFile.toURL(); + } + // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the + // xml files available in the META-INF/spring folder. + appXmlFolder = new File(locationFile, "META-INF" + File.separator + "spring"); + if (appXmlFolder.exists()) { + File[] files = appXmlFolder.listFiles(); + for (File appFile: files) { + if (appFile.getName().endsWith(".xml")) { + appCtxResources.add(appFile.toURI().toURL()); + } + } + return appCtxResources; } } catch (IOException e) { throw new ContributionReadException("Error reading manifest " + manifestFile); @@ -680,35 +989,42 @@ public class SpringXMLComponentTypeLoader { } else { if (locationFile.isFile() && locationFile.getName().endsWith(".jar")) { try { - JarFile jf = new JarFile(locationFile); + JarFile jf = new JarFile(locationFile); JarEntry je; Manifest mf = jf.getManifest(); if (mf != null) { Attributes mainAttrs = mf.getMainAttributes(); String appCtxPath = mainAttrs.getValue("Spring-Context"); if (appCtxPath != null) { - je = jf.getJarEntry(appCtxPath); - if (je != null) { - // TODO return a Spring specific Resource type for jars - return new URL("jar:" + locationFile.toURI().toURL() + "!/" + appCtxPath); - } + String[] cxtPaths = appCtxPath.split(";"); + for (String path : cxtPaths) { + je = jf.getJarEntry(path.trim()); + if (je != null) + appCtxResources.add(new URL("jar:" + locationFile.toURI().toURL() + "!/" + appCtxPath)); + } + return appCtxResources; } } - // Look for the default applicaiton-context.xml file, when MANIFEST.MF is absent. - je = jf.getJarEntry("META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); - if (je != null) { - return new URL("jar:" + locationFile.toURI().toURL() + "!/" + - "META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); + // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the + // xml files available in the META-INF/spring folder. + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + je = entries.nextElement(); + if (je.getName().startsWith("META-INF/spring/") && je.getName().endsWith(".xml")) { + appCtxResources.add(new URL("jar:" + locationFile.toURI().toURL() + "!/" + je.getName())); + } } + return appCtxResources; } catch (IOException e) { // TODO: create a more appropriate exception type - throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + throw new ContributionReadException("SpringXMLComponentTypeLoader getApplicationContextResource: " + " IO exception reading context file.", e); } } else { if (locationFile.getName().endsWith(".xml")) { - return url; + appCtxResources.add(url); + return appCtxResources; } else { // Deal with the directory inside a jar file, in case the contribution itself is a JAR file. @@ -723,19 +1039,26 @@ public class SpringXMLComponentTypeLoader { Attributes mainAttrs = mf.getMainAttributes(); String appCtxPath = mainAttrs.getValue("Spring-Context"); if (appCtxPath != null) { - je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + "/" + appCtxPath); - if (je != null) { - return new URL("jar:" + url.getPath() + "/" + appCtxPath); - } + String[] cxtPaths = appCtxPath.split(";"); + for (String path : cxtPaths) { + je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + "/" + path.trim()); + if (je != null) { + appCtxResources.add(new URL("jar:" + url.getPath() + "/" + path.trim())); + } + } + return appCtxResources; } - } - // Look for the default applicaiton-context.xml file, when MANIFEST.MF is absent. - je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + "/" + - "META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); - if (je != null) { - return new URL("jar:" + url.getPath() + "/" + - "META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); - } + } + // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the + // xml files available in the META-INF/spring folder. + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + je = entries.nextElement(); + if (je.getName().startsWith("META-INF/spring/") && je.getName().endsWith(".xml")) { + appCtxResources.add(new URL("jar:" + url.getPath() + "/" + je.getName())); + } + } + return appCtxResources; } } catch (IOException e) { throw new ContributionReadException("Error reading manifest " + manifestFile); @@ -744,8 +1067,8 @@ public class SpringXMLComponentTypeLoader { } } - throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " - + "META-INF/spring/" + SpringImplementationConstants.APPLICATION_CONTEXT + "not found"); + throw new ContributionReadException("SpringXMLComponentTypeLoader getApplicationContextResource: " + + "unable to read resource file " + url); } // end method getApplicationContextResource /** diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java index 5ca8c128f4..dcb9a53a33 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringContextStub.java @@ -22,7 +22,7 @@ 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.net.URL; +import java.util.List; import org.apache.tuscany.sca.core.invocation.ProxyFactory; import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; @@ -65,7 +65,7 @@ public class SpringContextStub { 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, URL.class}); + Constructor tieConstructor = tieClass.getConstructor(new Class[]{stubClass, List.class}); this.tie = tieConstructor.newInstance(stub, implementation.getResource()); this.startMethod = tieClass.getMethod("start"); diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java index 38883ec062..ce8c6522f4 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java @@ -195,7 +195,7 @@ public class SpringImplementationProcessor implements StAXArtifactProcessor element MUST be unique amongst the subelements of the element +ScaReferenceNameNotUnique = The value of the @name attribute of an element MUST be unique amongst the subelements of the element +ScaPropertyNameNotUnique = The value of the @name attribute of an element MUST be unique amongst the subelements of the element +DefaultBeanDoesNotExist = The @default attribute of a element MUST have the value of the @name attribute of one of the subelements of the element. +TargetBeanDoesNotExist = The @target attribute of a element MUST have the value of the @name attribute of one of the subelements of the element. -- cgit v1.2.3