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  import org.apache.logging.log4j.core.config.builder.api.ScriptComponentBuilder;
36  import org.apache.logging.log4j.core.config.builder.api.ScriptFileComponentBuilder;
37  
38  import java.lang.reflect.Constructor;
39  import java.util.List;
40  
41  /**
42   * @param <T> The BuiltConfiguration type.
43   *
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         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 }