1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.spi;
18
19 import java.lang.ref.WeakReference;
20 import java.net.URL;
21 import java.util.Properties;
22
23 import org.apache.logging.log4j.Logger;
24 import org.apache.logging.log4j.status.StatusLogger;
25
26
27
28
29
30
31 public class Provider {
32
33
34
35 public static final String FACTORY_PRIORITY = "FactoryPriority";
36
37
38
39 public static final String THREAD_CONTEXT_MAP = "ThreadContextMap";
40
41
42
43 public static final String LOGGER_CONTEXT_FACTORY = "LoggerContextFactory";
44
45 private static final Integer DEFAULT_PRIORITY = Integer.valueOf(-1);
46 private static final Logger LOGGER = StatusLogger.getLogger();
47
48 private final Integer priority;
49 private final String className;
50 private final Class<? extends LoggerContextFactory> loggerContextFactoryClass;
51 private final String threadContextMap;
52 private final Class<? extends ThreadContextMap> threadContextMapClass;
53 private final String versions;
54 private final URL url;
55 private final WeakReference<ClassLoader> classLoader;
56
57 public Provider(final Properties props, final URL url, final ClassLoader classLoader) {
58 this.url = url;
59 this.classLoader = new WeakReference<>(classLoader);
60 final String weight = props.getProperty(FACTORY_PRIORITY);
61 priority = weight == null ? DEFAULT_PRIORITY : Integer.valueOf(weight);
62 className = props.getProperty(LOGGER_CONTEXT_FACTORY);
63 threadContextMap = props.getProperty(THREAD_CONTEXT_MAP);
64 loggerContextFactoryClass = null;
65 threadContextMapClass = null;
66 versions = null;
67 }
68
69 public Provider(final Integer priority, final String versions,
70 final Class<? extends LoggerContextFactory> loggerContextFactoryClass) {
71 this(priority, versions, loggerContextFactoryClass, null);
72 }
73
74
75 public Provider(final Integer priority, final String versions,
76 final Class<? extends LoggerContextFactory> loggerContextFactoryClass,
77 final Class<? extends ThreadContextMap> threadContextMapClass) {
78 this.url = null;
79 this.classLoader = null;
80 this.priority = priority;
81 this.loggerContextFactoryClass = loggerContextFactoryClass;
82 this.threadContextMapClass = threadContextMapClass;
83 this.className = null;
84 this.threadContextMap = null;
85 this.versions = versions;
86 }
87
88
89
90
91
92 public String getVersions() {
93 return versions;
94 }
95
96
97
98
99
100
101 public Integer getPriority() {
102 return priority;
103 }
104
105
106
107
108
109
110
111 public String getClassName() {
112 if (loggerContextFactoryClass != null) {
113 return loggerContextFactoryClass.getName();
114 }
115 return className;
116 }
117
118
119
120
121
122
123 public Class<? extends LoggerContextFactory> loadLoggerContextFactory() {
124 if (loggerContextFactoryClass != null) {
125 return loggerContextFactoryClass;
126 }
127 if (className == null) {
128 return null;
129 }
130 final ClassLoader loader = classLoader.get();
131 if (loader == null) {
132 return null;
133 }
134 try {
135 final Class<?> clazz = loader.loadClass(className);
136 if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
137 return clazz.asSubclass(LoggerContextFactory.class);
138 }
139 } catch (final Exception e) {
140 LOGGER.error("Unable to create class {} specified in {}", className, url.toString(), e);
141 }
142 return null;
143 }
144
145
146
147
148
149
150 public String getThreadContextMap() {
151 if (threadContextMapClass != null) {
152 return threadContextMapClass.getName();
153 }
154 return threadContextMap;
155 }
156
157
158
159
160
161
162 public Class<? extends ThreadContextMap> loadThreadContextMap() {
163 if (threadContextMapClass != null) {
164 return threadContextMapClass;
165 }
166 if (threadContextMap == null) {
167 return null;
168 }
169 final ClassLoader loader = classLoader.get();
170 if (loader == null) {
171 return null;
172 }
173 try {
174 final Class<?> clazz = loader.loadClass(threadContextMap);
175 if (ThreadContextMap.class.isAssignableFrom(clazz)) {
176 return clazz.asSubclass(ThreadContextMap.class);
177 }
178 } catch (final Exception e) {
179 LOGGER.error("Unable to create class {} specified in {}", threadContextMap, url.toString(), e);
180 }
181 return null;
182 }
183
184
185
186
187
188
189 public URL getUrl() {
190 return url;
191 }
192
193 @Override
194 public String toString() {
195 final StringBuilder result = new StringBuilder("Provider[");
196 if (!DEFAULT_PRIORITY.equals(priority)) {
197 result.append("priority=").append(priority).append(", ");
198 }
199 if (threadContextMap != null) {
200 result.append("threadContextMap=").append(threadContextMap).append(", ");
201 } else if (threadContextMapClass != null) {
202 result.append("threadContextMapClass=").append(threadContextMapClass.getName());
203 }
204 if (className != null) {
205 result.append("className=").append(className).append(", ");
206 } else if (loggerContextFactoryClass != null) {
207 result.append("class=").append(loggerContextFactoryClass.getName());
208 }
209 if (url != null) {
210 result.append("url=").append(url);
211 }
212 final ClassLoader loader;
213 if (classLoader == null || (loader = classLoader.get()) == null) {
214 result.append(", classLoader=null(not reachable)");
215 } else {
216 result.append(", classLoader=").append(loader);
217 }
218 result.append("]");
219 return result.toString();
220 }
221
222 @Override
223 public boolean equals(final Object o) {
224 if (this == o) {
225 return true;
226 }
227 if (o == null || getClass() != o.getClass()) {
228 return false;
229 }
230
231 final Provider provider = (Provider) o;
232
233 if (priority != null ? !priority.equals(provider.priority) : provider.priority != null) {
234 return false;
235 }
236 if (className != null ? !className.equals(provider.className) : provider.className != null) {
237 return false;
238 }
239 if (loggerContextFactoryClass != null ? !loggerContextFactoryClass.equals(provider.loggerContextFactoryClass) : provider.loggerContextFactoryClass != null) {
240 return false;
241 }
242 return versions != null ? versions.equals(provider.versions) : provider.versions == null;
243 }
244
245 @Override
246 public int hashCode() {
247 int result = priority != null ? priority.hashCode() : 0;
248 result = 31 * result + (className != null ? className.hashCode() : 0);
249 result = 31 * result + (loggerContextFactoryClass != null ? loggerContextFactoryClass.hashCode() : 0);
250 result = 31 * result + (versions != null ? versions.hashCode() : 0);
251 return result;
252 }
253 }