1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.config;
18
19 import org.apache.logging.log4j.Logger;
20 import org.apache.logging.log4j.core.config.plugins.PluginManager;
21 import org.apache.logging.log4j.core.config.plugins.PluginType;
22 import org.apache.logging.log4j.core.helpers.FileUtils;
23 import org.apache.logging.log4j.core.helpers.Loader;
24 import org.apache.logging.log4j.status.StatusLogger;
25 import org.xml.sax.InputSource;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.net.MalformedURLException;
33 import java.net.URI;
34 import java.net.URISyntaxException;
35 import java.net.URL;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40 import java.util.TreeSet;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public abstract class ConfigurationFactory {
58
59
60
61 public static final String CONFIGURATION_FACTORY_PROPERTY = "log4j.configurationFactory";
62
63
64
65
66 public static final String CONFIGURATION_FILE_PROPERTY = "log4j.configurationFile";
67
68
69
70
71 protected static final Logger LOGGER = StatusLogger.getLogger();
72
73
74
75
76 protected static final String TEST_PREFIX = "log4j2-test";
77
78
79
80
81 protected static final String DEFAULT_PREFIX = "log4j2";
82
83 private static List<ConfigurationFactory> factories = new ArrayList<ConfigurationFactory>();
84
85 private static ConfigurationFactory configFactory = new Factory();
86
87
88
89
90 protected File configFile = null;
91
92
93
94
95
96 public static ConfigurationFactory getInstance() {
97 String factoryClass = System.getProperty(CONFIGURATION_FACTORY_PROPERTY);
98 if (factoryClass != null) {
99 addFactory(factoryClass);
100 }
101 PluginManager manager = new PluginManager("ConfigurationFactory");
102 manager.collectPlugins();
103 Map<String, PluginType> plugins = manager.getPlugins();
104 Set<WeightedFactory> ordered = new TreeSet<WeightedFactory>();
105 for (PluginType type : plugins.values()) {
106 try {
107 Class<ConfigurationFactory> clazz = type.getPluginClass();
108 Order o = clazz.getAnnotation(Order.class);
109 Integer weight = o.value();
110 if (o != null) {
111 ordered.add(new WeightedFactory(weight, clazz));
112 }
113 } catch (Exception ex) {
114 LOGGER.warn("Unable to add class " + type.getPluginClass());
115 }
116 }
117 for (WeightedFactory wf : ordered) {
118 addFactory(wf.factoryClass);
119 }
120 return configFactory;
121 }
122
123 private static void addFactory(String factoryClass) {
124 try {
125 Class clazz = Class.forName(factoryClass);
126 addFactory(clazz);
127 } catch (ClassNotFoundException ex) {
128 LOGGER.error("Unable to load class " + factoryClass, ex);
129 } catch (Exception ex) {
130 LOGGER.error("Unable to load class " + factoryClass, ex);
131 }
132 }
133
134 private static void addFactory(Class factoryClass) {
135 try {
136 factories.add((ConfigurationFactory) factoryClass.newInstance());
137 } catch (Exception ex) {
138 LOGGER.error("Unable to create instance of " + factoryClass.getName(), ex);
139 }
140 }
141
142
143
144
145
146 public static void setConfigurationFactory(ConfigurationFactory factory) {
147 configFactory = factory;
148 }
149
150
151
152
153 public static void resetConfigurationFactory() {
154 configFactory = new Factory();
155 }
156
157
158
159
160
161 public static void removeConfigurationFactory(ConfigurationFactory factory) {
162 factories.remove(factory);
163 }
164
165 protected abstract String[] getSupportedTypes();
166
167 protected boolean isActive() {
168 return true;
169 }
170
171 public abstract Configuration getConfiguration(InputSource source);
172
173
174
175
176
177
178
179 public Configuration getConfiguration(String name, URI configLocation) {
180 if (!isActive()) {
181 return null;
182 }
183 if (configLocation != null) {
184 InputSource source = getInputFromURI(configLocation);
185 if (source != null) {
186 return getConfiguration(source);
187 }
188 }
189 return null;
190 }
191
192
193
194
195
196
197 protected InputSource getInputFromURI(URI configLocation) {
198 configFile = FileUtils.fileFromURI(configLocation);
199 if (configFile != null && configFile.exists() && configFile.canRead()) {
200 try {
201 InputSource source = new InputSource(new FileInputStream(configFile));
202 source.setSystemId(configLocation.getPath());
203 return source;
204 } catch (FileNotFoundException ex) {
205 LOGGER.error("Cannot locate file " + configLocation.getPath(), ex);
206 }
207 }
208 try {
209 InputSource source = new InputSource(configLocation.toURL().openStream());
210 source.setSystemId(configLocation.getPath());
211 return source;
212 } catch (MalformedURLException ex) {
213 LOGGER.error("Invalid URL " + configLocation.toString(), ex);
214 } catch (IOException ex) {
215 LOGGER.error("Unable to access " + configLocation.toString(), ex);
216 }
217 return null;
218 }
219
220
221
222
223
224
225
226 protected InputSource getInputFromString(String config, ClassLoader loader) {
227 InputSource source;
228 try {
229 URL url = new URL(config);
230 source = new InputSource(url.openStream());
231 if (FileUtils.isFile(url)) {
232 configFile = FileUtils.fileFromURI(url.toURI());
233 }
234 source.setSystemId(config);
235 return source;
236 } catch (Exception ex) {
237 source = getInputFromResource(config, loader);
238 if (source == null) {
239 try {
240 File file = new File(config);
241 FileInputStream is = new FileInputStream(file);
242 configFile = file;
243 source = new InputSource(is);
244 source.setSystemId(config);
245 } catch (FileNotFoundException fnfe) {
246
247 }
248 }
249 }
250 return source;
251 }
252
253
254
255
256
257
258
259 protected InputSource getInputFromResource(String resource, ClassLoader loader) {
260 URL url = Loader.getResource(resource, loader);
261 if (url == null) {
262 return null;
263 }
264 InputStream is = null;
265 try {
266 is = url.openStream();
267 } catch (IOException ioe) {
268 return null;
269 }
270 if (is == null) {
271 return null;
272 }
273 InputSource source = new InputSource(is);
274 if (FileUtils.isFile(url)) {
275 try {
276 configFile = FileUtils.fileFromURI(url.toURI());
277 } catch (URISyntaxException ex) {
278
279 }
280 }
281 source.setSystemId(resource);
282 return source;
283 }
284
285
286
287
288 private static class WeightedFactory implements Comparable<WeightedFactory> {
289 private int weight;
290 private Class<ConfigurationFactory> factoryClass;
291
292
293
294
295
296
297 public WeightedFactory(int weight, Class<ConfigurationFactory> clazz) {
298 this.weight = weight;
299 this.factoryClass = clazz;
300 }
301
302 public int compareTo(WeightedFactory wf) {
303 int w = wf.weight;
304 if (weight == w) {
305 return 0;
306 } else if (weight > w) {
307 return -1;
308 } else {
309 return 1;
310 }
311 }
312 }
313
314
315
316
317 private static class Factory extends ConfigurationFactory {
318
319
320
321
322
323
324
325 public Configuration getConfiguration(String name, URI configLocation) {
326
327 if (configLocation == null) {
328 String config = System.getProperty(CONFIGURATION_FILE_PROPERTY);
329 if (config != null) {
330 ClassLoader loader = this.getClass().getClassLoader();
331 InputSource source = getInputFromString(config, loader);
332 if (source != null) {
333 for (ConfigurationFactory factory : factories) {
334 String[] types = factory.getSupportedTypes();
335 if (types != null) {
336 for (String type : types) {
337 if (type.equals("*") || config.endsWith(type)) {
338 Configuration c = factory.getConfiguration(source);
339 if (c != null) {
340 return c;
341 }
342 }
343 }
344 }
345 }
346 }
347 }
348 } else {
349 for (ConfigurationFactory factory : factories) {
350 Configuration config = factory.getConfiguration(name, configLocation);
351 if (config != null) {
352 return config;
353 }
354 }
355 }
356
357 Configuration config = getConfiguration(true, name);
358 if (config == null) {
359 config = getConfiguration(true, null);
360 if (config == null) {
361 config = getConfiguration(false, name);
362 if (config == null) {
363 config = getConfiguration(false, null);
364 }
365 }
366 }
367 return config != null ? config : new DefaultConfiguration();
368 }
369
370 private Configuration getConfiguration(boolean isTest, String name) {
371 boolean named = (name != null && name.length() > 0);
372 ClassLoader loader = this.getClass().getClassLoader();
373 for (ConfigurationFactory factory : factories) {
374 String configName;
375 String prefix = isTest ? TEST_PREFIX : DEFAULT_PREFIX;
376 String [] types = factory.getSupportedTypes();
377 if (types == null) {
378 continue;
379 }
380
381 for (String suffix : types) {
382 if (suffix.equals("*")) {
383 continue;
384 }
385 configName = named ? prefix + name + suffix : prefix + suffix;
386
387 InputSource source = getInputFromResource(configName, loader);
388 if (source != null) {
389 return factory.getConfiguration(source);
390 }
391 }
392 }
393 return null;
394 }
395
396 public String[] getSupportedTypes() {
397 return null;
398 }
399
400 public Configuration getConfiguration(InputSource source) {
401 return null;
402 }
403 }
404 }