From ab6904bc2f622129bc548391745b08eb0c219e57 Mon Sep 17 00:00:00 2001 From: rfeng Date: Tue, 21 Jul 2009 07:03:47 +0000 Subject: Fix svn:eol-style and svn:keywords properties for java/xml files git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@796166 13f79535-47bb-0310-9956-ffa450edef68 --- .../implementation/spring/SpringBeanElement.java | 152 +- .../spring/SpringConstructorArgElement.java | 156 +- .../spring/SpringImplementation.java | 440 +++--- .../spring/SpringImplementationConstants.java | 128 +- .../spring/SpringPropertyElement.java | 122 +- .../spring/SpringSCAPropertyElement.java | 104 +- .../spring/SpringSCAReferenceElement.java | 108 +- .../spring/SpringSCAServiceElement.java | 128 +- .../spring/introspect/SpringBeanIntrospector.java | 270 ++-- .../spring/introspect/SpringBeanPojoProcessor.java | 1312 ++++++++-------- .../introspect/SpringXMLComponentTypeLoader.java | 1562 ++++++++++---------- .../spring/invocation/ComponentTie.java | 82 +- .../spring/invocation/PropertyValueTie.java | 106 +- .../spring/invocation/SpringContextStub.java | 260 ++-- .../invocation/SpringImplementationProvider.java | 170 +-- .../SpringImplementationProviderFactory.java | 154 +- .../spring/invocation/SpringImplementationTie.java | 286 ++-- .../invocation/SpringInvocationException.java | 80 +- .../spring/invocation/SpringInvoker.java | 248 ++-- .../spring/xml/SpringImplementationProcessor.java | 466 +++--- .../impl-spring-validation-messages.properties | 44 +- 21 files changed, 3189 insertions(+), 3189 deletions(-) (limited to 'java/sca/modules/implementation-spring/src') 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 86902e5104..f098e2d78e 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 @@ -1,76 +1,76 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a element in a Spring application-context - * - this has id and className attributes - * - plus zero or more property elements as children - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringBeanElement { - - private String id; - private String className; - private boolean innerBean = false; - private List properties = new ArrayList(); - private List constructorargs = new ArrayList(); - - public SpringBeanElement(String id, String className) { - this.id = id; - this.className = className; - } - - public String getClassName() { - return className; - } - - public String getId() { - return id; - } - - public List getProperties() { - return properties; - } - - public void addProperty(SpringPropertyElement property) { - properties.add(property); - } - - public List getCustructorArgs() { - return constructorargs; - } - - public void addCustructorArgs(SpringConstructorArgElement args) { - constructorargs.add(args); - } - - public boolean isInnerBean() { - return innerBean; - } - - public void setInnerBean(boolean innerBean) { - this.innerBean = innerBean; - } - -} // end class SpringBeanElement +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev$ $Date$ + */ +public class SpringBeanElement { + + private String id; + private String className; + private boolean innerBean = false; + private List properties = new ArrayList(); + private List constructorargs = new ArrayList(); + + public SpringBeanElement(String id, String className) { + this.id = id; + this.className = className; + } + + public String getClassName() { + return className; + } + + public String getId() { + return id; + } + + public List getProperties() { + return properties; + } + + public void addProperty(SpringPropertyElement property) { + properties.add(property); + } + + public List getCustructorArgs() { + return constructorargs; + } + + public void addCustructorArgs(SpringConstructorArgElement args) { + constructorargs.add(args); + } + + public boolean isInnerBean() { + return innerBean; + } + + public void setInnerBean(boolean innerBean) { + this.innerBean = innerBean; + } + +} // 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 b644a69c15..88dbaaf119 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 @@ -1,78 +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; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a element in a Spring application-context - * - this has ref attribute - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringConstructorArgElement { - - private String ref; - private String type; - private int autoIndex = -1; - private int index = -1; - private List values = new ArrayList(); - - public SpringConstructorArgElement(String ref, String type) { - this.ref = ref; - this.type = type; - } - - public String getType() { - return this.type; - } - - public String getRef() { - return this.ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public int getIndex() { - return this.index; - } - - public void setIndex(int index) { - this.index = index; - } - - public int getAutoIndex() { - return this.autoIndex; - } - - public void setAutoIndex(int index) { - this.autoIndex = index; - } - - public List getValues() { - return this.values; - } - - public void addValue(String value) { - this.values.add(value); - } -} +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has ref attribute + * + * @version $Rev$ $Date$ + */ +public class SpringConstructorArgElement { + + private String ref; + private String type; + private int autoIndex = -1; + private int index = -1; + private List values = new ArrayList(); + + public SpringConstructorArgElement(String ref, String type) { + this.ref = ref; + this.type = type; + } + + public String getType() { + return this.type; + } + + public String getRef() { + return this.ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public int getIndex() { + return this.index; + } + + public void setIndex(int index) { + this.index = index; + } + + public int getAutoIndex() { + return this.autoIndex; + } + + public void setAutoIndex(int index) { + this.autoIndex = index; + } + + public List getValues() { + return this.values; + } + + public void addValue(String value) { + this.values.add(value); + } +} 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 72ad5adb61..0df04457fb 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 @@ -1,220 +1,220 @@ -/* - * 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; - -import java.net.URL; -import java.util.Hashtable; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.tuscany.sca.assembly.Component; -import org.apache.tuscany.sca.assembly.ComponentType; -import org.apache.tuscany.sca.assembly.Extensible; -import org.apache.tuscany.sca.assembly.Implementation; -import org.apache.tuscany.sca.assembly.Property; -import org.apache.tuscany.sca.assembly.Reference; -import org.apache.tuscany.sca.assembly.Service; -import org.apache.tuscany.sca.assembly.builder.ComponentPreProcessor; -import org.apache.tuscany.sca.assembly.impl.ImplementationImpl; -import org.apache.tuscany.sca.interfacedef.InterfaceContract; -import org.apache.tuscany.sca.runtime.RuntimeComponent; - - -/** - * Represents a Spring implementation. - * - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - */ -public class SpringImplementation extends ImplementationImpl implements Implementation, ComponentPreProcessor, Extensible { - private final static QName TYPE = new QName(SCA11_NS, "implementation.spring"); - // 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 ComponentType componentType; - // Mapping of Services to Beans - private Hashtable serviceMap; - // Mapping of property names to Java class - private Hashtable> propertyMap; - // List of unresolved bean property references - private Hashtable unresolvedBeanRef; - - public SpringImplementation() { - super(TYPE); - this.location = null; - this.resource = null; - setUnresolved(true); - serviceMap = new Hashtable(); - propertyMap = new Hashtable>(); - unresolvedBeanRef = new Hashtable(); - } // end method SpringImplementation - - /* Returns the location attribute for this Spring implementation */ - public String getLocation() { - return location; - } - - /** - * Sets the location attribute for this Spring implementation - * location - a URI to the Spring application-context file - */ - public void setLocation(String location) { - this.location = location; - return; - } - - public void setResource(URL resource) { - this.resource = resource; - } - - public URL getResource() { - return resource; - } - - /* - * Returns the componentType for this Spring implementation - */ - public ComponentType getComponentType() { - return componentType; - } - - /* - * Sets the componentType for this Spring implementation - */ - public void setComponentType(ComponentType componentType) { - this.componentType = componentType; - } - - @Override - public List getServices() { - return componentType.getServices(); - } - - @Override - public List getReferences() { - return componentType.getReferences(); - } - - @Override - public List getProperties() { - return componentType.getProperties(); - } - - /** - * Returns the Spring Bean which implements a particular service - * @param service the service - * @return the bean which implements the service, as a SpringBeanElement - */ - public SpringBeanElement getBeanFromService(Service service) { - SpringBeanElement theBean = serviceMap.get(service.getName()); - return theBean; - } - - /** - * Sets the mapping from a service to the Spring Bean that implements the service - * @param service the service - * @param theBean a SpringBeanElement for the Bean implementing the service - */ - public void setBeanForService(Service service, SpringBeanElement theBean) { - serviceMap.put(service.getName(), theBean); - } - - /** - * Add a mapping from a SCA property name to a Java class for the property - * @param propertyName - * @param propertyClass - */ - public void setPropertyClass(String propertyName, Class propertyClass) { - if (propertyName == null || propertyClass == null) - return; - propertyMap.put(propertyName, propertyClass); - return; - } // end method setPropertyClass - - /** - * Gets the Java Class for an SCA property - * @param propertyName - the property name - * @return - a Class object for the type of the property - */ - public Class getPropertyClass(String propertyName) { - return propertyMap.get(propertyName); - } // end method getPropertyClass - - public void setUnresolvedBeanRef(String refName, Reference reference) { - if (refName == null || reference == null) - return; - unresolvedBeanRef.put(refName, reference); - return; - } // end method setUnresolvedBeanRef - - public Reference getUnresolvedBeanRef(String refName) { - return unresolvedBeanRef.get(refName); - } // end method getUnresolvedBeanRef - - - /** - * Use preProcess to validate and map the references and properties dynamically - */ - public void preProcess(Component component) { - if (!(component instanceof RuntimeComponent)) - return; - - RuntimeComponent rtc = (RuntimeComponent) component; - - for (Reference reference : rtc.getReferences()) { - if (unresolvedBeanRef.containsKey(reference.getName())) { - Reference ref = unresolvedBeanRef.get(reference.getName()); - componentType.getReferences().add( - createReference(reference, ref.getInterfaceContract())); - unresolvedBeanRef.remove(reference.getName()); - } - } - - for (Property property : rtc.getProperties()) { - if (unresolvedBeanRef.containsKey(property.getName())) { - componentType.getProperties().add(createProperty(property)); - this.setPropertyClass(property.getName(), property.getClass()); - unresolvedBeanRef.remove(property.getName()); - } - } - } - - protected Reference createReference(Reference reference, InterfaceContract interfaze) { - Reference newReference; - try { - newReference = (Reference)reference.clone(); - if (newReference.getInterfaceContract() == null) - newReference.setInterfaceContract(interfaze); - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); // should not ever happen - } - return newReference; - } - - protected Property createProperty(Property property) { - Property newProperty; - try { - newProperty = (Property)property.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); // should not ever happen - } - return newProperty; - } -} +/* + * 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; + +import java.net.URL; +import java.util.Hashtable; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Extensible; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.builder.ComponentPreProcessor; +import org.apache.tuscany.sca.assembly.impl.ImplementationImpl; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + + +/** + * Represents a Spring implementation. + * + * @version $Rev$ $Date$ + */ +public class SpringImplementation extends ImplementationImpl implements Implementation, ComponentPreProcessor, Extensible { + private final static QName TYPE = new QName(SCA11_NS, "implementation.spring"); + // 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 ComponentType componentType; + // Mapping of Services to Beans + private Hashtable serviceMap; + // Mapping of property names to Java class + private Hashtable> propertyMap; + // List of unresolved bean property references + private Hashtable unresolvedBeanRef; + + public SpringImplementation() { + super(TYPE); + this.location = null; + this.resource = null; + setUnresolved(true); + serviceMap = new Hashtable(); + propertyMap = new Hashtable>(); + unresolvedBeanRef = new Hashtable(); + } // end method SpringImplementation + + /* Returns the location attribute for this Spring implementation */ + public String getLocation() { + return location; + } + + /** + * Sets the location attribute for this Spring implementation + * location - a URI to the Spring application-context file + */ + public void setLocation(String location) { + this.location = location; + return; + } + + public void setResource(URL resource) { + this.resource = resource; + } + + public URL getResource() { + return resource; + } + + /* + * Returns the componentType for this Spring implementation + */ + public ComponentType getComponentType() { + return componentType; + } + + /* + * Sets the componentType for this Spring implementation + */ + public void setComponentType(ComponentType componentType) { + this.componentType = componentType; + } + + @Override + public List getServices() { + return componentType.getServices(); + } + + @Override + public List getReferences() { + return componentType.getReferences(); + } + + @Override + public List getProperties() { + return componentType.getProperties(); + } + + /** + * Returns the Spring Bean which implements a particular service + * @param service the service + * @return the bean which implements the service, as a SpringBeanElement + */ + public SpringBeanElement getBeanFromService(Service service) { + SpringBeanElement theBean = serviceMap.get(service.getName()); + return theBean; + } + + /** + * Sets the mapping from a service to the Spring Bean that implements the service + * @param service the service + * @param theBean a SpringBeanElement for the Bean implementing the service + */ + public void setBeanForService(Service service, SpringBeanElement theBean) { + serviceMap.put(service.getName(), theBean); + } + + /** + * Add a mapping from a SCA property name to a Java class for the property + * @param propertyName + * @param propertyClass + */ + public void setPropertyClass(String propertyName, Class propertyClass) { + if (propertyName == null || propertyClass == null) + return; + propertyMap.put(propertyName, propertyClass); + return; + } // end method setPropertyClass + + /** + * Gets the Java Class for an SCA property + * @param propertyName - the property name + * @return - a Class object for the type of the property + */ + public Class getPropertyClass(String propertyName) { + return propertyMap.get(propertyName); + } // end method getPropertyClass + + public void setUnresolvedBeanRef(String refName, Reference reference) { + if (refName == null || reference == null) + return; + unresolvedBeanRef.put(refName, reference); + return; + } // end method setUnresolvedBeanRef + + public Reference getUnresolvedBeanRef(String refName) { + return unresolvedBeanRef.get(refName); + } // end method getUnresolvedBeanRef + + + /** + * Use preProcess to validate and map the references and properties dynamically + */ + public void preProcess(Component component) { + if (!(component instanceof RuntimeComponent)) + return; + + RuntimeComponent rtc = (RuntimeComponent) component; + + for (Reference reference : rtc.getReferences()) { + if (unresolvedBeanRef.containsKey(reference.getName())) { + Reference ref = unresolvedBeanRef.get(reference.getName()); + componentType.getReferences().add( + createReference(reference, ref.getInterfaceContract())); + unresolvedBeanRef.remove(reference.getName()); + } + } + + for (Property property : rtc.getProperties()) { + if (unresolvedBeanRef.containsKey(property.getName())) { + componentType.getProperties().add(createProperty(property)); + this.setPropertyClass(property.getName(), property.getClass()); + unresolvedBeanRef.remove(property.getName()); + } + } + } + + protected Reference createReference(Reference reference, InterfaceContract interfaze) { + Reference newReference; + try { + newReference = (Reference)reference.clone(); + if (newReference.getInterfaceContract() == null) + newReference.setInterfaceContract(interfaze); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // should not ever happen + } + return newReference; + } + + protected Property createProperty(Property property) { + Property newProperty; + try { + newProperty = (Property)property.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // should not ever happen + } + return newProperty; + } +} 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 339e753c04..0bccdb369c 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 @@ -1,64 +1,64 @@ -/* - * 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; - -import javax.xml.namespace.QName; - -/** - * Constants used in Spring Application Context XML files. - */ -public interface SpringImplementationConstants { - - String SCA_NS = "http://www.springframework.org/schema/sca"; - String SPRING_NS = "http://www.springframework.org/schema/beans"; - - String PROPERTY = "property"; - QName SCAPROPERTY_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 REFERENCE = "reference"; - QName REFERENCE_ELEMENT = new QName(SCA_NS, REFERENCE); - - String BEANS = "beans"; - QName BEANS_ELEMENT = new QName(SPRING_NS, BEANS); - - String IMPORT = "import"; - QName IMPORT_ELEMENT = new QName(SPRING_NS, IMPORT); - - String BEAN = "bean"; - QName BEAN_ELEMENT = new QName(SPRING_NS, BEAN); - - String CONSTRUCTORARG = "constructor-arg"; - QName CONSTRUCTORARG_ELEMENT = new QName(SPRING_NS, CONSTRUCTORARG); - - String LIST = "list"; - QName LIST_ELEMENT = new QName(SPRING_NS, LIST); - - String VALUE = "value"; - QName VALUE_ELEMENT = new QName(SPRING_NS, VALUE); - - String REF = "ref"; - QName REF_ELEMENT = new QName(SPRING_NS, REF); - - String APPLICATION_CONTEXT = "application-context.xml"; -} +/* + * 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; + +import javax.xml.namespace.QName; + +/** + * Constants used in Spring Application Context XML files. + */ +public interface SpringImplementationConstants { + + String SCA_NS = "http://www.springframework.org/schema/sca"; + String SPRING_NS = "http://www.springframework.org/schema/beans"; + + String PROPERTY = "property"; + QName SCAPROPERTY_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 REFERENCE = "reference"; + QName REFERENCE_ELEMENT = new QName(SCA_NS, REFERENCE); + + String BEANS = "beans"; + QName BEANS_ELEMENT = new QName(SPRING_NS, BEANS); + + String IMPORT = "import"; + QName IMPORT_ELEMENT = new QName(SPRING_NS, IMPORT); + + String BEAN = "bean"; + QName BEAN_ELEMENT = new QName(SPRING_NS, BEAN); + + String CONSTRUCTORARG = "constructor-arg"; + QName CONSTRUCTORARG_ELEMENT = new QName(SPRING_NS, CONSTRUCTORARG); + + String LIST = "list"; + QName LIST_ELEMENT = new QName(SPRING_NS, LIST); + + String VALUE = "value"; + QName VALUE_ELEMENT = new QName(SPRING_NS, VALUE); + + String REF = "ref"; + QName REF_ELEMENT = new QName(SPRING_NS, REF); + + 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 c6637d31c4..2a55e2c7c8 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 @@ -1,61 +1,61 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a element in a Spring application-context - * - this has name and ref attributes - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringPropertyElement { - - private String name; - private String ref; - private List values = new ArrayList(); - - public SpringPropertyElement(String name, String ref) { - this.name = name; - this.ref = ref; - } - - public String getName() { - return name; - } - - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public List getValues() { - return this.values; - } - - public void addValue(String value) { - this.values.add(value); - } - -} // end class SpringPropertyElement +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has name and ref attributes + * + * @version $Rev$ $Date$ + */ +public class SpringPropertyElement { + + private String name; + private String ref; + private List values = new ArrayList(); + + public SpringPropertyElement(String name, String ref) { + this.name = name; + this.ref = ref; + } + + public String getName() { + return name; + } + + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public List getValues() { + return this.values; + } + + 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/SpringSCAPropertyElement.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java index c666217777..b192580a78 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java @@ -1,52 +1,52 @@ -/* - * 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; - -/** - * Represents an element in a Spring application-context - * - this has name and type attributes - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - */ -public class SpringSCAPropertyElement { - - private String name; - private String type; - - public SpringSCAPropertyElement(String name, String type) { - this.name = name; - this.type = type; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setType(String type) { - this.type = type; - } - - public String getType() { - return type; - } - -} // end class SpringPropertyElement +/* + * 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; + +/** + * Represents an element in a Spring application-context + * - this has name and type attributes + * @version $Rev$ $Date$ + */ +public class SpringSCAPropertyElement { + + private String name; + private String type; + + public SpringSCAPropertyElement(String name, String type) { + this.name = name; + this.type = type; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} // 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 5b6206ef9b..47c87fe7fe 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 @@ -1,54 +1,54 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring; - -/** - * Represents a element in a Spring application-context - * - this has id and className attributes - * - plus zero or more property elements as children - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringSCAReferenceElement { - - private String name; - private String type; - - public SpringSCAReferenceElement(String name, String type) { - this.name = name; - this.type = type; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setType(String type) { - this.type = type; - } - - public String getType() { - return type; - } - -} // end class SpringSCAReferenceElement +/* + * 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; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev$ $Date$ + */ +public class SpringSCAReferenceElement { + + private String name; + private String type; + + public SpringSCAReferenceElement(String name, String type) { + this.name = name; + this.type = type; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} // 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 774bc051d3..7362a4521c 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 @@ -1,64 +1,64 @@ -/* - * 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; - -/** - * Represents a element in a Spring application-context - * - this has id and className attributes - * - plus zero or more property elements as children - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringSCAServiceElement { - - private String name; - private String type; - private String target; - - public SpringSCAServiceElement(String name, String type, String target) { - this.name = name; - this.type = type; - this.target = target; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setType(String type) { - this.type = type; - } - - public String getType() { - return type; - } - - public void setTarget(String target) { - this.target = target; - } - - public String getTarget() { - return target; - } - -} // end class SpringSCAServiceElement +/* + * 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; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev$ $Date$ + */ +public class SpringSCAServiceElement { + + private String name; + private String type; + private String target; + + public SpringSCAServiceElement(String name, String type, String target) { + this.name = name; + this.type = type; + this.target = target; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getTarget() { + return target; + } + +} // end class SpringSCAServiceElement diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java index de137e3d9c..720db77e35 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java @@ -1,135 +1,135 @@ -/* - * 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.introspect; - -import java.util.List; - -import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.ComponentType; -import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; -import org.apache.tuscany.sca.implementation.java.DefaultJavaImplementationFactory; -import org.apache.tuscany.sca.implementation.java.IntrospectionException; -import org.apache.tuscany.sca.implementation.java.JavaImplementation; -import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory; -import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor; -import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ComponentNameProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ConstructorProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ContextProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.DestroyProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.EagerInitProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.InitProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.PolicyProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.PropertyProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ReferenceProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ResourceProcessor; -import org.apache.tuscany.sca.implementation.java.introspect.impl.ServiceProcessor; -import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; -import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; -import org.apache.tuscany.sca.policy.PolicyFactory; - -/** - * Provides introspection functions for Spring beans - * This version leans heavily on the implementation-java classes - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringBeanIntrospector { - - private JavaImplementationFactory javaImplementationFactory; - - /** - * The constructor sets up the various visitor elements that will be used to introspect - * the Spring bean and extract SCA information. - * - * @param assemblyFactory The Assembly Factory to use - * @param javaFactory The Java Interface Factory to use - * @param policyFactory The Policy Factory to use. - */ - public SpringBeanIntrospector(AssemblyFactory assemblyFactory, - JavaInterfaceFactory javaFactory, - PolicyFactory policyFactory, - List conArgs) { - - javaImplementationFactory = new DefaultJavaImplementationFactory(); - - // Create the list of class visitors - BaseJavaClassVisitor[] extensions = - new BaseJavaClassVisitor[] { - new ConstructorProcessor(assemblyFactory), - new ComponentNameProcessor(assemblyFactory), - new ContextProcessor(assemblyFactory), - new DestroyProcessor(assemblyFactory), - new EagerInitProcessor(assemblyFactory), - new InitProcessor(assemblyFactory), - new PropertyProcessor(assemblyFactory), - new ReferenceProcessor(assemblyFactory, javaFactory), - new ResourceProcessor(assemblyFactory), - new ServiceProcessor(assemblyFactory, javaFactory), - new SpringBeanPojoProcessor(assemblyFactory, javaFactory, conArgs), - new PolicyProcessor(assemblyFactory, policyFactory)}; - for (JavaClassVisitor extension : extensions) { - javaImplementationFactory.addClassVisitor(extension); - } - - } // end constructor - - /** - * Introspect a Spring Bean and extract the features important to SCA - * @param beanClass the Spring Bean class to introspect - * @param componentType the componentType that is filled in through the introspection - * process (assumed empty on invocation, filled on return - * @return a Map of property names to JavaElementImpl - * @throws ContributionResolveException - if there was a problem resolving the - * Spring Bean or its componentType - * - */ - public JavaImplementation introspectBean(Class beanClass, ComponentType componentType) throws ContributionResolveException - { - if (componentType == null) - throw new ContributionResolveException("Introspect Spring bean: supplied componentType is null"); - - // Create a Java implementation ready for the introspection - JavaImplementation javaImplementation = javaImplementationFactory.createJavaImplementation(); - - try { - // Introspect the bean...the results of the introspection are placed into the Java implementation - javaImplementationFactory.createJavaImplementation(javaImplementation, beanClass); - - // Extract the services, references & properties found through introspection - // put the services, references and properties into the component type - componentType.getServices().addAll(javaImplementation.getServices()); - componentType.getReferences().addAll(javaImplementation.getReferences()); - componentType.getProperties().addAll(javaImplementation.getProperties()); - - } catch (IntrospectionException e) { - throw new ContributionResolveException(e); - } // end try - - /* List services = javaImplementation.getServices(); - for (Service service : services) { - String name = service.getName(); - System.out.println("Spring Bean: found service with name: " + name); - } // end for */ - - return javaImplementation; - - } // end method introspectBean - -} // end class SpringBeanIntrospector +/* + * 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.introspect; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.implementation.java.DefaultJavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.IntrospectionException; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ComponentNameProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ConstructorProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ContextProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.DestroyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.EagerInitProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.InitProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.PolicyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.PropertyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ReferenceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ResourceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ServiceProcessor; +import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * Provides introspection functions for Spring beans + * This version leans heavily on the implementation-java classes + * + * @version $Rev$ $Date$ + */ +public class SpringBeanIntrospector { + + private JavaImplementationFactory javaImplementationFactory; + + /** + * The constructor sets up the various visitor elements that will be used to introspect + * the Spring bean and extract SCA information. + * + * @param assemblyFactory The Assembly Factory to use + * @param javaFactory The Java Interface Factory to use + * @param policyFactory The Policy Factory to use. + */ + public SpringBeanIntrospector(AssemblyFactory assemblyFactory, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory, + List conArgs) { + + javaImplementationFactory = new DefaultJavaImplementationFactory(); + + // Create the list of class visitors + BaseJavaClassVisitor[] extensions = + new BaseJavaClassVisitor[] { + new ConstructorProcessor(assemblyFactory), + new ComponentNameProcessor(assemblyFactory), + new ContextProcessor(assemblyFactory), + new DestroyProcessor(assemblyFactory), + new EagerInitProcessor(assemblyFactory), + new InitProcessor(assemblyFactory), + new PropertyProcessor(assemblyFactory), + new ReferenceProcessor(assemblyFactory, javaFactory), + new ResourceProcessor(assemblyFactory), + new ServiceProcessor(assemblyFactory, javaFactory), + new SpringBeanPojoProcessor(assemblyFactory, javaFactory, conArgs), + new PolicyProcessor(assemblyFactory, policyFactory)}; + for (JavaClassVisitor extension : extensions) { + javaImplementationFactory.addClassVisitor(extension); + } + + } // end constructor + + /** + * Introspect a Spring Bean and extract the features important to SCA + * @param beanClass the Spring Bean class to introspect + * @param componentType the componentType that is filled in through the introspection + * process (assumed empty on invocation, filled on return + * @return a Map of property names to JavaElementImpl + * @throws ContributionResolveException - if there was a problem resolving the + * Spring Bean or its componentType + * + */ + public JavaImplementation introspectBean(Class beanClass, ComponentType componentType) throws ContributionResolveException + { + if (componentType == null) + throw new ContributionResolveException("Introspect Spring bean: supplied componentType is null"); + + // Create a Java implementation ready for the introspection + JavaImplementation javaImplementation = javaImplementationFactory.createJavaImplementation(); + + try { + // Introspect the bean...the results of the introspection are placed into the Java implementation + javaImplementationFactory.createJavaImplementation(javaImplementation, beanClass); + + // Extract the services, references & properties found through introspection + // put the services, references and properties into the component type + componentType.getServices().addAll(javaImplementation.getServices()); + componentType.getReferences().addAll(javaImplementation.getReferences()); + componentType.getProperties().addAll(javaImplementation.getProperties()); + + } catch (IntrospectionException e) { + throw new ContributionResolveException(e); + } // end try + + /* List services = javaImplementation.getServices(); + for (Service service : services) { + String name = service.getName(); + System.out.println("Spring Bean: found service with name: " + name); + } // end for */ + + return javaImplementation; + + } // end method introspectBean + +} // end class SpringBeanIntrospector diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java index 56b3ce2213..bef2d3665d 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java @@ -1,656 +1,656 @@ -/* - * 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.introspect; - -import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllInterfaces; -import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllPublicAndProtectedFields; -import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods; -import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getPrivateFields; -import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.toPropertyName; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.jws.WebService; - -import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.Contract; -import org.apache.tuscany.sca.assembly.Multiplicity; -import org.apache.tuscany.sca.implementation.java.IntrospectionException; -import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl; -import org.apache.tuscany.sca.implementation.java.JavaElementImpl; -import org.apache.tuscany.sca.implementation.java.JavaImplementation; -import org.apache.tuscany.sca.implementation.java.JavaParameterImpl; -import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor; -import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper; -import org.apache.tuscany.sca.implementation.java.introspect.impl.AmbiguousConstructorException; -import org.apache.tuscany.sca.implementation.java.introspect.impl.InvalidServiceTypeException; -import org.apache.tuscany.sca.implementation.java.introspect.impl.NoConstructorException; -import org.apache.tuscany.sca.implementation.java.introspect.impl.Resource; -import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; -import org.apache.tuscany.sca.interfacedef.Interface; -import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; -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.oasisopen.sca.annotation.Callback; -import org.oasisopen.sca.annotation.Context; -import org.oasisopen.sca.annotation.Property; -import org.oasisopen.sca.annotation.Reference; -import org.oasisopen.sca.annotation.Remotable; - -/** - * Heuristically evaluates an un-annotated Java implementation type to determine - * services, references, and properties according to the algorithm described in - * the SCA Java Client and Implementation Model Specification

