1 package br.ufsc.tlm.j2me.logging;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.util.Hashtable;
7
8 import javax.microedition.rms.RecordStore;
9 import javax.microedition.rms.RecordStoreException;
10
11 /***
12 * Created on Aug 26, 2003
13 * @author Eric Giguere
14 * Implemented by Thiago Lećo Moreira <thiago.leao.moreira@terra.com.br> from the article "A Simple MIDP Logging Facility"
15 * avaiable in http://wireless.java.sun.com/midp/ttips/logging/
16 */
17 public class Logger {
18
19 //Static data
20 private static Hashtable loggers = new Hashtable();
21 private static boolean logToRS = true;
22 private static boolean logToStdout = true;
23 private static Logger root = new Logger("");
24 private static RecordStore rs;
25
26 static {
27 // Initialize the root level
28 loggers.put("", root);
29 root.setParent(null);
30 root.setLevel(Level.INFO);
31 }
32
33 //Instance data
34 private Level level;
35 private String name;
36 private Logger parent;
37 private int version;
38
39 /***
40 * Call to close the log.
41 */
42 public static void closeLog() {
43 try {
44 if (rs != null) {
45 rs.closeRecordStore();
46 }
47 } catch (RecordStoreException e) {
48 }
49 rs = null;
50 }
51
52 /***
53 * Find the logger registered with a specific name.
54 */
55 public static synchronized Logger getLogger(String name) {
56 Logger logger = (Logger) loggers.get(name);
57 if (logger == null) {
58 logger = new Logger(name);
59 loggers.put(name, logger);
60 }
61 return logger;
62 }
63
64 /***
65 * Open the log file if not already open.
66 */
67 private static RecordStore openLog() throws RecordStoreException {
68 if (rs == null) {
69 rs = RecordStore.openRecordStore("log", true);
70 }
71 return rs;
72 }
73
74 /***
75 * Whether or not to log to the record store.
76 */
77 public static void setLogToRS(boolean log) {
78 Logger.logToRS = log;
79 }
80
81 /***
82 * Whether or not to log to System.out.
83 */
84 public static void setLogToStdout(boolean log) {
85 Logger.logToStdout = log;
86 }
87
88 /***
89 * Create a new instance of Logger
90 */
91 private Logger(String name) {
92 this.name = name;
93 }
94
95 /***
96 * Call to clear the log, which must be closed.
97 */
98 public synchronized void clearLog() throws RecordStoreException {
99 RecordStore.deleteRecordStore("log");
100 }
101
102 /***
103 * Finds the logger's parent by parsing the name into parts separated by '.'
104 */
105 private Logger findParent(String name) {
106 if (name == null || name.length() == 0) {
107 return null;
108 }
109 Logger parent;
110 synchronized (loggers) {
111 while (true) {
112 int pos = name.lastIndexOf('.');
113 if (pos < 0) {
114 parent = root;
115 break;
116 }
117
118 String pname = name.substring(0, pos);
119 parent = (Logger) loggers.get(pname);
120 if (parent != null) {
121 break;
122 }
123 name = pname;
124 }
125 }
126
127 return parent;
128 }
129
130 /***
131 * Log a message with the FINE level.
132 */
133 public void fine(String msg) {
134 log(Level.FINE, msg);
135 }
136
137 /***
138 * Get this logger's level, which may be null.
139 */
140 public Level getLevel() {
141 return level;
142 }
143
144 /***
145 * Return the logger's name.
146 */
147 public String getName() {
148 return name;
149 }
150
151 /***
152 * Return the logger's parent. The parent is reset if other loggers were created, in
153 * case children are created after their parents.
154 */
155 public Logger getParent() {
156 if (loggers.size() != version) {
157 setParent(findParent(name));
158 }
159 return parent;
160 }
161
162 /***
163 * Log a message with the INFO level.
164 */
165 public void info(String msg) {
166 log(Level.INFO, msg);
167 }
168
169 /***
170 * Test whether the given level is loggable according to this Logger.
171 */
172 public boolean isLoggable(Level test) {
173 if (test == null) {
174 return false;
175 }
176 Logger curr = this;
177 while (curr != null) {
178 Level actual = curr.getLevel();
179 if (actual != null) {
180 if (actual == Level.OFF) {
181 return false;
182 }
183 return (test.intValue() >= actual.intValue());
184 }
185 curr = curr.getParent();
186 }
187 return false;
188 }
189
190 /***
191 * Log a message using the given level.
192 */
193 public void log(Level level, String msg) {
194 log(level, msg, null);
195 }
196
197 /***
198 * Log a message using the given level including optional exception information.
199 */
200 public void log(Level level, String msg, Throwable e) {
201 if (level == null) {
202 level = Level.FINE;
203 }
204 if (!isLoggable(level)) {
205 return;
206 }
207 long time = System.currentTimeMillis();
208 String tname = Thread.currentThread().toString();
209
210 if (Logger.logToStdout) {
211 String tmp = msg;
212 if (e != null) {
213 tmp = msg + " " + e;
214 }
215 System.out.println(time + " " + tname + " " + level + " " + tmp);
216 }
217
218 if (!Logger.logToRS) {
219 return;
220 }
221
222 // Prepare the data
223 ByteArrayOutputStream bout = new ByteArrayOutputStream();
224 DataOutputStream dout = new DataOutputStream(bout);
225 try {
226 dout.writeInt(level.intValue());
227 dout.writeLong(System.currentTimeMillis());
228 dout.writeUTF(Thread.currentThread().toString());
229 dout.writeUTF(msg != null ? msg : "");
230 dout.writeUTF(e != null ? e.toString() : "");
231 dout.flush();
232 } catch (IOException ex) {
233 }
234 byte[] data = bout.toByteArray();
235
236 // Write it out
237 synchronized (this) {
238 RecordStore rs = null;
239 boolean closeIt = (rs == null);
240
241 try {
242 rs = openLog();
243 rs.addRecord(data, 0, data.length);
244 } catch (RecordStoreException ex) {
245 } finally {
246 if (closeIt) {
247 closeLog();
248 }
249 }
250 }
251 }
252
253 /***
254 * Sets the logger's level. May be null.
255 */
256 public void setLevel(Level level) {
257 this.level = level;
258 }
259
260 /***
261 * Sets the logger's parent.
262 */
263 public void setParent(Logger parent) {
264 this.parent = parent;
265 version = loggers.size();
266 }
267
268 /***
269 * Log a message with the SEVERE level.
270 */
271 public void severe(String msg) {
272 log(Level.SEVERE, msg);
273 }
274
275 /***
276 * Log a message with the WARNING level.
277 */
278 public void warning(String msg) {
279 log(Level.WARNING, msg);
280 }
281
282 }
This page was automatically generated by Maven