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