001: package org.swingml.system;
002:
003: import java.io.*;
004: import java.text.*;
005: import java.util.*;
006:
007: /**
008: * An encompasing class mainly providing logging capabilities for SwingML components and services.
009: *
010: * @author NumberSix
011: */
012: public class SwingMLLogger implements ILogCapable {
013:
014: private static SwingMLLogger instance = null;
015: private static String logDirectory = null;
016: private final static int NUM_LOGS_TO_KEEP = 7;
017:
018: public static SwingMLLogger getInstance() {
019: if (instance == null) {
020: instance = new SwingMLLogger();
021: }
022: return instance;
023: }
024:
025: public static String getLogDirectory() {
026: return logDirectory;
027: }
028:
029: public static SwingMLLogger getNewInstance(String appName,
030: String logDir) throws SwingMLLoggerException {
031: if (instance == null) {
032: instance = new SwingMLLogger(appName, logDir);
033: }
034: return instance;
035: }
036:
037: private static void setLogDirectory(String logDir) {
038: SwingMLLogger.logDirectory = logDir;
039: }
040:
041: private int defaultLevel = ILogCapable.TRIVIAL;
042: private List printStreams = new ArrayList();
043: private boolean started = false;
044:
045: private SwingMLLogger() {
046: super ();
047: setDefaultLevel(ILogCapable.INFO);
048: start();
049: }
050:
051: private SwingMLLogger(String appName, String logDir)
052: throws SwingMLLoggerException {
053: super ();
054: createLogFiles(appName, logDir);
055: setDefaultLevel(ILogCapable.INFO);
056: start();
057: cleanOldLogs(appName, logDir);
058: }
059:
060: private void addPrintStream(PrintStream printStream) {
061: if (!getPrintStreams().contains(printStream)) {
062: getPrintStreams().add(printStream);
063: }
064: }
065:
066: /**
067: * @param logDirectory
068: */
069: private void checkDirectory(String logDir)
070: throws SwingMLLoggerException {
071: String userName = System.getProperty("user.name");
072: File directory = new File(logDir + "/" + userName);
073: if (!directory.exists()) {
074: if (!directory.mkdirs()) {
075: throw new SwingMLLoggerException(
076: "Specified directory ["
077: + logDir
078: + "] does not exist and could not be created.");
079: }
080: }
081: setLogDirectory(directory.getAbsolutePath());
082: }
083:
084: private void cleanOldLogs(String appName, String logDir) {
085: String fileName = getPastErrorFileName(appName, logDir);
086: File errLog = new File(fileName);
087: if (errLog.exists() && errLog.isFile()) {
088: if (!errLog.delete()) {
089: log(ILogCapable.WARN,
090: "Failed to delete the error log file: "
091: + fileName);
092: }
093: }
094:
095: fileName = getPastStandardFileName(appName, logDir);
096: File outLog = new File(fileName);
097: if (outLog.exists() && outLog.isFile()) {
098: if (!outLog.delete()) {
099: log(ILogCapable.WARN,
100: "Failed to delete the standard log file: "
101: + fileName);
102: }
103: }
104:
105: }
106:
107: private void createLogFiles(String appName, String logDir)
108: throws SwingMLLoggerException {
109: try {
110: checkDirectory(logDir);
111:
112: System.setErr(new PrintStream(new FileOutputStream(
113: getErrorFileName(appName, logDir), true)));
114: System.setOut(new PrintStream(new FileOutputStream(
115: getStandardFileName(appName, logDir), true)));
116: } catch (IOException e) {
117: throw new SwingMLLoggerException(
118: "Failed to create log files in " + logDir);
119: }
120: }
121:
122: /**
123: * Iterate over the PrintStreams and log to them.
124: *
125: * @param message
126: */
127: private void doLog(String message) {
128: if (isStarted()) {
129: Iterator schmiterator = getPrintStreams().iterator();
130: PrintStream printStream;
131: while (schmiterator.hasNext()) {
132: printStream = (PrintStream) schmiterator.next();
133: printStream.println(message);
134: }
135: }
136: }
137:
138: public void end() {
139: log("SwingMLSystem Logging ended.");
140: setStarted(false);
141: removePrintStream(System.out);
142: removePrintStream(System.err);
143: }
144:
145: public void end(String message) {
146: log(message);
147: setStarted(false);
148: }
149:
150: protected void finalize() throws Throwable {
151: end();
152: }
153:
154: private String getCurrentDateTime() {
155: return new SimpleDateFormat("yyyyMMdd").format(new Date());
156: }
157:
158: public int getDefaultLevel() {
159: return defaultLevel;
160: }
161:
162: private String getErrorFileName(String appName, String logDir) {
163: return getFileName(appName, logDir, "_error_",
164: getCurrentDateTime());
165: }
166:
167: private String getFileName(String appName, String logDir,
168: String logName, String date) {
169: String userName = System.getProperty("user.name");
170: StringBuffer buf = new StringBuffer(logDir);
171: buf.append("/");
172: buf.append(userName);
173: buf.append("/");
174: buf.append(appName);
175: buf.append(logName);
176: buf.append(date);
177: buf.append(".log");
178: return buf.toString();
179: }
180:
181: private String getPastErrorFileName(String appName, String logDir) {
182: return getFileName(appName, logDir, "_error_",
183: getWeekOldDateTime());
184: }
185:
186: private String getPastStandardFileName(String appName, String logDir) {
187: return getFileName(appName, logDir, "_standard_",
188: getWeekOldDateTime());
189: }
190:
191: private List getPrintStreams() {
192: return printStreams;
193: }
194:
195: private String getSeverityName(int severityLevel) {
196: String result = "";
197:
198: if (isValidSeverity(severityLevel)) {
199: switch (severityLevel) {
200: case ILogCapable.TRIVIAL:
201: result = "TRIVIAL";
202: break;
203: case ILogCapable.INFO:
204: result = "INFO";
205: break;
206: case ILogCapable.WARN:
207: result = "WARNING";
208: break;
209: case ILogCapable.DEBUG:
210: result = "DEBUG";
211: break;
212: case ILogCapable.ERROR:
213: result = "ERROR";
214: break;
215: case ILogCapable.FATAL:
216: result = "FATAL";
217: break;
218: }
219: }
220:
221: return result;
222: }
223:
224: private String getStandardFileName(String appName, String logDir) {
225: return getFileName(appName, logDir, "_standard_",
226: getCurrentDateTime());
227: }
228:
229: private String getTimestamp() {
230: return Calendar.getInstance().getTime().toString();
231: }
232:
233: private String getWeekOldDateTime() {
234: GregorianCalendar aDate2 = new GregorianCalendar();
235: aDate2.add(GregorianCalendar.DAY_OF_MONTH,
236: (-1 * NUM_LOGS_TO_KEEP));
237: return new SimpleDateFormat("yyyyMMdd")
238: .format(aDate2.getTime());
239: }
240:
241: public boolean isStarted() {
242: return started;
243: }
244:
245: /**
246: * Returns true if the given severity level is valid.
247: *
248: * @param severityLevel
249: * @return
250: */
251: private boolean isValidSeverity(int severityLevel) {
252: boolean result = false;
253: switch (severityLevel) {
254: case ILogCapable.TRIVIAL:
255: result = true;
256: break;
257: case ILogCapable.DEBUG:
258: result = true;
259: break;
260: case ILogCapable.INFO:
261: result = true;
262: break;
263: case ILogCapable.WARN:
264: result = true;
265: break;
266: case ILogCapable.ERROR:
267: result = true;
268: break;
269: case ILogCapable.FATAL:
270: result = true;
271: break;
272: }
273:
274: return result;
275: }
276:
277: /**
278: * For this implementation, we'll simply always log to Stdout/Stderr, no matter what the severity level is.
279: *
280: */
281: public void log(int severityLevel, Object anObject) {
282: if (anObject instanceof Exception) {
283: // Print a message
284: Exception exception = (Exception) anObject;
285: String message = exception.getMessage();
286: doLog(getTimestamp() + " " + getSeverityName(severityLevel)
287: + ": " + message);
288:
289: if (isStarted()) {
290: // also print stacktaces out
291: Iterator schmiterator = getPrintStreams().iterator();
292: PrintStream printStream;
293: while (schmiterator.hasNext()) {
294: printStream = (PrintStream) schmiterator.next();
295: exception.printStackTrace(printStream);
296: }
297: }
298: } else {
299: // Just print the message
300: doLog(getTimestamp() + " " + getSeverityName(severityLevel)
301: + ": " + anObject);
302: }
303: }
304:
305: /**
306: * For this implementation, we'll simply always log to Stdout/Stderr, no matter what the severity level is.
307: *
308: */
309: public void log(int severityLevel, String message) {
310: doLog(getTimestamp() + " " + getSeverityName(severityLevel)
311: + ": " + message);
312: }
313:
314: public void log(Object anObject) {
315: log(getDefaultLevel(), anObject);
316: }
317:
318: public void log(String message) {
319: log(getDefaultLevel(), message);
320: }
321:
322: private void removePrintStream(PrintStream printStream) {
323: if (getPrintStreams().contains(printStream)) {
324: getPrintStreams().remove(printStream);
325: }
326: }
327:
328: public void setDefaultLevel(int severityLevel) {
329: if (isValidSeverity(severityLevel)) {
330: defaultLevel = severityLevel;
331: } else {
332: System.err
333: .println("Invalid severity level for default logging level.");
334: }
335: }
336:
337: private void setStarted(boolean isStarted) {
338: this .started = isStarted;
339: }
340:
341: public void start() {
342: setStarted(true);
343: addPrintStream(System.out);
344: addPrintStream(System.err);
345: log("SwingMLSystem Logging started.");
346: }
347:
348: public void start(String message) {
349: start();
350: log(message);
351: }
352: }
|