in modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java [379:591]
private void generateComponentType(SpringImplementation implementation,
ModelResolver resolver,
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 = resolveClass(resolver, serviceElement.getType());
Service theService = createService(interfaze, serviceElement.getName());
// Spring allows duplication of bean definitions in multiple context scenario,
// in such cases, the latest bean definition overrides the older ones, hence
// we will remove any older definition and use the latest.
Service duplicate = null;
for (Service service : componentType.getServices()) {
if (service.getName().equals(theService.getName()))
duplicate = service;
}
if (duplicate != null)
componentType.getServices().remove(duplicate);
componentType.getServices().add(theService);
// Add this service to the Service / Bean map
String beanName = serviceElement.getTarget();
for (SpringBeanElement beanElement : beans) {
if (beanName.equals(beanElement.getId())) {
implementation.setBeanForService(theService, beanElement);
}
} // end for
} // end while
// Next handle the references
Iterator<SpringSCAReferenceElement> itr = references.iterator();
while (itr.hasNext()) {
SpringSCAReferenceElement referenceElement = itr.next();
Class<?> interfaze = resolveClass(resolver, referenceElement.getType());
Reference theReference = createReference(interfaze, referenceElement.getName());
// Override the older bean definition with the latest ones.
Reference duplicate = null;
for (Reference reference : componentType.getReferences()) {
if (reference.getName().equals(theReference.getName()))
duplicate = reference;
}
if (duplicate != null)
componentType.getReferences().remove(duplicate);
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));
// Override the older bean definition with the latest ones.
Property duplicate = null;
for (Property property : componentType.getProperties()) {
if (property.getName().equals(theProperty.getName()))
duplicate = property;
}
if (duplicate != null)
componentType.getProperties().remove(duplicate);
componentType.getProperties().add(theProperty);
// Remember the Java Class (ie the type) for this property
implementation.setPropertyClass(theProperty.getName(), propType);
} // 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 = resolveClass(resolver, beanElement.getClassName());
// Introspect the bean
beanIntrospector =
new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory, beanElement.getCustructorArgs());
ComponentType beanComponentType = assemblyFactory.createComponentType();
javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType);
// Set the service name as bean name
for (Service componentService : beanComponentType.getServices())
componentService.setName(beanElement.getId());
// Get the service interface defined by this Spring Bean and add to
// the component type of the Spring Assembly
List<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 = 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<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 = 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<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 = resolveClass(resolver, paramType);
// Create a component type reference/property if the constructor-arg element has a
// type attribute OR index attribute declared...
if ((conArgElement.getType() != null && paramType.equals(conArgElement.getType())) ||
(conArgElement.getIndex() != -1 && (conArgElement.getIndex() == parameter.getIndex())))
{
if (parameter.getClassifer().getName().equals("org.osoa.sca.annotations.Reference")) {
Reference theReference = createReference(interfaze, 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