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 org.apache.logging.log4j.Level;
20  import org.apache.logging.log4j.core.Filter;
21  import org.apache.logging.log4j.core.config.Configuration;
22  import org.apache.logging.log4j.core.config.ConfigurationException;
23  import org.apache.logging.log4j.core.config.ConfigurationSource;
24  import org.apache.logging.log4j.core.config.LoggerConfig;
25  import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
26  import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
27  import org.apache.logging.log4j.core.config.builder.api.Component;
28  import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
29  import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
30  import org.apache.logging.log4j.core.config.builder.api.CustomLevelComponentBuilder;
31  import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder;
32  import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
33  import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
34  import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
35  
36  import java.lang.reflect.Constructor;
37  import java.util.List;
38  
39  /**
40   * @param <T> The BuiltConfiguration type.
41   *
42   */
43  public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implements ConfigurationBuilder<T> {
44  
45      private final Component root = new Component();
46      private Component loggers;
47      private Component appenders;
48      private Component filters;
49      private Component properties;
50      private Component customLevels;
51      private final Class<T> clazz;
52      private ConfigurationSource source;
53      private int monitorInterval = 0;
54      private Level level = null;
55      private String verbosity = null;
56      private String packages = null;
57      private String shutdownFlag = null;
58      private String advertiser = null;
59  
60      private String name = null;
61  
62      public DefaultConfigurationBuilder() {
63          this((Class<T>) BuiltConfiguration.class);
64          root.addAttribute("name", "Built");
65      }
66  
67      public DefaultConfigurationBuilder(final Class<T> clazz) {
68          if (clazz == null) {
69              throw new IllegalArgumentException("A Configuration class must be provided");
70          }
71          this.clazz = clazz;
72          final List<Component> components = root.getComponents();
73          properties = new Component("Properties");
74          components.add(properties);
75          customLevels = new Component("CustomLevels");
76          components.add(customLevels);
77          filters = new Component("Filters");
78          components.add(filters);
79          appenders = new Component("Appenders");
80          components.add(appenders);
81          loggers = new Component("Loggers");
82          components.add(loggers);
83      }
84      
85      protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) {
86          parent.getComponents().add(builder.build());
87          return this;
88      }
89  
90      @Override
91      public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) {
92          return add(appenders, builder);
93      }
94  
95      @Override
96      public ConfigurationBuilder<T> add(final CustomLevelComponentBuilder builder) {
97          return add(customLevels, builder);
98      }
99  
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 }