modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/HeuristicPojoProcessor.java [82:230]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @Override
    public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
        List<org.apache.tuscany.sca.assembly.Service> services = type.getServices();
        if (services.isEmpty()) {
            // heuristically determine the service
            /**
             * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation
             * In the cases described below, the services offered by a Java implementation class may be determined
             * through introspection, eliding the need to specify them using @Service. The following algorithm is used 
             * to determine how services are introspected from an implementation class:
             * 
             * If the interfaces of the SCA services are not specified with the @Service annotation on the 
             * implementation class, it is assumed that all implemented interfaces that have been annotated 
             * as @Remotable are the service interfaces provided by the component. If none of the implemented 
             * interfaces is remotable, then by default the implementation offers a single service whose type 
             * is the implementation class.
             */
            Set<Class> interfaces = getAllInterfaces(clazz);
            for (Class<?> i : interfaces) {
                if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) {
                    addService(type, i);
                }
            }
            if (services.isEmpty()) {
                // class is the interface
                addService(type, clazz);
            }
        }
        Set<Method> methods = getAllUniquePublicProtectedMethods(clazz, false);
        if (!type.getReferenceMembers().isEmpty() || !type.getPropertyMembers().isEmpty()) {
            // references and properties have been explicitly defined
            //            if (type.getServices().isEmpty()) {
            //                calculateServiceInterface(clazz, type, methods);
            //                if (type.getServices().isEmpty()) {
            //                    throw new ServiceTypeNotFoundException(clazz.getName());
            //                }
            //            }
            evaluateConstructor(type, clazz);
            return;
        }
        calcPropRefs(methods, services, type, clazz);
        evaluateConstructor(type, clazz);
    }

    private void addService(JavaImplementation type, Class<?> clazz) throws IntrospectionException {
        try {
            org.apache.tuscany.sca.assembly.Service service = createService(clazz);
            type.getServices().add(service);
        } catch (InvalidInterfaceException e) {
            throw new IntrospectionException(e);
        }
    }

    private boolean isPublicSetter(Method method) {
        return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers())
            && method.getName().startsWith("set")
            && method.getReturnType() == void.class;
    }

    private boolean isProtectedSetter(Method method) {
        return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers())
            && method.getName().startsWith("set")
            && method.getReturnType() == void.class;
    }

    private <T> void calcPropRefs(Set<Method> methods,
                                  List<org.apache.tuscany.sca.assembly.Service> services,
                                  JavaImplementation type,
                                  Class<T> clazz) throws IntrospectionException {
        // heuristically determine the properties references
        // make a first pass through all public methods with one param
        Set<String> setters = new HashSet<String>();
        Set<String> others = new HashSet<String>();
        for (Method method : methods) {
            if (!isPublicSetter(method)) {
                continue;
            }
            if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) {
                // Add the property name as others
                others.add(toPropertyName(method.getName()));
                continue;
            }
            if (!isInServiceInterface(method, services)) {
                // Not part of the service interface
                String name = toPropertyName(method.getName());
                setters.add(name);
                // avoid duplicate property or ref names
                if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) {
                    Class<?> param = method.getParameterTypes()[0];
                    Type genericType = method.getGenericParameterTypes()[0];
                    if (isReferenceType(param, genericType)) {
                        type.getReferences().add(createReference(name, param));
                        type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
                    } else {
                        type.getProperties().add(createProperty(name, param));
                        type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
                    }
                }
            }
        }
        // second pass for protected methods with one param
        for (Method method : methods) {
            if (!isProtectedSetter(method)) {
                continue;
            }
            if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) {
                // Add the property name as others
                others.add(toPropertyName(method.getName()));
                continue;
            }
            Class<?> param = method.getParameterTypes()[0];
            String name = toPropertyName(method.getName());
            setters.add(name);
            // avoid duplicate property or ref names
            if (isReferenceType(param, method.getGenericParameterTypes()[0])) {
                if (!type.getReferenceMembers().containsKey(name)) {
                    type.getReferences().add(createReference(name, param));
                    type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
                }
            } else {
                if (!type.getPropertyMembers().containsKey(name)) {
                    type.getProperties().add(createProperty(name, param));
                    type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
                }
            }
        }

        // Public or protected fields unless there is a public or protected
        // setter method
        // for the same name
        Set<Field> fields = getAllPublicAndProtectedFields(clazz, false);
        for (Field field : fields) {
            if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) {
                continue;
            }
            if (setters.contains(field.getName()) || others.contains(field.getName())) {
                continue;
            }
            String name = field.getName();
            Class<?> paramType = field.getType();
            if (isReferenceType(paramType, field.getGenericType())) {
                if (!type.getReferenceMembers().containsKey(name)) {
                    type.getReferences().add(createReference(name, paramType));
                    type.getReferenceMembers().put(name, new JavaElementImpl(field));
                }
            } else {
                if (!type.getPropertyMembers().containsKey(name)) {
                    type.getProperties().add(createProperty(name, paramType));
                    type.getPropertyMembers().put(name, new JavaElementImpl(field));
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanPojoProcessor.java [92:240]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @Override
    public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
        List<org.apache.tuscany.sca.assembly.Service> services = type.getServices();
        if (services.isEmpty()) {
            // heuristically determine the service
            /**
             * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation
             * In the cases described below, the services offered by a Java implementation class may be determined
             * through introspection, eliding the need to specify them using @Service. The following algorithm is used 
             * to determine how services are introspected from an implementation class:
             * 
             * If the interfaces of the SCA services are not specified with the @Service annotation on the 
             * implementation class, it is assumed that all implemented interfaces that have been annotated 
             * as @Remotable are the service interfaces provided by the component. If none of the implemented 
             * interfaces is remotable, then by default the implementation offers a single service whose type 
             * is the implementation class.
             */
            Set<Class> interfaces = getAllInterfaces(clazz);
            for (Class<?> i : interfaces) {
                if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) {
                    addService(type, i);
                }
            }
            if (services.isEmpty()) {
                // class is the interface
                addService(type, clazz);
            }
        }
        Set<Method> methods = getAllUniquePublicProtectedMethods(clazz, false);
        if (!type.getReferenceMembers().isEmpty() || !type.getPropertyMembers().isEmpty()) {
            // references and properties have been explicitly defined
            //            if (type.getServices().isEmpty()) {
            //                calculateServiceInterface(clazz, type, methods);
            //                if (type.getServices().isEmpty()) {
            //                    throw new ServiceTypeNotFoundException(clazz.getName());
            //                }
            //            }
            evaluateConstructor(type, clazz);
            return;
        }
        calcPropRefs(methods, services, type, clazz);
        evaluateConstructor(type, clazz);
    }

    private void addService(JavaImplementation type, Class<?> clazz) throws IntrospectionException {
        try {
            org.apache.tuscany.sca.assembly.Service service = createService(clazz);
            type.getServices().add(service);
        } catch (InvalidInterfaceException e) {
            throw new IntrospectionException(e);
        }
    }

    private boolean isPublicSetter(Method method) {
        return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers())
            && method.getName().startsWith("set")
            && method.getReturnType() == void.class;
    }

    private boolean isProtectedSetter(Method method) {
        return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers())
            && method.getName().startsWith("set")
            && method.getReturnType() == void.class;
    }

    private <T> void calcPropRefs(Set<Method> methods,
                                  List<org.apache.tuscany.sca.assembly.Service> services,
                                  JavaImplementation type,
                                  Class<T> clazz) throws IntrospectionException {
        // heuristically determine the properties references
        // make a first pass through all public methods with one param
        Set<String> setters = new HashSet<String>();
        Set<String> others = new HashSet<String>();
        for (Method method : methods) {
            if (!isPublicSetter(method)) {
                continue;
            }
            if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) {
                // Add the property name as others
                others.add(toPropertyName(method.getName()));
                continue;
            }
            if (!isInServiceInterface(method, services)) {
                // Not part of the service interface
                String name = toPropertyName(method.getName());
                setters.add(name);
                // avoid duplicate property or ref names
                if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) {
                    Class<?> param = method.getParameterTypes()[0];
                    Type genericType = method.getGenericParameterTypes()[0];
                    if (isReferenceType(param, genericType)) {
                        type.getReferences().add(createReference(name, param));
                        type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
                    } else {
                        type.getProperties().add(createProperty(name, param));
                        type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
                    }
                }
            }
        }
        // second pass for protected methods with one param
        for (Method method : methods) {
            if (!isProtectedSetter(method)) {
                continue;
            }
            if (method.isAnnotationPresent(Callback.class) || method.isAnnotationPresent(Context.class)) {
                // Add the property name as others
                others.add(toPropertyName(method.getName()));
                continue;
            }
            Class<?> param = method.getParameterTypes()[0];
            String name = toPropertyName(method.getName());
            setters.add(name);
            // avoid duplicate property or ref names
            if (isReferenceType(param, method.getGenericParameterTypes()[0])) {
                if (!type.getReferenceMembers().containsKey(name)) {
                    type.getReferences().add(createReference(name, param));
                    type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
                }
            } else {
                if (!type.getPropertyMembers().containsKey(name)) {
                    type.getProperties().add(createProperty(name, param));
                    type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
                }
            }
        }

        // Public or protected fields unless there is a public or protected
        // setter method
        // for the same name
        Set<Field> fields = getAllPublicAndProtectedFields(clazz, false);
        for (Field field : fields) {
            if (field.isAnnotationPresent(Callback.class) || field.isAnnotationPresent(Context.class)) {
                continue;
            }
            if (setters.contains(field.getName()) || others.contains(field.getName())) {
                continue;
            }
            String name = field.getName();
            Class<?> paramType = field.getType();
            if (isReferenceType(paramType, field.getGenericType())) {
                if (!type.getReferenceMembers().containsKey(name)) {
                    type.getReferences().add(createReference(name, paramType));
                    type.getReferenceMembers().put(name, new JavaElementImpl(field));
                }
            } else {
                if (!type.getPropertyMembers().containsKey(name)) {
                    type.getProperties().add(createProperty(name, paramType));
                    type.getPropertyMembers().put(name, new JavaElementImpl(field));
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



