private boolean convertValuesAndInvoke()

in commons-vfs2/src/main/java/org/apache/commons/vfs2/util/DelegatingFileSystemOptionsBuilder.java [107:195]


    private boolean convertValuesAndInvoke(final Method configSetter, final Context ctx) throws FileSystemException {
        final Class<?>[] parameters = configSetter.getParameterTypes();
        if (parameters.length < 2) {
            return false;
        }
        if (!parameters[0].isAssignableFrom(FileSystemOptions.class)) {
            return false;
        }

        final Class<?> valueParameter = parameters[1];
        Class<?> type;
        if (valueParameter.isArray()) {
            type = valueParameter.getComponentType();
        } else {
            if (ctx.values.length > 1) {
                return false;
            }

            type = valueParameter;
        }

        if (type.isPrimitive()) {
            final Class<?> objectType = PRIMITIVE_TO_OBJECT.get(type.getName());
            if (objectType == null) {
                log.warn(Messages.getString("vfs.provider/config-unexpected-primitive.error", type.getName()));
                return false;
            }
            type = objectType;
        }

        final Class<? extends Object> valueClass = ctx.values[0].getClass();
        if (type.isAssignableFrom(valueClass)) {
            // can set value directly
            invokeSetter(valueParameter, ctx, configSetter, ctx.values);
            return true;
        }
        if (valueClass != String.class) {
            log.warn(Messages.getString("vfs.provider/config-unexpected-value-class.error", valueClass.getName(), ctx.scheme, ctx.name));
            return false;
        }

        final Object convertedValues = Array.newInstance(type, ctx.values.length);

        Constructor<?> valueConstructor;
        try {
            valueConstructor = type.getConstructor(STRING_PARAM);
        } catch (final NoSuchMethodException e) {
            valueConstructor = null;
        }
        if (valueConstructor != null) {
            // can convert using constructor
            for (int iterValues = 0; iterValues < ctx.values.length; iterValues++) {
                try {
                    Array.set(convertedValues, iterValues, valueConstructor.newInstance(ctx.values[iterValues]));
                } catch (final InstantiationException | IllegalAccessException | InvocationTargetException e) {
                    throw new FileSystemException(e);
                }
            }

            invokeSetter(valueParameter, ctx, configSetter, convertedValues);
            return true;
        }

        Method valueFactory;
        try {
            valueFactory = type.getMethod("valueOf", STRING_PARAM);
            if (!Modifier.isStatic(valueFactory.getModifiers())) {
                valueFactory = null;
            }
        } catch (final NoSuchMethodException e) {
            valueFactory = null;
        }

        if (valueFactory != null) {
            // can convert using factory method (valueOf)
            for (int iterValues = 0; iterValues < ctx.values.length; iterValues++) {
                try {
                    Array.set(convertedValues, iterValues, valueFactory.invoke(null, ctx.values[iterValues]));
                } catch (final IllegalAccessException | InvocationTargetException e) {
                    throw new FileSystemException(e);
                }
            }

            invokeSetter(valueParameter, ctx, configSetter, convertedValues);
            return true;
        }

        return false;
    }