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.logging.log4j.core.config.builder.impl;
018
019import java.io.File;
020import java.io.IOException;
021import java.io.InputStream;
022import java.util.Arrays;
023import java.util.List;
024
025import org.apache.logging.log4j.core.LoggerContext;
026import org.apache.logging.log4j.core.config.AbstractConfiguration;
027import org.apache.logging.log4j.core.config.ConfigurationSource;
028import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
029import org.apache.logging.log4j.core.config.Node;
030import org.apache.logging.log4j.core.config.Reconfigurable;
031import org.apache.logging.log4j.core.config.builder.api.Component;
032import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
033import org.apache.logging.log4j.core.config.plugins.util.PluginType;
034import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
035import org.apache.logging.log4j.core.config.status.StatusConfiguration;
036import org.apache.logging.log4j.core.util.FileWatcher;
037import org.apache.logging.log4j.core.util.Patterns;
038
039/**
040 * This is the general version of the Configuration created by the Builder. It may be extended to
041 * enhance its functionality.
042 *
043 * @since 2.4
044 */
045public class BuiltConfiguration extends AbstractConfiguration {
046    private static final String[] VERBOSE_CLASSES = new String[] { ResolverUtil.class.getName() };
047    private final StatusConfiguration statusConfig;
048    protected Component rootComponent;
049    private Component loggersComponent;
050    private Component appendersComponent;
051    private Component filtersComponent;
052    private Component propertiesComponent;
053    private Component customLevelsComponent;
054    private Component scriptsComponent;
055    private String contentType = "text";
056
057    public BuiltConfiguration(final LoggerContext loggerContext, final ConfigurationSource source, final Component rootComponent) {
058        super(loggerContext, source);
059        statusConfig = new StatusConfiguration().withVerboseClasses(VERBOSE_CLASSES).withStatus(getDefaultStatus());
060        for (final Component component : rootComponent.getComponents()) {
061            switch (component.getPluginType()) {
062                case "Scripts": {
063                    scriptsComponent = component;
064                    break;
065                }
066                case "Loggers": {
067                    loggersComponent = component;
068                    break;
069                }
070                case "Appenders": {
071                    appendersComponent = component;
072                    break;
073                }
074                case "Filters": {
075                    filtersComponent = component;
076                    break;
077                }
078                case "Properties": {
079                    propertiesComponent = component;
080                    break;
081                }
082                case "CustomLevels": {
083                    customLevelsComponent = component;
084                    break;
085                }
086            }
087        }
088        this.rootComponent = rootComponent;
089    }
090
091    @Override
092    public void setup() {
093        final List<Node> children = rootNode.getChildren();
094        if (propertiesComponent.getComponents().size() > 0) {
095            children.add(convertToNode(rootNode, propertiesComponent));
096        }
097        if (scriptsComponent.getComponents().size() > 0) {
098            children.add(convertToNode(rootNode, scriptsComponent));
099        }
100        if (customLevelsComponent.getComponents().size() > 0) {
101            children.add(convertToNode(rootNode, customLevelsComponent));
102        }
103        children.add(convertToNode(rootNode, loggersComponent));
104        children.add(convertToNode(rootNode, appendersComponent));
105        if (filtersComponent.getComponents().size() > 0) {
106            if (filtersComponent.getComponents().size() == 1) {
107                children.add(convertToNode(rootNode, filtersComponent.getComponents().get(0)));
108            } else {
109                children.add(convertToNode(rootNode, filtersComponent));
110            }
111        }
112        rootComponent = null;
113    }
114
115    public String getContentType() {
116        return this.contentType;
117    }
118
119    public void setContentType(final String contentType) {
120        this.contentType = contentType;
121    }
122
123    public void createAdvertiser(final String advertiserString, final ConfigurationSource configSource) {
124        byte[] buffer = null;
125        try {
126            if (configSource != null) {
127                final InputStream is = configSource.getInputStream();
128                if (is != null) {
129                    buffer = toByteArray(is);
130                }
131            }
132        } catch (final IOException ioe) {
133            LOGGER.warn("Unable to read configuration source " + configSource.toString());
134        }
135        super.createAdvertiser(advertiserString, configSource, buffer, contentType);
136    }
137
138    public StatusConfiguration getStatusConfiguration() {
139        return statusConfig;
140    }
141
142    public void setPluginPackages(final String packages) {
143        pluginPackages.addAll(Arrays.asList(packages.split(Patterns.COMMA_SEPARATOR)));
144    }
145
146    public void setShutdownHook(final String flag) {
147        isShutdownHookEnabled = !"disable".equalsIgnoreCase(flag);
148    }
149
150    public void setShutdownTimeoutMillis(final long shutdownTimeoutMillis) {
151        this.shutdownTimeoutMillis = shutdownTimeoutMillis;
152    }
153
154    public void setMonitorInterval(final int intervalSeconds) {
155        if (this instanceof Reconfigurable && intervalSeconds > 0) {
156            final ConfigurationSource configSource = getConfigurationSource();
157            if (configSource != null) {
158                final File configFile = configSource.getFile();
159                if (intervalSeconds > 0) {
160                    getWatchManager().setIntervalSeconds(intervalSeconds);
161                    if (configFile != null) {
162                        final FileWatcher watcher = new ConfiguratonFileWatcher((Reconfigurable) this, listeners);
163                        getWatchManager().watchFile(configFile, watcher);
164                    }
165                }
166            }
167        }
168    }
169
170    @Override
171    public PluginManager getPluginManager() {
172        return pluginManager;
173    }
174
175    protected Node convertToNode(final Node parent, final Component component) {
176        final String name = component.getPluginType();
177        final PluginType<?> pluginType = pluginManager.getPluginType(name);
178        final Node node = new Node(parent, name, pluginType);
179        node.getAttributes().putAll(component.getAttributes());
180        node.setValue(component.getValue());
181        final List<Node> children = node.getChildren();
182        for (final Component child : component.getComponents()) {
183            children.add(convertToNode(node, child));
184        }
185        return node;
186    }
187}