private void generateComponentType()

in modules/implementation-spring-old/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLComponentTypeLoader.java [344:527]


    private void generateComponentType(SpringImplementation implementation,
                                       List<SpringBeanElement> beans,
                                       List<SpringSCAServiceElement> services,
                                       List<SpringSCAReferenceElement> references,
                                       List<SpringSCAPropertyElement> 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<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.equals(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
            
            // Next handle the properties
            Iterator<SpringSCAPropertyElement> 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<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();
                    // If its a innerBean, ignore it
                    if (beanElement.isInnerBean()) continue;
                    // Load the Spring bean class
                    Class<?> beanClass = cl.loadClass(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<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
          
            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 = cl.loadClass(beanElement.getClassName());
                // Introspect the bean
                beanIntrospector =
                    new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs());
                ComponentType beanComponentType = assemblyFactory.createComponentType();
                javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType);
                Map<String, JavaElementImpl> 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<Reference> beanReferences = beanComponentType.getReferences();
                List<Property> beanProperties = beanComponentType.getProperties();
                
                Iterator<SpringPropertyElement> 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 = cl.loadClass((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<SpringConstructorArgElement> 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 = cl.loadClass(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