TODO - * Implement:

When no service interface is annotated, need to calculate a - * single service comprising all public methods that are not reference or - * property injection sites. If that service can be exactly mapped to an - * interface implemented by the class then the service interface will be defined - * in terms of that interface. - * - * @version $Rev: 689426 $ $Date: 2008-08-27 14:56:06 +0530 (Wed, 27 Aug 2008) $ - */ -public class SpringBeanPojoProcessor extends BaseJavaClassVisitor { - private JavaInterfaceFactory javaFactory; - private List conArgs; - - public SpringBeanPojoProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory, List conArgs) { - super(assemblyFactory); - this.javaFactory = javaFactory; - this.conArgs = conArgs; - } - - @Override - public void visitEnd(Class clazz, JavaImplementation type) throws IntrospectionException { - List services = type.getServices(); - if (services.isEmpty()) { - // heuristically determine the service - /** - * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation - * In the cases described below, the services offered by a Java implementation class may be determined - * through introspection, eliding the need to specify them using @Service. The following algorithm is used - * to determine how services are introspected from an implementation class: - * - * If the interfaces of the SCA services are not specified with the @Service annotation on the - * implementation class, it is assumed that all implemented interfaces that have been annotated - * as @Remotable are the service interfaces provided by the component. If none of the implemented - * interfaces is remotable, then by default the implementation offers a single service whose type - * is the implementation class. - */ - Set> interfaces = getAllInterfaces(clazz); - for (Class i : interfaces) { - if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) { - addService(type, i); - } - } - if (services.isEmpty()) { - // class is the interface - addService(type, clazz); - } - } - Set methods = getAllUniquePublicProtectedMethods(clazz, false); - if (!type.getReferenceMembers().isEmpty() || !type.getPropertyMembers().isEmpty()) { - // references and properties have been explicitly defined - // if (type.getServices().isEmpty()) { - // calculateServiceInterface(clazz, type, methods); - // if (type.getServices().isEmpty()) { - // throw new ServiceTypeNotFoundException(clazz.getName()); - // } - // } - evaluateConstructor(type, clazz); - return; - } - calcPropRefs(methods, services, type, clazz); - evaluateConstructor(type, clazz); - } - - private void addService(JavaImplementation type, Class clazz) throws IntrospectionException { - try { - org.apache.tuscany.sca.assembly.Service service = createService(clazz); - type.getServices().add(service); - } catch (InvalidInterfaceException e) { - throw new IntrospectionException(e); - } - } - - private boolean isPublicSetter(Method method) { - return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers()) - && method.getName().startsWith("set") - && method.getReturnType() == void.class; - } - - private boolean isProtectedSetter(Method method) { - return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers()) - && method.getName().startsWith("set") - && method.getReturnType() == void.class; - } - - private void calcPropRefs(Set methods, - List services, - JavaImplementation type, - Class clazz) throws IntrospectionException { - // heuristically determine the properties references - // make a first pass through all public methods with one param - Set setters = new HashSet(); - Set others = new HashSet(); - for (Method method : methods) { - if (!isPublicSetter(method)) { - continue; - } - if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) { - // Add the property name as others - others.add(toPropertyName(method.getName())); - continue; - } - if (!isInServiceInterface(method, services)) { - // Not part of the service interface - String name = toPropertyName(method.getName()); - setters.add(name); - // avoid duplicate property or ref names - if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) { - Class param = method.getParameterTypes()[0]; - Type genericType = method.getGenericParameterTypes()[0]; - if (isReferenceType(param, genericType)) { - type.getReferences().add(createReference(name, param)); - type.getReferenceMembers().put(name, new JavaElementImpl(method, 0)); - } else { - type.getProperties().add(createProperty(name, param)); - type.getPropertyMembers().put(name, new JavaElementImpl(method, 0)); - } - } - } - } - // second pass for protected methods with one param - for (Method method : methods) { - if (!isProtectedSetter(method)) { - continue; - } - if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) { - // Add the property name as others - others.add(toPropertyName(method.getName())); - continue; - } - Class param = method.getParameterTypes()[0]; - String name = toPropertyName(method.getName()); - setters.add(name); - // avoid duplicate property or ref names - if (isReferenceType(param, method.getGenericParameterTypes()[0])) { - if (!type.getReferenceMembers().containsKey(name)) { - type.getReferences().add(createReference(name, param)); - type.getReferenceMembers().put(name, new JavaElementImpl(method, 0)); - } - } else { - if (!type.getPropertyMembers().containsKey(name)) { - type.getProperties().add(createProperty(name, param)); - type.getPropertyMembers().put(name, new JavaElementImpl(method, 0)); - } - } - } - - // Public or protected fields unless there is a public or protected - // setter method - // for the same name - Set fields = getAllPublicAndProtectedFields(clazz, false); - for (Field field : fields) { - if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) { - continue; - } - if (setters.contains(field.getName()) || others.contains(field.getName())) { - continue; - } - String name = field.getName(); - Class paramType = field.getType(); - if (isReferenceType(paramType, field.getGenericType())) { - if (!type.getReferenceMembers().containsKey(name)) { - type.getReferences().add(createReference(name, paramType)); - type.getReferenceMembers().put(name, new JavaElementImpl(field)); - } - } else { - if (!type.getPropertyMembers().containsKey(name)) { - type.getProperties().add(createProperty(name, paramType)); - type.getPropertyMembers().put(name, new JavaElementImpl(field)); - } - } - } - - // Private fields unless there is a public or protected - // setter method for the same name - Set privateFields = getPrivateFields(clazz); - for (Field field : privateFields) { - if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) { - continue; - } - if (setters.contains(field.getName()) || others.contains(field.getName())) { - continue; - } - String name = field.getName(); - Class paramType = field.getType(); - if (isReferenceType(paramType, field.getGenericType())) { - if (!type.getReferenceMembers().containsKey(name)) { - type.getReferences().add(createReference(name, paramType)); - type.getReferenceMembers().put(name, new JavaElementImpl(field)); - } - } else { - if (!type.getPropertyMembers().containsKey(name)) { - type.getProperties().add(createProperty(name, paramType)); - type.getPropertyMembers().put(name, new JavaElementImpl(field)); - } - } - } - } - - /** - * Determines the constructor to use based on the component type's - * references and properties - * - * @param type the component type - * @param clazz the implementation class corresponding to the component type - * @throws NoConstructorException if no suitable constructor is found - * @throws AmbiguousConstructorException if the parameters of a constructor - * cannot be unambiguously mapped to references and properties - */ - @SuppressWarnings("unchecked") - private void evaluateConstructor(JavaImplementation type, Class clazz) throws IntrospectionException { - // determine constructor if one is not annotated - JavaConstructorImpl definition = type.getConstructor(); - Map props = type.getPropertyMembers(); - Map refs = type.getReferenceMembers(); - Constructor constructor; - boolean explict = false; - if (definition != null && definition.getConstructor() - .isAnnotationPresent(org.oasisopen.sca.annotation.Constructor.class)) { - // the constructor was already defined explicitly - return; - } else if (definition != null) { - explict = true; - constructor = definition.getConstructor(); - } else { - // no definition, heuristically determine constructor - Constructor[] constructors = clazz.getConstructors(); - if (constructors.length == 0) { - throw new NoConstructorException("No public constructor for class"); - } else if (constructors.length == 1) { - // Only one constructor, take it - constructor = constructors[0]; - } else { - // multiple constructors scenario - Constructor selected = null; - for (Constructor ctor : constructors) { - if (ctor.getParameterTypes().length == 0) { - selected = ctor; - } else if (ctor.getParameterTypes().length == conArgs.size()) { - // we will find a constructor which has atleast one - // reference or property as its parameter types. - Class[] parametersTypes = ctor.getParameterTypes(); - for (Class pType: parametersTypes) { - for (JavaElementImpl property : props.values()) { - if (pType.equals(property.getType())) - selected = ctor; - } - for (JavaElementImpl reference : refs.values()) { - if (pType.equals(reference.getType())) - selected = ctor; - } - } - } - } - if (selected == null) { - throw new NoConstructorException(); - } - constructor = selected; - } - definition = type.getConstructors().get(constructor); - type.setConstructor(definition); - } - - JavaParameterImpl[] parameters = definition.getParameters(); - if (parameters.length == 0) { - return; - } - - Annotation[][] annotations = constructor.getParameterAnnotations(); - if (!explict) { - // the constructor wasn't defined by an annotation, so check to see - // if any of the params have an annotation - // which we can impute as explicitly defining the constructor, e.g. - // @Property, @Reference, or @Autowire - explict = injectionAnnotationsPresent(annotations); - } - if (explict) { - for (int i = 0; i < parameters.length; i++) { - if (isAnnotated(parameters[i])) { - continue; - } else if (!findReferenceOrProperty(parameters[i], props, refs)) { - throw new AmbiguousConstructorException(parameters[i].toString()); - } - } - } else { - if (!areUnique(parameters)) { - throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); - } - if (!calcPropRefUniqueness(props.values(), refs.values())) { - throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); - } - if (!(props.isEmpty() && refs.isEmpty())) { - calcParamNames(parameters, props, refs); - } else { - heuristicParamNames(type, parameters); - - } - } - } - - private void calcParamNames(JavaParameterImpl[] parameters, - Map props, - Map refs) throws AmbiguousConstructorException { - // the constructor param types must unambiguously match defined - // reference or property types - for (JavaParameterImpl param : parameters) { - if (!findReferenceOrProperty(param, props, refs)) { - throw new AmbiguousConstructorException(param.getName()); - } - } - } - - private void heuristicParamNames(JavaImplementation type, JavaParameterImpl[] parameters) - throws IntrospectionException { - // heuristically determine refs and props from the parameter types - for (JavaParameterImpl p : parameters) { - String name = p.getType().getSimpleName().toLowerCase(); - if (isReferenceType(p.getType(), p.getGenericType())) { - type.getReferences().add(createReference(name, p.getType())); - p.setClassifer(Reference.class); - type.getReferenceMembers().put(name, p); - } else { - type.getProperties().add(createProperty(name, p.getType())); - p.setClassifer(Property.class); - type.getPropertyMembers().put(name, p); - } - p.setName(name); - } - } - - private static boolean areUnique(Class[] collection) { - Set set = new HashSet(Arrays.asList(collection)); - return set.size() == collection.length; - } - - /** - * Returns true if the union of the given collections of properties and - * references have unique Java types - */ - private boolean calcPropRefUniqueness(Collection props, Collection refs) { - - Class[] classes = new Class[props.size() + refs.size()]; - int i = 0; - for (JavaElementImpl property : props) { - classes[i] = property.getType(); - i++; - } - for (JavaElementImpl reference : refs) { - classes[i] = reference.getType(); - i++; - } - return areUnique(classes); - } - - /** - * Unambiguously finds the reference or property associated with the given - * type - * - * @return the name of the reference or property if found, null if not - * @throws AmbiguousConstructorException if the constructor parameter cannot - * be resolved to a property or reference - */ - private boolean findReferenceOrProperty(JavaParameterImpl parameter, - Map props, - Map refs) throws AmbiguousConstructorException { - - boolean found = false; - if (!"".equals(parameter.getName())) { - // Match by name - JavaElementImpl prop = props.get(parameter.getName()); - if (prop != null && prop.getType() == parameter.getType()) { - parameter.setClassifer(Property.class); - return true; - } - JavaElementImpl ref = refs.get(parameter.getName()); - if (ref != null && ref.getType() == parameter.getType()) { - parameter.setClassifer(Reference.class); - return true; - } - } - for (JavaElementImpl property : props.values()) { - if (property.getType() == parameter.getType()) { - if (found) { - throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", - (Member)parameter.getAnchor()); - } - parameter.setClassifer(Property.class); - parameter.setName(property.getName()); - found = true; - // do not break since ambiguities must be checked, i.e. more - // than one prop or ref of the same type - } - } - for (JavaElementImpl reference : refs.values()) { - if (reference.getType() == parameter.getType()) { - if (found) { - throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", - (Member)parameter.getAnchor()); - } - parameter.setClassifer(Reference.class); - parameter.setName(reference.getName()); - found = true; - // do not break since ambiguities must be checked, i.e. more - // than one prop or ref of the same type - } - } - return found; - } - - /** - * Returns true if a given type is reference according to the SCA - * specification rules for determining reference types The following rules - * are used to determine whether an unannotated field or setter method is a - * property or reference: - *

    - *
  1. If its type is simple, then it is a property. - *
  2. If its type is complex, then if the type is an interface marked by - * - * @Remotable, then it is a reference; otherwise, it is a property. - *
  3. Otherwise, if the type associated with the member is an - * array or a java.util.Collection, the basetype is the element - * type of the array or the parameterized type of the - * Collection; otherwise the basetype is the member type. If the - * basetype is an interface with an - * @Remotable or - * @Service annotation then the member is defined as a reference. Otherwise, - * it is defined as a property. - *
- *

- * The name of the reference or of the property is derived from the - * name found on the setter method or on the field. - */ - private boolean isReferenceType(Class cls, Type genericType) { - Class baseType = JavaIntrospectionHelper.getBaseType(cls, genericType); - return baseType.isInterface() && baseType.isAnnotationPresent(Remotable.class); - } - - /** - * Returns true if the given operation is defined in the collection of - * service interfaces - */ - private boolean isInServiceInterface(Method operation, List services) { - for (org.apache.tuscany.sca.assembly.Service service : services) { - Interface interface1 = service.getInterfaceContract().getInterface(); - if (interface1 instanceof JavaInterface) { - Class clazz = ((JavaInterface)interface1).getJavaClass(); - if (isMethodMatched(clazz, operation)) { - return true; - } - } - } - return false; - } - - /** - * Test if the class declares a method which matches the signature of the - * given method - * - * @param clazz - * @param method - * @return - */ - private boolean isMethodMatched(Class clazz, Method method) { - if (method.getDeclaringClass() == clazz) { - return true; - } - Method[] methods = clazz.getMethods(); - for (Method m : methods) { - if (JavaIntrospectionHelper.exactMethodMatch(method, m)) { - return true; - } - } - return false; - } - - /** - * Creates a mapped property. - * - * @param name the property name - * @param paramType the property type - */ - private org.apache.tuscany.sca.assembly.Property createProperty(String name, Class paramType) { - org.apache.tuscany.sca.assembly.Property property = assemblyFactory.createProperty(); - property.setName(name); - property.setXSDType(JavaXMLMapper.getXMLType(paramType)); - return property; - } - - private boolean isAnnotated(JavaParameterImpl parameter) { - for (Annotation annotation : parameter.getAnnotations()) { - Class annotType = annotation.annotationType(); - if (annotType.equals(Property.class) || annotType.equals(Reference.class) - || annotType.equals(Resource.class)) { - return true; - } - } - return false; - } - - public boolean areUnique(JavaParameterImpl[] parameters) { - Set set = new HashSet(parameters.length); - for (JavaParameterImpl p : parameters) { - if (!set.add(p.getType())) { - return false; - } - } - return true; - } - - public org.apache.tuscany.sca.assembly.Reference createReference(String name, Class paramType) - throws IntrospectionException { - org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference(); - reference.setName(name); - JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); - reference.setInterfaceContract(interfaceContract); - try { - JavaInterface callInterface = javaFactory.createJavaInterface(paramType); - reference.getInterfaceContract().setInterface(callInterface); - if (callInterface.getCallbackClass() != null) { - JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); - reference.getInterfaceContract().setCallbackInterface(callbackInterface); - } - reference.setMultiplicity(Multiplicity.ZERO_ONE); - } catch (InvalidInterfaceException e1) { - throw new IntrospectionException(e1); - } - - // FIXME: This part seems to have already been taken care above!! - try { - processCallback(paramType, reference); - } catch (InvalidServiceTypeException e) { - throw new IntrospectionException(e); - } - return reference; - } - - public org.apache.tuscany.sca.assembly.Service createService(Class interfaze) throws InvalidInterfaceException { - org.apache.tuscany.sca.assembly.Service service = assemblyFactory.createService(); - service.setName(interfaze.getSimpleName()); - - JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); - service.setInterfaceContract(interfaceContract); - - JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); - service.getInterfaceContract().setInterface(callInterface); - if (callInterface.getCallbackClass() != null) { - JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); - service.getInterfaceContract().setCallbackInterface(callbackInterface); - } - - Interface javaInterface = service.getInterfaceContract().getInterface(); - javaInterface.setRemotable(interfaze.getAnnotation(Remotable.class) != null); - service.getInterfaceContract().setInterface(javaInterface); - return service; - } - - public void processCallback(Class interfaze, Contract contract) throws InvalidServiceTypeException { - Callback callback = interfaze.getAnnotation(Callback.class); - if (callback != null && !Void.class.equals(callback.value())) { - Class callbackClass = callback.value(); - JavaInterface javaInterface; - try { - javaInterface = javaFactory.createJavaInterface(callbackClass); - contract.getInterfaceContract().setCallbackInterface(javaInterface); - } catch (InvalidInterfaceException e) { - throw new InvalidServiceTypeException("Invalid callback interface "+callbackClass, interfaze); - } - } else if (callback != null && Void.class.equals(callback.value())) { - throw new InvalidServiceTypeException("No callback interface specified on annotation", interfaze); - } - } - - public boolean injectionAnnotationsPresent(Annotation[][] annots) { - for (Annotation[] annotations : annots) { - for (Annotation annotation : annotations) { - Class annotType = annotation.annotationType(); - if (annotType.equals(Property.class) || annotType.equals(Reference.class) - || annotType.equals(Resource.class)) { - return true; - } - } - } - return false; - } -} +/* + * 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.introspect; + +import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllInterfaces; +import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllPublicAndProtectedFields; +import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods; +import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getPrivateFields; +import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.toPropertyName; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.jws.WebService; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.implementation.java.IntrospectionException; +import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl; +import org.apache.tuscany.sca.implementation.java.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.JavaParameterImpl; +import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper; +import org.apache.tuscany.sca.implementation.java.introspect.impl.AmbiguousConstructorException; +import org.apache.tuscany.sca.implementation.java.introspect.impl.InvalidServiceTypeException; +import org.apache.tuscany.sca.implementation.java.introspect.impl.NoConstructorException; +import org.apache.tuscany.sca.implementation.java.introspect.impl.Resource; +import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +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.oasisopen.sca.annotation.Callback; +import org.oasisopen.sca.annotation.Context; +import org.oasisopen.sca.annotation.Property; +import org.oasisopen.sca.annotation.Reference; +import org.oasisopen.sca.annotation.Remotable; + +/** + * Heuristically evaluates an un-annotated Java implementation type to determine + * services, references, and properties according to the algorithm described in + * the SCA Java Client and Implementation Model Specification

TODO + * Implement:

When no service interface is annotated, need to calculate a + * single service comprising all public methods that are not reference or + * property injection sites. If that service can be exactly mapped to an + * interface implemented by the class then the service interface will be defined + * in terms of that interface. + * + * @version $Rev$ $Date$ + */ +public class SpringBeanPojoProcessor extends BaseJavaClassVisitor { + private JavaInterfaceFactory javaFactory; + private List conArgs; + + public SpringBeanPojoProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory, List conArgs) { + super(assemblyFactory); + this.javaFactory = javaFactory; + this.conArgs = conArgs; + } + + @Override + public void visitEnd(Class clazz, JavaImplementation type) throws IntrospectionException { + List services = type.getServices(); + if (services.isEmpty()) { + // heuristically determine the service + /** + * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation + * In the cases described below, the services offered by a Java implementation class may be determined + * through introspection, eliding the need to specify them using @Service. The following algorithm is used + * to determine how services are introspected from an implementation class: + * + * If the interfaces of the SCA services are not specified with the @Service annotation on the + * implementation class, it is assumed that all implemented interfaces that have been annotated + * as @Remotable are the service interfaces provided by the component. If none of the implemented + * interfaces is remotable, then by default the implementation offers a single service whose type + * is the implementation class. + */ + Set> interfaces = getAllInterfaces(clazz); + for (Class i : interfaces) { + if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) { + addService(type, i); + } + } + if (services.isEmpty()) { + // class is the interface + addService(type, clazz); + } + } + Set methods = getAllUniquePublicProtectedMethods(clazz, false); + if (!type.getReferenceMembers().isEmpty() || !type.getPropertyMembers().isEmpty()) { + // references and properties have been explicitly defined + // if (type.getServices().isEmpty()) { + // calculateServiceInterface(clazz, type, methods); + // if (type.getServices().isEmpty()) { + // throw new ServiceTypeNotFoundException(clazz.getName()); + // } + // } + evaluateConstructor(type, clazz); + return; + } + calcPropRefs(methods, services, type, clazz); + evaluateConstructor(type, clazz); + } + + private void addService(JavaImplementation type, Class clazz) throws IntrospectionException { + try { + org.apache.tuscany.sca.assembly.Service service = createService(clazz); + type.getServices().add(service); + } catch (InvalidInterfaceException e) { + throw new IntrospectionException(e); + } + } + + private boolean isPublicSetter(Method method) { + return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers()) + && method.getName().startsWith("set") + && method.getReturnType() == void.class; + } + + private boolean isProtectedSetter(Method method) { + return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers()) + && method.getName().startsWith("set") + && method.getReturnType() == void.class; + } + + private void calcPropRefs(Set methods, + List services, + JavaImplementation type, + Class clazz) throws IntrospectionException { + // heuristically determine the properties references + // make a first pass through all public methods with one param + Set setters = new HashSet(); + Set others = new HashSet(); + for (Method method : methods) { + if (!isPublicSetter(method)) { + continue; + } + if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) { + // Add the property name as others + others.add(toPropertyName(method.getName())); + continue; + } + if (!isInServiceInterface(method, services)) { + // Not part of the service interface + String name = toPropertyName(method.getName()); + setters.add(name); + // avoid duplicate property or ref names + if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) { + Class param = method.getParameterTypes()[0]; + Type genericType = method.getGenericParameterTypes()[0]; + if (isReferenceType(param, genericType)) { + type.getReferences().add(createReference(name, param)); + type.getReferenceMembers().put(name, new JavaElementImpl(method, 0)); + } else { + type.getProperties().add(createProperty(name, param)); + type.getPropertyMembers().put(name, new JavaElementImpl(method, 0)); + } + } + } + } + // second pass for protected methods with one param + for (Method method : methods) { + if (!isProtectedSetter(method)) { + continue; + } + if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) { + // Add the property name as others + others.add(toPropertyName(method.getName())); + continue; + } + Class param = method.getParameterTypes()[0]; + String name = toPropertyName(method.getName()); + setters.add(name); + // avoid duplicate property or ref names + if (isReferenceType(param, method.getGenericParameterTypes()[0])) { + if (!type.getReferenceMembers().containsKey(name)) { + type.getReferences().add(createReference(name, param)); + type.getReferenceMembers().put(name, new JavaElementImpl(method, 0)); + } + } else { + if (!type.getPropertyMembers().containsKey(name)) { + type.getProperties().add(createProperty(name, param)); + type.getPropertyMembers().put(name, new JavaElementImpl(method, 0)); + } + } + } + + // Public or protected fields unless there is a public or protected + // setter method + // for the same name + Set fields = getAllPublicAndProtectedFields(clazz, false); + for (Field field : fields) { + if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) { + continue; + } + if (setters.contains(field.getName()) || others.contains(field.getName())) { + continue; + } + String name = field.getName(); + Class paramType = field.getType(); + if (isReferenceType(paramType, field.getGenericType())) { + if (!type.getReferenceMembers().containsKey(name)) { + type.getReferences().add(createReference(name, paramType)); + type.getReferenceMembers().put(name, new JavaElementImpl(field)); + } + } else { + if (!type.getPropertyMembers().containsKey(name)) { + type.getProperties().add(createProperty(name, paramType)); + type.getPropertyMembers().put(name, new JavaElementImpl(field)); + } + } + } + + // Private fields unless there is a public or protected + // setter method for the same name + Set privateFields = getPrivateFields(clazz); + for (Field field : privateFields) { + if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) { + continue; + } + if (setters.contains(field.getName()) || others.contains(field.getName())) { + continue; + } + String name = field.getName(); + Class paramType = field.getType(); + if (isReferenceType(paramType, field.getGenericType())) { + if (!type.getReferenceMembers().containsKey(name)) { + type.getReferences().add(createReference(name, paramType)); + type.getReferenceMembers().put(name, new JavaElementImpl(field)); + } + } else { + if (!type.getPropertyMembers().containsKey(name)) { + type.getProperties().add(createProperty(name, paramType)); + type.getPropertyMembers().put(name, new JavaElementImpl(field)); + } + } + } + } + + /** + * Determines the constructor to use based on the component type's + * references and properties + * + * @param type the component type + * @param clazz the implementation class corresponding to the component type + * @throws NoConstructorException if no suitable constructor is found + * @throws AmbiguousConstructorException if the parameters of a constructor + * cannot be unambiguously mapped to references and properties + */ + @SuppressWarnings("unchecked") + private void evaluateConstructor(JavaImplementation type, Class clazz) throws IntrospectionException { + // determine constructor if one is not annotated + JavaConstructorImpl definition = type.getConstructor(); + Map props = type.getPropertyMembers(); + Map refs = type.getReferenceMembers(); + Constructor constructor; + boolean explict = false; + if (definition != null && definition.getConstructor() + .isAnnotationPresent(org.oasisopen.sca.annotation.Constructor.class)) { + // the constructor was already defined explicitly + return; + } else if (definition != null) { + explict = true; + constructor = definition.getConstructor(); + } else { + // no definition, heuristically determine constructor + Constructor[] constructors = clazz.getConstructors(); + if (constructors.length == 0) { + throw new NoConstructorException("No public constructor for class"); + } else if (constructors.length == 1) { + // Only one constructor, take it + constructor = constructors[0]; + } else { + // multiple constructors scenario + Constructor selected = null; + for (Constructor ctor : constructors) { + if (ctor.getParameterTypes().length == 0) { + selected = ctor; + } else if (ctor.getParameterTypes().length == conArgs.size()) { + // we will find a constructor which has atleast one + // reference or property as its parameter types. + Class[] parametersTypes = ctor.getParameterTypes(); + for (Class pType: parametersTypes) { + for (JavaElementImpl property : props.values()) { + if (pType.equals(property.getType())) + selected = ctor; + } + for (JavaElementImpl reference : refs.values()) { + if (pType.equals(reference.getType())) + selected = ctor; + } + } + } + } + if (selected == null) { + throw new NoConstructorException(); + } + constructor = selected; + } + definition = type.getConstructors().get(constructor); + type.setConstructor(definition); + } + + JavaParameterImpl[] parameters = definition.getParameters(); + if (parameters.length == 0) { + return; + } + + Annotation[][] annotations = constructor.getParameterAnnotations(); + if (!explict) { + // the constructor wasn't defined by an annotation, so check to see + // if any of the params have an annotation + // which we can impute as explicitly defining the constructor, e.g. + // @Property, @Reference, or @Autowire + explict = injectionAnnotationsPresent(annotations); + } + if (explict) { + for (int i = 0; i < parameters.length; i++) { + if (isAnnotated(parameters[i])) { + continue; + } else if (!findReferenceOrProperty(parameters[i], props, refs)) { + throw new AmbiguousConstructorException(parameters[i].toString()); + } + } + } else { + if (!areUnique(parameters)) { + throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); + } + if (!calcPropRefUniqueness(props.values(), refs.values())) { + throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); + } + if (!(props.isEmpty() && refs.isEmpty())) { + calcParamNames(parameters, props, refs); + } else { + heuristicParamNames(type, parameters); + + } + } + } + + private void calcParamNames(JavaParameterImpl[] parameters, + Map props, + Map refs) throws AmbiguousConstructorException { + // the constructor param types must unambiguously match defined + // reference or property types + for (JavaParameterImpl param : parameters) { + if (!findReferenceOrProperty(param, props, refs)) { + throw new AmbiguousConstructorException(param.getName()); + } + } + } + + private void heuristicParamNames(JavaImplementation type, JavaParameterImpl[] parameters) + throws IntrospectionException { + // heuristically determine refs and props from the parameter types + for (JavaParameterImpl p : parameters) { + String name = p.getType().getSimpleName().toLowerCase(); + if (isReferenceType(p.getType(), p.getGenericType())) { + type.getReferences().add(createReference(name, p.getType())); + p.setClassifer(Reference.class); + type.getReferenceMembers().put(name, p); + } else { + type.getProperties().add(createProperty(name, p.getType())); + p.setClassifer(Property.class); + type.getPropertyMembers().put(name, p); + } + p.setName(name); + } + } + + private static boolean areUnique(Class[] collection) { + Set set = new HashSet(Arrays.asList(collection)); + return set.size() == collection.length; + } + + /** + * Returns true if the union of the given collections of properties and + * references have unique Java types + */ + private boolean calcPropRefUniqueness(Collection props, Collection refs) { + + Class[] classes = new Class[props.size() + refs.size()]; + int i = 0; + for (JavaElementImpl property : props) { + classes[i] = property.getType(); + i++; + } + for (JavaElementImpl reference : refs) { + classes[i] = reference.getType(); + i++; + } + return areUnique(classes); + } + + /** + * Unambiguously finds the reference or property associated with the given + * type + * + * @return the name of the reference or property if found, null if not + * @throws AmbiguousConstructorException if the constructor parameter cannot + * be resolved to a property or reference + */ + private boolean findReferenceOrProperty(JavaParameterImpl parameter, + Map props, + Map refs) throws AmbiguousConstructorException { + + boolean found = false; + if (!"".equals(parameter.getName())) { + // Match by name + JavaElementImpl prop = props.get(parameter.getName()); + if (prop != null && prop.getType() == parameter.getType()) { + parameter.setClassifer(Property.class); + return true; + } + JavaElementImpl ref = refs.get(parameter.getName()); + if (ref != null && ref.getType() == parameter.getType()) { + parameter.setClassifer(Reference.class); + return true; + } + } + for (JavaElementImpl property : props.values()) { + if (property.getType() == parameter.getType()) { + if (found) { + throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", + (Member)parameter.getAnchor()); + } + parameter.setClassifer(Property.class); + parameter.setName(property.getName()); + found = true; + // do not break since ambiguities must be checked, i.e. more + // than one prop or ref of the same type + } + } + for (JavaElementImpl reference : refs.values()) { + if (reference.getType() == parameter.getType()) { + if (found) { + throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", + (Member)parameter.getAnchor()); + } + parameter.setClassifer(Reference.class); + parameter.setName(reference.getName()); + found = true; + // do not break since ambiguities must be checked, i.e. more + // than one prop or ref of the same type + } + } + return found; + } + + /** + * Returns true if a given type is reference according to the SCA + * specification rules for determining reference types The following rules + * are used to determine whether an unannotated field or setter method is a + * property or reference: + *

    + *
  1. If its type is simple, then it is a property. + *
  2. If its type is complex, then if the type is an interface marked by + * + * @Remotable, then it is a reference; otherwise, it is a property. + *
  3. Otherwise, if the type associated with the member is an + * array or a java.util.Collection, the basetype is the element + * type of the array or the parameterized type of the + * Collection; otherwise the basetype is the member type. If the + * basetype is an interface with an + * @Remotable or + * @Service annotation then the member is defined as a reference. Otherwise, + * it is defined as a property. + *
+ *

+ * The name of the reference or of the property is derived from the + * name found on the setter method or on the field. + */ + private boolean isReferenceType(Class cls, Type genericType) { + Class baseType = JavaIntrospectionHelper.getBaseType(cls, genericType); + return baseType.isInterface() && baseType.isAnnotationPresent(Remotable.class); + } + + /** + * Returns true if the given operation is defined in the collection of + * service interfaces + */ + private boolean isInServiceInterface(Method operation, List services) { + for (org.apache.tuscany.sca.assembly.Service service : services) { + Interface interface1 = service.getInterfaceContract().getInterface(); + if (interface1 instanceof JavaInterface) { + Class clazz = ((JavaInterface)interface1).getJavaClass(); + if (isMethodMatched(clazz, operation)) { + return true; + } + } + } + return false; + } + + /** + * Test if the class declares a method which matches the signature of the + * given method + * + * @param clazz + * @param method + * @return + */ + private boolean isMethodMatched(Class clazz, Method method) { + if (method.getDeclaringClass() == clazz) { + return true; + } + Method[] methods = clazz.getMethods(); + for (Method m : methods) { + if (JavaIntrospectionHelper.exactMethodMatch(method, m)) { + return true; + } + } + return false; + } + + /** + * Creates a mapped property. + * + * @param name the property name + * @param paramType the property type + */ + private org.apache.tuscany.sca.assembly.Property createProperty(String name, Class paramType) { + org.apache.tuscany.sca.assembly.Property property = assemblyFactory.createProperty(); + property.setName(name); + property.setXSDType(JavaXMLMapper.getXMLType(paramType)); + return property; + } + + private boolean isAnnotated(JavaParameterImpl parameter) { + for (Annotation annotation : parameter.getAnnotations()) { + Class annotType = annotation.annotationType(); + if (annotType.equals(Property.class) || annotType.equals(Reference.class) + || annotType.equals(Resource.class)) { + return true; + } + } + return false; + } + + public boolean areUnique(JavaParameterImpl[] parameters) { + Set set = new HashSet(parameters.length); + for (JavaParameterImpl p : parameters) { + if (!set.add(p.getType())) { + return false; + } + } + return true; + } + + public org.apache.tuscany.sca.assembly.Reference createReference(String name, Class paramType) + throws IntrospectionException { + org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference(); + reference.setName(name); + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + reference.setInterfaceContract(interfaceContract); + try { + JavaInterface callInterface = javaFactory.createJavaInterface(paramType); + reference.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + reference.getInterfaceContract().setCallbackInterface(callbackInterface); + } + reference.setMultiplicity(Multiplicity.ZERO_ONE); + } catch (InvalidInterfaceException e1) { + throw new IntrospectionException(e1); + } + + // FIXME: This part seems to have already been taken care above!! + try { + processCallback(paramType, reference); + } catch (InvalidServiceTypeException e) { + throw new IntrospectionException(e); + } + return reference; + } + + public org.apache.tuscany.sca.assembly.Service createService(Class interfaze) throws InvalidInterfaceException { + org.apache.tuscany.sca.assembly.Service service = assemblyFactory.createService(); + service.setName(interfaze.getSimpleName()); + + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + service.setInterfaceContract(interfaceContract); + + JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); + service.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + service.getInterfaceContract().setCallbackInterface(callbackInterface); + } + + Interface javaInterface = service.getInterfaceContract().getInterface(); + javaInterface.setRemotable(interfaze.getAnnotation(Remotable.class) != null); + service.getInterfaceContract().setInterface(javaInterface); + return service; + } + + public void processCallback(Class interfaze, Contract contract) throws InvalidServiceTypeException { + Callback callback = interfaze.getAnnotation(Callback.class); + if (callback != null && !Void.class.equals(callback.value())) { + Class callbackClass = callback.value(); + JavaInterface javaInterface; + try { + javaInterface = javaFactory.createJavaInterface(callbackClass); + contract.getInterfaceContract().setCallbackInterface(javaInterface); + } catch (InvalidInterfaceException e) { + throw new InvalidServiceTypeException("Invalid callback interface "+callbackClass, interfaze); + } + } else if (callback != null && Void.class.equals(callback.value())) { + throw new InvalidServiceTypeException("No callback interface specified on annotation", interfaze); + } + } + + public boolean injectionAnnotationsPresent(Annotation[][] annots) { + for (Annotation[] annotations : annots) { + for (Annotation annotation : annotations) { + Class annotType = annotation.annotationType(); + if (annotType.equals(Property.class) || annotType.equals(Reference.class) + || annotType.equals(Resource.class)) { + return true; + } + } + } + return false; + } +} 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 b880e7ba2a..efc4b309e0 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 @@ -1,781 +1,781 @@ -/* - * 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.introspect; - -import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; -import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.Manifest; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.ComponentType; -import org.apache.tuscany.sca.assembly.Multiplicity; -import org.apache.tuscany.sca.assembly.Property; -import org.apache.tuscany.sca.assembly.Reference; -import org.apache.tuscany.sca.assembly.Service; -import org.apache.tuscany.sca.contribution.Artifact; -import org.apache.tuscany.sca.contribution.ContributionFactory; -import org.apache.tuscany.sca.contribution.processor.ContributionReadException; -import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; -import org.apache.tuscany.sca.contribution.resolver.ClassReference; -import org.apache.tuscany.sca.contribution.resolver.ModelResolver; -import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl; -import org.apache.tuscany.sca.implementation.java.JavaElementImpl; -import org.apache.tuscany.sca.implementation.java.JavaImplementation; -import org.apache.tuscany.sca.implementation.java.JavaParameterImpl; -import org.apache.tuscany.sca.implementation.spring.SpringBeanElement; -import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.implementation.spring.SpringImplementationConstants; -import org.apache.tuscany.sca.implementation.spring.SpringPropertyElement; -import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement; -import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement; -import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement; -import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; -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.policy.PolicyFactory; - -/** - * Introspects a Spring XML application-context configuration file to create - * component type information. - * - * - * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ - */ -public class SpringXMLComponentTypeLoader { - - private XMLInputFactory xmlInputFactory; - private ContributionFactory contributionFactory; - private AssemblyFactory assemblyFactory; - private JavaInterfaceFactory javaFactory; - private PolicyFactory policyFactory; - - private SpringBeanIntrospector beanIntrospector; - - public SpringXMLComponentTypeLoader(FactoryExtensionPoint factories, - AssemblyFactory assemblyFactory, - JavaInterfaceFactory javaFactory, - PolicyFactory policyFactory) { - super(); - this.assemblyFactory = assemblyFactory; - this.javaFactory = javaFactory; - this.policyFactory = policyFactory; - this.contributionFactory = factories.getFactory(ContributionFactory.class); - this.xmlInputFactory = factories.getFactory(XMLInputFactory.class); - } - - protected Class getImplementationClass() { - return SpringImplementation.class; - } - - /** - * Base method which loads the component type from the application-context attached to the - * Spring implementation - * - */ - public void load(SpringImplementation implementation, ModelResolver resolver) throws ContributionReadException { - //System.out.println("Spring TypeLoader - load method start"); - ComponentType componentType = implementation.getComponentType(); - /* Check that there is a component type object already set */ - if (componentType == null) { - throw new ContributionReadException("SpringXMLLoader load: implementation has no ComponentType object"); - } - if (componentType.isUnresolved()) { - /* Fetch the location of the application-context file from the implementation */ - loadFromXML(implementation, resolver); - if (!componentType.isUnresolved()) - implementation.setUnresolved(false); - } // end if - //System.out.println("Spring TypeLoader - load method complete"); - } // end method load - - private Class resolveClass(ModelResolver resolver, String className) throws ClassNotFoundException { - ClassReference classReference = new ClassReference(className); - classReference = resolver.resolveModel(ClassReference.class, classReference); - if (classReference.isUnresolved()) { - throw new ClassNotFoundException(className); - } - Class javaClass = classReference.getJavaClass(); - return javaClass; - } - - /** - * Method which fills out the component type for a Spring implementation by reading the - * Spring application-context.xml file. - * - * @param implementation SpringImplementation into which to load the component type information - * @throws ContributionReadException Failed to read the contribution - */ - private void loadFromXML(SpringImplementation implementation, ModelResolver resolver) throws ContributionReadException { - XMLStreamReader reader; - List beans = new ArrayList(); - List services = new ArrayList(); - List references = new ArrayList(); - List scaproperties = new ArrayList(); - - URL resource; - - String contextPath = implementation.getLocation(); - - try { - resource = resolveLocation(resolver, contextPath); - resource = getApplicationContextResource(resource); - implementation.setResource(resource); - // 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); - - } catch (IOException e) { - throw new ContributionReadException(e); - } catch (XMLStreamException e) { - throw new ContributionReadException(e); - } - - /* At this point, the complete application-context.xml file has been read and its contents */ - /* stored in the lists of beans, services, references. These are now used to generate */ - /* the implied componentType for the application context */ - generateComponentType(implementation, resolver, beans, services, references, scaproperties); - - return; - } // end method loadFromXML - - private URL resolveLocation(ModelResolver resolver, String contextPath) throws MalformedURLException, - ContributionReadException { - URL resource = null; - URI uri = URI.create(contextPath); - if (!uri.isAbsolute()) { - Artifact artifact = contributionFactory.createArtifact(); - artifact.setUnresolved(true); - artifact.setURI(contextPath); - artifact = resolver.resolveModel(Artifact.class, artifact); - if (!artifact.isUnresolved()) { - resource = new URL(artifact.getLocation()); - } else { - throw new ContributionReadException("Location cannot be resloved: " + contextPath); - } - } else { - resource = new URL(contextPath); - } - return resource; - } - - /** - * Method which returns the XMLStreamReader for the Spring application-context.xml file - * specified in the location attribute - */ - private XMLStreamReader getApplicationContextReader(ModelResolver resolver, String location) throws ContributionReadException { - - try { - URL resource = getApplicationContextResource(resolveLocation(resolver, location)); - XMLStreamReader reader = - xmlInputFactory.createXMLStreamReader(resource.openStream()); - return reader; - } catch (IOException e) { - throw new ContributionReadException(e); - } catch (XMLStreamException e) { - throw new ContributionReadException(e); - } - } - - /** - * Method which reads the spring context definitions from Spring application-context.xml - * file and identifies the defined beans, properties, services and references - */ - private void readContextDefinition(ModelResolver resolver, - XMLStreamReader reader, - String contextPath, - List beans, - List services, - List references, - List scaproperties) throws ContributionReadException { - - SpringBeanElement bean = null; - - try { - boolean completed = false; - while (!completed) { - switch (reader.next()) { - case START_ELEMENT: - QName qname = reader.getName(); - //System.out.println("Spring TypeLoader - found element with name: " + qname.toString()); - if (SpringImplementationConstants.IMPORT_ELEMENT.equals(qname)) { - //FIXME - put the sequence of code below which gets the ireader into a subsidiary method - String location = reader.getAttributeValue(null, "resource"); - if (location != null) { - // FIXME - need to find a right way of generating this path - String resourcePath = contextPath.substring(0, contextPath.lastIndexOf("/")+1) + location; - XMLStreamReader ireader = getApplicationContextReader(resolver, resourcePath); - // 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")); - 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 = - 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")); - beans.add(bean); - // Read the element and its child elements - readBeanDefinition(resolver, reader, contextPath, bean, beans, services, references, scaproperties); - } // end if*/ - break; - case END_ELEMENT: - if (SpringImplementationConstants.BEANS_ELEMENT.equals(reader.getName())) { - //System.out.println("Spring TypeLoader - finished read of context file"); - completed = true; - break; - } // end if - } // end switch - } // end while - } catch (XMLStreamException e) { - throw new ContributionReadException(e); - } - } - - - /** - * 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, - SpringBeanElement bean, - List beans, - List services, - List references, - List scaproperties) throws ContributionReadException { - - SpringBeanElement innerbean = null; - SpringPropertyElement property = null; - SpringConstructorArgElement constructorArg = null; - int autoConstructorIndex = -1; - - 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")); - innerbean.setInnerBean(true); - beans.add(innerbean); - readBeanDefinition(resolver, reader, contextPath, innerbean, beans, services, references, scaproperties); - } else if (SpringImplementationConstants.PROPERTY_ELEMENT.equals(qname)) { - property = new SpringPropertyElement(reader.getAttributeValue(null, "name"), 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); - 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); - } - } - } - bean.addCustructorArgs(constructorArg); - } else if (SpringImplementationConstants.REF_ELEMENT.equals(qname)) { - String ref = reader.getAttributeValue(null, "bean"); - // Check if the parent element is a property - if (property != null) property.setRef(ref); - // Check if the parent element is a constructor-arg - if (constructorArg != null) constructorArg.setRef(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); - } - } - } - } // end if - break; - case END_ELEMENT: - if (SpringImplementationConstants.BEAN_ELEMENT.equals(reader.getName())) { - completed = true; - break; - } else if (SpringImplementationConstants.PROPERTY_ELEMENT.equals(reader.getName())) { - property = null; - } else if (SpringImplementationConstants.CONSTRUCTORARG_ELEMENT.equals(reader.getName())) { - constructorArg = null; - } // 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 - * lists of beans, services, references and scaproperties derived from the application context - */ - private void generateComponentType(SpringImplementation implementation, - ModelResolver resolver, - List beans, - List services, - List references, - List scaproperties) throws ContributionReadException { - /* - * 1. Each sca:service becomes a service in the component type - * 2. Each sca:reference becomes a reference in the component type - * 3. Each sca:property becomes a property in the component type - * 4. IF there are no explicit service elements, each bean becomes a service - * 5. Each bean property which is a reference not pointing at another bean in the - * application context becomes a reference unless it is pointing at one of the references - * 6. Each bean property which is not a reference and which is not pointing - * at another bean in the application context becomes a property in the component type - */ - - JavaImplementation javaImplementation = null; - ComponentType componentType = implementation.getComponentType(); - - try { - // Deal with the services first.... - Iterator its = services.iterator(); - while (its.hasNext()) { - SpringSCAServiceElement serviceElement = its.next(); - Class interfaze = resolveClass(resolver, serviceElement.getType()); - Service theService = createService(interfaze, serviceElement.getName()); - 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); - } - } // end for - } // end while - - // Next handle the references - Iterator itr = references.iterator(); - while (itr.hasNext()) { - SpringSCAReferenceElement referenceElement = itr.next(); - Class interfaze = resolveClass(resolver, referenceElement.getType()); - Reference theReference = createReference(interfaze, referenceElement.getName()); - componentType.getReferences().add(theReference); - } // end while - - // Next handle the properties - Iterator itsp = scaproperties.iterator(); - while (itsp.hasNext()) { - SpringSCAPropertyElement scaproperty = itsp.next(); - // Create a component type property if the SCA property element has a name - // and a type declared... - if (scaproperty.getType() != null && scaproperty.getName() != null) { - Property theProperty = assemblyFactory.createProperty(); - theProperty.setName(scaproperty.getName()); - // Get the Java class and then an XSD element type for the property - Class propType = Class.forName(scaproperty.getType()); - theProperty.setXSDType(JavaXMLMapper.getXMLType(propType)); - componentType.getProperties().add(theProperty); - // Remember the Java Class (ie the type) for this property - implementation.setPropertyClass(theProperty.getName(), propType); - } // end if - } // end while - - // Finally deal with the beans - Iterator itb; - // If there are no explicit service elements, then expose all the beans - if (services.isEmpty()) { - itb = beans.iterator(); - // Loop through all the beans found - while (itb.hasNext()) { - SpringBeanElement beanElement = itb.next(); - // If its a innerBean, ignore it - if (beanElement.isInnerBean()) continue; - // Load the Spring bean class - Class beanClass = resolveClass(resolver, beanElement.getClassName()); - // Introspect the bean - beanIntrospector = - new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs()); - ComponentType beanComponentType = assemblyFactory.createComponentType(); - javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType); - // Get the service interface defined by this Spring Bean and add to - // the component type of the Spring Assembly - List beanServices = beanComponentType.getServices(); - componentType.getServices().addAll(beanServices); - // Add these services to the Service / Bean map - for (Service beanService : beanServices) { - implementation.setBeanForService(beanService, beanElement); - } - } // end while - } // end if - - itb = beans.iterator(); - while (itb.hasNext()) { - SpringBeanElement beanElement = itb.next(); - // Ignore if the bean has no properties and constructor arguments - if (beanElement.getProperties().isEmpty() && beanElement.getCustructorArgs().isEmpty()) - continue; - - Class beanClass = resolveClass(resolver, beanElement.getClassName()); - // Introspect the bean - beanIntrospector = - new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs()); - ComponentType beanComponentType = assemblyFactory.createComponentType(); - javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType); - Map propertyMap = javaImplementation.getPropertyMembers(); - JavaConstructorImpl constructor = javaImplementation.getConstructor(); - // Get the references by this Spring Bean and add the unresolved ones to - // the component type of the Spring Assembly - List beanReferences = beanComponentType.getReferences(); - List beanProperties = beanComponentType.getProperties(); - - 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 - } // 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 - } // end while - - } // end while - - } catch (ClassNotFoundException e) { - // Means that either an interface class, property class or a bean was not found - throw new ContributionReadException(e); - } catch (InvalidInterfaceException e) { - throw new ContributionReadException(e); - } catch (ContributionResolveException e) { - - } // end try - - // If we get here, the Spring assembly component type is resolved - componentType.setUnresolved(false); - implementation.setComponentType(componentType); - return; - } // end method generateComponentType - - /* - * Determines whether a reference attribute of a Spring property element is resolved either - * by a bean in the application context or by an SCA reference element or by an SCA property - * element - * @param ref - a String containing the name of the reference - may be null - * @param beans - a List of SpringBean elements - * @param references - a List of SCA reference elements - * @return true if the property is not resolved, false if it is resolved - */ - private boolean propertyRefUnresolved(String ref, - List beans, - List references, - List scaproperties) { - boolean unresolved = true; - - if (ref != null) { - // Scan over the beans looking for a match - Iterator itb = beans.iterator(); - while (itb.hasNext()) { - SpringBeanElement beanElement = itb.next(); - // Does the bean name match the ref? - if (ref.equals(beanElement.getId())) { - unresolved = false; - break; - } // end if - } // end while - // Scan over the SCA reference elements looking for a match - if (unresolved) { - Iterator itr = references.iterator(); - while (itr.hasNext()) { - SpringSCAReferenceElement referenceElement = itr.next(); - if (ref.equals(referenceElement.getName())) { - unresolved = false; - break; - } // end if - } // end while - } // end if - // Scan over the SCA property elements looking for a match - if (unresolved) { - Iterator itsp = scaproperties.iterator(); - while (itsp.hasNext()) { - SpringSCAPropertyElement propertyElement = itsp.next(); - if (ref.equals(propertyElement.getName())) { - unresolved = false; - break; - } // end if - } // end while - } // end if - } else { - // In the case where ref = null, the property is not going to be a reference of any - // kind and can be ignored - unresolved = false; - } // end if - - return unresolved; - - } // end method propertyRefUnresolved - - /** - * 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) - throws ContributionReadException { - File manifestFile = null; - File appXmlFile; - File locationFile = null; - - if (url != null) { - String path = url.getPath(); - locationFile = new File(path); - } else { - throw new ContributionReadException( - "SpringXMLLoader getApplicationContextResource: " + "unable to find resource file " - + url); - } - - if (locationFile.isDirectory()) { - try { - manifestFile = new File(locationFile, "META-INF"+ File.separator +"MANIFEST.MF"); - if (manifestFile.exists()) { - Manifest mf = new Manifest(new FileInputStream(manifestFile)); - Attributes mainAttrs = mf.getMainAttributes(); - String appCtxPath = mainAttrs.getValue("Spring-Context"); - if (appCtxPath != null) { - appXmlFile = new File(locationFile, appCtxPath); - if (appXmlFile.exists()) { - return appXmlFile.toURL(); - } - } - } - // 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(); - } - } catch (IOException e) { - throw new ContributionReadException("Error reading manifest " + manifestFile); - } - } else { - if (locationFile.isFile() && locationFile.getName().endsWith(".jar")) { - try { - 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); - } - } - } - je = jf.getJarEntry("META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); - if (je != null) { - return new URL("jar:" + locationFile.toURI().toURL() + "!/" + SpringImplementationConstants.APPLICATION_CONTEXT); - } - } catch (IOException e) { - // bad archive - // TODO: create a more appropriate exception type - throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " - + " IO exception reading context file.", e); - } - } - else { - if (locationFile.getName().endsWith(".xml")) { - return url; - } - else { - // Deal with the directory inside a jar file, in case the contribution itself is a JAR file. - try { - if (locationFile.getPath().indexOf(".jar") > 0) { - String jarEntry = url.getPath().substring(6, url.getPath().indexOf("!")); - JarFile jf = new JarFile(jarEntry); - JarEntry je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) - + "/" + "META-INF" + "/" + "MANIFEST.MF"); - if (je != null) { - Manifest mf = new Manifest(jf.getInputStream(je)); - 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); - } - } - } - } - } catch (IOException e) { - throw new ContributionReadException("Error reading manifest " + manifestFile); - } - } - } - } - - throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " - + "META-INF/spring/" + SpringImplementationConstants.APPLICATION_CONTEXT + "not found"); - } // end method getApplicationContextResource - - /** - * Creates a Service for the component type based on its name and Java interface - */ - public Service createService(Class interfaze, String name) throws InvalidInterfaceException { - Service service = assemblyFactory.createService(); - JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); - service.setInterfaceContract(interfaceContract); - - // Set the name for the service - service.setName(name); - - // Set the call interface and, if present, the callback interface - JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); - service.getInterfaceContract().setInterface(callInterface); - if (callInterface.getCallbackClass() != null) { - JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); - service.getInterfaceContract().setCallbackInterface(callbackInterface); - } - return service; - } // end method createService - - /** - * Creates a Reference for the component type based on its name and Java interface - */ - private org.apache.tuscany.sca.assembly.Reference createReference(Class interfaze, String name) - throws InvalidInterfaceException { - org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference(); - JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); - reference.setInterfaceContract(interfaceContract); - - // Set the name of the reference to the supplied name and the multiplicity of the reference - // to 1..1 - for Spring implementations, this is the only multiplicity supported - reference.setName(name); - reference.setMultiplicity(Multiplicity.ONE_ONE); - - // Set the call interface and, if present, the callback interface - JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); - reference.getInterfaceContract().setInterface(callInterface); - if (callInterface.getCallbackClass() != null) { - JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); - reference.getInterfaceContract().setCallbackInterface(callbackInterface); - } - - return reference; - } -} // end class SpringXMLComponentTypeLoader +/* + * 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.introspect; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl; +import org.apache.tuscany.sca.implementation.java.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.JavaParameterImpl; +import org.apache.tuscany.sca.implementation.spring.SpringBeanElement; +import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.implementation.spring.SpringImplementationConstants; +import org.apache.tuscany.sca.implementation.spring.SpringPropertyElement; +import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement; +import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement; +import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +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.policy.PolicyFactory; + +/** + * Introspects a Spring XML application-context configuration file to create + * component type information. + * + * + * @version $Rev$ $Date$ + */ +public class SpringXMLComponentTypeLoader { + + private XMLInputFactory xmlInputFactory; + private ContributionFactory contributionFactory; + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + private PolicyFactory policyFactory; + + private SpringBeanIntrospector beanIntrospector; + + public SpringXMLComponentTypeLoader(FactoryExtensionPoint factories, + AssemblyFactory assemblyFactory, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory) { + super(); + this.assemblyFactory = assemblyFactory; + this.javaFactory = javaFactory; + this.policyFactory = policyFactory; + this.contributionFactory = factories.getFactory(ContributionFactory.class); + this.xmlInputFactory = factories.getFactory(XMLInputFactory.class); + } + + protected Class getImplementationClass() { + return SpringImplementation.class; + } + + /** + * Base method which loads the component type from the application-context attached to the + * Spring implementation + * + */ + public void load(SpringImplementation implementation, ModelResolver resolver) throws ContributionReadException { + //System.out.println("Spring TypeLoader - load method start"); + ComponentType componentType = implementation.getComponentType(); + /* Check that there is a component type object already set */ + if (componentType == null) { + throw new ContributionReadException("SpringXMLLoader load: implementation has no ComponentType object"); + } + if (componentType.isUnresolved()) { + /* Fetch the location of the application-context file from the implementation */ + loadFromXML(implementation, resolver); + if (!componentType.isUnresolved()) + implementation.setUnresolved(false); + } // end if + //System.out.println("Spring TypeLoader - load method complete"); + } // end method load + + private Class resolveClass(ModelResolver resolver, String className) throws ClassNotFoundException { + ClassReference classReference = new ClassReference(className); + classReference = resolver.resolveModel(ClassReference.class, classReference); + if (classReference.isUnresolved()) { + throw new ClassNotFoundException(className); + } + Class javaClass = classReference.getJavaClass(); + return javaClass; + } + + /** + * Method which fills out the component type for a Spring implementation by reading the + * Spring application-context.xml file. + * + * @param implementation SpringImplementation into which to load the component type information + * @throws ContributionReadException Failed to read the contribution + */ + private void loadFromXML(SpringImplementation implementation, ModelResolver resolver) throws ContributionReadException { + XMLStreamReader reader; + List beans = new ArrayList(); + List services = new ArrayList(); + List references = new ArrayList(); + List scaproperties = new ArrayList(); + + URL resource; + + String contextPath = implementation.getLocation(); + + try { + resource = resolveLocation(resolver, contextPath); + resource = getApplicationContextResource(resource); + implementation.setResource(resource); + // 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); + + } catch (IOException e) { + throw new ContributionReadException(e); + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + + /* At this point, the complete application-context.xml file has been read and its contents */ + /* stored in the lists of beans, services, references. These are now used to generate */ + /* the implied componentType for the application context */ + generateComponentType(implementation, resolver, beans, services, references, scaproperties); + + return; + } // end method loadFromXML + + private URL resolveLocation(ModelResolver resolver, String contextPath) throws MalformedURLException, + ContributionReadException { + URL resource = null; + URI uri = URI.create(contextPath); + if (!uri.isAbsolute()) { + Artifact artifact = contributionFactory.createArtifact(); + artifact.setUnresolved(true); + artifact.setURI(contextPath); + artifact = resolver.resolveModel(Artifact.class, artifact); + if (!artifact.isUnresolved()) { + resource = new URL(artifact.getLocation()); + } else { + throw new ContributionReadException("Location cannot be resloved: " + contextPath); + } + } else { + resource = new URL(contextPath); + } + return resource; + } + + /** + * Method which returns the XMLStreamReader for the Spring application-context.xml file + * specified in the location attribute + */ + private XMLStreamReader getApplicationContextReader(ModelResolver resolver, String location) throws ContributionReadException { + + try { + URL resource = getApplicationContextResource(resolveLocation(resolver, location)); + XMLStreamReader reader = + xmlInputFactory.createXMLStreamReader(resource.openStream()); + return reader; + } catch (IOException e) { + throw new ContributionReadException(e); + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + } + + /** + * Method which reads the spring context definitions from Spring application-context.xml + * file and identifies the defined beans, properties, services and references + */ + private void readContextDefinition(ModelResolver resolver, + XMLStreamReader reader, + String contextPath, + List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + + SpringBeanElement bean = null; + + try { + boolean completed = false; + while (!completed) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + //System.out.println("Spring TypeLoader - found element with name: " + qname.toString()); + if (SpringImplementationConstants.IMPORT_ELEMENT.equals(qname)) { + //FIXME - put the sequence of code below which gets the ireader into a subsidiary method + String location = reader.getAttributeValue(null, "resource"); + if (location != null) { + // FIXME - need to find a right way of generating this path + String resourcePath = contextPath.substring(0, contextPath.lastIndexOf("/")+1) + location; + XMLStreamReader ireader = getApplicationContextReader(resolver, resourcePath); + // 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")); + 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 = + 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")); + beans.add(bean); + // Read the element and its child elements + readBeanDefinition(resolver, reader, contextPath, bean, beans, services, references, scaproperties); + } // end if*/ + break; + case END_ELEMENT: + if (SpringImplementationConstants.BEANS_ELEMENT.equals(reader.getName())) { + //System.out.println("Spring TypeLoader - finished read of context file"); + completed = true; + break; + } // end if + } // end switch + } // end while + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + } + + + /** + * 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, + SpringBeanElement bean, + List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + + SpringBeanElement innerbean = null; + SpringPropertyElement property = null; + SpringConstructorArgElement constructorArg = null; + int autoConstructorIndex = -1; + + 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")); + innerbean.setInnerBean(true); + beans.add(innerbean); + readBeanDefinition(resolver, reader, contextPath, innerbean, beans, services, references, scaproperties); + } else if (SpringImplementationConstants.PROPERTY_ELEMENT.equals(qname)) { + property = new SpringPropertyElement(reader.getAttributeValue(null, "name"), 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); + 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); + } + } + } + bean.addCustructorArgs(constructorArg); + } else if (SpringImplementationConstants.REF_ELEMENT.equals(qname)) { + String ref = reader.getAttributeValue(null, "bean"); + // Check if the parent element is a property + if (property != null) property.setRef(ref); + // Check if the parent element is a constructor-arg + if (constructorArg != null) constructorArg.setRef(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); + } + } + } + } // end if + break; + case END_ELEMENT: + if (SpringImplementationConstants.BEAN_ELEMENT.equals(reader.getName())) { + completed = true; + break; + } else if (SpringImplementationConstants.PROPERTY_ELEMENT.equals(reader.getName())) { + property = null; + } else if (SpringImplementationConstants.CONSTRUCTORARG_ELEMENT.equals(reader.getName())) { + constructorArg = null; + } // 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 + * lists of beans, services, references and scaproperties derived from the application context + */ + private void generateComponentType(SpringImplementation implementation, + ModelResolver resolver, + List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + /* + * 1. Each sca:service becomes a service in the component type + * 2. Each sca:reference becomes a reference in the component type + * 3. Each sca:property becomes a property in the component type + * 4. IF there are no explicit service elements, each bean becomes a service + * 5. Each bean property which is a reference not pointing at another bean in the + * application context becomes a reference unless it is pointing at one of the references + * 6. Each bean property which is not a reference and which is not pointing + * at another bean in the application context becomes a property in the component type + */ + + JavaImplementation javaImplementation = null; + ComponentType componentType = implementation.getComponentType(); + + try { + // Deal with the services first.... + Iterator its = services.iterator(); + while (its.hasNext()) { + SpringSCAServiceElement serviceElement = its.next(); + Class interfaze = resolveClass(resolver, serviceElement.getType()); + Service theService = createService(interfaze, serviceElement.getName()); + 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); + } + } // end for + } // end while + + // Next handle the references + Iterator itr = references.iterator(); + while (itr.hasNext()) { + SpringSCAReferenceElement referenceElement = itr.next(); + Class interfaze = resolveClass(resolver, referenceElement.getType()); + Reference theReference = createReference(interfaze, referenceElement.getName()); + componentType.getReferences().add(theReference); + } // end while + + // Next handle the properties + Iterator itsp = scaproperties.iterator(); + while (itsp.hasNext()) { + SpringSCAPropertyElement scaproperty = itsp.next(); + // Create a component type property if the SCA property element has a name + // and a type declared... + if (scaproperty.getType() != null && scaproperty.getName() != null) { + Property theProperty = assemblyFactory.createProperty(); + theProperty.setName(scaproperty.getName()); + // Get the Java class and then an XSD element type for the property + Class propType = Class.forName(scaproperty.getType()); + theProperty.setXSDType(JavaXMLMapper.getXMLType(propType)); + componentType.getProperties().add(theProperty); + // Remember the Java Class (ie the type) for this property + implementation.setPropertyClass(theProperty.getName(), propType); + } // end if + } // end while + + // Finally deal with the beans + Iterator itb; + // If there are no explicit service elements, then expose all the beans + if (services.isEmpty()) { + itb = beans.iterator(); + // Loop through all the beans found + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + // If its a innerBean, ignore it + if (beanElement.isInnerBean()) continue; + // Load the Spring bean class + Class beanClass = resolveClass(resolver, beanElement.getClassName()); + // Introspect the bean + beanIntrospector = + new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs()); + ComponentType beanComponentType = assemblyFactory.createComponentType(); + javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType); + // Get the service interface defined by this Spring Bean and add to + // the component type of the Spring Assembly + List beanServices = beanComponentType.getServices(); + componentType.getServices().addAll(beanServices); + // Add these services to the Service / Bean map + for (Service beanService : beanServices) { + implementation.setBeanForService(beanService, beanElement); + } + } // end while + } // end if + + itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + // Ignore if the bean has no properties and constructor arguments + if (beanElement.getProperties().isEmpty() && beanElement.getCustructorArgs().isEmpty()) + continue; + + Class beanClass = resolveClass(resolver, beanElement.getClassName()); + // Introspect the bean + beanIntrospector = + new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs()); + ComponentType beanComponentType = assemblyFactory.createComponentType(); + javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType); + Map propertyMap = javaImplementation.getPropertyMembers(); + JavaConstructorImpl constructor = javaImplementation.getConstructor(); + // Get the references by this Spring Bean and add the unresolved ones to + // the component type of the Spring Assembly + List beanReferences = beanComponentType.getReferences(); + List beanProperties = beanComponentType.getProperties(); + + 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 + } // 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 + } // end while + + } // end while + + } catch (ClassNotFoundException e) { + // Means that either an interface class, property class or a bean was not found + throw new ContributionReadException(e); + } catch (InvalidInterfaceException e) { + throw new ContributionReadException(e); + } catch (ContributionResolveException e) { + + } // end try + + // If we get here, the Spring assembly component type is resolved + componentType.setUnresolved(false); + implementation.setComponentType(componentType); + return; + } // end method generateComponentType + + /* + * Determines whether a reference attribute of a Spring property element is resolved either + * by a bean in the application context or by an SCA reference element or by an SCA property + * element + * @param ref - a String containing the name of the reference - may be null + * @param beans - a List of SpringBean elements + * @param references - a List of SCA reference elements + * @return true if the property is not resolved, false if it is resolved + */ + private boolean propertyRefUnresolved(String ref, + List beans, + List references, + List scaproperties) { + boolean unresolved = true; + + if (ref != null) { + // Scan over the beans looking for a match + Iterator itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + // Does the bean name match the ref? + if (ref.equals(beanElement.getId())) { + unresolved = false; + break; + } // end if + } // end while + // Scan over the SCA reference elements looking for a match + if (unresolved) { + Iterator itr = references.iterator(); + while (itr.hasNext()) { + SpringSCAReferenceElement referenceElement = itr.next(); + if (ref.equals(referenceElement.getName())) { + unresolved = false; + break; + } // end if + } // end while + } // end if + // Scan over the SCA property elements looking for a match + if (unresolved) { + Iterator itsp = scaproperties.iterator(); + while (itsp.hasNext()) { + SpringSCAPropertyElement propertyElement = itsp.next(); + if (ref.equals(propertyElement.getName())) { + unresolved = false; + break; + } // end if + } // end while + } // end if + } else { + // In the case where ref = null, the property is not going to be a reference of any + // kind and can be ignored + unresolved = false; + } // end if + + return unresolved; + + } // end method propertyRefUnresolved + + /** + * 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) + throws ContributionReadException { + File manifestFile = null; + File appXmlFile; + File locationFile = null; + + if (url != null) { + String path = url.getPath(); + locationFile = new File(path); + } else { + throw new ContributionReadException( + "SpringXMLLoader getApplicationContextResource: " + "unable to find resource file " + + url); + } + + if (locationFile.isDirectory()) { + try { + manifestFile = new File(locationFile, "META-INF"+ File.separator +"MANIFEST.MF"); + if (manifestFile.exists()) { + Manifest mf = new Manifest(new FileInputStream(manifestFile)); + Attributes mainAttrs = mf.getMainAttributes(); + String appCtxPath = mainAttrs.getValue("Spring-Context"); + if (appCtxPath != null) { + appXmlFile = new File(locationFile, appCtxPath); + if (appXmlFile.exists()) { + return appXmlFile.toURL(); + } + } + } + // 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(); + } + } catch (IOException e) { + throw new ContributionReadException("Error reading manifest " + manifestFile); + } + } else { + if (locationFile.isFile() && locationFile.getName().endsWith(".jar")) { + try { + 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); + } + } + } + je = jf.getJarEntry("META-INF" + "/" + "spring" + "/" + SpringImplementationConstants.APPLICATION_CONTEXT); + if (je != null) { + return new URL("jar:" + locationFile.toURI().toURL() + "!/" + SpringImplementationConstants.APPLICATION_CONTEXT); + } + } catch (IOException e) { + // bad archive + // TODO: create a more appropriate exception type + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + " IO exception reading context file.", e); + } + } + else { + if (locationFile.getName().endsWith(".xml")) { + return url; + } + else { + // Deal with the directory inside a jar file, in case the contribution itself is a JAR file. + try { + if (locationFile.getPath().indexOf(".jar") > 0) { + String jarEntry = url.getPath().substring(6, url.getPath().indexOf("!")); + JarFile jf = new JarFile(jarEntry); + JarEntry je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + + "/" + "META-INF" + "/" + "MANIFEST.MF"); + if (je != null) { + Manifest mf = new Manifest(jf.getInputStream(je)); + 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); + } + } + } + } + } catch (IOException e) { + throw new ContributionReadException("Error reading manifest " + manifestFile); + } + } + } + } + + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + "META-INF/spring/" + SpringImplementationConstants.APPLICATION_CONTEXT + "not found"); + } // end method getApplicationContextResource + + /** + * Creates a Service for the component type based on its name and Java interface + */ + public Service createService(Class interfaze, String name) throws InvalidInterfaceException { + Service service = assemblyFactory.createService(); + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + service.setInterfaceContract(interfaceContract); + + // Set the name for the service + service.setName(name); + + // Set the call interface and, if present, the callback interface + JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); + service.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + service.getInterfaceContract().setCallbackInterface(callbackInterface); + } + return service; + } // end method createService + + /** + * Creates a Reference for the component type based on its name and Java interface + */ + private org.apache.tuscany.sca.assembly.Reference createReference(Class interfaze, String name) + throws InvalidInterfaceException { + org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference(); + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + reference.setInterfaceContract(interfaceContract); + + // Set the name of the reference to the supplied name and the multiplicity of the reference + // to 1..1 - for Spring implementations, this is the only multiplicity supported + reference.setName(name); + reference.setMultiplicity(Multiplicity.ONE_ONE); + + // Set the call interface and, if present, the callback interface + JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); + reference.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + reference.getInterfaceContract().setCallbackInterface(callbackInterface); + } + + return reference; + } +} // end class SpringXMLComponentTypeLoader diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java index 2f245d7f06..b97c02d216 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/ComponentTie.java @@ -1,41 +1,41 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.tuscany.sca.implementation.spring.invocation; - -/** - * This is the Tuscany side tie for the corresponding Spring runtime side stub class. - * It enables the Tuscany code to invoke methods on a Spring context without - * needing to know about any Spring classes. See the ComponentStub class - * in the implementation-spring-runtime module for what the stub does. - */ -import org.apache.tuscany.sca.runtime.RuntimeComponent; - -public class ComponentTie { - - private RuntimeComponent component; - - public ComponentTie(RuntimeComponent component) { - this.component = component; - } - - public Object getService(Class type, String name) { - return component.getComponentContext().getService(type, name); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.spring.invocation; + +/** + * This is the Tuscany side tie for the corresponding Spring runtime side stub class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the ComponentStub class + * in the implementation-spring-runtime module for what the stub does. + */ +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class ComponentTie { + + private RuntimeComponent component; + + public ComponentTie(RuntimeComponent component) { + this.component = component; + } + + public Object getService(Class type, String name) { + return component.getComponentContext().getService(type, name); + } +} diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java index 743abaa79b..89d14961ac 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/PropertyValueTie.java @@ -1,53 +1,53 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.tuscany.sca.implementation.spring.invocation; - -import java.util.List; - -import org.apache.tuscany.sca.assembly.ComponentProperty; -import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; -import org.apache.tuscany.sca.runtime.RuntimeComponent; - -/** - * This is the Tuscany side tie for the corresponding Spring runtime side stub class. - * It enables the Tuscany code to invoke methods on a Spring context without - * needing to know about any Spring classes. See the PropertyValueStub class - * in the implementation-spring-runtime module for what the stub does. - */ -public class PropertyValueTie { - - private RuntimeComponent component; - private JavaPropertyValueObjectFactory propertyFactory; - - public PropertyValueTie(RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { - this.component = component; - this.propertyFactory = propertyFactory; - } - - public Object getPropertyObj(Class type, String name) { - List props = component.getProperties(); - for (ComponentProperty prop : props) { - if (prop.getName().equals(name)) { - return propertyFactory.createValueFactory(prop, prop.getValue(), type).getInstance(); - } - } - return null; // property name not found - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.spring.invocation; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side tie for the corresponding Spring runtime side stub class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the PropertyValueStub class + * in the implementation-spring-runtime module for what the stub does. + */ +public class PropertyValueTie { + + private RuntimeComponent component; + private JavaPropertyValueObjectFactory propertyFactory; + + public PropertyValueTie(RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { + this.component = component; + this.propertyFactory = propertyFactory; + } + + public Object getPropertyObj(Class type, String name) { + List props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + return propertyFactory.createValueFactory(prop, prop.getValue(), type).getInstance(); + } + } + return null; // property name not found + } +} diff --git a/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 3d8d4112f0..6a7eb2e024 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 @@ -1,130 +1,130 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.tuscany.sca.implementation.spring.invocation; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; - -import org.apache.tuscany.sca.core.invocation.ProxyFactory; -import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.runtime.RuntimeComponent; - -/** - * This is the Tuscany side stub for the corresponding runtime tie class. - * It enables the Tuscany code to invoke methods on a Spring context without - * needing to know about any Spring classes. See the SpringContextTie class - * in the implementation-spring-runtime module for what the tie does. - */ -public class SpringContextStub { - - private Object tie; - private Method startMethod; - private Method closeMethod; - private Method getBeanMethod; - - public SpringContextStub(RuntimeComponent component, - SpringImplementation implementation, - ProxyFactory proxyService, - JavaPropertyValueObjectFactory propertyValueObjectFactory) { - - initTie(component, implementation, propertyValueObjectFactory); - - } - - private void initTie(RuntimeComponent component, - SpringImplementation implementation, - JavaPropertyValueObjectFactory propertyValueObjectFactory) { - - // TODO: what class loader to use? - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - - try { - - Class stubClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringImplementationStub", true, cl); - Constructor stubConstructor = stubClass.getConstructor(new Class[]{Object.class}); - Object stub = stubConstructor.newInstance(new SpringImplementationTie(implementation, component, propertyValueObjectFactory)); - - Class tieClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringContextTie", true, cl); - Constructor tieConstructor = tieClass.getConstructor(new Class[]{stubClass, URL.class}); - this.tie = tieConstructor.newInstance(stub, implementation.getResource()); - - this.startMethod = tieClass.getMethod("start"); - this.closeMethod = tieClass.getMethod("close"); - this.getBeanMethod = tieClass.getMethod("getBean", String.class); - - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } catch (SecurityException e) { - throw new RuntimeException(e); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - public void start() { - try { - startMethod.invoke(tie); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - public void close() { - try { - closeMethod.invoke(tie); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - public Object getBean(String id) throws SpringInvocationException { - try { - - return getBeanMethod.invoke(tie, id); - - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.spring.invocation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; + +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side stub for the corresponding runtime tie class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the SpringContextTie class + * in the implementation-spring-runtime module for what the tie does. + */ +public class SpringContextStub { + + private Object tie; + private Method startMethod; + private Method closeMethod; + private Method getBeanMethod; + + public SpringContextStub(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + + initTie(component, implementation, propertyValueObjectFactory); + + } + + private void initTie(RuntimeComponent component, + SpringImplementation implementation, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + + // TODO: what class loader to use? + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + try { + + Class stubClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringImplementationStub", true, cl); + Constructor stubConstructor = stubClass.getConstructor(new Class[]{Object.class}); + Object stub = stubConstructor.newInstance(new SpringImplementationTie(implementation, component, propertyValueObjectFactory)); + + Class tieClass = Class.forName("org.apache.tuscany.sca.implementation.spring.runtime.context.SpringContextTie", true, cl); + Constructor tieConstructor = tieClass.getConstructor(new Class[]{stubClass, URL.class}); + this.tie = tieConstructor.newInstance(stub, implementation.getResource()); + + this.startMethod = tieClass.getMethod("start"); + this.closeMethod = tieClass.getMethod("close"); + this.getBeanMethod = tieClass.getMethod("getBean", String.class); + + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + public void start() { + try { + startMethod.invoke(tie); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + public void close() { + try { + closeMethod.invoke(tie); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + public Object getBean(String id) throws SpringInvocationException { + try { + + return getBeanMethod.invoke(tie, id); + + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java index e010f30776..0ecd00d5a8 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProvider.java @@ -1,85 +1,85 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring.invocation; - -import org.apache.tuscany.sca.core.invocation.ProxyFactory; -import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.provider.ImplementationProvider; -import org.apache.tuscany.sca.runtime.RuntimeComponent; -import org.apache.tuscany.sca.runtime.RuntimeComponentService; - -/** - * A provider class for runtime Spring implementation instances - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - */ -public class SpringImplementationProvider implements ImplementationProvider { - private RuntimeComponent component; - - // A Spring application context object - private SpringContextStub springContext; - - private SpringImplementation implementation; - - private JavaPropertyValueObjectFactory propertyValueObjectFactory; - - /** - * Constructor for the provider - takes a component definition and a Spring implementation - * description - * @param component - the component in the assembly - * @param implementation - the implementation - */ - public SpringImplementationProvider(RuntimeComponent component, - SpringImplementation implementation, - ProxyFactory proxyService, - JavaPropertyValueObjectFactory propertyValueObjectFactory) { - super(); - this.implementation = implementation; - this.component = component; - this.propertyValueObjectFactory = propertyValueObjectFactory; - - springContext = new SpringContextStub(component, implementation, proxyService, propertyValueObjectFactory); - - } // end constructor - - public Invoker createInvoker(RuntimeComponentService service, Operation operation) { - return new SpringInvoker(component, springContext, service, operation); - } - - public boolean supportsOneWayInvocation() { - return false; - } - - /** - * Start this Spring implementation instance - */ - public void start() { - springContext.start(); - } - - /** - * Stop this implementation instance - */ - public void stop() { - springContext.close(); - } - -} // end class SpringImplementationProvider +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.spring.invocation; + +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * A provider class for runtime Spring implementation instances + * @version $Rev$ $Date$ + */ +public class SpringImplementationProvider implements ImplementationProvider { + private RuntimeComponent component; + + // A Spring application context object + private SpringContextStub springContext; + + private SpringImplementation implementation; + + private JavaPropertyValueObjectFactory propertyValueObjectFactory; + + /** + * Constructor for the provider - takes a component definition and a Spring implementation + * description + * @param component - the component in the assembly + * @param implementation - the implementation + */ + public SpringImplementationProvider(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + super(); + this.implementation = implementation; + this.component = component; + this.propertyValueObjectFactory = propertyValueObjectFactory; + + springContext = new SpringContextStub(component, implementation, proxyService, propertyValueObjectFactory); + + } // end constructor + + public Invoker createInvoker(RuntimeComponentService service, Operation operation) { + return new SpringInvoker(component, springContext, service, operation); + } + + public boolean supportsOneWayInvocation() { + return false; + } + + /** + * Start this Spring implementation instance + */ + public void start() { + springContext.start(); + } + + /** + * Stop this implementation instance + */ + public void stop() { + springContext.close(); + } + +} // end class SpringImplementationProvider diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java index b7deeb2eb5..5dfdbffd84 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationProviderFactory.java @@ -1,77 +1,77 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring.invocation; - -import org.apache.tuscany.sca.core.ExtensionPointRegistry; -import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory; -import org.apache.tuscany.sca.core.invocation.ProxyFactory; -import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint; -import org.apache.tuscany.sca.databinding.impl.MediatorImpl; -import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.provider.ImplementationProvider; -import org.apache.tuscany.sca.provider.ImplementationProviderFactory; -import org.apache.tuscany.sca.runtime.RuntimeComponent; - -/** - * ImplementationProviderFactory for Spring implementation type - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - * - */ -public class SpringImplementationProviderFactory implements ImplementationProviderFactory { - - private ProxyFactory proxyFactory; - private JavaPropertyValueObjectFactory propertyFactory; - - /** - * Simple constructor - * - */ - public SpringImplementationProviderFactory(ExtensionPointRegistry extensionPoints) { - super(); - - ProxyFactoryExtensionPoint proxyFactories = extensionPoints.getExtensionPoint(ProxyFactoryExtensionPoint.class); - proxyFactory = new ExtensibleProxyFactory(proxyFactories); - - // TODO: could the runtime have a default PropertyValueObjectFactory? - propertyFactory = new JavaPropertyValueObjectFactory(new MediatorImpl(extensionPoints)); - } - - /** - * Returns a SpringImplementationProvider for a given component and Spring implementation - * @param component the component for which implementation instances are required - * @param implementation the Spring implementation with details of the component - * implementation - * @return the SpringImplementationProvider for the specified component - */ - public ImplementationProvider createImplementationProvider(RuntimeComponent component, - SpringImplementation implementation) { - return new SpringImplementationProvider(component, - implementation, - proxyFactory, - propertyFactory); - } - - /** - * Returns the class of the Spring implementation - */ - public Class getModelType() { - return SpringImplementation.class; - } -} // end class SpringImplementationProviderFactory +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.spring.invocation; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint; +import org.apache.tuscany.sca.databinding.impl.MediatorImpl; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * ImplementationProviderFactory for Spring implementation type + * @version $Rev$ $Date$ + * + */ +public class SpringImplementationProviderFactory implements ImplementationProviderFactory { + + private ProxyFactory proxyFactory; + private JavaPropertyValueObjectFactory propertyFactory; + + /** + * Simple constructor + * + */ + public SpringImplementationProviderFactory(ExtensionPointRegistry extensionPoints) { + super(); + + ProxyFactoryExtensionPoint proxyFactories = extensionPoints.getExtensionPoint(ProxyFactoryExtensionPoint.class); + proxyFactory = new ExtensibleProxyFactory(proxyFactories); + + // TODO: could the runtime have a default PropertyValueObjectFactory? + propertyFactory = new JavaPropertyValueObjectFactory(new MediatorImpl(extensionPoints)); + } + + /** + * Returns a SpringImplementationProvider for a given component and Spring implementation + * @param component the component for which implementation instances are required + * @param implementation the Spring implementation with details of the component + * implementation + * @return the SpringImplementationProvider for the specified component + */ + public ImplementationProvider createImplementationProvider(RuntimeComponent component, + SpringImplementation implementation) { + return new SpringImplementationProvider(component, + implementation, + proxyFactory, + propertyFactory); + } + + /** + * Returns the class of the Spring implementation + */ + public Class getModelType() { + return SpringImplementation.class; + } +} // end class SpringImplementationProviderFactory diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java index 6bdafdccd2..590b278e4c 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringImplementationTie.java @@ -1,143 +1,143 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.tuscany.sca.implementation.spring.invocation; - -import java.util.List; - -import org.apache.tuscany.sca.assembly.ComponentProperty; -import org.apache.tuscany.sca.assembly.Property; -import org.apache.tuscany.sca.assembly.Reference; -import org.apache.tuscany.sca.core.factory.ObjectFactory; -import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.interfacedef.java.JavaInterface; -import org.apache.tuscany.sca.runtime.RuntimeComponent; - -/** - * This is the Tuscany side tie for the corresponding runtime stub class. - * It enables the Sping code in the runtime module to invoke methods on a - * Tuscany SpringImplementation without the Spring runtime module - * needing to know about any Tuscany classes. See the SpringImplementationStub class - * in the implementation-spring-runtime module for what the stub does. - */ -public class SpringImplementationTie { - - private SpringImplementation implementation; - private RuntimeComponent component; - private JavaPropertyValueObjectFactory propertyFactory; - - public SpringImplementationTie(SpringImplementation implementation, RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { - this.implementation = implementation; - this.component = component; - this.propertyFactory = propertyFactory; - } - - public String getURI() { - throw new IllegalStateException("Not yet impl"); - } - - public String getComponentName() { - return component.getName(); - } - /** - * Method to create a Java Bean for a Property value - * @param 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 getPropertyBean(Class requiredType, String name) { - B propertyObject = null; - // Get the component's list of properties - List props = component.getProperties(); - for (ComponentProperty prop : props) { - if (prop.getName().equals(name)) { - // On finding the property, create a factory for it and create a Bean using - // the factory - ObjectFactory factory = propertyFactory.createValueFactory(prop, prop.getValue(), requiredType); - propertyObject = (B)factory.getInstance(); - } // end if - } // end for - - return propertyObject; - } - - /** - * Creates a proxy Bean for a reference - * @param 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 - */ - private B getService(Class 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) { - System.out.println("Spring parent context - getBean called for name: " + name); - // The expectation is that the requested Bean is either a reference or a property - // from the Spring context - for (Reference reference : implementation.getReferences()) { - if (reference.getName().equals(name)) { - // Extract the Java interface for the reference (it can't be any other interface type - // for a Spring application context) - if (requiredType == null) { - JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface(); - requiredType = javaInterface.getJavaClass(); - } - // Create and return the proxy for the reference - return getService(requiredType, reference.getName()); - } // end if - } // end for - - // For a property, get the name and the required Java type and create a Bean - // of that type with the value inserted. - for (Property property : implementation.getProperties()) { - if (property.getName().equals(name)) { - if (requiredType == null) { - // The following code only deals with a subset of types and was superceded - // by the information from the implementation (which uses Classes as found - // in the Spring implementation itself. - //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() ); - requiredType = implementation.getPropertyClass(name); - } - return getPropertyBean(requiredType, property.getName()); - } // end if - } // end for - // TODO: NoSuchBeanException - throw new RuntimeException("Unable to find Bean with name " + name); - - } // end method getBean( String, Class ) - - public Object getComponentTie() { - return new ComponentTie(component); - } - - public Object getPropertyValueTie() { - return new PropertyValueTie(component, propertyFactory); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.spring.invocation; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * This is the Tuscany side tie for the corresponding runtime stub class. + * It enables the Sping code in the runtime module to invoke methods on a + * Tuscany SpringImplementation without the Spring runtime module + * needing to know about any Tuscany classes. See the SpringImplementationStub class + * in the implementation-spring-runtime module for what the stub does. + */ +public class SpringImplementationTie { + + private SpringImplementation implementation; + private RuntimeComponent component; + private JavaPropertyValueObjectFactory propertyFactory; + + public SpringImplementationTie(SpringImplementation implementation, RuntimeComponent component, JavaPropertyValueObjectFactory propertyFactory) { + this.implementation = implementation; + this.component = component; + this.propertyFactory = propertyFactory; + } + + public String getURI() { + throw new IllegalStateException("Not yet impl"); + } + + public String getComponentName() { + return component.getName(); + } + /** + * Method to create a Java Bean for a Property value + * @param 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 getPropertyBean(Class requiredType, String name) { + B propertyObject = null; + // Get the component's list of properties + List props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + // On finding the property, create a factory for it and create a Bean using + // the factory + ObjectFactory factory = propertyFactory.createValueFactory(prop, prop.getValue(), requiredType); + propertyObject = (B)factory.getInstance(); + } // end if + } // end for + + return propertyObject; + } + + /** + * Creates a proxy Bean for a reference + * @param 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 + */ + private B getService(Class 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) { + System.out.println("Spring parent context - getBean called for name: " + name); + // The expectation is that the requested Bean is either a reference or a property + // from the Spring context + for (Reference reference : implementation.getReferences()) { + if (reference.getName().equals(name)) { + // Extract the Java interface for the reference (it can't be any other interface type + // for a Spring application context) + if (requiredType == null) { + JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface(); + requiredType = javaInterface.getJavaClass(); + } + // Create and return the proxy for the reference + return getService(requiredType, reference.getName()); + } // end if + } // end for + + // For a property, get the name and the required Java type and create a Bean + // of that type with the value inserted. + for (Property property : implementation.getProperties()) { + if (property.getName().equals(name)) { + if (requiredType == null) { + // The following code only deals with a subset of types and was superceded + // by the information from the implementation (which uses Classes as found + // in the Spring implementation itself. + //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() ); + requiredType = implementation.getPropertyClass(name); + } + return getPropertyBean(requiredType, property.getName()); + } // end if + } // end for + // TODO: NoSuchBeanException + throw new RuntimeException("Unable to find Bean with name " + name); + + } // end method getBean( String, Class ) + + public Object getComponentTie() { + return new ComponentTie(component); + } + + public Object getPropertyValueTie() { + return new PropertyValueTie(component, propertyFactory); + } +} diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java index d1330f8471..6a23830aa9 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvocationException.java @@ -1,40 +1,40 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring.invocation; - -/** - * @version $Rev$ $Date$ - */ -public class SpringInvocationException extends Exception { - - private static final long serialVersionUID = -1157790036638157513L; - - public SpringInvocationException(String msg) { - super(msg); - } - - public SpringInvocationException(Throwable e) { - super(e); - } - - public SpringInvocationException(String msg,Throwable e) { - super(msg,e); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.spring.invocation; + +/** + * @version $Rev$ $Date$ + */ +public class SpringInvocationException extends Exception { + + private static final long serialVersionUID = -1157790036638157513L; + + public SpringInvocationException(String msg) { + super(msg); + } + + public SpringInvocationException(Throwable e) { + super(e); + } + + public SpringInvocationException(String msg,Throwable e) { + super(msg,e); + } + +} diff --git a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java index 3bf68a689c..1f9796ccc4 100644 --- a/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java +++ b/java/sca/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/invocation/SpringInvoker.java @@ -1,124 +1,124 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.implementation.spring.invocation; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.apache.tuscany.sca.implementation.spring.SpringBeanElement; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.runtime.RuntimeComponent; -import org.apache.tuscany.sca.runtime.RuntimeComponentService; - -/** - * Initial implementation of a Spring bean invoker - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - */ -public class SpringInvoker implements Invoker { - - private Method theMethod = null; - private Object bean; - private SpringBeanElement beanElement; - private boolean badInvoker = false; - - private SpringContextStub springContext; - private Operation operation; - - /** - * SpringInvoker constructor - * @param component - the Spring component to invoke - * @param service - the service to invoke - * @param operation - the operation to invoke - */ - public SpringInvoker(RuntimeComponent component, - SpringContextStub springContext, - RuntimeComponentService service, - Operation operation) { - - this.springContext = springContext; - this.operation = operation; - - // From the component and the service, identify the Spring Bean which is the target - SpringImplementation theImplementation = (SpringImplementation)component.getImplementation(); - beanElement = theImplementation.getBeanFromService(service.getService()); - - if (beanElement == null) { - badInvoker = true; - return; - } - - } // end constructor SpringInvoker - - // Lazy-load the method to avoid timing problems with the Spring Context - private void setupMethod() throws SpringInvocationException{ - try { - bean = springContext.getBean(beanElement.getId()); - Class beanClass = bean.getClass(); - theMethod = JavaInterfaceUtil.findMethod(beanClass, operation); - //System.out.println("SpringInvoker - found method " + theMethod.getName() ); - } catch (NoSuchMethodException e) { - throw new SpringInvocationException(e); - } - } - - private Object doInvoke(Object payload) throws SpringInvocationException { - if (theMethod == null) - setupMethod(); - - if (badInvoker) - throw new SpringInvocationException("Spring invoker incorrectly configured"); - // Invoke the method on the Spring bean using the payload, returning the results - try { - Object ret; - - if (payload != null && !payload.getClass().isArray()) { - ret = theMethod.invoke(bean, payload); - } else { - ret = theMethod.invoke(bean, (Object[])payload); - } - return ret; - } catch (InvocationTargetException e) { - throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e.getCause()); - } catch (Exception e) { - throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e); - } - - } // end method doInvoke - - /** - * @param msg the message to invoke on the target bean - */ - public Message invoke(Message msg) { - try { - Object resp = doInvoke(msg.getBody()); - msg.setBody(resp); - } catch (SpringInvocationException e) { - msg.setFaultBody(e.getCause()); - }catch (Throwable e) { - msg.setFaultBody(e); - } - //System.out.println("Spring Invoker - invoke called"); - return msg; - } // end method invoke - -} // end class SpringInvoker +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.spring.invocation; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.sca.implementation.spring.SpringBeanElement; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * Initial implementation of a Spring bean invoker + * @version $Rev$ $Date$ + */ +public class SpringInvoker implements Invoker { + + private Method theMethod = null; + private Object bean; + private SpringBeanElement beanElement; + private boolean badInvoker = false; + + private SpringContextStub springContext; + private Operation operation; + + /** + * SpringInvoker constructor + * @param component - the Spring component to invoke + * @param service - the service to invoke + * @param operation - the operation to invoke + */ + public SpringInvoker(RuntimeComponent component, + SpringContextStub springContext, + RuntimeComponentService service, + Operation operation) { + + this.springContext = springContext; + this.operation = operation; + + // From the component and the service, identify the Spring Bean which is the target + SpringImplementation theImplementation = (SpringImplementation)component.getImplementation(); + beanElement = theImplementation.getBeanFromService(service.getService()); + + if (beanElement == null) { + badInvoker = true; + return; + } + + } // end constructor SpringInvoker + + // Lazy-load the method to avoid timing problems with the Spring Context + private void setupMethod() throws SpringInvocationException{ + try { + bean = springContext.getBean(beanElement.getId()); + Class beanClass = bean.getClass(); + theMethod = JavaInterfaceUtil.findMethod(beanClass, operation); + //System.out.println("SpringInvoker - found method " + theMethod.getName() ); + } catch (NoSuchMethodException e) { + throw new SpringInvocationException(e); + } + } + + private Object doInvoke(Object payload) throws SpringInvocationException { + if (theMethod == null) + setupMethod(); + + if (badInvoker) + throw new SpringInvocationException("Spring invoker incorrectly configured"); + // Invoke the method on the Spring bean using the payload, returning the results + try { + Object ret; + + if (payload != null && !payload.getClass().isArray()) { + ret = theMethod.invoke(bean, payload); + } else { + ret = theMethod.invoke(bean, (Object[])payload); + } + return ret; + } catch (InvocationTargetException e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e.getCause()); + } catch (Exception e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e); + } + + } // end method doInvoke + + /** + * @param msg the message to invoke on the target bean + */ + public Message invoke(Message msg) { + try { + Object resp = doInvoke(msg.getBody()); + msg.setBody(resp); + } catch (SpringInvocationException e) { + msg.setFaultBody(e.getCause()); + }catch (Throwable e) { + msg.setFaultBody(e); + } + //System.out.println("Spring Invoker - invoke called"); + return msg; + } // end method invoke + +} // end class SpringInvoker 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 eab0fb8942..ed67479eed 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 @@ -1,233 +1,233 @@ -/* - * 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.xml; - -import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.XMLStreamWriter; - -import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.ComponentType; -import org.apache.tuscany.sca.assembly.xml.Constants; -import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor; -import org.apache.tuscany.sca.contribution.processor.ContributionReadException; -import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; -import org.apache.tuscany.sca.contribution.processor.ContributionWriteException; -import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; -import org.apache.tuscany.sca.contribution.resolver.ModelResolver; -import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.implementation.spring.SpringImplementation; -import org.apache.tuscany.sca.implementation.spring.introspect.SpringXMLComponentTypeLoader; -import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; -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; - -/** - * SpringArtifactProcessor is responsible for processing the XML of an - * element in an SCA SCDL file. - * - * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ - */ -public class SpringImplementationProcessor implements StAXArtifactProcessor { - - private static final String LOCATION = "location"; - private static final String IMPLEMENTATION_SPRING = "implementation.spring"; - private static final QName IMPLEMENTATION_SPRING_QNAME = new QName(Constants.SCA11_NS, IMPLEMENTATION_SPRING); - private static final String MSG_LOCATION_MISSING = "Reading implementation.spring - location attribute missing"; - - private AssemblyFactory assemblyFactory; - private JavaInterfaceFactory javaFactory; - private PolicyFactory policyFactory; - private PolicySubjectProcessor policyProcessor; - private Monitor monitor; - - private FactoryExtensionPoint factories; - - public SpringImplementationProcessor(FactoryExtensionPoint modelFactories, Monitor monitor) { - this.factories = modelFactories; - this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); - this.javaFactory = modelFactories.getFactory(JavaInterfaceFactory.class); - this.policyFactory = modelFactories.getFactory(PolicyFactory.class); - this.policyProcessor = new PolicySubjectProcessor(policyFactory); - 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); - } - } - - /* - * Read the XML and parse out the attributes. - * - * has a single required attribute: - * "location" - which is the target URI of of an archive file or a directory that contains the Spring - * application context files. - * If the resource identified by the location attribute is an archive file, then the file - * META-INF/MANIFEST.MF is read from the archive. - * If the location URI identifies a directory, then META-INF/MANIFEST.MF must exist - * underneath that directory. - * If the manifest file contains a header "Spring-Context" of the format: - * Spring-Context ::= path ( ';' path )* - * - * Where path is a relative path with respect to the location URI, then the set of paths - * specified in the header identify the context configuration files. - * If there is no MANIFEST.MF file or no Spring-Context header within that file, - * then the default behaviour is to build an application context using all the *.xml files - * in the METAINF/spring directory. - */ - public SpringImplementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { - - // Create the Spring implementation - SpringImplementation springImplementation = null; - - // Read the location attribute for the spring implementation - String springLocation = reader.getAttributeValue(null, LOCATION); - if (springLocation != null) { - springImplementation = new SpringImplementation(); - springImplementation.setLocation(springLocation); - springImplementation.setUnresolved(true); - processComponentType(springImplementation); - } else { - error("LocationAttributeMissing", reader); - //throw new ContributionReadException(MSG_LOCATION_MISSING); - } - - // Read policies - policyProcessor.readPolicies(springImplementation, reader); - - // Skip to end element - while (reader.hasNext()) { - if (reader.next() == END_ELEMENT && IMPLEMENTATION_SPRING_QNAME.equals(reader.getName())) { - break; - } - } // end while - - return springImplementation; - } // end read - - /* - * Handles the component type for the Spring implementation - * @param springImplementation - a Spring implementation. The component type information - * is created for this implementation - * - */ - private void processComponentType(SpringImplementation springImplementation) { - - // Create a ComponentType and mark it unresolved - ComponentType componentType = assemblyFactory.createComponentType(); - componentType.setUnresolved(true); - springImplementation.setComponentType(componentType); - } // end processComponentType - - /* - * Write out the XML representation of the Spring implementation - * - */ - public void write(SpringImplementation springImplementation, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { - - // Write - policyProcessor.writePolicyPrefixes(springImplementation, writer); - writer.writeStartElement(Constants.SCA11_NS, IMPLEMENTATION_SPRING); - policyProcessor.writePolicyAttributes(springImplementation, writer); - - if (springImplementation.getLocation() != null) { - writer.writeAttribute(LOCATION, springImplementation.getLocation()); - } - - writer.writeEndElement(); - - } // end write - - /** - * Resolves the Spring implementation - loads the Spring application-context XML and - * derives the spring implementation componentType from it - */ - public void resolve(SpringImplementation springImplementation, ModelResolver resolver) - throws ContributionResolveException { - - if (springImplementation == null) - return; - - /* Load the Spring component type by reading the Spring application context */ - SpringXMLComponentTypeLoader springLoader = - new SpringXMLComponentTypeLoader(factories, assemblyFactory, javaFactory, policyFactory); - try { - // Load the Spring Implementation information from its application context file... - springLoader.load(springImplementation, resolver); - } catch (ContributionReadException e) { - ContributionResolveException ce = new ContributionResolveException(e); - error("ContributionResolveException", resolver, ce); - throw ce; - } - - ComponentType ct = springImplementation.getComponentType(); - if (ct.isUnresolved()) { - // If the introspection fails to resolve, try to find a side file... - ComponentType componentType = resolver.resolveModel(ComponentType.class, ct); - if (componentType.isUnresolved()) { - error("UnableToResolveComponentType", resolver); - //throw new ContributionResolveException("SpringArtifactProcessor: unable to resolve componentType for Spring component"); - } else { - springImplementation.setComponentType(componentType); - springImplementation.setUnresolved(false); - } - - } // end if - - } // end method resolve - - public QName getArtifactType() { - return IMPLEMENTATION_SPRING_QNAME; - } - - public Class getModelType() { - return SpringImplementation.class; - } - -} // end class SpringArtifactProcessor +/* + * 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.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.processor.ContributionWriteException; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.implementation.spring.introspect.SpringXMLComponentTypeLoader; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +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; + +/** + * SpringArtifactProcessor is responsible for processing the XML of an + * element in an SCA SCDL file. + * + * @version $Rev$ $Date$ + */ +public class SpringImplementationProcessor implements StAXArtifactProcessor { + + private static final String LOCATION = "location"; + private static final String IMPLEMENTATION_SPRING = "implementation.spring"; + private static final QName IMPLEMENTATION_SPRING_QNAME = new QName(Constants.SCA11_NS, IMPLEMENTATION_SPRING); + private static final String MSG_LOCATION_MISSING = "Reading implementation.spring - location attribute missing"; + + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + private PolicyFactory policyFactory; + private PolicySubjectProcessor policyProcessor; + private Monitor monitor; + + private FactoryExtensionPoint factories; + + public SpringImplementationProcessor(FactoryExtensionPoint modelFactories, Monitor monitor) { + this.factories = modelFactories; + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + this.javaFactory = modelFactories.getFactory(JavaInterfaceFactory.class); + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.policyProcessor = new PolicySubjectProcessor(policyFactory); + 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); + } + } + + /* + * Read the XML and parse out the attributes. + * + * has a single required attribute: + * "location" - which is the target URI of of an archive file or a directory that contains the Spring + * application context files. + * If the resource identified by the location attribute is an archive file, then the file + * META-INF/MANIFEST.MF is read from the archive. + * If the location URI identifies a directory, then META-INF/MANIFEST.MF must exist + * underneath that directory. + * If the manifest file contains a header "Spring-Context" of the format: + * Spring-Context ::= path ( ';' path )* + * + * Where path is a relative path with respect to the location URI, then the set of paths + * specified in the header identify the context configuration files. + * If there is no MANIFEST.MF file or no Spring-Context header within that file, + * then the default behaviour is to build an application context using all the *.xml files + * in the METAINF/spring directory. + */ + public SpringImplementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + + // Create the Spring implementation + SpringImplementation springImplementation = null; + + // Read the location attribute for the spring implementation + String springLocation = reader.getAttributeValue(null, LOCATION); + if (springLocation != null) { + springImplementation = new SpringImplementation(); + springImplementation.setLocation(springLocation); + springImplementation.setUnresolved(true); + processComponentType(springImplementation); + } else { + error("LocationAttributeMissing", reader); + //throw new ContributionReadException(MSG_LOCATION_MISSING); + } + + // Read policies + policyProcessor.readPolicies(springImplementation, reader); + + // Skip to end element + while (reader.hasNext()) { + if (reader.next() == END_ELEMENT && IMPLEMENTATION_SPRING_QNAME.equals(reader.getName())) { + break; + } + } // end while + + return springImplementation; + } // end read + + /* + * Handles the component type for the Spring implementation + * @param springImplementation - a Spring implementation. The component type information + * is created for this implementation + * + */ + private void processComponentType(SpringImplementation springImplementation) { + + // Create a ComponentType and mark it unresolved + ComponentType componentType = assemblyFactory.createComponentType(); + componentType.setUnresolved(true); + springImplementation.setComponentType(componentType); + } // end processComponentType + + /* + * Write out the XML representation of the Spring implementation + * + */ + public void write(SpringImplementation springImplementation, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write + policyProcessor.writePolicyPrefixes(springImplementation, writer); + writer.writeStartElement(Constants.SCA11_NS, IMPLEMENTATION_SPRING); + policyProcessor.writePolicyAttributes(springImplementation, writer); + + if (springImplementation.getLocation() != null) { + writer.writeAttribute(LOCATION, springImplementation.getLocation()); + } + + writer.writeEndElement(); + + } // end write + + /** + * Resolves the Spring implementation - loads the Spring application-context XML and + * derives the spring implementation componentType from it + */ + public void resolve(SpringImplementation springImplementation, ModelResolver resolver) + throws ContributionResolveException { + + if (springImplementation == null) + return; + + /* Load the Spring component type by reading the Spring application context */ + SpringXMLComponentTypeLoader springLoader = + new SpringXMLComponentTypeLoader(factories, assemblyFactory, javaFactory, policyFactory); + try { + // Load the Spring Implementation information from its application context file... + springLoader.load(springImplementation, resolver); + } catch (ContributionReadException e) { + ContributionResolveException ce = new ContributionResolveException(e); + error("ContributionResolveException", resolver, ce); + throw ce; + } + + ComponentType ct = springImplementation.getComponentType(); + if (ct.isUnresolved()) { + // If the introspection fails to resolve, try to find a side file... + ComponentType componentType = resolver.resolveModel(ComponentType.class, ct); + if (componentType.isUnresolved()) { + error("UnableToResolveComponentType", resolver); + //throw new ContributionResolveException("SpringArtifactProcessor: unable to resolve componentType for Spring component"); + } else { + springImplementation.setComponentType(componentType); + springImplementation.setUnresolved(false); + } + + } // end if + + } // end method resolve + + public QName getArtifactType() { + return IMPLEMENTATION_SPRING_QNAME; + } + + public Class getModelType() { + return SpringImplementation.class; + } + +} // end class SpringArtifactProcessor diff --git a/java/sca/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties b/java/sca/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties index a348225d31..6fce02664a 100644 --- a/java/sca/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties +++ b/java/sca/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties @@ -1,23 +1,23 @@ -# -# -# 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. -# -# -LocationAttributeMissing = Reading implementation.spring - location attribute missing -ContributionResolveException = ContributionResolveException occured due to: +# +# +# 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. +# +# +LocationAttributeMissing = Reading implementation.spring - location attribute missing +ContributionResolveException = ContributionResolveException occured due to: UnableToResolveComponentType = SpringArtifactProcessor: unable to resolve componentType for Spring component \ No newline at end of file -- cgit v1.2.3