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.HashSet;
24 import java.util.Properties;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantLock;
27
28 import org.apache.logging.log4j.Logger;
29 import org.apache.logging.log4j.spi.Provider;
30 import org.apache.logging.log4j.status.StatusLogger;
31
32
33
34
35
36
37
38 public final class ProviderUtil {
39
40
41
42
43 protected static final String PROVIDER_RESOURCE = "META-INF/log4j-provider.properties";
44 private static final String API_VERSION = "Log4jAPIVersion";
45
46 private static final String[] COMPATIBLE_API_VERSIONS = {
47 "2.0.0", "2.1.0"
48 };
49
50 private static final Logger LOGGER = StatusLogger.getLogger();
51
52 protected static final Collection<Provider> PROVIDERS = new HashSet<Provider>();
53
54
55
56
57
58
59 protected static final Lock STARTUP_LOCK = new ReentrantLock();
60
61
62 private static volatile ProviderUtil INSTANCE;
63
64 private ProviderUtil() {
65 for (final LoaderUtil.UrlResource resource : LoaderUtil.findUrlResources(PROVIDER_RESOURCE)) {
66 loadProvider(resource.getUrl(), resource.getClassLoader());
67 }
68 }
69
70
71
72
73
74
75
76
77 protected static void loadProvider(final URL url, final ClassLoader cl) {
78 try {
79 final Properties props = PropertiesUtil.loadClose(url.openStream(), url);
80 if (validVersion(props.getProperty(API_VERSION))) {
81 PROVIDERS.add(new Provider(props, url, cl));
82 }
83 } catch (final IOException e) {
84 LOGGER.error("Unable to open {}", url, e);
85 }
86 }
87
88
89
90
91 @Deprecated
92 protected static void loadProviders(final Enumeration<URL> urls, final ClassLoader cl) {
93 if (urls != null) {
94 while (urls.hasMoreElements()) {
95 loadProvider(urls.nextElement(), cl);
96 }
97 }
98 }
99
100 public static Iterable<Provider> getProviders() {
101 lazyInit();
102 return PROVIDERS;
103 }
104
105 public static boolean hasProviders() {
106 lazyInit();
107 return !PROVIDERS.isEmpty();
108 }
109
110
111
112
113
114
115 protected static void lazyInit() {
116
117 if (INSTANCE == null) {
118 try {
119 STARTUP_LOCK.lockInterruptibly();
120 try {
121 if (INSTANCE == null) {
122 INSTANCE = new ProviderUtil();
123 }
124 } finally {
125 STARTUP_LOCK.unlock();
126 }
127 } catch (final InterruptedException e) {
128 LOGGER.fatal("Interrupted before Log4j Providers could be loaded.", e);
129 Thread.currentThread().interrupt();
130 }
131 }
132 }
133
134 public static ClassLoader findClassLoader() {
135 return LoaderUtil.getThreadContextClassLoader();
136 }
137
138 private static boolean validVersion(final String version) {
139 for (final String v : COMPATIBLE_API_VERSIONS) {
140 if (version.startsWith(v)) {
141 return true;
142 }
143 }
144 return false;
145 }
146 }