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