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.builder.api.AppenderComponentBuilder;
25  import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
26  import org.apache.logging.log4j.core.config.builder.api.Component;
27  import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
28  import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
29  import org.apache.logging.log4j.core.config.builder.api.CustomLevelComponentBuilder;
30  import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder;
31  import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
32  import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
33  import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
34  
35  import java.lang.reflect.Constructor;
36  import java.util.List;
37  
38  /**
39   * @param <T> The BuiltConfiguration type.
40   *
41   */
42  public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implements ConfigurationBuilder<T> {
43  
44      private final Component root = new Component();
45      private Component loggers;
46      private Component appenders;
47      private Component filters;
48      private Component properties;
49      private Component customLevels;
50      private final Class<T> clazz;
51      private ConfigurationSource source;
52      private int monitorInterval = 0;
53      private Level level = null;
54      private String verbosity = null;
55      private String packages = null;
56      private String shutdownFlag = null;
57      private String advertiser = null;
58  
59      private String name = null;
60  
61      public DefaultConfigurationBuilder() {
62          this((Class<T>) BuiltConfiguration.class);
63          root.addAttribute("name", "Built");
64      }
65  
66      public DefaultConfigurationBuilder(final Class<T> clazz) {
67          if (clazz == null) {
68              throw new IllegalArgumentException("A Configuration class must be provided");
69          }
70          this.clazz = clazz;
71          final List<Component> components = root.getComponents();
72          properties = new Component("Properties");
73          components.add(properties);
74          customLevels = new Component("CustomLevels");
75          components.add(customLevels);
76          filters = new Component("Filters");
77          components.add(filters);
78          appenders = new Component("Appenders");
79          components.add(appenders);
80          loggers = new Component("Loggers");
81          components.add(loggers);
82      }
83      
84      protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) {
85          parent.getComponents().add(builder.build());
86          return this;
87      }
88  
89      @Override
90      public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) {
91          return add(appenders, builder);
92      }
93  
94      @Override
95      public ConfigurationBuilder<T> add(final CustomLevelComponentBuilder builder) {
96          return add(customLevels, builder);
97      }
98  
99      @Override
100     public ConfigurationBuilder<T> add(final FilterComponentBuilder builder) {
101         return add(filters, builder);
102     }
103 
104     @Override
105     public ConfigurationBuilder<T> add(final LoggerComponentBuilder builder) {
106         return add(loggers, builder);
107     }
108 
109     @Override
110     public ConfigurationBuilder<T> add(final RootLoggerComponentBuilder builder) {
111         for (final Component c : loggers.getComponents()) {
112             if (c.getPluginType().equals("root")) {
113                 throw new ConfigurationException("Root Logger was previously defined");
114             }
115         }
116         return add(loggers, builder);
117     }
118 
119     @Override
120     public ConfigurationBuilder<T> addProperty(final String key, final String value) {
121         properties.addComponent(newComponent(key, "Property", value).build());
122         return this;
123     }
124 
125     @Override
126     public T build() {
127         T configuration;
128         try {
129             if (source == null) {
130                 source = ConfigurationSource.NULL_SOURCE;
131             }
132             final Constructor<T> constructor = clazz.getConstructor(ConfigurationSource.class, Component.class);
133             configuration = constructor.newInstance(source, root);
134             configuration.setMonitorInterval(monitorInterval);
135             if (name != null) {
136                 configuration.setName(name);
137             }
138             if (level != null) {
139                 configuration.getStatusConfiguration().withStatus(level);
140             }
141             if (verbosity != null) {
142                 configuration.getStatusConfiguration().withVerbosity(verbosity);
143             }
144             if (packages != null) {
145                 configuration.setPluginPackages(packages);
146             }
147             if (shutdownFlag != null) {
148                 configuration.setShutdownHook(shutdownFlag);
149             }
150             if (advertiser != null) {
151                 configuration.createAdvertiser(advertiser, source);
152             }
153         } catch (final Exception ex) {
154             throw new IllegalArgumentException("Invalid Configuration class specified", ex);
155         }
156         configuration.getStatusConfiguration().initialize();
157         configuration.initialize();
158         return configuration;
159     }
160 
161     @Override
162     public AppenderComponentBuilder newAppender(final String name, final String type) {
163         return new DefaultAppenderComponentBuilder(this, name, type);
164     }
165 
166     @Override
167     public AppenderRefComponentBuilder newAppenderRef(final String ref) {
168         return new DefaultAppenderRefComponentBuilder(this, ref);
169     }
170 
171     @Override
172     public LoggerComponentBuilder newAsyncLogger(final String name, final Level level) {
173         return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger");
174     }
175 
176     @Override
177     public LoggerComponentBuilder newAsyncLogger(final String name, final String level) {
178         return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger");
179     }
180 
181     @Override
182     public RootLoggerComponentBuilder newAsyncRootLogger(final Level level) {
183         return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot");
184     }
185 
186     @Override
187     public RootLoggerComponentBuilder newAsyncRootLogger(final String level) {
188         return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot");
189     }
190 
191     @Override
192     public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type) {
193         return new DefaultComponentBuilder<>(this, name, type);
194     }
195 
196     @Override
197     public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type, final String value) {
198         return new DefaultComponentBuilder<>(this, name, type, value);
199     }
200 
201 
202     @Override
203     public CustomLevelComponentBuilder newCustomLevel(final String name, final int level) {
204         return new DefaultCustomLevelComponentBuilder(this, name, level);
205     }
206 
207     @Override
208     public FilterComponentBuilder newFilter(final String type, final Filter.Result onMatch, final Filter.Result onMisMatch) {
209         return new DefaultFilterComponentBuilder(this, type, onMatch.name(), onMisMatch.name());
210     }
211 
212     @Override
213     public FilterComponentBuilder newFilter(final String type, final String onMatch, final String onMisMatch) {
214         return new DefaultFilterComponentBuilder(this, type, onMatch, onMisMatch);
215     }
216 
217     @Override
218     public LayoutComponentBuilder newLayout(final String type) {
219         return new DefaultLayoutComponentBuilder(this, type);
220     }
221 
222 
223     @Override
224     public LoggerComponentBuilder newLogger(final String name, final Level level) {
225         return new DefaultLoggerComponentBuilder(this, name, level.toString());
226     }
227 
228     @Override
229     public LoggerComponentBuilder newLogger(final String name, final String level) {
230         return new DefaultLoggerComponentBuilder(this, name, level);
231     }
232 
233     @Override
234     public RootLoggerComponentBuilder newRootLogger(final Level level) {
235         return new DefaultRootLoggerComponentBuilder(this, level.toString());
236     }
237 
238     @Override
239     public RootLoggerComponentBuilder newRootLogger(final String level) {
240         return new DefaultRootLoggerComponentBuilder(this, level);
241     }
242 
243     @Override
244     public ConfigurationBuilder<T> setAdvertiser(final String advertiser) {
245         this.advertiser = advertiser;
246         return this;
247     }
248 
249     /**
250      * Set the name of the configuration.
251      *
252      * @param name the name of the {@link Configuration}. By default is {@code "Assembled"}.
253      * @return this builder instance
254      */
255     @Override
256     public ConfigurationBuilder<T> setConfigurationName(final String name) {
257         this.name = name;
258         return this;
259     }
260 
261     /**
262      * Set the ConfigurationSource.
263      *
264      * @param configurationSource the {@link ConfigurationSource}
265      * @return this builder instance
266      */
267     @Override
268     public ConfigurationBuilder<T> setConfigurationSource(final ConfigurationSource configurationSource) {
269         source = configurationSource;
270         return this;
271     }
272 
273     @Override
274     public ConfigurationBuilder<T> setMonitorInterval(final String intervalSeconds) {
275         monitorInterval = Integer.parseInt(intervalSeconds);
276         return this;
277     }
278 
279     @Override
280     public ConfigurationBuilder<T> setPackages(final String packages) {
281         this.packages = packages;
282         return this;
283     }
284 
285     @Override
286     public ConfigurationBuilder<T> setShutdownHook(final String flag) {
287         this.shutdownFlag = flag;
288         return this;
289     }
290 
291     @Override
292     public ConfigurationBuilder<T> setStatusLevel(final Level level) {
293         this.level = level;
294         return this;
295     }
296 
297     @Override
298     public ConfigurationBuilder<T> setVerbosity(final String verbosity) {
299         this.verbosity = verbosity;
300         return this;
301     }
302 }