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