logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Sicker <mattsic...@apache.org>
Subject Re: svn commit: r1586456 - in /logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config: AbstractConfiguration.java plugins/PluginBuilder.java
Date Thu, 10 Apr 2014 20:13:21 GMT
You may notice that the diff is not very good at showing this, but the
PluginBuilder class I added was essentially created by moving a lot of code
from AbstractConfiguration to its own class. Now that method is a bit
easier to understand, so now I'll be working on supporting more attribute
types and such.


On 10 April 2014 15:06, <mattsicker@apache.org> wrote:

> Author: mattsicker
> Date: Thu Apr 10 20:06:14 2014
> New Revision: 1586456
>
> URL: http://svn.apache.org/r1586456
> Log:
> Create PluginBuilder for Configuration objects.
>
> Added:
>
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java
>   (with props)
> Modified:
>
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
>
> Modified:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> URL:
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java?rev=1586456&r1=1586455&r2=1586456&view=diff
>
> ==============================================================================
> ---
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> (original)
> +++
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> Thu Apr 10 20:06:14 2014
> @@ -20,11 +20,6 @@ import java.io.ByteArrayOutputStream;
>  import java.io.IOException;
>  import java.io.InputStream;
>  import java.io.Serializable;
> -import java.lang.annotation.Annotation;
> -import java.lang.reflect.Array;
> -import java.lang.reflect.Method;
> -import java.lang.reflect.Modifier;
> -import java.util.ArrayList;
>  import java.util.Collection;
>  import java.util.Collections;
>  import java.util.HashSet;
> @@ -34,7 +29,6 @@ import java.util.Set;
>  import java.util.concurrent.ConcurrentHashMap;
>  import java.util.concurrent.ConcurrentMap;
>  import java.util.concurrent.CopyOnWriteArrayList;
> -
>  import org.apache.logging.log4j.Level;
>  import org.apache.logging.log4j.LogManager;
>  import org.apache.logging.log4j.Logger;
> @@ -46,15 +40,10 @@ import org.apache.logging.log4j.core.app
>  import org.apache.logging.log4j.core.appender.ConsoleAppender;
>  import org.apache.logging.log4j.core.async.AsyncLoggerConfig;
>  import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
> -import org.apache.logging.log4j.core.config.plugins.PluginAliases;
> -import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
> -import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
> -import org.apache.logging.log4j.core.config.plugins.PluginElement;
> +import org.apache.logging.log4j.core.config.plugins.PluginBuilder;
>  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
>  import org.apache.logging.log4j.core.config.plugins.PluginManager;
> -import org.apache.logging.log4j.core.config.plugins.PluginNode;
>  import org.apache.logging.log4j.core.config.plugins.PluginType;
> -import org.apache.logging.log4j.core.config.plugins.PluginValue;
>  import org.apache.logging.log4j.core.filter.AbstractFilterable;
>  import org.apache.logging.log4j.core.helpers.Constants;
>  import org.apache.logging.log4j.core.helpers.NameUtil;
> @@ -666,10 +655,11 @@ public abstract class AbstractConfigurat
>          }
>      }
>
> -   /*
> -    * Retrieve a static public 'method to create the desired object.
> Every parameter
> -    * will be annotated to identify the appropriate attribute or element
> to use to
> +   /**
> +    * Invokes a static factory method to create the desired object. Every
> parameter
> +    * must be annotated to identify the appropriate attribute or element
> to use to
>      * set the value of the parameter.
> +    *
>      * Parameters annotated with PluginAttribute will always be set as
> Strings.
>      * Parameters annotated with PluginElement may be Objects or arrays.
> Collections
>      * and Maps are currently not supported, although the factory method
> that is called
> @@ -677,9 +667,11 @@ public abstract class AbstractConfigurat
>      *
>      * Although the happy path works, more work still needs to be done to
> log incorrect
>      * parameters. These will generally result in unhelpful
> InvocationTargetExceptions.
> -    * @param classClass the class.
> -    * @return the instantiate method or null if there is none by that
> -    * description.
> +    *
> +    * @param type the type of plugin to create.
> +    * @param node the corresponding configuration node for this plugin to
> create.
> +    * @param event the LogEvent that spurred the creation of this plugin
> +    * @return the created plugin object or {@code null} if there was an
> error setting it up.
>      */
>      private <T> Object createPluginObject(final PluginType<T> type, final
> Node node, final LogEvent event)
>      {
> @@ -702,216 +694,17 @@ public abstract class AbstractConfigurat
>              }
>          }
>
> -        Method factoryMethod = findFactoryMethod(clazz);
> -        if (factoryMethod == null) return null;
> -
> -        final Annotation[][] parmArray =
> factoryMethod.getParameterAnnotations();
> -        final Class<?>[] parmClasses = factoryMethod.getParameterTypes();
> -        if (parmArray.length != parmClasses.length) {
> -            LOGGER.error("Number of parameter annotations ({}) does not
> equal the number of parameters ({})",
> -                    parmArray.length, parmClasses.length
> -            );
> -        }
> -        final Object[] parms = new Object[parmClasses.length];
> -
> -        int index = 0;
> -        final Map<String, String> attrs = node.getAttributes();
> -        final List<Node> children = node.getChildren();
> -        final StringBuilder sb = new StringBuilder();
> -        final List<Node> used = new ArrayList<Node>();
> -
> -        /*
> -         * For each parameter:
> -         * If the parameter is an attribute store the value of the
> attribute in the parameter array.
> -         * If the parameter is an element:
> -         *   Determine if the required parameter is an array.
> -         *     If so, if a child contains the array, use it,
> -         *      otherwise create the array from all child nodes of the
> correct type.
> -         *     Store the array into the parameter array.
> -         *   If not an array, store the object in the child node into the
> parameter array.
> -         */
> -        for (final Annotation[] parmTypes : parmArray) {
> -            String[] aliases = extractPluginAliases(parmTypes);
> -            for (final Annotation a : parmTypes) {
> -                if (a instanceof PluginAliases) {
> -                    continue;
> -                }
> -                if (sb.length() == 0) {
> -                    sb.append(" with params(");
> -                } else {
> -                    sb.append(", ");
> -                }
> -                if (a instanceof PluginNode) {
> -                    parms[index] = node;
> -                    sb.append("Node=").append(node.getName());
> -                } else if (a instanceof PluginConfiguration) {
> -                    parms[index] = this;
> -                    if (this.name != null) {
> -
>  sb.append("Configuration(").append(name).append(')');
> -                    } else {
> -                        sb.append("Configuration");
> -                    }
> -                } else if (a instanceof PluginValue) {
> -                    final String name = ((PluginValue) a).value();
> -                    String v = node.getValue();
> -                    if (v == null) {
> -                        v = getAttrValue("value", null, attrs);
> -                    }
> -                    final String value = subst.replace(event, v);
> -
>  sb.append(name).append("=\"").append(value).append('"');
> -                    parms[index] = value;
> -                } else if (a instanceof PluginAttribute) {
> -                    PluginAttribute attr = (PluginAttribute) a;
> -                    final String name = attr.value();
> -                    final String value = subst.replace(event,
> getAttrValue(name, aliases, attrs));
> -
>  sb.append(name).append("=\"").append(value).append('"');
> -                    parms[index] = value;
> -                } else if (a instanceof PluginElement) {
> -                    final PluginElement elem = (PluginElement) a;
> -                    final String name = elem.value();
> -                    if (parmClasses[index].isArray()) {
> -                        final Class<?> parmClass =
> parmClasses[index].getComponentType();
> -                        final List<Object> list = new ArrayList<Object>();
> -                        sb.append(name).append("={");
> -                        boolean first = true;
> -                        for (final Node child : children) {
> -                            final PluginType<?> childType =
> child.getType();
> -                            if
> (name.equalsIgnoreCase(childType.getElementName()) ||
> -
>  parmClass.isAssignableFrom(childType.getPluginClass())) {
> -                                used.add(child);
> -                                if (!first) {
> -                                    sb.append(", ");
> -                                }
> -                                first = false;
> -                                final Object obj = child.getObject();
> -                                if (obj == null) {
> -                                    LOGGER.error("Null object returned
> for {} in {}", child.getName(), node.getName());
> -                                    continue;
> -                                }
> -                                if (obj.getClass().isArray()) {
> -                                    printArray(sb, (Object[]) obj);
> -                                    parms[index] = obj;
> -                                    break;
> -                                }
> -                                sb.append(child.toString());
> -                                list.add(obj);
> -                            }
> -                        }
> -                        sb.append('}');
> -                        if (parms[index] != null) {
> -                            break;
> -                        }
> -                        if (!(list.isEmpty() ||
> parmClass.isAssignableFrom(list.get(0).getClass()))) {
> -                            LOGGER.error(
> -                                    "Attempted to assign List containing
> class {} to array of type {} for attribute {}",
> -                                    list.get(0).getClass().getName(),
> parmClass, name
> -                            );
> -                            break;
> -                        }
> -                        parms[index] = collectionToArray(list, parmClass);
> -                    } else {
> -                        final Node child = findNamedNode(name,
> parmClasses[index], children);
> -                        if (child == null) {
> -                            sb.append("null");
> -                        } else {
> -
>  sb.append(child.getName()).append('(').append(child.toString()).append(')');
> -                            used.add(child);
> -                            parms[index] = child.getObject();
> -                        }
> -                    }
> -                }
> -            }
> -            ++index;
> -        }
> -        if (sb.length() > 0) {
> -            sb.append(')');
> -        }
> -
> -        checkForRemainingAttributes(node);
> -
> -        if (!type.isDeferChildren() && used.size() != children.size()) {
> -            children.removeAll(used);
> -            for (final Node child : children) {
> -                final String nodeType = node.getType().getElementName();
> -                final String start = nodeType.equals(node.getName()) ?
> node.getName() : nodeType + ' ' + node.getName();
> -                LOGGER.error("{} has no parameter that matches element
> {}", start, child.getName());
> -            }
> -        }
> -
>          try {
> -            final int mod = factoryMethod.getModifiers();
> -            if (!Modifier.isStatic(mod)) {
> -                LOGGER.error("{} method is not static on class {} for
> element {}",
> -                        factoryMethod.getName(), clazz.getName(),
> node.getName());
> -                return null;
> -            }
> -            LOGGER.debug("Calling {} on class {} for element {}{}",
> factoryMethod.getName(), clazz.getName(),
> -                    node.getName(), sb.toString());
> -            //if (parms.length > 0) {
> -            return factoryMethod.invoke(null, parms);
> -            //}
> -            //return factoryMethod.invoke(null, node);
> -        } catch (final Exception e) {
> -            LOGGER.error("Unable to invoke method {} in class {} for
> element {}",
> -                    factoryMethod.getName(), clazz.getName(),
> node.getName(), e);
> -        }
> -        return null;
> -    }
> -
> -    private static Object[] collectionToArray(final Collection<?>
> collection, final Class<?> type) {
> -        final Object[] array = (Object[]) Array.newInstance(type,
> collection.size());
> -        int i = 0;
> -        for (final Object obj : collection) {
> -            array[i] = obj;
> -            ++i;
> -        }
> -        return array;
> -    }
> -
> -    private static Node findNamedNode(final String name, final Class<?>
> type, final Iterable<Node> nodes) {
> -        for (final Node child : nodes) {
> -            final PluginType<?> childType = child.getType();
> -            if (name.equalsIgnoreCase(childType.getElementName()) ||
> -                    type.isAssignableFrom(childType.getPluginClass())) {
> -                return child;
> -            }
> -        }
> -        return null;
> -    }
> -
> -    private static void checkForRemainingAttributes(final Node node) {
> -        final Map<String, String> attrs = node.getAttributes();
> -        if (!attrs.isEmpty()) {
> -            final StringBuilder eb = new StringBuilder();
> -            for (final String key : attrs.keySet()) {
> -                if (eb.length() == 0) {
> -                    eb.append(node.getName());
> -                    eb.append(" contains ");
> -                    if (attrs.size() == 1) {
> -                        eb.append("an invalid element or attribute ");
> -                    } else {
> -                        eb.append("invalid attributes ");
> -                    }
> -                } else {
> -                    eb.append(", ");
> -                }
> -                eb.append('"');
> -                eb.append(key);
> -                eb.append('"');
> -
> -            }
> -            LOGGER.error(eb.toString());
> -        }
> -    }
> -
> -    private static String[] extractPluginAliases(final Annotation...
> parmTypes) {
> -        String[] aliases = null;
> -        for (final Annotation a : parmTypes) {
> -            if (a instanceof PluginAliases) {
> -                aliases = ((PluginAliases) a).value();
> -            }
> +            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;
>          }
> -        return aliases;
>      }
>
>      private static <T> Object createPluginMap(final Node node, final
> Class<T> clazz) throws InstantiationException, IllegalAccessException {
> @@ -932,48 +725,6 @@ public abstract class AbstractConfigurat
>          return list;
>      }
>
> -    private static <T> Method findFactoryMethod(final Class<T> clazz) {
> -        for (final Method method : clazz.getMethods()) {
> -            if (method.isAnnotationPresent(PluginFactory.class)) {
> -                return method;
> -            }
> -        }
> -        // TODO: this should probably throw an exception instead of
> returning null
> -        return null;
> -    }
> -
> -    private void printArray(final StringBuilder sb, final Object...
> array) {
> -        boolean first = true;
> -        for (final Object obj : array) {
> -            if (!first) {
> -                sb.append(", ");
> -            }
> -            sb.append(obj.toString());
> -            first = false;
> -        }
> -    }
> -
> -    private String getAttrValue(final String name, final String[]
> aliases, final Map<String, String> attrs) {
> -        for (final Map.Entry<String, String> entry : attrs.entrySet()) {
> -            final String key = entry.getKey();
> -            if (key.equalsIgnoreCase(name)) {
> -                final String attr = entry.getValue();
> -                attrs.remove(key);
> -                return attr;
> -            }
> -            if (aliases != null) {
> -                for (String alias : aliases) {
> -                    if (key.equalsIgnoreCase(alias)) {
> -                        final String attr = entry.getValue();
> -                        attrs.remove(key);
> -                        return attr;
> -                    }
> -                }
> -            }
> -        }
> -        return null;
> -    }
> -
>      private void setParents() {
>           for (final Map.Entry<String, LoggerConfig> entry :
> loggers.entrySet()) {
>              final LoggerConfig logger = entry.getValue();
>
> Added:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java
> URL:
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java?rev=1586456&view=auto
>
> ==============================================================================
> ---
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java
> (added)
> +++
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java
> Thu Apr 10 20:06:14 2014
> @@ -0,0 +1,337 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +package org.apache.logging.log4j.core.config.plugins;
> +
> +import java.lang.annotation.Annotation;
> +import java.lang.reflect.Array;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Modifier;
> +import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.Collection;
> +import java.util.HashSet;
> +import java.util.List;
> +import java.util.Map;
> +import org.apache.logging.log4j.Logger;
> +import org.apache.logging.log4j.core.LogEvent;
> +import org.apache.logging.log4j.core.config.Configuration;
> +import org.apache.logging.log4j.core.config.Node;
> +import org.apache.logging.log4j.status.StatusLogger;
> +
> +/**
> + * Builder class to instantiate and configure a Plugin object using a
> PluginFactory method.
> + *
> + * @param <T> type of Plugin class.
> + */
> +public class PluginBuilder<T> {
> +
> +    private static final Logger LOGGER = StatusLogger.getLogger();
> +
> +    private final PluginType<T> pluginType;
> +    private final Class<T> clazz;
> +
> +    private Configuration configuration;
> +    private Node node;
> +    private LogEvent event;
> +
> +    private Method factory;
> +    private Annotation[][] annotations;
> +    private Class<?>[] types;
> +    private List<Node> children;
> +    private Collection<Node> used;
> +
> +    /**
> +     * Constructs a PluginBuilder for a given PluginType.
> +     *
> +     * @param pluginType type of plugin to configure
> +     */
> +    public PluginBuilder(final PluginType<T> pluginType) {
> +        this.pluginType = pluginType;
> +        this.clazz = pluginType.getPluginClass();
> +    }
> +
> +    /**
> +     * Specifies which annotation denotes a plugin factory method. The
> method must be static.
> +     *
> +     * @param annotationType class of annotation marking the plugin
> factory.
> +     * @param <A>            type of annotation.
> +     * @return {@code this}
> +     * @throws NoSuchMethodException
> +     */
> +    public <A extends Annotation> PluginBuilder<T>
> withFactoryMethodAnnotatedBy(final Class<A> annotationType)
> +            throws NoSuchMethodException {
> +        for (final Method method : clazz.getMethods()) {
> +            if (method.isAnnotationPresent(annotationType) &&
> Modifier.isStatic(method.getModifiers())) {
> +                factory = method;
> +                LOGGER.trace("Using factory method {} on class {}",
> method.getName(), clazz.getName());
> +                return this;
> +            }
> +        }
> +        throw new NoSuchMethodException("No method annotated with " +
> annotationType.getName() + "was found in " + clazz.getName());
> +    }
> +
> +    /**
> +     * Specifies the Configuration to use for constructing the plugin
> instance.
> +     *
> +     * @param configuration the configuration to use.
> +     * @return {@code this}
> +     */
> +    public PluginBuilder<T> withConfiguration(final Configuration
> configuration) {
> +        this.configuration = configuration;
> +        return this;
> +    }
> +
> +    /**
> +     * Specifies the Node corresponding to the plugin object that will be
> created.
> +     *
> +     * @param node the plugin configuration node to use.
> +     * @return {@code this}
> +     */
> +    public PluginBuilder<T> withConfigurationNode(final Node node) {
> +        this.node = node;
> +        this.children = this.node.getChildren();
> +        this.used = new HashSet<Node>(this.children.size());
> +        return this;
> +    }
> +
> +    /**
> +     * Specifies the LogEvent that may be used to provide extra context
> for string substitutions.
> +     *
> +     * @param event the event to use for extra information.
> +     * @return {@code this}
> +     */
> +    public PluginBuilder<T> forLogEvent(final LogEvent event) {
> +        this.event = event;
> +        return this;
> +    }
> +
> +    /**
> +     * Builds the plugin object.
> +     *
> +     * @return the plugin object or {@code null} if there was a problem
> creating it.
> +     */
> +    public Object build() {
> +        init();
> +        try {
> +            return factory.invoke(null, generateParameters());
> +        } catch (final Exception e) {
> +            LOGGER.error("Unable to invoke method {} in class {} for
> element {}",
> +                    factory.getName(), clazz.getName(), node.getName(),
> e);
> +            return null;
> +        }
> +    }
> +
> +    private void init() {
> +        if (factory == null) {
> +            throw new IllegalStateException("No factory method was
> found.");
> +        }
> +        if (configuration == null) {
> +            throw new IllegalStateException("No Configuration object was
> set.");
> +        }
> +        if (node == null) {
> +            throw new IllegalStateException("No Node object was set.");
> +        }
> +        annotations = factory.getParameterAnnotations();
> +        types = factory.getParameterTypes();
> +    }
> +
> +    private Object[] generateParameters() {
> +        final StringBuilder sb = new StringBuilder();
> +        final Object[] args = new Object[annotations.length];
> +        for (int i = 0; i < annotations.length; i++) {
> +            final String[] aliases = extractPluginAliases(annotations[i]);
> +            for (Annotation a : annotations[i]) {
> +                if (a instanceof PluginAliases) {
> +                    continue; // already processed
> +                }
> +                sb.append(sb.length() == 0 ? "with params(" : ", ");
> +                if (a instanceof PluginNode) {
> +                    args[i] = node;
> +                    sb.append("Node=").append(node.getName());
> +                } else if (a instanceof PluginConfiguration) {
> +                    args[i] = configuration;
> +                    sb.append("Configuration");
> +                    if (configuration.getName() != null) {
> +
>  sb.append('(').append(configuration.getName()).append(')');
> +                    }
> +                } else if (a instanceof PluginValue) {
> +                    final String name = ((PluginValue) a).value();
> +                    final String v = node.getValue() != null ?
> node.getValue() : getAttrValue("value");
> +                    final String value =
> configuration.getStrSubstitutor().replace(event, v);
> +                    args[i] = value;
> +
>  sb.append(name).append("=\"").append(value).append('"');
> +                } else if (a instanceof PluginAttribute) {
> +                    final PluginAttribute attribute = (PluginAttribute) a;
> +                    final String name = attribute.value();
> +                    final String value =
> configuration.getStrSubstitutor().replace(event, getAttrValue(name,
> aliases));
> +                    args[i] = value;
> +
>  sb.append(name).append("=\"").append(value).append('"');
> +                } else if (a instanceof PluginElement) {
> +                    final PluginElement element = (PluginElement) a;
> +                    final String name = element.value();
> +                    if (types[i].isArray()) {
> +                        final Class<?> type = types[i].getComponentType();
> +                        sb.append(name).append("={");
> +                        final List<Object> values = new
> ArrayList<Object>();
> +                        boolean first = true;
> +                        for (final Node child : children) {
> +                            final PluginType<?> childType =
> child.getType();
> +                            if
> (name.equalsIgnoreCase(childType.getElementName()) ||
> +
>  type.isAssignableFrom(childType.getPluginClass())) {
> +                                if (!first) {
> +                                    sb.append(", ");
> +                                }
> +                                first = false;
> +                                used.add(child);
> +                                final Object o = child.getObject();
> +                                if (o == null) {
> +                                    LOGGER.error("Null object returned
> for {} in {}", child.getName(), node.getName());
> +                                    continue;
> +                                }
> +                                if (o.getClass().isArray()) {
> +                                    sb.append(Arrays.toString((Object[])
> o));
> +                                    args[i] = o;
> +                                    break;
> +                                }
> +                                sb.append(child.toString());
> +                                values.add(o);
> +                            }
> +                        }
> +                        sb.append('}');
> +                        if (args[i] != null) {
> +                            break;
> +                        }
> +                        if (!(values.isEmpty() ||
> type.isAssignableFrom(values.get(0).getClass()))) {
> +                            LOGGER.error(
> +                                    "Attempted to assign List containing
> class {} to array of type {} for attribute {}",
> +                                    values.get(0).getClass().getName(),
> type, name
> +                            );
> +                            break;
> +                        }
> +                        args[i] = collectionToArray(values, type);
> +                    } else {
> +                        final Node namedNode = findNamedNode(name,
> types[i], children);
> +                        if (namedNode == null) {
> +                            sb.append("null");
> +                        } else {
> +
>  sb.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
> +                            used.add(namedNode);
> +                            args[i] = namedNode.getObject();
> +                        }
> +                    }
> +                }
> +            }
> +        }
> +        if (sb.length() > 0) {
> +            sb.append(')');
> +        }
> +        checkForRemainingAttributes();
> +        verifyNodeChildrenUsed();
> +        LOGGER.debug("Calling {} on class {} for element {} {}",
> factory.getName(), clazz.getName(), node.getName(), sb.toString());
> +        return args;
> +    }
> +
> +    private static String[] extractPluginAliases(final Annotation...
> parmTypes) {
> +        String[] aliases = null;
> +        for (final Annotation a : parmTypes) {
> +            if (a instanceof PluginAliases) {
> +                aliases = ((PluginAliases) a).value();
> +            }
> +        }
> +        return aliases;
> +    }
> +
> +    private String getAttrValue(final String name, final String...
> aliases) {
> +        final Map<String, String> attrs = node.getAttributes();
> +        for (final Map.Entry<String, String> entry : attrs.entrySet()) {
> +            final String key = entry.getKey();
> +            if (key.equalsIgnoreCase(name)) {
> +                final String attr = entry.getValue();
> +                attrs.remove(key);
> +                return attr;
> +            }
> +            if (aliases != null) {
> +                for (String alias : aliases) {
> +                    if (key.equalsIgnoreCase(alias)) {
> +                        final String attr = entry.getValue();
> +                        attrs.remove(key);
> +                        return attr;
> +                    }
> +                }
> +            }
> +        }
> +        return null;
> +    }
> +
> +    private static Object[] collectionToArray(final Collection<?>
> collection, final Class<?> type) {
> +        final Object[] array = (Object[]) Array.newInstance(type,
> collection.size());
> +        int i = 0;
> +        for (final Object obj : collection) {
> +            array[i] = obj;
> +            ++i;
> +        }
> +        return array;
> +    }
> +
> +    private static Node findNamedNode(final String name, final Class<?>
> type, final Iterable<Node> nodes) {
> +        for (final Node child : nodes) {
> +            final PluginType<?> childType = child.getType();
> +            if (name.equalsIgnoreCase(childType.getElementName()) ||
> +                    type.isAssignableFrom(childType.getPluginClass())) {
> +                return child;
> +            }
> +        }
> +        return null;
> +    }
> +
> +    private void checkForRemainingAttributes() {
> +        final Map<String, String> attrs = node.getAttributes();
> +        if (!attrs.isEmpty()) {
> +            final StringBuilder eb = new StringBuilder();
> +            for (final String key : attrs.keySet()) {
> +                if (eb.length() == 0) {
> +                    eb.append(node.getName());
> +                    eb.append(" contains ");
> +                    if (attrs.size() == 1) {
> +                        eb.append("an invalid element or attribute ");
> +                    } else {
> +                        eb.append("invalid attributes ");
> +                    }
> +                } else {
> +                    eb.append(", ");
> +                }
> +                eb.append('"');
> +                eb.append(key);
> +                eb.append('"');
> +
> +            }
> +            LOGGER.error(eb.toString());
> +        }
> +    }
> +
> +    private void verifyNodeChildrenUsed() {
> +        if (!(pluginType.isDeferChildren() || used.size() ==
> children.size())) {
> +            children.removeAll(used);
> +            for (final Node child : children) {
> +                final String nodeType = node.getType().getElementName();
> +                final String start = nodeType.equals(node.getName()) ?
> node.getName() : nodeType + ' ' + node.getName();
> +                LOGGER.error("{} has no parameter that matches element
> {}", start, child.getName());
> +            }
> +        }
> +    }
> +}
>
> Propchange:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilder.java
>
> ------------------------------------------------------------------------------
>     svn:eol-style = native
>
>
>

Mime
View raw message