in modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java [282:370]
private <T> void evaluateConstructor(JavaImplementation type, Class<T> clazz) throws IntrospectionException {
// determine constructor if one is not annotated
JavaConstructorImpl<?> definition = type.getConstructor();
Map<String, JavaElementImpl> props = type.getPropertyMembers();
Map<String, JavaElementImpl> refs = type.getReferenceMembers();
Constructor constructor;
boolean explict = false;
if (definition != null && definition.getConstructor()
.isAnnotationPresent(org.osoa.sca.annotations.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<T> selected = null;
for (Constructor<T> 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);
}
}
}