001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.log4j.builders;
018
019import org.apache.log4j.Appender;
020import org.apache.log4j.Layout;
021import org.apache.log4j.builders.appender.AppenderBuilder;
022import org.apache.log4j.builders.filter.FilterBuilder;
023import org.apache.log4j.builders.layout.LayoutBuilder;
024import org.apache.log4j.builders.rewrite.RewritePolicyBuilder;
025import org.apache.log4j.config.PropertiesConfiguration;
026import org.apache.log4j.rewrite.RewritePolicy;
027import org.apache.log4j.spi.Filter;
028import org.apache.log4j.xml.XmlConfiguration;
029import org.apache.logging.log4j.Logger;
030import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
031import org.apache.logging.log4j.core.config.plugins.util.PluginType;
032import org.apache.logging.log4j.status.StatusLogger;
033import org.apache.logging.log4j.util.LoaderUtil;
034import org.w3c.dom.Element;
035
036import java.lang.reflect.Constructor;
037import java.lang.reflect.InvocationTargetException;
038import java.util.Map;
039import java.util.Properties;
040
041/**
042 *
043 */
044public class BuilderManager {
045
046    public static final String CATEGORY = "Log4j Builder";
047    private static final Logger LOGGER = StatusLogger.getLogger();
048    private final Map<String, PluginType<?>> plugins;
049    private static Class<?>[] constructorParams = new Class[] { String.class, Properties.class};
050
051    public BuilderManager() {
052        final PluginManager manager = new PluginManager(CATEGORY);
053        manager.collectPlugins();
054        plugins = manager.getPlugins();
055    }
056
057    public Appender parseAppender(String className, Element appenderElement, XmlConfiguration config) {
058        PluginType<?> plugin = plugins.get(className.toLowerCase());
059        if (plugin != null) {
060            try {
061                AppenderBuilder builder = (AppenderBuilder) LoaderUtil.newInstanceOf(plugin.getPluginClass());
062                return builder.parseAppender(appenderElement, config);
063            } catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
064                LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
065            }
066        }
067        return null;
068    }
069
070    public Appender parseAppender(String name, String className, String prefix, String layoutPrefix,
071            String filterPrefix, Properties props, PropertiesConfiguration config) {
072        PluginType<?> plugin = plugins.get(className.toLowerCase());
073        if (plugin != null) {
074            AppenderBuilder builder = createBuilder(plugin, prefix, props);
075            if (builder != null) {
076                return builder.parseAppender(name, prefix, layoutPrefix, filterPrefix, props, config);
077            }
078        }
079        return null;
080    }
081
082    public Filter parseFilter(String className, Element filterElement, XmlConfiguration config) {
083        PluginType<?> plugin = plugins.get(className.toLowerCase());
084        if (plugin != null) {
085            try {
086                FilterBuilder builder = (FilterBuilder) LoaderUtil.newInstanceOf(plugin.getPluginClass());
087                return builder.parseFilter(filterElement, config);
088            } catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
089                LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
090            }
091        }
092        return null;
093    }
094
095    public Filter parseFilter(String className, String filterPrefix, Properties props, PropertiesConfiguration config) {
096        PluginType<?> plugin = plugins.get(className.toLowerCase());
097        if (plugin != null) {
098            FilterBuilder builder = createBuilder(plugin, filterPrefix, props);
099            if (builder != null) {
100                return builder.parseFilter(config);
101            }
102        }
103        return null;
104    }
105
106    public Layout parseLayout(String className, Element layoutElement, XmlConfiguration config) {
107        PluginType<?> plugin = plugins.get(className.toLowerCase());
108        if (plugin != null) {
109            try {
110                LayoutBuilder builder = (LayoutBuilder) LoaderUtil.newInstanceOf(plugin.getPluginClass());
111                return builder.parseLayout(layoutElement, config);
112            } catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
113                LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
114            }
115        }
116        return null;
117    }
118    public Layout parseLayout(String className, String layoutPrefix, Properties props, PropertiesConfiguration config) {
119        PluginType<?> plugin = plugins.get(className.toLowerCase());
120        if (plugin != null) {
121            LayoutBuilder builder = createBuilder(plugin, layoutPrefix, props);
122            if (builder != null) {
123                return builder.parseLayout(config);
124            }
125        }
126        return null;
127    }
128
129    public RewritePolicy parseRewritePolicy(String className, Element rewriteElement, XmlConfiguration config) {
130        PluginType<?> plugin = plugins.get(className.toLowerCase());
131        if (plugin != null) {
132            try {
133                RewritePolicyBuilder builder = (RewritePolicyBuilder) LoaderUtil.newInstanceOf(plugin.getPluginClass());
134                return builder.parseRewritePolicy(rewriteElement, config);
135            } catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
136                LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
137            }
138        }
139        return null;
140    }
141    public RewritePolicy parseRewritePolicy(String className, String policyPrefix, Properties props, PropertiesConfiguration config) {
142        PluginType<?> plugin = plugins.get(className.toLowerCase());
143        if (plugin != null) {
144            RewritePolicyBuilder builder = createBuilder(plugin, policyPrefix, props);
145            if (builder != null) {
146                return builder.parseRewritePolicy(config);
147            }
148        }
149        return null;
150    }
151
152    private <T extends AbstractBuilder> T createBuilder(PluginType<?> plugin, String prefix, Properties props) {
153        try {
154            Class<?> clazz = plugin.getPluginClass();
155            if (AbstractBuilder.class.isAssignableFrom(clazz)) {
156                @SuppressWarnings("unchecked")
157                Constructor<T> constructor =
158                        (Constructor<T>) clazz.getConstructor(constructorParams);
159                return constructor.newInstance(prefix, props);
160            }
161            @SuppressWarnings("unchecked")
162            T builder = (T) LoaderUtil.newInstanceOf(clazz);
163            return builder;
164        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
165            LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
166            return null;
167        }
168    }
169
170}