in modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java [289:379]
private <T> void evaluateConstructor(JavaImplementation type, Class<T> clazz) throws IntrospectionException {
// determine constructor if one is not annotated
JavaConstructorImpl<?> definition = type.getConstructor();
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 {
if (!isImplementationJava(type)) {
// FIXME: [rfeng] Don't process the constructors for non implementation.java types
return;
}
// no definition, heuristically determine constructor
Constructor[] constructors = clazz.getConstructors();
if (constructors.length == 0) {
throw new NoConstructorException("[JCI50001] No public constructor for class :" + type.getName());
} else if (constructors.length == 1) {
// Only one constructor, take it
constructor = constructors[0];
} else {
Constructor<T> selected = null;
for (Constructor<T> ctor : constructors) {
if (allArgsAnnotated(ctor)) {
selected = ctor;
for (Constructor<T> ctor2 : constructors) {
if (selected != ctor2 && allArgsAnnotated(ctor2)) {
throw new InvalidConstructorException("[JCI50005] Multiple annotated constructors for class :" + type.getName());
}
}
}
}
if (selected == null) {
for (Constructor<T> ctor : constructors) {
if (ctor.getParameterTypes().length == 0) {
selected = ctor;
break;
}
}
}
if (selected == null) {
throw new NoConstructorException();
}
constructor = selected;
definition = type.getConstructors().get(selected);
type.setConstructor(definition);
}
definition = type.getConstructors().get(constructor);
type.setConstructor(definition);
}
JavaParameterImpl[] parameters = definition.getParameters();
if (parameters.length == 0) {
return;
}
Map<String, JavaElementImpl> props = type.getPropertyMembers();
Map<String, JavaElementImpl> refs = type.getReferenceMembers();
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);
}
}
}