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