public static Method findInstanceFactory()

in xbean-reflect/src/main/java/org/apache/xbean/recipe/ReflectionUtil.java [829:904]


    public static Method findInstanceFactory(Class typeClass, String factoryMethod, Set<Option> options) {
        if (typeClass == null) throw new NullPointerException("typeClass is null");
        if (factoryMethod == null) throw new NullPointerException("name is null");
        if (factoryMethod.length() == 0) throw new IllegalArgumentException("name is an empty string");
        if (options == null) options = EnumSet.noneOf(Option.class);
        
        int matchLevel = 0;
        MissingFactoryMethodException missException = null;

        boolean allowPrivate = options.contains(Option.PRIVATE_FACTORY);
        boolean caseInsesnitive = options.contains(Option.CASE_INSENSITIVE_FACTORY);

        List<Method> methods = new ArrayList<Method>(Arrays.asList(typeClass.getMethods()));
        methods.addAll(Arrays.asList(typeClass.getDeclaredMethods()));
        for (Method method : methods) {
            if (method.getName().equals(factoryMethod) || (caseInsesnitive && method.getName().equalsIgnoreCase(method.getName()))) {
                if (Modifier.isStatic(method.getModifiers())) {
                    if (matchLevel < 1) {
                        matchLevel = 1;
                        missException = new MissingFactoryMethodException("Instance factory method is static: " + method);
                    }
                    continue;
                }

                if (method.getParameterTypes().length != 0) {
                    if (matchLevel < 2) {
                        matchLevel = 2;
                        missException = new MissingFactoryMethodException("Instance factory method has signature " +
                                "public " + typeClass.getName() + "." + factoryMethod + toParameterList(method.getParameterTypes()) +
                                " but expected signature " +
                                "public " + typeClass.getName() + "." + factoryMethod + "()");
                    }
                    continue;
                }

                if (method.getReturnType() == Void.TYPE) {
                    if (matchLevel < 3) {
                        matchLevel = 3;
                        missException = new MissingFactoryMethodException("Instance factory method does not return a value: " + method);
                    }
                    continue;
                }

                if (Modifier.isAbstract(method.getModifiers())) {
                    if (matchLevel < 4) {
                        matchLevel = 4;
                        missException = new MissingFactoryMethodException("Instance factory method is abstract: " + method);
                    }
                    continue;
                }

                if (!allowPrivate && !Modifier.isPublic(method.getModifiers())) {
                    if (matchLevel < 5) {
                        matchLevel = 5;
                        missException = new MissingFactoryMethodException("Instance factory method is not public: " + method);
                    }
                    continue;
                }

                if (allowPrivate && !Modifier.isPublic(method.getModifiers())) {
                    setAccessible(method);
                }

                return method;
            }
        }

        if (missException != null) {
            throw missException;
        } else {
            StringBuffer buffer = new StringBuffer("Unable to find a valid factory method: ");
            buffer.append("public void ").append(typeClass.getName()).append(".");
            buffer.append(factoryMethod).append("()");
            throw new MissingFactoryMethodException(buffer.toString());
        }
    }