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.Level; 020import org.apache.logging.log4j.core.Filter; 021import org.apache.logging.log4j.core.config.Configuration; 022import org.apache.logging.log4j.core.config.ConfigurationException; 023import org.apache.logging.log4j.core.config.ConfigurationSource; 024import org.apache.logging.log4j.core.config.LoggerConfig; 025import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; 026import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder; 027import org.apache.logging.log4j.core.config.builder.api.Component; 028import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; 029import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; 030import org.apache.logging.log4j.core.config.builder.api.CustomLevelComponentBuilder; 031import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; 032import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; 033import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; 034import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; 035 036import java.lang.reflect.Constructor; 037import java.util.List; 038 039/** 040 * @param <T> The BuiltConfiguration type. 041 * 042 */ 043public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implements ConfigurationBuilder<T> { 044 045 private final Component root = new Component(); 046 private Component loggers; 047 private Component appenders; 048 private Component filters; 049 private Component properties; 050 private Component customLevels; 051 private final Class<T> clazz; 052 private ConfigurationSource source; 053 private int monitorInterval = 0; 054 private Level level = null; 055 private String verbosity = null; 056 private String packages = null; 057 private String shutdownFlag = null; 058 private String advertiser = null; 059 060 private String name = null; 061 062 public DefaultConfigurationBuilder() { 063 this((Class<T>) BuiltConfiguration.class); 064 root.addAttribute("name", "Built"); 065 } 066 067 public DefaultConfigurationBuilder(final Class<T> clazz) { 068 if (clazz == null) { 069 throw new IllegalArgumentException("A Configuration class must be provided"); 070 } 071 this.clazz = clazz; 072 final List<Component> components = root.getComponents(); 073 properties = new Component("Properties"); 074 components.add(properties); 075 customLevels = new Component("CustomLevels"); 076 components.add(customLevels); 077 filters = new Component("Filters"); 078 components.add(filters); 079 appenders = new Component("Appenders"); 080 components.add(appenders); 081 loggers = new Component("Loggers"); 082 components.add(loggers); 083 } 084 085 protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) { 086 parent.getComponents().add(builder.build()); 087 return this; 088 } 089 090 @Override 091 public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) { 092 return add(appenders, builder); 093 } 094 095 @Override 096 public ConfigurationBuilder<T> add(final CustomLevelComponentBuilder builder) { 097 return add(customLevels, builder); 098 } 099 100 @Override 101 public ConfigurationBuilder<T> add(final FilterComponentBuilder builder) { 102 return add(filters, builder); 103 } 104 105 @Override 106 public ConfigurationBuilder<T> add(final LoggerComponentBuilder builder) { 107 return add(loggers, builder); 108 } 109 110 @Override 111 public ConfigurationBuilder<T> add(final RootLoggerComponentBuilder builder) { 112 for (final Component c : loggers.getComponents()) { 113 if (c.getPluginType().equals(LoggerConfig.ROOT)) { 114 throw new ConfigurationException("Root Logger was previously defined"); 115 } 116 } 117 return add(loggers, builder); 118 } 119 120 @Override 121 public ConfigurationBuilder<T> addProperty(final String key, final String value) { 122 properties.addComponent(newComponent(key, "Property", value).build()); 123 return this; 124 } 125 126 @Override 127 public T build() { 128 T configuration; 129 try { 130 if (source == null) { 131 source = ConfigurationSource.NULL_SOURCE; 132 } 133 final Constructor<T> constructor = clazz.getConstructor(ConfigurationSource.class, Component.class); 134 configuration = constructor.newInstance(source, root); 135 configuration.setMonitorInterval(monitorInterval); 136 if (name != null) { 137 configuration.setName(name); 138 } 139 if (level != null) { 140 configuration.getStatusConfiguration().withStatus(level); 141 } 142 if (verbosity != null) { 143 configuration.getStatusConfiguration().withVerbosity(verbosity); 144 } 145 if (packages != null) { 146 configuration.setPluginPackages(packages); 147 } 148 if (shutdownFlag != null) { 149 configuration.setShutdownHook(shutdownFlag); 150 } 151 if (advertiser != null) { 152 configuration.createAdvertiser(advertiser, source); 153 } 154 } catch (final Exception ex) { 155 throw new IllegalArgumentException("Invalid Configuration class specified", ex); 156 } 157 configuration.getStatusConfiguration().initialize(); 158 configuration.initialize(); 159 return configuration; 160 } 161 162 @Override 163 public AppenderComponentBuilder newAppender(final String name, final String type) { 164 return new DefaultAppenderComponentBuilder(this, name, type); 165 } 166 167 @Override 168 public AppenderRefComponentBuilder newAppenderRef(final String ref) { 169 return new DefaultAppenderRefComponentBuilder(this, ref); 170 } 171 172 @Override 173 public LoggerComponentBuilder newAsyncLogger(final String name, final Level level) { 174 return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger"); 175 } 176 177 @Override 178 public LoggerComponentBuilder newAsyncLogger(final String name, final String level) { 179 return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger"); 180 } 181 182 @Override 183 public RootLoggerComponentBuilder newAsyncRootLogger(final Level level) { 184 return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot"); 185 } 186 187 @Override 188 public RootLoggerComponentBuilder newAsyncRootLogger(final String level) { 189 return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot"); 190 } 191 192 @Override 193 public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type) { 194 return new DefaultComponentBuilder<>(this, name, type); 195 } 196 197 @Override 198 public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type, final String value) { 199 return new DefaultComponentBuilder<>(this, name, type, value); 200 } 201 202 203 @Override 204 public CustomLevelComponentBuilder newCustomLevel(final String name, final int level) { 205 return new DefaultCustomLevelComponentBuilder(this, name, level); 206 } 207 208 @Override 209 public FilterComponentBuilder newFilter(final String type, final Filter.Result onMatch, final Filter.Result onMisMatch) { 210 return new DefaultFilterComponentBuilder(this, type, onMatch.name(), onMisMatch.name()); 211 } 212 213 @Override 214 public FilterComponentBuilder newFilter(final String type, final String onMatch, final String onMisMatch) { 215 return new DefaultFilterComponentBuilder(this, type, onMatch, onMisMatch); 216 } 217 218 @Override 219 public LayoutComponentBuilder newLayout(final String type) { 220 return new DefaultLayoutComponentBuilder(this, type); 221 } 222 223 224 @Override 225 public LoggerComponentBuilder newLogger(final String name, final Level level) { 226 return new DefaultLoggerComponentBuilder(this, name, level.toString()); 227 } 228 229 @Override 230 public LoggerComponentBuilder newLogger(final String name, final String level) { 231 return new DefaultLoggerComponentBuilder(this, name, level); 232 } 233 234 @Override 235 public RootLoggerComponentBuilder newRootLogger(final Level level) { 236 return new DefaultRootLoggerComponentBuilder(this, level.toString()); 237 } 238 239 @Override 240 public RootLoggerComponentBuilder newRootLogger(final String level) { 241 return new DefaultRootLoggerComponentBuilder(this, level); 242 } 243 244 @Override 245 public ConfigurationBuilder<T> setAdvertiser(final String advertiser) { 246 this.advertiser = advertiser; 247 return this; 248 } 249 250 /** 251 * Set the name of the configuration. 252 * 253 * @param name the name of the {@link Configuration}. By default is {@code "Assembled"}. 254 * @return this builder instance 255 */ 256 @Override 257 public ConfigurationBuilder<T> setConfigurationName(final String name) { 258 this.name = name; 259 return this; 260 } 261 262 /** 263 * Set the ConfigurationSource. 264 * 265 * @param configurationSource the {@link ConfigurationSource} 266 * @return this builder instance 267 */ 268 @Override 269 public ConfigurationBuilder<T> setConfigurationSource(final ConfigurationSource configurationSource) { 270 source = configurationSource; 271 return this; 272 } 273 274 @Override 275 public ConfigurationBuilder<T> setMonitorInterval(final String intervalSeconds) { 276 monitorInterval = Integer.parseInt(intervalSeconds); 277 return this; 278 } 279 280 @Override 281 public ConfigurationBuilder<T> setPackages(final String packages) { 282 this.packages = packages; 283 return this; 284 } 285 286 @Override 287 public ConfigurationBuilder<T> setShutdownHook(final String flag) { 288 this.shutdownFlag = flag; 289 return this; 290 } 291 292 @Override 293 public ConfigurationBuilder<T> setStatusLevel(final Level level) { 294 this.level = level; 295 return this; 296 } 297 298 @Override 299 public ConfigurationBuilder<T> setVerbosity(final String verbosity) { 300 this.verbosity = verbosity; 301 return this; 302 } 303}