modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/JavaIntrospectionHelper.java [52:344]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public final class JavaIntrospectionHelper {
    private static final Logger logger = Logger.getLogger(JavaIntrospectionHelper.class.getName());
    private static final Class<?>[] EMPTY_CLASS_ARRY = new Class[0];

    /**
     * Hide the constructor
     */
    private JavaIntrospectionHelper() {
    }

    /**
     * Returns a collection of public, and protected fields declared by a class
     * or one of its supertypes
     */
    public static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, boolean validating) {
        return getAllPublicAndProtectedFields(clazz, new HashSet<Field>(), validating);
    }

    private static void checkInvalidAnnotations(AnnotatedElement element) {
        for (Annotation a : element.getAnnotations()) {
            if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.")) {
                logger.warning("Invalid annotation " + a + " is found on " + element);
            }
        }
    }

    /**
     * Recursively evaluates the type hierarchy to return all fields that are
     * public or protected
     */
    private static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, Set<Field> fields, boolean validating) {
        if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
            return fields;
        }
        fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields, validating);

        Field[] declaredFields = null;

        try {
        	declaredFields = clazz.getDeclaredFields();
        } catch(Throwable t) {
        	//TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
        	logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
        }

        if( declaredFields != null ) {
            for (final Field field : declaredFields) {
                int modifiers = field.getModifiers();
                // The field should be non-final and non-static
                if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            field.setAccessible(true); // ignore Java accessibility
                            return null;
                        }
                    });
                    fields.add(field);
                } /*else {
                    if (validating) {
                        checkInvalidAnnotations(field);
                    }
                }*/
            }
        }
        return fields;
    }

    /**
     * Returns a collection of injectable fields declared by a class
     * or one of its supertypes
     *
     * For now we will include final or static fields so that validation problems can be reported
     */
    public static Set<Field> getInjectableFields(Class<?> clazz, boolean validating) {
        return getInjectableFields(clazz, new HashSet<Field>(), validating);
    }

    /**
     * Recursively evaluates the type hierarchy to return all fields
     */
    private static Set<Field> getInjectableFields(Class<?> clazz, Set<Field> fields, boolean validating) {
        if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
            return fields;
        }

        fields = getInjectableFields(clazz.getSuperclass(), fields, validating);

        Field[] declaredFields = null;

        try {
        	declaredFields = clazz.getDeclaredFields();
        } catch(Throwable t) {
        	//TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
        	logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
        }

        if( declaredFields != null ) {
            for (final Field field : declaredFields) {
                int modifiers = field.getModifiers();
                // The field should be non-final and non-static
                if (!Modifier.isStatic(modifiers)
                    // && !Modifier.isFinal(modifiers)
                    ) {

                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            field.setAccessible(true); // ignore Java accessibility
                            return null;
                        }
                    });
                    fields.add(field);
                } else {
                    if (validating) {
                        checkInvalidAnnotations(field);
                    }
                }
            }
        }


        return fields;
    }

    /**
     * Returns a collection of public and protected methods declared by a class
     * or one of its supertypes. Note that overridden methods will not be
     * returned in the collection (i.e. only the method override will be). <p/>
     * This method can potentially be expensive as reflection information is not
     * cached. It is assumed that this method will be used during a
     * configuration phase.
     */
    public static Set<Method> getAllUniquePublicProtectedMethods(Class<?> clazz, boolean validating) {
        return getAllUniqueMethods(clazz, new HashSet<Method>(), validating);
    }

    /**
     * Recursively evaluates the type hierarchy to return all unique methods
     */
    private static Set<Method> getAllUniqueMethods(Class<?> pClass, Set<Method> methods, boolean validating) {
        if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) {
            return methods;
        }
        // we first evaluate methods of the subclass and then move to the parent
        Method[] declaredMethods = pClass.getDeclaredMethods();
        for (final Method declaredMethod : declaredMethods) {
            int modifiers = declaredMethod.getModifiers();
            if ((!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) || Modifier.isStatic(modifiers)) {
                if (validating) {
                    checkInvalidAnnotations(declaredMethod);
                }
                continue;
            }
            if (methods.size() == 0) {
                methods.add(declaredMethod);
            } else {
                List<Method> temp = new ArrayList<Method>();
                boolean matched = false;
                for (Method method : methods) {
                    // only add if not already in the set from a superclass (i.e.
                    // the method is not overridden)
                    if (exactMethodMatch(declaredMethod, method)) {
                        matched = true;
                        break;
                    }
                }
                if (!matched) {
                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            declaredMethod.setAccessible(true);
                            return null;
                        }
                    });
                    temp.add(declaredMethod);
                }
                methods.addAll(temp);
                temp.clear();
            }
        }
        // evaluate class hierarchy - this is done last to track inherited
        // methods
        methods = getAllUniqueMethods(pClass.getSuperclass(), methods, validating);
        return methods;
    }

    /**
     * Finds the closest matching field with the given name, that is, a field of
     * the exact specified type or, alternately, of a supertype.
     *
     * @param name the name of the field
     * @param type the field type
     * @param fields the collection of fields to search
     * @return the matching field or null if not found
     */
    public static Field findClosestMatchingField(String name, Class type, Set<Field> fields) {
        Field candidate = null;
        for (Field field : fields) {
            if (field.getName().equals(name)) {
                if (field.getType().equals(type)) {
                    return field; // exact match
                } else if (field.getType().isAssignableFrom(type) || (field.getType().isPrimitive() && primitiveAssignable(field
                                                                                                                               .getType(),
                                                                                                                           type))) {
                    // We could have the situation where a field parameter is a
                    // primitive and the demarshalled value is
                    // an object counterpart (e.g. Integer and int)
                    // @spec issue
                    // either an interface or super class, so keep a reference
                    // until
                    // we know there are no closer types
                    candidate = field;
                }
            }
        }
        if (candidate != null) {
            return candidate;
        } else {
            return null;
        }
    }

    /**
     * Finds the closest matching method with the given name, that is, a method
     * taking the exact parameter types or, alternately, parameter supertypes.
     *
     * @param name the name of the method
     * @param types the method parameter types
     * @param methods the collection of methods to search
     * @return the matching method or null if not found
     */
    public static Method findClosestMatchingMethod(String name, Class[] types, Set<Method> methods) {
        if (types == null) {
            types = EMPTY_CLASS_ARRY;
        }
        Method candidate = null;
        for (Method method : methods) {
            if (method.getName().equals(name) && method.getParameterTypes().length == types.length) {
                Class<?>[] params = method.getParameterTypes();
                boolean disqualify = false;
                boolean exactMatch = true;
                for (int i = 0; i < params.length; i++) {
                    if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) {
                        // no match
                        disqualify = true;
                        exactMatch = false;
                        break;
                    } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) {
                        // not exact match
                        exactMatch = false;
                    }
                }
                if (disqualify) {
                    continue;
                } else if (exactMatch) {
                    return method;
                } else {
                    candidate = method;
                }
            }
        }
        if (candidate != null) {
            return candidate;
        } else {
            return null;
        }
    }

    /**
     * Determines if two methods "match" - that is, they have the same method
     * names and exact parameter types (one is not a supertype of the other)
     */
    public static boolean exactMethodMatch(Method method1, Method method2) {
        if (!method1.getName().equals(method2.getName())) {
            return false;
        }
        Class<?>[] types1 = method1.getParameterTypes();
        Class<?>[] types2 = method2.getParameterTypes();
        if (types1.length != types2.length) {
            return false;
        }
        boolean matched = true;
        for (int i = 0; i < types1.length; i++) {
            if (types1[i] != types2[i]) {
                matched = false;
                break;
            }
        }
        return matched;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaIntrospectionHelper.java [52:344]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public final class JavaIntrospectionHelper {
    private static final Logger logger = Logger.getLogger(JavaIntrospectionHelper.class.getName());
    private static final Class<?>[] EMPTY_CLASS_ARRY = new Class[0];

    /**
     * Hide the constructor
     */
    private JavaIntrospectionHelper() {
    }

    /**
     * Returns a collection of public, and protected fields declared by a class
     * or one of its supertypes
     */
    public static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, boolean validating) {
        return getAllPublicAndProtectedFields(clazz, new HashSet<Field>(), validating);
    }

    private static void checkInvalidAnnotations(AnnotatedElement element) {
        for (Annotation a : element.getAnnotations()) {
            if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.")) {
                logger.warning("Invalid annotation " + a + " is found on " + element);
            }
        }
    }

    /**
     * Recursively evaluates the type hierarchy to return all fields that are
     * public or protected
     */
    private static Set<Field> getAllPublicAndProtectedFields(Class<?> clazz, Set<Field> fields, boolean validating) {
        if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
            return fields;
        }
        fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields, validating);

        Field[] declaredFields = null;

        try {
        	declaredFields = clazz.getDeclaredFields();
        } catch(Throwable t) {
        	//TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
        	logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
        }

        if( declaredFields != null ) {
            for (final Field field : declaredFields) {
                int modifiers = field.getModifiers();
                // The field should be non-final and non-static
                if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            field.setAccessible(true); // ignore Java accessibility
                            return null;
                        }
                    });
                    fields.add(field);
                } /*else {
                    if (validating) {
                        checkInvalidAnnotations(field);
                    }
                }*/
            }
        }
        return fields;
    }

    /**
     * Returns a collection of injectable fields declared by a class
     * or one of its supertypes
     *
     * For now we will include final or static fields so that validation problems can be reported
     */
    public static Set<Field> getInjectableFields(Class<?> clazz, boolean validating) {
        return getInjectableFields(clazz, new HashSet<Field>(), validating);
    }

    /**
     * Recursively evaluates the type hierarchy to return all fields
     */
    private static Set<Field> getInjectableFields(Class<?> clazz, Set<Field> fields, boolean validating) {
        if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
            return fields;
        }

        fields = getInjectableFields(clazz.getSuperclass(), fields, validating);

        Field[] declaredFields = null;

        try {
        	declaredFields = clazz.getDeclaredFields();
        } catch(Throwable t) {
        	//TUSCANY-3667 - clazz.getDeclaredFields might fail in GAE environment (log and ignore)
        	logger.log(Level.WARNING, "Error retrieving declared fields from class : " + t.getMessage());
        }

        if( declaredFields != null ) {
            for (final Field field : declaredFields) {
                int modifiers = field.getModifiers();
                // The field should be non-final and non-static
                if (!Modifier.isStatic(modifiers)
                    // && !Modifier.isFinal(modifiers)
                    ) {

                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            field.setAccessible(true); // ignore Java accessibility
                            return null;
                        }
                    });
                    fields.add(field);
                } else {
                    if (validating) {
                        checkInvalidAnnotations(field);
                    }
                }
            }
        }


        return fields;
    }

    /**
     * Returns a collection of public and protected methods declared by a class
     * or one of its supertypes. Note that overridden methods will not be
     * returned in the collection (i.e. only the method override will be). <p/>
     * This method can potentially be expensive as reflection information is not
     * cached. It is assumed that this method will be used during a
     * configuration phase.
     */
    public static Set<Method> getAllUniquePublicProtectedMethods(Class<?> clazz, boolean validating) {
        return getAllUniqueMethods(clazz, new HashSet<Method>(), validating);
    }

    /**
     * Recursively evaluates the type hierarchy to return all unique methods
     */
    private static Set<Method> getAllUniqueMethods(Class<?> pClass, Set<Method> methods, boolean validating) {
        if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) {
            return methods;
        }
        // we first evaluate methods of the subclass and then move to the parent
        Method[] declaredMethods = pClass.getDeclaredMethods();
        for (final Method declaredMethod : declaredMethods) {
            int modifiers = declaredMethod.getModifiers();
            if ((!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) || Modifier.isStatic(modifiers)) {
                if (validating) {
                    checkInvalidAnnotations(declaredMethod);
                }
                continue;
            }
            if (methods.size() == 0) {
                methods.add(declaredMethod);
            } else {
                List<Method> temp = new ArrayList<Method>();
                boolean matched = false;
                for (Method method : methods) {
                    // only add if not already in the set from a superclass (i.e.
                    // the method is not overridden)
                    if (exactMethodMatch(declaredMethod, method)) {
                        matched = true;
                        break;
                    }
                }
                if (!matched) {
                    // Allow privileged access to set accessibility. Requires ReflectPermission
                    // in security policy.
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        public Object run() {
                            declaredMethod.setAccessible(true);
                            return null;
                        }
                    });
                    temp.add(declaredMethod);
                }
                methods.addAll(temp);
                temp.clear();
            }
        }
        // evaluate class hierarchy - this is done last to track inherited
        // methods
        methods = getAllUniqueMethods(pClass.getSuperclass(), methods, validating);
        return methods;
    }

    /**
     * Finds the closest matching field with the given name, that is, a field of
     * the exact specified type or, alternately, of a supertype.
     *
     * @param name the name of the field
     * @param type the field type
     * @param fields the collection of fields to search
     * @return the matching field or null if not found
     */
    public static Field findClosestMatchingField(String name, Class type, Set<Field> fields) {
        Field candidate = null;
        for (Field field : fields) {
            if (field.getName().equals(name)) {
                if (field.getType().equals(type)) {
                    return field; // exact match
                } else if (field.getType().isAssignableFrom(type) || (field.getType().isPrimitive() && primitiveAssignable(field
                                                                                                                               .getType(),
                                                                                                                           type))) {
                    // We could have the situation where a field parameter is a
                    // primitive and the demarshalled value is
                    // an object counterpart (e.g. Integer and int)
                    // @spec issue
                    // either an interface or super class, so keep a reference
                    // until
                    // we know there are no closer types
                    candidate = field;
                }
            }
        }
        if (candidate != null) {
            return candidate;
        } else {
            return null;
        }
    }

    /**
     * Finds the closest matching method with the given name, that is, a method
     * taking the exact parameter types or, alternately, parameter supertypes.
     *
     * @param name the name of the method
     * @param types the method parameter types
     * @param methods the collection of methods to search
     * @return the matching method or null if not found
     */
    public static Method findClosestMatchingMethod(String name, Class[] types, Set<Method> methods) {
        if (types == null) {
            types = EMPTY_CLASS_ARRY;
        }
        Method candidate = null;
        for (Method method : methods) {
            if (method.getName().equals(name) && method.getParameterTypes().length == types.length) {
                Class<?>[] params = method.getParameterTypes();
                boolean disqualify = false;
                boolean exactMatch = true;
                for (int i = 0; i < params.length; i++) {
                    if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) {
                        // no match
                        disqualify = true;
                        exactMatch = false;
                        break;
                    } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) {
                        // not exact match
                        exactMatch = false;
                    }
                }
                if (disqualify) {
                    continue;
                } else if (exactMatch) {
                    return method;
                } else {
                    candidate = method;
                }
            }
        }
        if (candidate != null) {
            return candidate;
        } else {
            return null;
        }
    }

    /**
     * Determines if two methods "match" - that is, they have the same method
     * names and exact parameter types (one is not a supertype of the other)
     */
    public static boolean exactMethodMatch(Method method1, Method method2) {
        if (!method1.getName().equals(method2.getName())) {
            return false;
        }
        Class<?>[] types1 = method1.getParameterTypes();
        Class<?>[] types2 = method2.getParameterTypes();
        if (types1.length != types2.length) {
            return false;
        }
        boolean matched = true;
        for (int i = 0; i < types1.length; i++) {
            if (types1[i] != types2[i]) {
                matched = false;
                break;
            }
        }
        return matched;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



