[ 
https://issues.apache.org/jira/browse/LOG4J2-653?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14009039#comment-14009039
 ] 

Matt Sicker commented on LOG4J2-653:
------------------------------------

I'm not speaking of injection for tests, but we currently use reflection to 
inject configuration values from the config files. The existing logic used to 
build a list of parameters for the factory method can now be reused to do the 
same thing to inject field values on a class instance. I think this will be 
easier to understand once I add what I'm talking about. It's simpler than I'm 
making it out to be.

Ralph, in regards to the AbstractConfiguration bit, let's just say I've been 
unintentionally planning this whole thing out. Here's the current method that's 
used:

{code}
    private <T> Object createPluginObject(final PluginType<T> type, final Node 
node, final LogEvent event)
    {
        // TODO: add support for type conversion
        final Class<T> clazz = type.getPluginClass();

        if (Map.class.isAssignableFrom(clazz)) {
            try {
                return createPluginMap(node, clazz);
            } catch (final Exception ex) {
                LOGGER.warn("Unable to create Map for {} of class {}", 
type.getElementName(), clazz);
            }
        }

        if (Collection.class.isAssignableFrom(clazz)) {
            try {
                return createPluginCollection(node, clazz);
            } catch (final Exception ex) {
                LOGGER.warn("Unable to create List for {} of class {}", 
type.getElementName(), clazz);
            }
        }

        try {
            return new PluginBuilder<T>(type)
                    .withFactoryMethodAnnotatedBy(PluginFactory.class)
                    .withConfiguration(this)
                    .withConfigurationNode(node)
                    .forLogEvent(event)
                    .build();
        } catch (NoSuchMethodException e) {
            LOGGER.error("No suitable factory method could be found on class 
{}", clazz, e);
            return null;
        }
    }

    private static <T> Object createPluginMap(final Node node, final Class<T> 
clazz) throws InstantiationException, IllegalAccessException {
        @SuppressWarnings("unchecked")
        final Map<String, Object> map = (Map<String, Object>) 
clazz.newInstance();
        for (final Node child : node.getChildren()) {
            map.put(child.getName(), child.getObject());
        }
        return map;
    }

    private static <T> Object createPluginCollection(final Node node, final 
Class<T> clazz) throws InstantiationException, IllegalAccessException {
        @SuppressWarnings("unchecked")
        final Collection<Object> list = (Collection<Object>) 
clazz.newInstance();
        for (final Node child : node.getChildren()) {
            list.add(child.getObject());
        }
        return list;
    }
{code}

I'd probably get rid of the withFactoryMethodAnnotatedBy bit to handle the 
separate cases in PluginBuilder instead. I've already refactored the re-usable 
logic into the PluginVisitor classes added yesterday.

> Add plugin builder classes as alternative to factory methods.
> -------------------------------------------------------------
>
>                 Key: LOG4J2-653
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-653
>             Project: Log4j 2
>          Issue Type: Improvement
>          Components: Core
>            Reporter: Matt Sicker
>            Assignee: Matt Sicker
>              Labels: config
>
> It would be useful to have builder-style classes as an alternative to plugin 
> factory methods. This would be useful in two settings:
> # Easier to construct plugins in tests and in the code.
> # Can add annotations to fields for value injection in the PluginBuilder 
> class.
> This could replace the existing factory methods, or it could complement it. 
> This would also make it easier to support programmatic configuration.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to