diff options
Diffstat (limited to 'sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml')
6 files changed, 832 insertions, 0 deletions
diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanElement.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanElement.java new file mode 100644 index 0000000000..d658859e60 --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanElement.java @@ -0,0 +1,60 @@ +/* + * 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.implementation.spring.xml; + +import java.util.List; +import java.util.ArrayList; + + +/** + * Represents a <bean> 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 List<SpringPropertyElement> properties = new ArrayList<SpringPropertyElement>(); + + public SpringBeanElement( String id, String className ) { + this.id = id; + this.className = className; + } + + public String getClassName() { + return className; + } + + public String getId() { + return id; + } + + public List<SpringPropertyElement> getProperties() { + return properties; + } + + public void addProperty( SpringPropertyElement property ) { + properties.add( property ); + } + + +} // end class SpringBeanElement
\ No newline at end of file diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanIntrospector.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanIntrospector.java new file mode 100644 index 0000000000..0fdeb4da71 --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringBeanIntrospector.java @@ -0,0 +1,151 @@ +/* + * 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.implementation.spring.xml; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceIntrospector; +import org.apache.tuscany.sca.implementation.java.DefaultJavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.introspect.DefaultJavaClassIntrospectorExtensionPoint; +import org.apache.tuscany.sca.implementation.java.introspect.ExtensibleJavaClassIntrospector; +import org.apache.tuscany.sca.implementation.java.introspect.IntrospectionException; +import org.apache.tuscany.sca.implementation.java.introspect.JavaClassIntrospector; +import org.apache.tuscany.sca.implementation.java.introspect.JavaClassIntrospectorExtensionPoint; +import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.AllowsPassByReferenceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.BaseJavaClassVisitor; +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.ConversationProcessor; +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.HeuristicPojoProcessor; +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.ScopeProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ServiceProcessor; +import org.apache.tuscany.sca.policy.PolicyFactory; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; + +/** + * 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 JavaClassIntrospector classIntrospector; + private JavaClassIntrospectorExtensionPoint classVisitors = + new DefaultJavaClassIntrospectorExtensionPoint(); + private JavaImplementationFactory javaImplementationFactory; + + /** + * The constructor sets up the various visitor elements that will be used to inrospect + * the Spring bean and extract SCA information + * @param assemblyFactory - an AssemblyFactory + * @param interfaceIntrospector - an Java InterfaceIntrospector + * @param javaFactory - a Java Interface Factory + */ + public SpringBeanIntrospector( AssemblyFactory assemblyFactory, + JavaInterfaceIntrospector interfaceIntrospector, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory ) { + + // Create the list of class visitors + BaseJavaClassVisitor[] extensions = new BaseJavaClassVisitor[] { + new ConstructorProcessor(assemblyFactory), + new AllowsPassByReferenceProcessor(assemblyFactory), + new ContextProcessor(assemblyFactory), + new ConversationProcessor(assemblyFactory), + new DestroyProcessor(assemblyFactory), + new EagerInitProcessor(assemblyFactory), + new InitProcessor(assemblyFactory), + new PropertyProcessor(assemblyFactory), + new ReferenceProcessor(assemblyFactory, javaFactory, interfaceIntrospector), + new ResourceProcessor(assemblyFactory), + new ScopeProcessor(assemblyFactory), + new ServiceProcessor(assemblyFactory, javaFactory, interfaceIntrospector), + new HeuristicPojoProcessor(assemblyFactory, javaFactory, interfaceIntrospector), + new PolicyProcessor(assemblyFactory, policyFactory) + }; + for (JavaClassVisitor extension : extensions) { + classVisitors.addClassVisitor(extension); + } + this.classIntrospector = new ExtensibleJavaClassIntrospector(classVisitors); + + javaImplementationFactory = new DefaultJavaImplementationFactory(); + + } // 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 + * @throws ContributionResolveException - if there was a problem resolving the + * Spring Bean or its componentType + * + */ + public void 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 + classIntrospector.introspect( beanClass, javaImplementation); + + // 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<Service> services = javaImplementation.getServices(); + for ( Service service : services ) { + String name = service.getName(); + System.out.println("Spring Bean: found service with name: " + name); + } // end for + + } // end method introspectBean + + + +} // end class SpringBeanIntrospector
\ No newline at end of file diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringPropertyElement.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringPropertyElement.java new file mode 100644 index 0000000000..45cb4f01b6 --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringPropertyElement.java @@ -0,0 +1,46 @@ +/* + * 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.implementation.spring.xml; + + +/** + * Represents a <property> 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; + + public SpringPropertyElement( String name, String ref ) { + this.name = name; + this.ref = ref; + } + + public String getName() { + return name; + } + + public String getRef() { + return ref; + } + +} // end class SpringPropertyElement
\ No newline at end of file diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAReferenceElement.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAReferenceElement.java new file mode 100644 index 0000000000..4105034f54 --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAReferenceElement.java @@ -0,0 +1,47 @@ +/* + * 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.implementation.spring.xml; + + +/** + * Represents a <sca:reference> 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 String getName() { + return name; + } + + public String getType() { + return type; + } + +} // end class SpringSCAReferenceElement
\ No newline at end of file diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAServiceElement.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAServiceElement.java new file mode 100644 index 0000000000..ad2060b8d7 --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringSCAServiceElement.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.implementation.spring.xml; + + +/** + * Represents a <sca:service> 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 String getName() { + return name; + } + + public String getType() { + return type; + } + + public String getTarget() { + return target; + } + +} // end class SpringSCAServiceElement
\ No newline at end of file diff --git a/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringXMLComponentTypeLoader.java b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringXMLComponentTypeLoader.java new file mode 100644 index 0000000000..ee6a0423bd --- /dev/null +++ b/sandbox/implementation-spring2/src/main/java/org/apache/tuscany/implementation/spring/xml/SpringXMLComponentTypeLoader.java @@ -0,0 +1,475 @@ +/* + * 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.implementation.spring.xml; + +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.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceIntrospector; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; + +/** + * Introspects a Spring XML application-context configuration file to create <implementation-spring../> + * component type information. + * + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringXMLComponentTypeLoader { + private static final String SCA_NS = "http://www.springframework.org/schema/sca"; + private static final String SPRING_NS = "http://www.springframework.org/schema/beans"; + private static final QName SERVICE_ELEMENT = new QName(SCA_NS, "service"); + private static final QName REFERENCE_ELEMENT = new QName(SCA_NS, "reference"); + private static final QName BEANS_ELEMENT = new QName(SPRING_NS, "beans"); + private static final QName BEAN_ELEMENT = new QName(SPRING_NS, "bean"); + private static final QName PROPERTY_ELEMENT = new QName(SPRING_NS, "property"); + private static final String APPLICATION_CONTEXT = "application-context.xml"; + + private AssemblyFactory assemblyFactory; + private JavaInterfaceIntrospector interfaceIntrospector; + private JavaInterfaceFactory javaFactory; + private PolicyFactory policyFactory; + private ClassLoader cl; + + private SpringBeanIntrospector beanIntrospector; + + public SpringXMLComponentTypeLoader( AssemblyFactory assemblyFactory, + JavaInterfaceIntrospector interfaceIntrospector, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory) { + super(); + this.assemblyFactory = assemblyFactory; + this.interfaceIntrospector = interfaceIntrospector; + this.javaFactory = javaFactory; + this.policyFactory = policyFactory; + beanIntrospector = new SpringBeanIntrospector( assemblyFactory, + interfaceIntrospector, javaFactory, policyFactory ); + } + + protected Class<SpringImplementation> 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 ) 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 ); + if( !componentType.isUnresolved() ) implementation.setUnresolved( false ); + } // end if + System.out.println("Spring TypeLoader - load method complete"); + } // end method load + + /** + * Method which fills out the component type for a Spring implementation by reading the + * Spring application-context.xml file + * @param componentType - the component type to complete + * @param location - a string containing the relative location of the application-context.xml + * @return a Spring Resource for the application-context + * file + */ + private void loadFromXML( SpringImplementation implementation ) + throws ContributionReadException { + XMLStreamReader reader; + List<SpringBeanElement> beans = new ArrayList<SpringBeanElement>(); + List<SpringSCAServiceElement> services = new ArrayList<SpringSCAServiceElement>(); + List<SpringSCAReferenceElement> references = new ArrayList<SpringSCAReferenceElement>(); + SpringBeanElement bean = null; + + Resource resource; + + String location = implementation.getSpringLocation(); + + try { + // FIXME - is the ContextClassLoader the right place to start the search? + cl = Thread.currentThread().getContextClassLoader(); + + resource = getApplicationContextResource( location, cl ); + implementation.setResource( resource ); + // FIXME - need a better way to handle the XMLInputFactory than allocating a new one every time + XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); + reader = xmlFactory.createXMLStreamReader(resource.getInputStream()); + + // System.out.println("Spring TypeLoader - starting to read context file"); + + 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 (SERVICE_ELEMENT.equals(qname)) { + SpringSCAServiceElement service = new SpringSCAServiceElement( + reader.getAttributeValue(SCA_NS, "name"), + reader.getAttributeValue(SCA_NS, "type"), + reader.getAttributeValue(SCA_NS, "target") ); + services.add( service ); + } else if (REFERENCE_ELEMENT.equals(qname)) { + SpringSCAReferenceElement reference = new SpringSCAReferenceElement( + reader.getAttributeValue(SCA_NS, "name"), + reader.getAttributeValue(SCA_NS, "type") ); + references.add( reference ); + } else if (BEAN_ELEMENT.equals(qname)) { + // TODO FIX THIS !! + int count=reader.getAttributeCount(); + bean = new SpringBeanElement( + reader.getAttributeValue( null, "id"), + reader.getAttributeValue( null, "class") ); + beans.add( bean ); + } else if (PROPERTY_ELEMENT.equals(qname)) { + SpringPropertyElement property = new SpringPropertyElement( + reader.getAttributeValue(SPRING_NS, "name"), + reader.getAttributeValue(SPRING_NS, "ref")); + bean.addProperty( property ); + } // end if + break; + case END_ELEMENT: + if (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 (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, beans, services, references ); + + return; + } // end method loadFromXML + + /** + * Generates the Spring implementation component type from the configuration contained in the + * lists of beans, services and references derived from the application context + */ + private void generateComponentType( SpringImplementation implementation, + List<SpringBeanElement> beans, + List<SpringSCAServiceElement> services, + List<SpringSCAReferenceElement> references ) + throws ContributionReadException { + /* + * Each service becomes a service in the component type + * Each reference becomes a reference in the component type + * Each bean becomes a service, unless it is the target of a service element or unless it + * is the target of a bean reference property + * 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 + */ + + ComponentType componentType = implementation.getComponentType(); + + try { + // Deal with the services first.... + Iterator<SpringSCAServiceElement> its = services.iterator(); + while( its.hasNext() ) { + SpringSCAServiceElement serviceElement = its.next(); + Class<?> interfaze = cl.loadClass( 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 == beanElement.getId() ) { + implementation.setBeanForService( theService, beanElement ); + } + } // end for + } // end while + + // Next handle the references + Iterator<SpringSCAReferenceElement> itr = references.iterator(); + while( itr.hasNext() ) { + SpringSCAReferenceElement referenceElement = itr.next(); + Class<?> interfaze = cl.loadClass( referenceElement.getType() ); + Reference theReference = createReference( interfaze, referenceElement.getName() ); + componentType.getReferences().add( theReference ); + } // end while + + // Finally deal with the beans + Iterator<SpringBeanElement> 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(); + // Load the Spring bean class + Class<?> beanClass = cl.loadClass( beanElement.getClassName() ); + // Introspect the bean + ComponentType beanComponentType = assemblyFactory.createComponentType(); + beanIntrospector.introspectBean( beanClass, beanComponentType ); + // Get the service interface defined by this Spring Bean and add to + // the component type of the Spring Assembly + List<Service> 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 + // Now check to see if there are any more references + itb = beans.iterator(); + while( itb.hasNext() ) { + SpringBeanElement beanElement = itb.next(); + if( !beanElement.getProperties().isEmpty() ) { + Iterator<SpringPropertyElement> itp = beanElement.getProperties().iterator(); + while( itp.hasNext() ) { + SpringPropertyElement propertyElement = itp.next(); + if( propertyRefUnresolved( propertyElement.getRef(), beans, references ) ) { + // This means an unresolved reference from the spring bean... + // TODO + } // end if + } // end while + } // end if + + //Reference theReference = createReference( interfaze, referenceElement.getName() ); + //componentType.getReferences().add( theReference ); + } // end while + + } catch ( ClassNotFoundException e ) { + // Means that either an interface 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 + * @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<SpringBeanElement> beans, + List<SpringSCAReferenceElement> references ) { + boolean unresolved = true; + + if( ref != null ) { + // Scan over the beans looking for a match + Iterator<SpringBeanElement> 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 references looking for a match + if( unresolved ) { + Iterator<SpringSCAReferenceElement> itr = references.iterator(); + while( itr.hasNext() ) { + SpringSCAReferenceElement referenceElement = itr.next(); + if( ref.equals(referenceElement.getName()) ) { + unresolved = false; + break; + } // end if + } // end while + } // end if + } // 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 <implementation.spring../> element + * @param cl - the classloader for the Spring implementation + */ + protected Resource getApplicationContextResource( String locationAttr, ClassLoader cl ) + throws ContributionReadException { + File manifestFile = null; + File appXmlFile; + File locationFile = new File(locationAttr); + + if (!locationFile.exists()) { + // FIXME hack + URL url = cl.getResource(locationAttr); + if (url != null) { + return new UrlResource(url); + } + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + "unable to find resource file " + locationFile.toString()); + } + + if (locationFile.isDirectory()) { + try { + manifestFile = new File(locationFile, "META-INF/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 new UrlResource(appXmlFile.toURL()); + } + } + } + // no manifest-specified Spring context, use default + appXmlFile = new File(locationFile, APPLICATION_CONTEXT); + if (appXmlFile.exists()) { + return new UrlResource(appXmlFile.toURL()); + } + } catch (IOException e) { + throw new ContributionReadException("Error reading manifest " + manifestFile); + } + } else { + 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 Resouce type for jars + return new UrlResource(new URL("jar:" + locationFile.toURL() + "!/" + appCtxPath)); + } + } + } + je = jf.getJarEntry(APPLICATION_CONTEXT); + if (je != null) { + return new UrlResource(new URL("jar:" + locationFile.toURI().toURL() + "!" + 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); + } + } + + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + 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 = interfaceIntrospector.introspect(interfaze); + service.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = interfaceIntrospector.introspect(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 = interfaceIntrospector.introspect( interfaze ); + reference.getInterfaceContract().setInterface( callInterface ); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = + interfaceIntrospector.introspect(callInterface.getCallbackClass()); + reference.getInterfaceContract().setCallbackInterface(callbackInterface); + } + + return reference; + } +} // end class SpringXMLComponentTypeLoader
\ No newline at end of file |