1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.slf4j;
26
27 import java.io.IOException;
28 import java.net.URL;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Enumeration;
32 import java.util.List;
33
34 import org.slf4j.helpers.SubstituteLoggerFactory;
35 import org.slf4j.helpers.Util;
36 import org.slf4j.impl.StaticLoggerBinder;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public final class LoggerFactory {
56
57 static final String NO_STATICLOGGERBINDER_URL = "http://www.slf4j.org/codes.html#StaticLoggerBinder";
58 static final String MULTIPLE_BINDINGS_URL = "http://www.slf4j.org/codes.html#multiple_bindings";
59 static final String NULL_LF_URL = "http://www.slf4j.org/codes.html#null_LF";
60 static final String VERSION_MISMATCH = "http://www.slf4j.org/codes.html#version_mismatch";
61 static final String SUBSTITUTE_LOGGER_URL = "http://www.slf4j.org/codes.html#substituteLogger";
62
63 static final String UNSUCCESSFUL_INIT_URL = "http://www.slf4j.org/codes.html#unsuccessfulInit";
64 static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also "
65 + UNSUCCESSFUL_INIT_URL;
66
67 static final int UNINITIALIZED = 0;
68 static final int ONGOING_INITILIZATION = 1;
69 static final int FAILED_INITILIZATION = 2;
70 static final int SUCCESSFUL_INITILIZATION = 3;
71
72 static final int GET_SINGLETON_INEXISTENT = 1;
73 static final int GET_SINGLETON_EXISTS = 2;
74
75 static int INITIALIZATION_STATE = UNINITIALIZED;
76 static int GET_SINGLETON_METHOD = UNINITIALIZED;
77 static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
78
79
80
81
82
83
84
85
86
87 static private final String[] API_COMPATIBILITY_LIST = new String[] {
88 "1.5.5", "1.5.6", "1.5.7", "1.5.8", "1.5.9", "1.5.10" };
89
90
91 private LoggerFactory() {
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105 static void reset() {
106 INITIALIZATION_STATE = UNINITIALIZED;
107 GET_SINGLETON_METHOD = UNINITIALIZED;
108 TEMP_FACTORY = new SubstituteLoggerFactory();
109 }
110
111 private final static void performInitialization() {
112 bind();
113 versionSanityCheck();
114 singleImplementationSanityCheck();
115
116 }
117
118 private final static void bind() {
119 try {
120
121 getSingleton();
122 INITIALIZATION_STATE = SUCCESSFUL_INITILIZATION;
123 emitSubstituteLoggerWarning();
124 } catch (NoClassDefFoundError ncde) {
125 INITIALIZATION_STATE = FAILED_INITILIZATION;
126 String msg = ncde.getMessage();
127 if (msg != null && msg.indexOf("org/slf4j/impl/StaticLoggerBinder") != -1) {
128 Util
129 .reportFailure("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
130 Util.reportFailure("See " + NO_STATICLOGGERBINDER_URL
131 + " for further details.");
132
133 }
134 throw ncde;
135 } catch (Exception e) {
136 INITIALIZATION_STATE = FAILED_INITILIZATION;
137
138 Util.reportFailure("Failed to instantiate logger ["
139 + getSingleton().getLoggerFactoryClassStr() + "]", e);
140 }
141 }
142
143 private final static void emitSubstituteLoggerWarning() {
144 List loggerNameList = TEMP_FACTORY.getLoggerNameList();
145 if (loggerNameList.size() == 0) {
146 return;
147 }
148 Util
149 .reportFailure("The following loggers will not work becasue they were created");
150 Util
151 .reportFailure("during the default configuration phase of the underlying logging system.");
152 Util.reportFailure("See also " + SUBSTITUTE_LOGGER_URL);
153 for (int i = 0; i < loggerNameList.size(); i++) {
154 String loggerName = (String) loggerNameList.get(i);
155 Util.reportFailure(loggerName);
156 }
157 }
158
159 private final static void versionSanityCheck() {
160 try {
161 String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
162
163 boolean match = false;
164 for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
165 if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
166 match = true;
167 }
168 }
169 if (!match) {
170 Util.reportFailure("The requested version " + requested
171 + " by your slf4j binding is not compatible with "
172 + Arrays.asList(API_COMPATIBILITY_LIST).toString());
173 Util.reportFailure("See " + VERSION_MISMATCH + " for further details.");
174 }
175 } catch (java.lang.NoSuchFieldError nsfe) {
176
177
178
179
180 } catch (Throwable e) {
181
182 Util.reportFailure(
183 "Unexpected problem occured during version sanity check", e);
184 }
185 }
186
187
188
189 private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
190
191 private static void singleImplementationSanityCheck() {
192 try {
193 ClassLoader loggerFactoryClassLoader = LoggerFactory.class
194 .getClassLoader();
195 if (loggerFactoryClassLoader == null) {
196
197 return;
198 }
199 Enumeration paths = loggerFactoryClassLoader
200 .getResources(STATIC_LOGGER_BINDER_PATH);
201 List implementationList = new ArrayList();
202 while (paths.hasMoreElements()) {
203 URL path = (URL) paths.nextElement();
204 implementationList.add(path);
205 }
206 if (implementationList.size() > 1) {
207 Util.reportFailure("Class path contains multiple SLF4J bindings.");
208 for (int i = 0; i < implementationList.size(); i++) {
209 Util.reportFailure("Found binding in [" + implementationList.get(i)
210 + "]");
211 }
212 Util.reportFailure("See " + MULTIPLE_BINDINGS_URL
213 + " for an explanation.");
214 }
215 } catch (IOException ioe) {
216 Util.reportFailure("Error getting resources from path", ioe);
217 }
218 }
219
220 private final static StaticLoggerBinder getSingleton() {
221 if (GET_SINGLETON_METHOD == GET_SINGLETON_INEXISTENT) {
222 return StaticLoggerBinder.SINGLETON;
223 }
224
225 if (GET_SINGLETON_METHOD == GET_SINGLETON_EXISTS) {
226 return StaticLoggerBinder.getSingleton();
227 }
228
229 try {
230 StaticLoggerBinder singleton = StaticLoggerBinder.getSingleton();
231 GET_SINGLETON_METHOD = GET_SINGLETON_EXISTS;
232 return singleton;
233 } catch (NoSuchMethodError nsme) {
234 GET_SINGLETON_METHOD = GET_SINGLETON_INEXISTENT;
235 return StaticLoggerBinder.SINGLETON;
236 }
237 }
238
239
240
241
242
243
244
245
246
247 public static Logger getLogger(String name) {
248 ILoggerFactory iLoggerFactory = getILoggerFactory();
249 return iLoggerFactory.getLogger(name);
250 }
251
252
253
254
255
256
257
258
259
260 public static Logger getLogger(Class clazz) {
261 return getLogger(clazz.getName());
262 }
263
264
265
266
267
268
269
270
271
272 public static ILoggerFactory getILoggerFactory() {
273 if (INITIALIZATION_STATE == UNINITIALIZED) {
274 INITIALIZATION_STATE = ONGOING_INITILIZATION;
275 performInitialization();
276
277 }
278 switch (INITIALIZATION_STATE) {
279 case SUCCESSFUL_INITILIZATION:
280 return getSingleton().getLoggerFactory();
281 case FAILED_INITILIZATION:
282 throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
283 case ONGOING_INITILIZATION:
284
285
286 return TEMP_FACTORY;
287 }
288 throw new IllegalStateException("Unreachable code");
289 }
290 }