private PatternConverter createConverter()

in log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java [586:674]


    private PatternConverter createConverter(
            final String converterId,
            final StringBuilder currentLiteral,
            final Map<String, Class<PatternConverter>> rules,
            final List<String> options,
            final boolean disableAnsi,
            final boolean noConsoleNoAnsi) {
        String converterName = converterId;
        Class<PatternConverter> converterClass = null;

        if (rules == null) {
            LOGGER.error("Null rules for [" + converterId + ']');
            return null;
        }
        for (int i = converterId.length(); i > 0 && converterClass == null; i--) {
            converterName = converterName.substring(0, i);
            converterClass = rules.get(converterName);
        }

        if (converterClass == null) {
            LOGGER.error("Unrecognized format specifier [" + converterId + ']');
            return null;
        }

        if (AnsiConverter.class.isAssignableFrom(converterClass)) {
            options.add(DISABLE_ANSI + '=' + disableAnsi);
            options.add(NO_CONSOLE_NO_ANSI + '=' + noConsoleNoAnsi);
        }
        // Work around the regression bug in Class.getDeclaredMethods() in Oracle Java in version > 1.6.0_17:
        // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6815786
        final Method[] methods = converterClass.getDeclaredMethods();
        Method newInstanceMethod = null;
        for (final Method method : methods) {
            if (Modifier.isStatic(method.getModifiers())
                    && method.getDeclaringClass().equals(converterClass)
                    && method.getName().equals("newInstance")
                    && areValidNewInstanceParameters(method.getParameterTypes())) {
                if (newInstanceMethod == null) {
                    newInstanceMethod = method;
                } else if (method.getReturnType().equals(newInstanceMethod.getReturnType())) {
                    LOGGER.error("Class " + converterClass + " cannot contain multiple static newInstance methods");
                    return null;
                }
            }
        }
        if (newInstanceMethod == null) {
            LOGGER.error("Class " + converterClass + " does not contain a static newInstance method");
            return null;
        }

        final Class<?>[] parmTypes = newInstanceMethod.getParameterTypes();
        final Object[] parms = parmTypes.length > 0 ? new Object[parmTypes.length] : null;

        if (parms != null) {
            int i = 0;
            boolean errors = false;
            for (final Class<?> clazz : parmTypes) {
                if (clazz.isArray() && clazz.getName().equals("[Ljava.lang.String;")) {
                    final String[] optionsArray = options.toArray(Strings.EMPTY_ARRAY);
                    parms[i] = optionsArray;
                } else if (clazz.isAssignableFrom(Configuration.class)) {
                    parms[i] = config;
                } else {
                    LOGGER.error("Unknown parameter type " + clazz.getName() + " for static newInstance method of "
                            + converterClass.getName());
                    errors = true;
                }
                ++i;
            }
            if (errors) {
                return null;
            }
        }

        try {
            final Object newObj = newInstanceMethod.invoke(null, parms);

            if (newObj instanceof PatternConverter) {
                currentLiteral.delete(0, currentLiteral.length() - (converterId.length() - converterName.length()));

                return (PatternConverter) newObj;
            }
            LOGGER.warn("Class {} does not extend PatternConverter.", converterClass.getName());
        } catch (final Exception ex) {
            LOGGER.error("Error creating converter for " + converterId, ex);
        }

        return null;
    }