View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.config.builder.impl;
18  
19  import java.lang.reflect.Constructor;
20  import java.util.List;
21  
22  import org.apache.logging.log4j.Level;
23  import org.apache.logging.log4j.core.Filter;
24  import org.apache.logging.log4j.core.config.Configuration;
25  import org.apache.logging.log4j.core.config.ConfigurationException;
26  import org.apache.logging.log4j.core.config.ConfigurationSource;
27  import org.apache.logging.log4j.core.config.LoggerConfig;
28  import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
29  import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
30  import org.apache.logging.log4j.core.config.builder.api.Component;
31  import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
32  import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
33  import org.apache.logging.log4j.core.config.builder.api.CustomLevelComponentBuilder;
34  import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder;
35  import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
36  import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
37  import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
38  import org.apache.logging.log4j.core.config.builder.api.ScriptComponentBuilder;
39  import org.apache.logging.log4j.core.config.builder.api.ScriptFileComponentBuilder;
40  
41  /**
42   * @param <T> The BuiltConfiguration type.
43   * @since 2.4
44   */
45  public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implements ConfigurationBuilder<T> {
46  
47      private final Component root = new Component();
48      private Component loggers;
49      private Component appenders;
50      private Component filters;
51      private Component properties;
52      private Component customLevels;
53      private Component scripts;
54      private final Class<T> clazz;
55      private ConfigurationSource source;
56      private int monitorInterval = 0;
57      private Level level = null;
58      private String verbosity = null;
59      private String packages = null;
60      private String shutdownFlag = null;
61      private String advertiser = null;
62  
63      private String name = null;
64  
65      @SuppressWarnings("unchecked")
66      public DefaultConfigurationBuilder() {
67          this((Class<T>) BuiltConfiguration.class);
68          root.addAttribute("name", "Built");
69      }
70  
71      public DefaultConfigurationBuilder(final Class<T> clazz) {
72          if (clazz == null) {
73              throw new IllegalArgumentException("A Configuration class must be provided");
74          }
75          this.clazz = clazz;
76          final List<Component> components = root.getComponents();
77          properties = new Component("Properties");
78          components.add(properties);
79          scripts = new Component("Scripts");
80          components.add(scripts);
81          customLevels = new Component("CustomLevels");
82          components.add(customLevels);
83          filters = new Component("Filters");
84          components.add(filters);
85          appenders = new Component("Appenders");
86          components.add(appenders);
87          loggers = new Component("Loggers");
88          components.add(loggers);
89      }
90  
91      protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) {
92          parent.getComponents().add(builder.build());
93          return this;
94      }
95  
96      @Override
97      public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) {
98          return add(appenders, builder);
99      }
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         return build(true);
145     }
146 
147     @Override
148     public T build(final boolean initialize) {
149         T configuration;
150         try {
151             if (source == null) {
152                 source = ConfigurationSource.NULL_SOURCE;
153             }
154             final Constructor<T> constructor = clazz.getConstructor(ConfigurationSource.class, Component.class);
155             configuration = constructor.newInstance(source, root);
156             configuration.setMonitorInterval(monitorInterval);
157             configuration.getRootNode().getAttributes().putAll(root.getAttributes());
158             if (name != null) {
159                 configuration.setName(name);
160             }
161             if (level != null) {
162                 configuration.getStatusConfiguration().withStatus(level);
163             }
164             if (verbosity != null) {
165                 configuration.getStatusConfiguration().withVerbosity(verbosity);
166             }
167             if (packages != null) {
168                 configuration.setPluginPackages(packages);
169             }
170             if (shutdownFlag != null) {
171                 configuration.setShutdownHook(shutdownFlag);
172             }
173             if (advertiser != null) {
174                 configuration.createAdvertiser(advertiser, source);
175             }
176         } catch (final Exception ex) {
177             throw new IllegalArgumentException("Invalid Configuration class specified", ex);
178         }
179         configuration.getStatusConfiguration().initialize();
180         if (initialize) {
181             configuration.initialize();
182         }
183         return configuration;
184     }
185 
186     @Override
187     public ScriptComponentBuilder newScript(final String name, final String language, final String text) {
188         return new DefaultScriptComponentBuilder(this, name, language, text);
189     }
190 
191 
192     @Override
193     public ScriptFileComponentBuilder newScriptFile(final String path) {
194         return new DefaultScriptFileComponentBuilder(this, path, path);
195     }
196 
197     @Override
198     public ScriptFileComponentBuilder newScriptFile(final String name, final String path) {
199         return new DefaultScriptFileComponentBuilder(this, name, path);
200     }
201 
202     @Override
203     public AppenderComponentBuilder newAppender(final String name, final String type) {
204         return new DefaultAppenderComponentBuilder(this, name, type);
205     }
206 
207     @Override
208     public AppenderRefComponentBuilder newAppenderRef(final String ref) {
209         return new DefaultAppenderRefComponentBuilder(this, ref);
210     }
211 
212     @Override
213     public LoggerComponentBuilder newAsyncLogger(final String name, final Level level) {
214         return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger", false);
215     }
216 
217     @Override
218     public LoggerComponentBuilder newAsyncLogger(final String name, final Level level, final boolean includeLocation) {
219         return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger", includeLocation);
220     }
221 
222     @Override
223     public LoggerComponentBuilder newAsyncLogger(final String name, final String level) {
224         return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger", false);
225     }
226 
227     @Override
228     public LoggerComponentBuilder newAsyncLogger(final String name, final String level, final boolean includeLocation) {
229         return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger");
230     }
231 
232     @Override
233     public RootLoggerComponentBuilder newAsyncRootLogger(final Level level) {
234         return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot", false);
235     }
236 
237     @Override
238     public RootLoggerComponentBuilder newAsyncRootLogger(final Level level, final boolean includeLocation) {
239         return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot", includeLocation);
240     }
241 
242     @Override
243     public RootLoggerComponentBuilder newAsyncRootLogger(final String level) {
244         return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot", false);
245     }
246 
247     @Override
248     public RootLoggerComponentBuilder newAsyncRootLogger(final String level, final boolean includeLocation) {
249         return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot", includeLocation);
250     }
251 
252 
253     @Override
254     public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String type) {
255         return new DefaultComponentBuilder<>(this, type);
256     }
257 
258     @Override
259     public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type) {
260         return new DefaultComponentBuilder<>(this, name, type);
261     }
262 
263     @Override
264     public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type,
265                                                                             final String value) {
266         return new DefaultComponentBuilder<>(this, name, type, value);
267     }
268 
269 
270     @Override
271     public CustomLevelComponentBuilder newCustomLevel(final String name, final int level) {
272         return new DefaultCustomLevelComponentBuilder(this, name, level);
273     }
274 
275     @Override
276     public FilterComponentBuilder newFilter(final String type, final Filter.Result onMatch,
277                                             final Filter.Result onMisMatch) {
278         return new DefaultFilterComponentBuilder(this, type, onMatch.name(), onMisMatch.name());
279     }
280 
281     @Override
282     public FilterComponentBuilder newFilter(final String type, final String onMatch, final String onMisMatch) {
283         return new DefaultFilterComponentBuilder(this, type, onMatch, onMisMatch);
284     }
285 
286     @Override
287     public LayoutComponentBuilder newLayout(final String type) {
288         return new DefaultLayoutComponentBuilder(this, type);
289     }
290 
291 
292     @Override
293     public LoggerComponentBuilder newLogger(final String name, final Level level) {
294         return new DefaultLoggerComponentBuilder(this, name, level.toString(), true);
295     }
296 
297     @Override
298     public LoggerComponentBuilder newLogger(final String name, final Level level, final boolean includeLocation) {
299         return new DefaultLoggerComponentBuilder(this, name, level.toString(), includeLocation);
300     }
301 
302     @Override
303     public LoggerComponentBuilder newLogger(final String name, final String level) {
304         return new DefaultLoggerComponentBuilder(this, name, level, true);
305     }
306 
307     @Override
308     public LoggerComponentBuilder newLogger(final String name, final String level, final boolean includeLocation) {
309         return new DefaultLoggerComponentBuilder(this, name, level, includeLocation);
310     }
311 
312     @Override
313     public RootLoggerComponentBuilder newRootLogger(final Level level) {
314         return new DefaultRootLoggerComponentBuilder(this, level.toString(), true);
315     }
316 
317     @Override
318     public RootLoggerComponentBuilder newRootLogger(final Level level, final boolean includeLocation) {
319         return new DefaultRootLoggerComponentBuilder(this, level.toString(), includeLocation);
320     }
321 
322     @Override
323     public RootLoggerComponentBuilder newRootLogger(final String level) {
324         return new DefaultRootLoggerComponentBuilder(this, level, true);
325     }
326 
327     @Override
328     public RootLoggerComponentBuilder newRootLogger(final String level, final boolean includeLocation) {
329         return new DefaultRootLoggerComponentBuilder(this, level, includeLocation);
330     }
331 
332     @Override
333     public ConfigurationBuilder<T> setAdvertiser(final String advertiser) {
334         this.advertiser = advertiser;
335         return this;
336     }
337 
338     /**
339      * Set the name of the configuration.
340      *
341      * @param name the name of the {@link Configuration}. By default is {@code "Assembled"}.
342      * @return this builder instance
343      */
344     @Override
345     public ConfigurationBuilder<T> setConfigurationName(final String name) {
346         this.name = name;
347         return this;
348     }
349 
350     /**
351      * Set the ConfigurationSource.
352      *
353      * @param configurationSource the {@link ConfigurationSource}
354      * @return this builder instance
355      */
356     @Override
357     public ConfigurationBuilder<T> setConfigurationSource(final ConfigurationSource configurationSource) {
358         source = configurationSource;
359         return this;
360     }
361 
362     @Override
363     public ConfigurationBuilder<T> setMonitorInterval(final String intervalSeconds) {
364         monitorInterval = Integer.parseInt(intervalSeconds);
365         return this;
366     }
367 
368     @Override
369     public ConfigurationBuilder<T> setPackages(final String packages) {
370         this.packages = packages;
371         return this;
372     }
373 
374     @Override
375     public ConfigurationBuilder<T> setShutdownHook(final String flag) {
376         this.shutdownFlag = flag;
377         return this;
378     }
379 
380     @Override
381     public ConfigurationBuilder<T> setStatusLevel(final Level level) {
382         this.level = level;
383         return this;
384     }
385 
386     @Override
387     public ConfigurationBuilder<T> setVerbosity(final String verbosity) {
388         this.verbosity = verbosity;
389         return this;
390     }
391 
392     @Override
393     public ConfigurationBuilder<T> addRootProperty(final String key, final String value) {
394         root.getAttributes().put(key, value);
395         return this;
396     }
397 }