private void evaluateConstructor()

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);

            }
        }
    }