001package arcommon.exception;
002
003import java.awt.event.ActionEvent;
004import java.awt.event.ActionListener;
005import java.io.File;
006import java.util.ArrayList;
007import java.util.Date;
008import java.util.Iterator;
009import java.util.List;
010
011import arcommon.DateUtil;
012import arcommon.FileUtil;
013import arcommon.StringUtil;
014
015public class MyLog {
016    public static final int ERROR = 3;
017    public static final int WARNING = 2;
018    public static final int INFO = 1;
019    public static final int CHECKPOINT = 0;
020    
021    public static final String NEWLINE_REPLACEMENT = "<newline>";
022
023    public static String logFileName;
024    public static String logFileEncoding = "UTF-8";
025
026    private static ArrayList<ActionListener> actionListeners;
027    
028    private static boolean logToFile = true;
029    private static int logLevel = CHECKPOINT;
030    
031    public static void setLogToFile(boolean plogToFile) {
032        logToFile = plogToFile;
033    }
034    
035    public static boolean getLogToFile() {
036        return logToFile;
037    }
038
039    public static void setLogLevel(int plogLevel) {
040        logLevel = plogLevel;
041    }
042
043    public static int getLogLevel() {
044        return logLevel;
045    }
046    
047    public static void logLine(String text, int type) {
048        logLine(text, type, 4, null);
049    }
050    
051    public static synchronized void logLine(String text, int type, int stackOffset, String timeString) {
052        if (type < logLevel) {
053            return ;
054        }
055        
056        String line = "On the ";
057        if (timeString == null) {
058            line = line + DateUtil.dateToDateAndTimeString(new Date());
059        } else {
060            line = line + timeString;
061        }
062
063        if (text == null) {
064            text = "";
065        }
066        
067        if (!text.endsWith(System.getProperty("line.separator"))) {
068            text = "\"" + text + "\" ";
069        }
070
071        switch (type) {
072            case ERROR :
073                if (text.equals("")) {
074                    line = line + " an     ERROR     occurred ";
075                } else {
076                    line = line + " the    ERROR     " + text + "was logged ";
077                }
078            break;
079            case WARNING :
080                if (text.equals("")) {
081                    line = line + " an    WARNING    was send from ";
082                } else {
083                    line = line + " the   WARNING    " + text + "was logged ";
084                }
085            break;
086            case INFO :
087                line = line + " the  INFOMATION  " + text + "was logged ";
088            break;
089            case CHECKPOINT :
090                if (text.equals("")) {
091                    line = line + " the  CHECKPOINT  in ";
092                } else {
093                    line = line + " the  CHECKPOINT  " + text;
094                }
095            break;
096            default :
097                throw new RuntimeException("Unknown type");
098        }
099
100        String stack = ExceptionUtil.stackToString(stackOffset);
101        stack = StringUtil.replace(stack, "\r\n", NEWLINE_REPLACEMENT);
102        stack = StringUtil.replace(stack, "\n", NEWLINE_REPLACEMENT);
103        stack = StringUtil.replace(stack, "\t", "    ");
104
105        line = line + NEWLINE_REPLACEMENT + stack;
106
107        if (type == CHECKPOINT) {
108            line = line + " was passed";
109        }
110        
111        if (!line.endsWith("\n")) {
112            line += "\n";
113        }
114
115        if (actionListeners != null) {
116            Iterator<ActionListener> i = actionListeners.iterator();
117            ActionEvent e = new ActionEvent(line, 0, line);
118            while (i.hasNext()) {
119                ActionListener actionListener = i.next();
120                actionListener.actionPerformed(e);
121            }
122        }
123        
124        if (logToFile) {
125            if (logFileName == null) {
126                throw new RuntimeException("LOG_FILE_NAME == null");
127            }
128    
129            File file = new File(logFileName).getParentFile();
130            if (file != null) {
131                FileUtil.mkdirs(file);
132            }
133            
134            FileUtil.writeFile(logFileName, line, true, logFileEncoding);
135        }
136    }
137
138    public static List<String> getLog() {
139        if (logFileName == null) {
140            throw new RuntimeException("LOG_FILE_NAME == null");
141        }
142
143        if (!new File(logFileName).exists()) {
144            return new ArrayList<String>();
145        }
146
147        return FileUtil.readLinesInFile(logFileName, logFileEncoding);
148    }
149
150    public static void logError() {
151        logLine(null, ERROR, 4, null);
152    }
153
154    public static void logError(String text) {
155        logLine(text, ERROR, 4, null);
156    }
157
158    public static void logWarning() {
159        logLine(null, WARNING, 4, null);
160    }
161
162    public static void logWarning(String text) {
163        logLine(text, WARNING, 4, null);
164    }
165
166    public static void logInfo(String info) {
167        logLine(info, INFO, 4, null);
168    }
169    
170    public static void logCheckpoint() {
171        logLine(null, CHECKPOINT, 4, null);
172    }
173
174    public static void logCheckpoint(String text) {
175        logLine(text, CHECKPOINT, 4, null);
176    }
177
178    public static void logException(Exception e) {
179        logException(new ExceptionData(e));
180    }
181
182    public static void logException(Thread t, Throwable e) {
183        logExceptionLocal(new ExceptionData(t, e));
184    }
185    
186    public static void logException(ExceptionData exceptionData) { // This is done to make the stack offset the same
187        logExceptionLocal(exceptionData);
188    }
189    
190    private static void logExceptionLocal(ExceptionData exceptionData) {
191        String exceptionString = exceptionData.exceptionStackToString(false);
192        logLine(exceptionString, ERROR, 5, exceptionData.getTimeString());
193    }
194
195    // NOTE: Is fired just before the log file is updated.
196    public static void addActionListener(ActionListener pactionListener) {
197        if (actionListeners == null) {
198            actionListeners = new ArrayList<ActionListener>();
199        }
200        actionListeners.add(pactionListener);
201    }
202    
203    public static void removeActionListener(ActionListener pactionListener) {
204        if (actionListeners == null) {
205            return ;
206        }
207        actionListeners.remove(pactionListener);
208        if (actionListeners.size() == 0) {
209            actionListeners = null;
210        }
211    }
212}