View Javadoc

1   /**
2    *  MicroEmulator
3    *  Copyright (C) 2001-2007 Bartek Teodorczyk <barteo@barteo.net>
4    *  Copyright (C) 2006-2007 Vlad Skarzhevskyy
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or (at your option) any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   *  @version $Id: Logger.java 1557 2008-01-30 15:42:52Z barteo $
21   */
22  package org.microemu.log;
23  
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Set;
28  import java.util.Vector;
29  
30  /**
31   * 
32   * This class is used as abstraction layer for log messages Minimum Log4j
33   * implemenation with multiple overloaded functions
34   * 
35   * @author vlads
36   * 
37   */
38  public class Logger {
39  
40  	private static final String FQCN = Logger.class.getName();
41  
42  	private static final Set fqcnSet = new HashSet();
43  
44  	private static final Set logFunctionsSet = new HashSet();
45  
46  	private static boolean java13 = false;
47  	
48  	private static boolean locationEnabled = true;
49  
50  	private static List loggerAppenders = new Vector();
51  
52  	static {
53  		fqcnSet.add(FQCN);
54  		// Message class can be moved to different sub project, See call to
55  		// addLogOrigin
56  		// Also Message calss can be refactored by ProGuard
57  		// fqcnSet.add("org.microemu.app.ui.Message");
58  
59  		addAppender(new StdOutAppender());
60  
61  		// This is done for MIDletInternlaLogger a wrapper for
62  		// System.out.println functions.
63  		logFunctionsSet.add("debug");
64  		logFunctionsSet.add("log");
65  		logFunctionsSet.add("error");
66  		logFunctionsSet.add("fatal");
67  		logFunctionsSet.add("info");
68  		logFunctionsSet.add("warn");
69  	}
70  
71  	public static boolean isDebugEnabled() {
72  		return true;
73  	}
74  
75  	public static boolean isErrorEnabled() {
76  		return true;
77  	}
78  	
79  	public static boolean isLocationEnabled() {
80  		return locationEnabled;
81  	}
82  	
83  	public static void setLocationEnabled(boolean state) {
84  		locationEnabled = state;
85  	}
86  
87  	private static StackTraceElement getLocation() {
88  		if (java13 || !locationEnabled) {
89  			return null;
90  		}
91  		try {
92  			StackTraceElement[] ste = new Throwable().getStackTrace();
93  			boolean wrapperFound = false;
94  			for (int i = 0; i < ste.length - 1; i++) {
95  				if (fqcnSet.contains(ste[i].getClassName())) {
96  					wrapperFound = false;
97  					String nextClassName = ste[i + 1].getClassName();
98  					if (nextClassName.startsWith("java.") || nextClassName.startsWith("sun.")) {
99  						continue;
100 					}
101 					if (!fqcnSet.contains(nextClassName)) {
102 						if (logFunctionsSet.contains(ste[i + 1].getMethodName())) {
103 							wrapperFound = true;
104 						} else {
105 							// if dynamic proxy classes
106 							if (nextClassName.startsWith("$Proxy")) {
107 								return ste[i + 2];
108 							} else {
109 								return ste[i + 1];
110 							}
111 						}
112 					}
113 				} else if (wrapperFound) {
114 					if (!logFunctionsSet.contains(ste[i].getMethodName())) {
115 						return ste[i];
116 					}
117 				}
118 			}
119 			return ste[ste.length - 1];
120 		} catch (Throwable e) {
121 			java13 = true;
122 		}
123 		return null;
124 	}
125 
126 	private static void write(int level, String message, Throwable throwable) {
127 		callAppenders(new LoggingEvent(level, message, getLocation(), throwable));
128 	}
129 
130 	private static void write(int level, String message, Throwable throwable, Object data) {
131 		callAppenders(new LoggingEvent(level, message, getLocation(), throwable, data));
132 	}
133 
134 	public static void debug(String message) {
135 		if (isDebugEnabled()) {
136 			write(LoggingEvent.DEBUG, message, null);
137 		}
138 	}
139 
140 	public static void debug(String message, Throwable t) {
141 		if (isDebugEnabled()) {
142 			write(LoggingEvent.DEBUG, message, t);
143 		}
144 	}
145 
146 	public static void debug(Throwable t) {
147 		if (isDebugEnabled()) {
148 			write(LoggingEvent.DEBUG, "error", t);
149 		}
150 	}
151 
152 	public static void debug(String message, String v) {
153 		if (isDebugEnabled()) {
154 			write(LoggingEvent.DEBUG, message, null, v);
155 		}
156 	}
157 
158 	public static void debug(String message, Object o) {
159 		if (isDebugEnabled()) {
160 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper(o));
161 		}
162 	}
163 
164 	public static void debug(String message, String v1, String v2) {
165 		if (isDebugEnabled()) {
166 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper(v1, v2));
167 		}
168 	}
169 
170 	public static void debug(String message, long v) {
171 		if (isDebugEnabled()) {
172 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper(v));
173 		}
174 	}
175 
176 	public static void debug0x(String message, long v) {
177 		if (isDebugEnabled()) {
178 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper("0x" + Long.toHexString(v)));
179 		}
180 	}
181 
182 	public static void debug(String message, long v1, long v2) {
183 		if (isDebugEnabled()) {
184 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper(v1, v2));
185 		}
186 	}
187 
188 	public static void debug(String message, boolean v) {
189 		if (isDebugEnabled()) {
190 			write(LoggingEvent.DEBUG, message, null, new LoggerDataWrapper(v));
191 		}
192 	}
193 
194 	public static void debugClassLoader(String message, Object obj) {
195 		if (obj == null) {
196 			write(LoggingEvent.DEBUG, message + " no class, no object", null, null);
197 			return;
198 		}
199 		Class klass;
200 		StringBuffer buf = new StringBuffer();
201 		buf.append(message).append(" ");
202 		if (obj instanceof Class) {
203 			klass = (Class) obj;
204 			buf.append("class ");
205 		} else {
206 			klass = obj.getClass();
207 			buf.append("instance ");
208 		}
209 		buf.append(klass.getName() + " loaded by ");
210 		if (klass.getClassLoader() != null) {
211 			buf.append(klass.getClassLoader().hashCode());
212 			buf.append(" ");
213 			buf.append(klass.getClassLoader().getClass().getName());
214 		} else {
215 			buf.append("system");
216 		}
217 		write(LoggingEvent.DEBUG, buf.toString(), null, null);
218 	}
219 
220 	public static void info(String message) {
221 		if (isErrorEnabled()) {
222 			write(LoggingEvent.INFO, message, null);
223 		}
224 	}
225 
226 	public static void info(String message, String data) {
227 		if (isErrorEnabled()) {
228 			write(LoggingEvent.INFO, message, null, data);
229 		}
230 	}
231 
232 	public static void warn(String message) {
233 		if (isErrorEnabled()) {
234 			write(LoggingEvent.WARN, message, null);
235 		}
236 	}
237 
238 	public static void error(String message) {
239 		if (isErrorEnabled()) {
240 			write(LoggingEvent.ERROR, "error " + message, null);
241 		}
242 	}
243 
244 	public static void error(String message, long v) {
245 		if (isErrorEnabled()) {
246 			write(LoggingEvent.ERROR, "error " + message, null, new LoggerDataWrapper(v));
247 		}
248 	}
249 
250 	public static void error(String message, String v) {
251 		if (isErrorEnabled()) {
252 			write(LoggingEvent.ERROR, "error " + message, null, v);
253 		}
254 	}
255 
256 	public static void error(String message, String v, Throwable t) {
257 		if (isErrorEnabled()) {
258 			write(LoggingEvent.ERROR, "error " + message, t, v);
259 		}
260 	}
261 
262 	public static void error(Throwable t) {
263 		if (isErrorEnabled()) {
264 			write(LoggingEvent.ERROR, "error " + t.toString(), t);
265 		}
266 	}
267 
268 	public static void error(String message, Throwable t) {
269 		if (isErrorEnabled()) {
270 			write(LoggingEvent.ERROR, "error " + message + " " + t.toString(), t);
271 		}
272 	}
273 
274 	private static void callAppenders(LoggingEvent event) {
275 		for (Iterator iter = loggerAppenders.iterator(); iter.hasNext();) {
276 			LoggerAppender a = (LoggerAppender) iter.next();
277 			a.append(event);
278 		}
279 		;
280 	}
281 
282 	/**
283 	 * Add the Class which serves as entry point for log message location.
284 	 * 
285 	 * @param origin
286 	 *            Class
287 	 */
288 	public static void addLogOrigin(Class origin) {
289 		fqcnSet.add(origin.getName());
290 	}
291 
292 	public static void addAppender(LoggerAppender newAppender) {
293 		loggerAppenders.add(newAppender);
294 	}
295 
296 	public static void removeAppender(LoggerAppender appender) {
297 		loggerAppenders.remove(appender);
298 	}
299 
300 	public static void removeAllAppenders() {
301 		loggerAppenders.clear();
302 	}
303 
304 }