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 java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.net.MalformedURLException;
31 import java.net.URI;
32 import java.net.URISyntaxException;
33 import java.net.URL;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.TreeSet;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public abstract class ConfigurationFactory {
63
64
65
66 public static final String CONFIGURATION_FACTORY_PROPERTY = "log4j.configurationFactory";
67
68
69
70
71 public static final String CONFIGURATION_FILE_PROPERTY = "log4j.configurationFile";
72
73
74
75
76 protected static final Logger LOGGER = StatusLogger.getLogger();
77
78
79
80
81 protected static final String TEST_PREFIX = "log4j2-test";
82
83
84
85
86 protected static final String DEFAULT_PREFIX = "log4j2";
87
88 private static List<ConfigurationFactory> factories = new ArrayList<ConfigurationFactory>();
89
90 private static ConfigurationFactory configFactory = new Factory();
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(ConfigurationSource 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 ConfigurationSource 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 ConfigurationSource getInputFromURI(URI configLocation) {
198 File configFile = FileUtils.fileFromURI(configLocation);
199 if (configFile != null && configFile.exists() && configFile.canRead()) {
200 try {
201 return new ConfigurationSource(new FileInputStream(configFile), configFile);
202 } catch (FileNotFoundException ex) {
203 LOGGER.error("Cannot locate file " + configLocation.getPath(), ex);
204 }
205 }
206 String scheme = configLocation.getScheme();
207 if (scheme == null || scheme.equals("classloader")) {
208 ClassLoader loader = this.getClass().getClassLoader();
209 ConfigurationSource source = getInputFromResource(configLocation.getPath(), loader);
210 if (source != null) {
211 return source;
212 }
213 }
214 try {
215 return new ConfigurationSource(configLocation.toURL().openStream(), configLocation.getPath());
216 } catch (MalformedURLException ex) {
217 LOGGER.error("Invalid URL " + configLocation.toString(), ex);
218 } catch (IOException ex) {
219 LOGGER.error("Unable to access " + configLocation.toString(), ex);
220 } catch (Exception ex) {
221 LOGGER.error("Unable to access " + configLocation.toString(), ex);
222 }
223 return null;
224 }
225
226
227
228
229
230
231
232 protected ConfigurationSource getInputFromString(String config, ClassLoader loader) {
233 try {
234 URL url = new URL(config);
235 return new ConfigurationSource(url.openStream(), FileUtils.fileFromURI(url.toURI()));
236 } catch (Exception ex) {
237 ConfigurationSource source = getInputFromResource(config, loader);
238 if (source == null) {
239 try {
240 File file = new File(config);
241 return new ConfigurationSource(new FileInputStream(file), file);
242 } catch (FileNotFoundException fnfe) {
243
244 }
245 }
246 return source;
247 }
248 }
249
250
251
252
253
254
255
256 protected ConfigurationSource getInputFromResource(String resource, ClassLoader loader) {
257 URL url = Loader.getResource(resource, loader);
258 if (url == null) {
259 return null;
260 }
261 InputStream is = null;
262 try {
263 is = url.openStream();
264 } catch (IOException ioe) {
265 return null;
266 }
267 if (is == null) {
268 return null;
269 }
270
271 if (FileUtils.isFile(url)) {
272 try {
273 return new ConfigurationSource(is, FileUtils.fileFromURI((url.toURI())));
274 } catch (URISyntaxException ex) {
275
276 }
277 }
278 return new ConfigurationSource(is, resource);
279 }
280
281
282
283
284 private static class WeightedFactory implements Comparable<WeightedFactory> {
285 private int weight;
286 private Class<ConfigurationFactory> factoryClass;
287
288
289
290
291
292
293 public WeightedFactory(int weight, Class<ConfigurationFactory> clazz) {
294 this.weight = weight;
295 this.factoryClass = clazz;
296 }
297
298 public int compareTo(WeightedFactory wf) {
299 int w = wf.weight;
300 if (weight == w) {
301 return 0;
302 } else if (weight > w) {
303 return -1;
304 } else {
305 return 1;
306 }
307 }
308 }
309
310
311
312
313 private static class Factory extends ConfigurationFactory {
314
315
316
317
318
319
320
321 @Override
322 public Configuration getConfiguration(String name, URI configLocation) {
323
324 if (configLocation == null) {
325 String config = System.getProperty(CONFIGURATION_FILE_PROPERTY);
326 if (config != null) {
327 ClassLoader loader = this.getClass().getClassLoader();
328 ConfigurationSource source = getInputFromString(config, loader);
329 if (source != null) {
330 for (ConfigurationFactory factory : factories) {
331 String[] types = factory.getSupportedTypes();
332 if (types != null) {
333 for (String type : types) {
334 if (type.equals("*") || config.endsWith(type)) {
335 Configuration c = factory.getConfiguration(source);
336 if (c != null) {
337 return c;
338 }
339 }
340 }
341 }
342 }
343 }
344 }
345 } else {
346 for (ConfigurationFactory factory : factories) {
347 String[] types = factory.getSupportedTypes();
348 if (types != null) {
349 for (String type : types) {
350 if (type.equals("*") || configLocation.getPath().endsWith(type)) {
351 Configuration config = factory.getConfiguration(name, configLocation);
352 if (config != null) {
353 return config;
354 }
355 }
356 }
357 }
358 }
359 }
360
361 Configuration config = getConfiguration(true, name);
362 if (config == null) {
363 config = getConfiguration(true, null);
364 if (config == null) {
365 config = getConfiguration(false, name);
366 if (config == null) {
367 config = getConfiguration(false, null);
368 }
369 }
370 }
371 return config != null ? config : new DefaultConfiguration();
372 }
373
374 private Configuration getConfiguration(boolean isTest, String name) {
375 boolean named = (name != null && name.length() > 0);
376 ClassLoader loader = this.getClass().getClassLoader();
377 for (ConfigurationFactory factory : factories) {
378 String configName;
379 String prefix = isTest ? TEST_PREFIX : DEFAULT_PREFIX;
380 String [] types = factory.getSupportedTypes();
381 if (types == null) {
382 continue;
383 }
384
385 for (String suffix : types) {
386 if (suffix.equals("*")) {
387 continue;
388 }
389 configName = named ? prefix + name + suffix : prefix + suffix;
390
391 ConfigurationSource source = getInputFromResource(configName, loader);
392 if (source != null) {
393 return factory.getConfiguration(source);
394 }
395 }
396 }
397 return null;
398 }
399
400 @Override
401 public String[] getSupportedTypes() {
402 return null;
403 }
404
405 @Override
406 public Configuration getConfiguration(ConfigurationSource source) {
407 if (source != null) {
408 String config = source.getLocation();
409 for (ConfigurationFactory factory : factories) {
410 String[] types = factory.getSupportedTypes();
411 if (types != null) {
412 for (String type : types) {
413 if (type.equals("*") || (config != null && config.endsWith(type))) {
414 Configuration c = factory.getConfiguration(source);
415 if (c != null) {
416 return c;
417 } else {
418 LOGGER.error("Cannot determine the ConfigurationFactory to use for {}", config);
419 return null;
420 }
421 }
422 }
423 }
424 }
425 }
426 LOGGER.error("Cannot process configuration, input source is null");
427 return null;
428 }
429 }
430
431 public static class ConfigurationSource {
432
433 private File file;
434
435 private String location;
436
437 private InputStream stream;
438
439 public ConfigurationSource() {
440 }
441
442 public ConfigurationSource(InputStream stream) {
443 this.stream = stream;
444 this .file = null;
445 this.location = null;
446 }
447
448 public ConfigurationSource(InputStream stream, File file) {
449 this.stream = stream;
450 this.file = file;
451 this.location = file.getAbsolutePath();
452 }
453
454 public ConfigurationSource(InputStream stream, String location) {
455 this.stream = stream;
456 this.location = location;
457 this.file = null;
458 }
459
460 public File getFile() {
461 return file;
462 }
463
464 public void setFile(File file) {
465 this.file = file;
466 }
467
468 public String getLocation() {
469 return location;
470 }
471
472 public void setLocation(String location) {
473 this.location = location;
474 }
475
476 public InputStream getInputStream() {
477 return stream;
478 }
479
480 public void setInputStream(InputStream stream) {
481 this.stream = stream;
482 }
483 }
484 }