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