001package bradleyross.library.helpers;
002import java.io.StringWriter;
003import java.io.PrintWriter;
004import java.util.List;
005import java.util.Iterator;
006import java.util.ArrayList;
007import java.io.IOException;
008import java.io.LineNumberReader;
009import java.io.StringReader;
010// import java.io.PrintWriter;
011import java.io.PrintStream;
012import java.util.Properties;
013/*
014 * SQLException and SOAPFault are in Java SE library.
015 * SOAPFaultException is in Java EE library.
016 */
017import java.sql.SQLException;
018import javax.xml.ws.soap.SOAPFaultException;
019import javax.xml.soap.SOAPFault;
020import bradleyross.library.helpers.ExceptionProcessor;
021// import java.util.regex.Matcher;
022//  import java.util.regex.Pattern;
023// import java.util.regex.PatternSyntaxException;
024/*
025 * Although this exception is mentioned in the Java EE 6 documentation,
026 * I am unable to find it.  According to 
027 * http://stackoverflow.com/questions/17008188/the-import-javax-xml-rpc-encoding-cannot-be-resolved
028 * this requires the jar files xerces.jar, jaxrpc.jar, and axis.jar.
029 */
030// import javax.xml.rpc.soap.SOAPFaultException;
031/**
032 * An attempt to write a generic exception logger that will
033 * provide both the location of the exception and the location
034 * of the log request.
035 * 
036 * <p>The following is a sample log using this class.</p>
037 * <p><pre>
038 * 2015-11-29 19:21:03,278 INFO  [SQLExample] -       Database is now open
039 *    Location where log statement called
040 *            java.lang.Thread.getStackTrace(Thread.java:1589)
041 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
042 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
043 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
044 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:92)
045 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
046 *
047 * 2015-11-29 19:21:03,279 INFO  [SQLExample] -       First statement is SELECT STATE, NAME FROM STATE
048 *    Location where log statement called
049 *            java.lang.Thread.getStackTrace(Thread.java:1589)
050 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
051 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
052 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
053 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:93)
054 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
055 *
056 * 2015-11-29 19:21:03,280 INFO  [SQLExample] -       Statement created
057 *    Location where log statement called
058 *            java.lang.Thread.getStackTrace(Thread.java:1589)
059 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
060 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
061 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
062 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:96)
063 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
064 *
065 * 2015-11-29 19:21:03,288 INFO  [SQLExample] -       ResultSet created
066 *    Location where log statement called
067 *            java.lang.Thread.getStackTrace(Thread.java:1589)
068 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
069 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
070 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
071 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:98)
072 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
073 * 
074 * 2015-11-29 19:21:03,291 INFO  [SQLExample] -       Second statement is SELECT STATE, NAME FROM NOTTHERE
075 *    Location where log statement called
076 *            java.lang.Thread.getStackTrace(Thread.java:1589)
077 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
078 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
079 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
080 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:120)
081 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
082 * 
083 * 2015-11-29 19:21:03,292 INFO  [SQLExample] -       Statement created
084 *    Location where log statement called
085 *            java.lang.Thread.getStackTrace(Thread.java:1589)
086 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
087 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
088 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
089 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:123)
090 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
091 * 
092 * 2015-11-29 19:21:03,302 ERROR [SQLExample] -       Problem with second statement
093 *    Subclass of SQLException
094 *    Location of exception
095 *       com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'sample.notthere' doesn't exist
096 *              at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
097 *              at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
098 *              at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
099 *              at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
100 *              at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
101 *              at com.mysql.jdbc.Util.getInstance(Util.java:383)
102 *              at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)
103 *              at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4208)
104 *              at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4140)
105 *              at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2597)
106 *              at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2758)
107 *              at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2820)
108 *              at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2769)
109 *              at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1569)
110 *              at bradleyross.library.debugging.SQLExample.run(SQLExample.java:124)
111 *              at bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
112 *    Exception is subclass of SQLException
113 *    Vendor specific error code is 1146
114 *    SQL State is 42S02
115 *    Location where log statement called
116 *            java.lang.Thread.getStackTrace(Thread.java:1589)
117 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
118 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
119 *            bradleyross.library.helpers.ExceptionHelper.error(ExceptionHelper.java:273)
120 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:131)
121 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
122 * 
123 * 2015-11-29 19:21:03,303 INFO  [SQLExample] -       Third statement is SELECT STATE, NAME, NOTTHERE FROM STATE
124 *    Location where log statement called
125 *            java.lang.Thread.getStackTrace(Thread.java:1589)
126 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
127 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
128 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
129 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:144)
130 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
131 * 
132 * 2015-11-29 19:21:03,303 INFO  [SQLExample] -       Statement created
133 *    Location where log statement called
134 *            java.lang.Thread.getStackTrace(Thread.java:1589)
135 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
136 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
137 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
138 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:147)
139 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
140 * 
141 * 2015-11-29 19:21:03,304 ERROR [SQLExample] -       Problem with third statement
142 *    Subclass of SQLException
143 *    Location of exception
144 *       com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'NOTTHERE' in 'field list'
145 *              at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
146 *              at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
147 *              at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
148 *              at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
149 *              at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
150 *              at com.mysql.jdbc.Util.getInstance(Util.java:383)
151 *              at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)
152 *              at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4208)
153 *              at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4140)
154 *              at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2597)
155 *              at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2758)
156 *              at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2820)
157 *              at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2769)
158 *              at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1569)
159 *              at bradleyross.library.debugging.SQLExample.run(SQLExample.java:148)
160 *              at bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
161 *    Exception is subclass of SQLException
162 *    Vendor specific error code is 1054
163 *    SQL State is 42S22
164 *    Location where log statement called
165 *            java.lang.Thread.getStackTrace(Thread.java:1589)
166 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
167 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
168 *            bradleyross.library.helpers.ExceptionHelper.error(ExceptionHelper.java:273)
169 *            bradleyross.library.debugging.SQLExample.run(SQLExample.java:155)
170 *            bradleyross.library.debugging.SQLExample.main(SQLExample.java:177)
171 * 
172 * 2015-11-29 19:22:29,874 INFO  [test3] - Starting test with log4j
173 * 2015-11-29 19:22:29,876 INFO  [test3] -       Trap and throw in level 2 - level info
174 *    Location of exception
175 *       java.io.IOException: Triggering IOException
176 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
177 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
178 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
179 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
180 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
181 *    Location where log statement called
182 *            java.lang.Thread.getStackTrace(Thread.java:1589)
183 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
184 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
185 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
186 *            bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:592)
187 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
188 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
189 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
190 * 
191 * 2015-11-29 19:22:29,876 WARN  [test3] -       Trap and throw in level 2 - level warn
192 *    Location of exception
193 *       java.io.IOException: Triggering IOException
194 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
195 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
196 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
197 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
198 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
199 *    Location where log statement called
200 *            java.lang.Thread.getStackTrace(Thread.java:1589)
201 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
202 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
203 *            bradleyross.library.helpers.ExceptionHelper.warn(ExceptionHelper.java:323)
204 *            bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:593)
205 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
206 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
207 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
208 * 
209 * 2015-11-29 19:22:29,877 INFO  [test3] -       Trapping in method level1
210 *    Location of exception
211 *       java.io.IOException: Triggering IOException
212 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
213 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
214 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
215 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
216 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
217 *    Location where log statement called
218 *            java.lang.Thread.getStackTrace(Thread.java:1589)
219 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
220 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
221 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
222 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:584)
223 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
224 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
225 * 
226 * 2015-11-29 19:22:29,878 INFO  [test3] -       Trapping in method run
227 *    Location of exception
228 *       java.io.IOException: Triggering IOException
229 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
230 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
231 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
232 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
233 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
234 *    Location where log statement called
235 *            java.lang.Thread.getStackTrace(Thread.java:1589)
236 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
237 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
238 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
239 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:577)
240 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:641)
241 * 
242 * 2015-11-29 19:22:29,878 INFO  [ExceptionHelper] -       Starting test with org.slf4j
243 *    Location where log statement called
244 *            java.lang.Thread.getStackTrace(Thread.java:1589)
245 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
246 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
247 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:379)
248 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:643)
249 * 
250 * 2015-11-29 19:22:29,879 INFO  [ExceptionHelper] -       Trap and throw in level 2 - level info
251 *    Location of exception
252 *       java.io.IOException: Triggering IOException
253 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
254 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
255 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
256 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
257 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
258 *    Location where log statement called
259 *            java.lang.Thread.getStackTrace(Thread.java:1589)
260 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
261 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
262 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
263 *            bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:592)
264 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
265 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
266 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
267 * 
268 * 2015-11-29 19:22:29,879 WARN  [ExceptionHelper] -       Trap and throw in level 2 - level warn
269 *    Location of exception
270 *       java.io.IOException: Triggering IOException
271 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
272 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
273 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
274 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
275 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
276 *    Location where log statement called
277 *            java.lang.Thread.getStackTrace(Thread.java:1589)
278 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
279 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
280 *            bradleyross.library.helpers.ExceptionHelper.warn(ExceptionHelper.java:323)
281 *            bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:593)
282 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
283 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
284 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
285 * 
286 * 2015-11-29 19:22:29,880 INFO  [ExceptionHelper] -       Trapping in method level1
287 *    Location of exception
288 *       java.io.IOException: Triggering IOException
289 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
290 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
291 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
292 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
293 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
294 *    Location where log statement called
295 *            java.lang.Thread.getStackTrace(Thread.java:1589)
296 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
297 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
298 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
299 *            bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:584)
300 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
301 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
302 * 
303 * 2015-11-29 19:22:29,881 INFO  [ExceptionHelper] -       Trapping in method run
304 *    Location of exception
305 *       java.io.IOException: Triggering IOException
306 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level3(ExceptionHelper.java:598)
307 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level2(ExceptionHelper.java:590)
308 *              at bradleyross.library.helpers.ExceptionHelper$Tester.level1(ExceptionHelper.java:582)
309 *              at bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:575)
310 *              at bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
311 *    Location where log statement called
312 *            java.lang.Thread.getStackTrace(Thread.java:1589)
313 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:123)
314 *            bradleyross.library.helpers.ExceptionHelper.logException(ExceptionHelper.java:168)
315 *            bradleyross.library.helpers.ExceptionHelper.info(ExceptionHelper.java:372)
316 *            bradleyross.library.helpers.ExceptionHelper$Tester.run(ExceptionHelper.java:577)
317 *            bradleyross.library.helpers.ExceptionHelper.main(ExceptionHelper.java:645)
318 * </pre></p>
319 * @author Bradley Ross
320 * @see bradleyross.library.helpers.ExceptionProcessor
321 * @see bradleyross.library.debugging.SQLExample
322 * 
323 */
324public class ExceptionHelper {
325        /**
326         * An implementation of {@link ExceptionProcessor} can be used to customize
327         * the log messages for various types of exceptions.
328         * 
329         * <p>It should be noted that the information returned by 
330         *    {@link SOAPFaultException} is very complicated.  This is intended solely
331         *    as an example.</p>
332         * 
333         * @author Bradley Boss
334         *
335         */
336        public class DummyExceptionProcessor implements ExceptionProcessor {
337                public List<String> getInformation(Exception e) {
338                        List<String> notes = new ArrayList<String>();
339                        if (e == null) {
340                                return notes;
341                        }
342                        if (SQLException.class.isAssignableFrom(e.getClass())) {
343                                SQLException e2 = (SQLException) e;
344                                notes.add("Exception is subclass of SQLException");
345                                notes.add("Vendor specific error code is " + Integer.toString(e2.getErrorCode()));
346                                String sqlState = e2.getSQLState();
347                                if (sqlState != null && sqlState.trim().length() > 0) {
348                                        notes.add("SQL State is " + sqlState);
349                                }
350                        } else if (SOAPFaultException.class.isAssignableFrom(e.getClass())) {
351                                SOAPFaultException e2 = (SOAPFaultException) e;
352                                notes.add("Exception is subclass of SOAPFaultException");
353                                SOAPFault fault = e2.getFault();
354                                if (fault == null) {
355                                        notes.add("SOAPFault object is null");
356                                } else {
357                                        notes.add("SOAPFault object is not null");
358                                }
359                        }
360                        return notes;
361                }
362        }
363        public static final int FATAL = 1;
364        public static final int ERROR = 2;
365        public static final int WARN  = 3;
366        public static final int INFO  = 4;
367        public static final int DEBUG = 5;
368        public static final int TRACE = 6;
369        protected org.apache.log4j.Logger apacheLogger = null;
370        protected org.slf4j.Logger slf4jLogger = null;
371        public ExceptionHelper(org.apache.log4j.Logger logger) {
372                apacheLogger = logger;
373        }
374        public ExceptionHelper(org.slf4j.Logger logger) {
375                slf4jLogger = logger;
376        }
377        /**
378         * This object can be used to provide extra processing of
379         * various exception subclasses.
380         */
381        protected ExceptionProcessor extra = new DummyExceptionProcessor();
382        /**
383         * Setter for {@link #extra}
384         * @param value object to be used for extra processing
385         */
386        public void setExceptionProcessor(ExceptionProcessor value) {
387                extra = value;
388        }
389        protected void logException(int level, List<String> value, Exception e) {
390                StringWriter writer = new StringWriter();
391                PrintWriter out = new PrintWriter(writer);
392                try {
393                        List<String> strings = new ArrayList<String>(splitLines(value));
394                        if (e != null && SQLException.class.isAssignableFrom(e.getClass())) {
395                                strings.add("Subclass of SQLException");
396                        }
397                        if (e != null) {
398                                strings.add("Location of exception");
399                                StringWriter writer2 = new StringWriter();
400                                PrintWriter out2 = new PrintWriter(writer2);
401                                e.printStackTrace(out2);
402                                strings.addAll(splitLines(writer2.toString()));
403                        }
404                        strings.addAll(extra.getInformation(e));
405                        strings.add("Location where log statement called");
406                        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
407                        if (stack != null && stack.length > 0) {
408                                for (int i = 0; i < stack.length; i++) {
409                                        strings.addAll(splitLines("     " + stack[i].toString()));
410                                }
411                        }
412                        Iterator<String> iter = strings.iterator();
413                        while (iter.hasNext()) {
414                                out.println("   " + iter.next());
415                        }
416                } catch (IOException eio) {
417                        if (apacheLogger != null){
418                                apacheLog(ERROR, "IOException while writing to log", eio);
419                        }
420                        if (slf4jLogger != null) {
421                                slf4jLog(ERROR, "IOException while writing to log", eio);
422                        }
423                        return;
424                }
425                if (apacheLogger != null) {
426                        apacheLog(level, writer.toString(), e);
427                } else if (slf4jLogger != null) {
428                        slf4jLog(level, writer.toString(), e);
429                }
430        }
431
432        public void logException(int level, String string, Exception e) {
433                List<String> list = new ArrayList<String>();
434                StringReader reader = new StringReader(string);
435                LineNumberReader in = new LineNumberReader(reader);
436                try {
437                        while (true) {
438                                String line = in.readLine();
439                                if (line == null) { break; }
440                                list.add(line);
441                        }
442                } catch (IOException eio) {
443                        if (apacheLogger != null){
444                                apacheLog(ERROR, "IOException while writing to log", eio);
445                        }
446                        if (slf4jLogger != null) {
447                                slf4jLog(ERROR, "IOException while writing to log", eio);
448                        }
449                        return;
450                }
451                logException(level, list, e);
452        }
453        protected void apacheLog(int level, String message, Exception e) {
454                switch (level) {
455                case FATAL :
456                        apacheLogger.fatal(message);
457                        break;
458                case ERROR :
459                        apacheLogger.error(message);
460                        break;                  
461                case WARN :
462                        apacheLogger.warn(message);
463                        break;                  
464                case INFO :
465                        apacheLogger.info(message);
466                        break;
467                case DEBUG :
468                        apacheLogger.debug(message);
469                        break;                  
470                case TRACE :
471                        apacheLogger.trace(message);
472                        break;  
473                }
474        }
475        protected void slf4jLog(int level, String message, Exception e) {
476                switch (level) {
477                case FATAL :
478                        slf4jLogger.error(message);
479                        break;
480                case ERROR :
481                        slf4jLogger.error(message);
482                        break;                  
483                case WARN :
484                        slf4jLogger.warn(message);
485                        break;                  
486                case INFO :
487                        slf4jLogger.info(message);
488                        break;
489                case DEBUG :
490                        slf4jLogger.debug(message);
491                        break;                  
492                case TRACE :
493                        slf4jLogger.trace(message);
494                        break;  
495                }
496        }
497
498        /**
499         * Helper method for fatal messages.
500         * @param string messages
501         * @param e exception
502         */
503        public void fatal(String string, Exception e) {
504                logException(FATAL, string, e);
505        }
506        /**
507         * Helper method for fatal messages.
508         * @param string message
509         */
510        public void fatal(String string) {
511                logException(FATAL, string, (Exception) null);
512        }
513        /**
514         * Helper method for fatal messages.
515         * @param strings messages
516         * @param e exception
517         */
518        public void fatal(List<String> strings, Exception e) {
519                logException(FATAL, strings, e);
520        }
521        /**
522         * Helper method for fatal messages.
523         * @param strings messages
524         */
525        public void fatal(List<String> strings) {
526                logException(FATAL, strings, (Exception) null);
527        }
528        /**
529         * Helper method for fatal messages.
530         * @param strings messages
531         * @param e exception
532         */
533        public void fatal(String[] strings, Exception e) {
534                List<String> list = new ArrayList<String>();
535                for (int i = 0; i < strings.length; i++) {
536                        list.add(strings[i]);
537                }
538                logException(FATAL, list, e);
539        }       
540        /**
541         * Helper method for fatal messages.
542         * @param strings messages
543         */
544        public void fatal(String[] strings) {
545                fatal(strings, (Exception) null);
546        }
547        /*
548         * Helper methods for error messages.
549         */
550        /**
551         * Helper method for error messages.
552         * @param string message
553         * @param e exception
554         */
555        public void error(String string, Exception e) {
556                logException(ERROR, string, e);
557        }
558        /**
559         * Helper method for error messages.
560         * @param string message
561         */
562        public void error(String string) {
563                logException(ERROR, string, (Exception) null);
564        }
565        /**
566         * Helper method for error messages.
567         * @param strings messages
568         * @param e exception
569         */
570        public void error(List<String> strings, Exception e) {
571                logException(ERROR, strings, e);
572        }
573        /**
574         * Helper method for error messages.
575         * @param strings messages
576         */
577        public void error(List<String> strings) {
578                logException(ERROR, strings, (Exception) null);
579        }
580        /**
581         * Helper method for error messages.
582         * @param strings messages
583         * @param e exception
584         */
585        public void error(String[] strings, Exception e) {
586                List<String> list = new ArrayList<String>();
587
588                for (int i = 0; i < strings.length; i++) {
589                        list.add(strings[i]);
590                }
591                logException(ERROR, list, e);
592        }
593        /**
594         * Helper method for error messages.
595         * @param strings messages
596         */
597        public void error (String[] strings) {
598                error(strings, (Exception) null);
599        }
600        /**
601         * Helper method for warn messages.
602         * @param string messages
603         * @param e exception
604         */
605        public void warn(String string, Exception e) {
606                logException(WARN, string, e);
607        }
608        /**
609         * Helper method for warn messages.
610         * @param string message
611         */
612        public void warn(String string) {
613                logException(WARN, string, (Exception) null);
614        }
615        /**
616         * Helper method for warn messages.
617         * @param strings messages
618         * @param e exception
619         */
620        public void warn(List<String> strings, Exception e) {
621                logException(WARN, strings, e);
622        }
623        /**
624         * Helper method for warn messages.
625         * @param strings messages
626         */
627        public void warn(List<String> strings) {
628                logException(WARN, strings, (Exception) null);
629        }
630        /**
631         * Helper method for warn messages.
632         * @param strings messages
633         * @param e exception
634         */
635        public void warn(String[] strings, Exception e) {
636                List<String> list = new ArrayList<String>();
637                for (int i = 0; i < strings.length; i++) {
638                        list.add(strings[i]);
639                }
640                logException(WARN, list, e);
641        }       
642        /**
643         * Helper method for warn messages.
644         * @param strings messages
645         */
646        public void warn(String[] strings) {
647                warn(strings, (Exception) null);
648        }
649        /**
650         * Helper method for info messages.
651         * @param string message
652         * @param e exception
653         */
654        public void info(String string, Exception e) {
655                logException(INFO, string, e);
656        }
657        /**
658         * Helper method for info messages.
659         * @param string message
660         */
661        public void info(String string) {
662                logException(INFO, string, (Exception) null);
663        }
664        /**
665         * Helper method for info messages.
666         * @param strings messages
667         * @param e exception
668         */
669        public void info(List<String> strings, Exception e) {
670                logException(INFO, strings, e);
671        }
672        /**
673         * Helper method for info messages.
674         * @param strings messages
675         */
676        public void info(List<String> strings) {
677                logException(INFO, strings, (Exception) null);
678        }
679        /**
680         * Helper method for info messages.
681         * @param strings messages
682         * @param e exception
683         */
684        public void info(String[] strings, Exception e) {
685                List<String> list = new ArrayList<String>();
686                for (int i = 0; i < strings.length; i++) {
687                        list.add(strings[i]);
688                }
689                logException(INFO, list, e);
690        }
691        /**
692         * Helper method for info messages.
693         * @param strings messages
694         */
695        public void info (String[] strings) {
696                info(strings, (Exception) null);
697        }
698        /**
699         * Helper method for debug messages.
700         * @param string messages
701         * @param e exception
702         */
703        public void debug(String string, Exception e) {
704                logException(DEBUG, string, e);
705        }
706        /**
707         * Helper method for debug messages.
708         * @param string message
709         */
710        public void debug(String string) {
711                logException(DEBUG, string, (Exception) null);
712        }
713        /**
714         * Helper method for debug messages.
715         * @param strings messages
716         * @param e exception
717         */
718        public void debug(List<String> strings, Exception e) {
719                logException(DEBUG, strings, e);
720        }
721        /**
722         * Helper method for debug messages.
723         * @param strings messages
724         */
725        public void debug(List<String> strings) {
726                logException(DEBUG, strings, (Exception) null);
727        }
728        /**
729         * Helper method for debug messages.
730         * @param strings messages
731         * @param e exception
732         */
733        public void debug(String[] strings, Exception e) {
734                List<String> list = new ArrayList<String>();
735                for (int i = 0; i < strings.length; i++) {
736                        list.add(strings[i]);
737                }
738                logException(DEBUG, list, e);
739        }       
740        /**
741         * Helper method for debug messages.
742         * @param strings messages
743         */
744        public void debug(String[] strings) {
745                debug(strings, (Exception) null);
746        }
747        /**
748         * Helper method for trace messages.
749         * @param string message
750         * @param e exception
751         */
752        public void trace(String string, Exception e) {
753                logException(TRACE, string, e);
754        }
755        /**
756         * Helper method for trace messages.
757         * @param string message
758         */
759        public void trace(String string) {
760                logException(TRACE, string, (Exception) null);
761        }
762        /**
763         * Helper method for trace messages.
764         * @param strings messages
765         * @param e exception
766         */
767        public void trace(List<String> strings, Exception e) {
768                logException(TRACE, strings, e);
769        }
770        /**
771         * Helper method for trace messages.
772         * @param strings messages
773         */
774        public void trace(List<String> strings) {
775                logException(TRACE, strings, (Exception) null);
776        }
777        /**
778         * Helper method for trace messages.
779         * @param strings messages
780         * @param e exception
781         */
782        public void trace(String[] strings, Exception e) {
783                List<String> list = new ArrayList<String>();
784                for (int i = 0; i < strings.length; i++) {
785                        list.add(strings[i]);
786                }
787                logException(TRACE, list, e);
788        }
789        /**
790         * Helper method for trace messages.
791         * @param strings messages
792         */
793        public void trace (String[] strings) {
794                trace(strings, (Exception) null);
795        }
796        protected List<String> splitLines(List<String> start) throws IOException {
797                return splitLines(start, 3);
798        }
799        public List<String> splitLines(List<String> start, int indent) throws IOException {
800                StringBuffer temp = new StringBuffer();
801                int size = indent;
802                if (size < 0) {
803                        size = 3;
804                }
805                for (int i = 0; i < size; i++) {
806                        temp.append(" ");
807                }
808                String prefix = temp.toString();
809                List<String> result = new ArrayList<String>();
810                if (start == null) { return result; }
811                Iterator<String> iter = start.iterator();
812                while (iter.hasNext()) {
813                        String preSplit = iter.next();
814                        LineNumberReader reader = new LineNumberReader(new StringReader(preSplit));
815                        while (true) {
816                                String line = reader.readLine();
817                                if (line == null) { break; }
818                                result.add(prefix + line);
819                        }
820                }
821                return result;
822        }
823        protected List<String> splitLines(String start) throws IOException {
824                List<String> result = new ArrayList<String>();
825                result.add(start);
826                return splitLines(result);
827        }
828        /**
829         * Internal debugging aid for printing list of strings.
830         * @param list list to be printed
831         * @param out destination for printing
832         */
833        protected void printList(List<String> list, PrintStream out) {
834                if (list == null ) { return; }
835                if (out == null) { return; }
836                Iterator<String> iter = list.iterator();
837                while (iter.hasNext()) {
838                        out.println("line: " + iter.next());
839                }
840        }
841        protected void printList(List<String> list) {
842                printList(list, System.out);
843        }
844        /**
845         * Demonstrates many of the features of the
846         * {@link ExceptionHelper} class.
847         * 
848         * @author Bradley Ross
849         *
850         */
851        protected class Tester implements Runnable {
852                protected ExceptionHelper helper = null;
853                public Tester(ExceptionHelper value) {
854                        helper = value;
855                }
856                public void run() {
857                        try {
858                                level1();
859                        } catch (Exception e) {
860                                helper.info("Trapping in method run", e);
861                        }
862                }
863                protected void level1() throws IOException {
864                        try {
865                                level2();
866                        } catch (Exception e) {
867                                helper.info("Trapping in method level1", e);
868                                throw e;
869                        }
870                }
871                protected void level2() throws IOException {
872                        try {
873                                level3();
874                        } catch (Exception e) {
875                                helper.info("Trap and throw in level 2 - level info", e);
876                                helper.warn("Trap and throw in level 2 - level warn", e);
877                                throw e;
878                        }
879                }
880                protected void level3() throws IOException {
881                        IOException  e = new IOException("Triggering IOException");
882                        throw e;
883                }
884        }
885        /**
886         * Test driver.
887         * 
888         * <p>Log4j or Slf4j must be set up separately so that this code will work.</p>
889         * 
890         * @param params - not used
891         */
892        public static void main(String[] params) {
893                /*
894                 * If the catalina.home Java system variable is not set,  
895                 * catalina.home will be set
896                 * to the home directory.
897                 */
898                Properties props = System.getProperties();
899                if (!props.containsKey("catalina.home")) {
900                        System.setProperty("catalina.home", System.getProperty("user.home"));
901                }
902                org.slf4j.Logger logger2 = org.slf4j.LoggerFactory.getLogger(ExceptionHelper.class);
903                org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("test3");
904
905                ExceptionHelper helper = new ExceptionHelper(logger);
906                /*
907                 * Test of splitting input lines using line feeds and carriage returns.
908                 */
909                try {
910                        System.out.println("Testing line splitters");
911                        StringBuilder test1 = new StringBuilder("abc\r\n");
912                        test1.append("def\n");
913                        test1.append("ghi\n");                  
914                        List<String> test2 = helper.splitLines(test1.toString());
915                        helper.printList(test2);
916                } catch (IOException e) {
917                        helper.error("IOException Error in splitLines", e);
918                }
919                /*
920                 * Testing with log4j
921                 */
922                Runnable run = helper.new Tester(helper);
923                logger.info("Starting test with log4j");
924                run.run();
925                ExceptionHelper helper2 = new ExceptionHelper(logger2);
926                helper2.info("Starting test with org.slf4j");
927                Runnable run2 = helper2.new Tester(helper2);
928                run2.run();
929        }
930}