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