1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.util;
18
19 import java.io.IOException;
20 import java.net.URL;
21 import java.util.Collection;
22 import java.util.Enumeration;
23 import java.util.Properties;
24 import java.util.concurrent.CopyOnWriteArraySet;
25
26 import org.apache.logging.log4j.Logger;
27 import org.apache.logging.log4j.spi.Provider;
28 import org.apache.logging.log4j.status.StatusLogger;
29
30
31
32
33 public final class ProviderUtil {
34
35
36
37
38 protected static final String PROVIDER_RESOURCE = "META-INF/log4j-provider.properties";
39 private static final String API_VERSION = "Log4jAPIVersion";
40
41 private static final String[] COMPATIBLE_API_VERSIONS = {
42 "2.0.0"
43 };
44
45 private static final Logger LOGGER = StatusLogger.getLogger();
46
47 private static final Collection<Provider> PROVIDERS = new CopyOnWriteArraySet<Provider>();
48
49 private ProviderUtil() {
50 }
51
52 static {
53 final ClassLoader cl = findClassLoader();
54 Enumeration<URL> enumResources = null;
55 try {
56 enumResources = cl.getResources(PROVIDER_RESOURCE);
57 } catch (final IOException e) {
58 LOGGER.fatal("Unable to locate {}", PROVIDER_RESOURCE, e);
59 }
60 loadProviders(enumResources, cl);
61 }
62
63 protected static void loadProviders(final Enumeration<URL> enumResources, ClassLoader cl) {
64 if (enumResources != null) {
65 while (enumResources.hasMoreElements()) {
66 final URL url = enumResources.nextElement();
67 loadProvider(url, cl);
68 }
69 }
70 }
71
72
73
74
75
76
77
78
79 protected static void loadProvider(final URL url, final ClassLoader cl) {
80 try {
81 final Properties props = PropertiesUtil.loadClose(url.openStream(), url);
82 if (validVersion(props.getProperty(API_VERSION))) {
83 PROVIDERS.add(new Provider(props, url, cl));
84 }
85 } catch (final IOException e) {
86 LOGGER.error("Unable to open {}", url, e);
87 }
88 }
89
90 public static Iterable<Provider> getProviders() {
91 return PROVIDERS;
92 }
93
94 public static boolean hasProviders() {
95 return !PROVIDERS.isEmpty();
96 }
97
98 public static ClassLoader findClassLoader() {
99 return LoaderUtil.getThreadContextClassLoader();
100 }
101
102 private static boolean validVersion(final String version) {
103 for (final String v : COMPATIBLE_API_VERSIONS) {
104 if (version.startsWith(v)) {
105 return true;
106 }
107 }
108 return false;
109 }
110 }