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 * <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>
319 * 
320 * @author Bradley Ross
321 * @see bradleyross.library.helpers.ExceptionProcessor
322 * @see bradleyross.library.debugging.SQLExample
323 * 
324 */
325public class ExceptionHelper {
326        /**
327         * An implementation of {@link ExceptionProcessor} can be used to customize
328         * the log messages for various types of exceptions.
329         * 
330         * <p>It should be noted that the information returned by 
331         *    {@link SOAPFaultException} is very complicated.  This is intended solely
332         *    as an example.</p>
333         * 
334         * @author Bradley Boss
335         *
336         */
337        public class DummyExceptionProcessor implements ExceptionProcessor {
338                public List<String> getInformation(Exception e) {
339                        List<String> notes = new ArrayList<String>();
340                        if (e == null) {
341                                return notes;
342                        }
343                        if (SQLException.class.isAssignableFrom(e.getClass())) {
344                                SQLException e2 = (SQLException) e;
345                                notes.add("Exception is subclass of SQLException");
346                                notes.add("Vendor specific error code is " + Integer.toString(e2.getErrorCode()));
347                                String sqlState = e2.getSQLState();
348                                if (sqlState != null && sqlState.trim().length() > 0) {
349                                        notes.add("SQL State is " + sqlState);
350                                }
351                        } else if (SOAPFaultException.class.isAssignableFrom(e.getClass())) {
352                                SOAPFaultException e2 = (SOAPFaultException) e;
353                                notes.add("Exception is subclass of SOAPFaultException");
354                                SOAPFault fault = e2.getFault();
355                                if (fault == null) {
356                                        notes.add("SOAPFault object is null");
357                                } else {
358                                        notes.add("SOAPFault object is not null");
359                                }
360                        }
361                        return notes;
362                }
363        }
364        public static final int FATAL = 1;
365        public static final int ERROR = 2;
366        public static final int WARN  = 3;
367        public static final int INFO  = 4;
368        public static final int DEBUG = 5;
369        public static final int TRACE = 6;
370        /**
371         * Logger for use with log4j 1.x logging framework API.
372         */
373        protected org.apache.log4j.Logger apacheLogger = null;
374        /** 
375         * Logger for use with slf4j logging framework API.
376         */
377        protected org.slf4j.Logger slf4jLogger = null;
378        /**
379         * Logger for use with log4j 2 logging framework API.
380         */
381        protected org.apache.logging.log4j.Logger log4j2Logger = null;
382        /**
383         * Constructor for working with log4j 1 logging framework API.
384         * @param logger Logger object to which messages will be passed.
385         */
386        public ExceptionHelper(org.apache.log4j.Logger logger) {
387                apacheLogger = logger;
388        }
389        /**
390         * Constructor for working with slf4j logging framework API.
391         * @param logger Logger object to which messages will be sent.
392         */
393        public ExceptionHelper(org.slf4j.Logger logger) {
394                slf4jLogger = logger;
395        }
396        /**
397         * Constructor for working with log4j 2 logging framework API.
398         * @param logger Logger object to which messages will be sent.
399         */
400        public ExceptionHelper(org.apache.logging.log4j.Logger logger) {
401                log4j2Logger = logger;
402        }
403        /**
404         * This object can be used to provide extra processing of
405         * various exception subclasses.
406         */
407        protected ExceptionProcessor extra = new DummyExceptionProcessor();
408        /**
409         * Setter for {@link #extra} allowing additional features to be added.
410         * @param value object to be used for extra processing
411         */
412        public void setExceptionProcessor(ExceptionProcessor value) {
413                extra = value;
414        }
415        protected void logException(int level, List<String> value, Exception e) {
416                StringWriter writer = new StringWriter();
417                PrintWriter out = new PrintWriter(writer);
418                try {
419                        List<String> strings = new ArrayList<String>(splitLines(value));
420                        if (e != null && SQLException.class.isAssignableFrom(e.getClass())) {
421                                strings.add("Subclass of SQLException");
422                        }
423                        if (e != null) {
424                                strings.add("Location of exception");
425                                StringWriter writer2 = new StringWriter();
426                                PrintWriter out2 = new PrintWriter(writer2);
427                                e.printStackTrace(out2);
428                                strings.addAll(splitLines(writer2.toString()));
429                        }
430                        strings.addAll(extra.getInformation(e));
431                        strings.add("Location where log statement called");
432                        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
433                        if (stack != null && stack.length > 0) {
434                                for (int i = 0; i < stack.length; i++) {
435                                        strings.addAll(splitLines("     " + stack[i].toString()));
436                                }
437                        }
438                        Iterator<String> iter = strings.iterator();
439                        while (iter.hasNext()) {
440                                out.println("   " + iter.next());
441                        }
442                } catch (IOException eio) {
443                        if (apacheLogger != null){
444                                apacheLog(ERROR, "IOException while writing to log", eio);
445                        }
446                        if (log4j2Logger != null){
447                                apache2Log(ERROR, "IOException while writing to log", eio);
448                        }                       
449                        if (slf4jLogger != null) {
450                                slf4jLog(ERROR, "IOException while writing to log", eio);
451                        }
452                        return;
453                }
454                if (apacheLogger != null) {
455                        apacheLog(level, writer.toString(), e);
456                } else if (log4j2Logger != null) {
457                        apache2Log(level, writer.toString(), e);
458                } else if (slf4jLogger != null) {
459                        slf4jLog(level, writer.toString(), e);
460                }
461        }
462
463        public void logException(int level, String string, Exception e) {
464                List<String> list = new ArrayList<String>();
465                StringReader reader = new StringReader(string);
466                LineNumberReader in = new LineNumberReader(reader);
467                try {
468                        while (true) {
469                                String line = in.readLine();
470                                if (line == null) { break; }
471                                list.add(line);
472                        }
473                } catch (IOException eio) {
474                        if (apacheLogger != null){
475                                apacheLog(ERROR, "IOException while writing to log", eio);
476                        }
477                        if (log4j2Logger != null){
478                                apache2Log(ERROR, "IOException while writing to log", eio);
479                        }
480                        if (slf4jLogger != null) {
481                                slf4jLog(ERROR, "IOException while writing to log", eio);
482                        }
483                        return;
484                }
485                logException(level, list, e);
486        }
487        protected void apacheLog(int level, String message, Exception e) {
488                switch (level) {
489                case FATAL :
490                        apacheLogger.fatal(message);
491                        break;
492                case ERROR :
493                        apacheLogger.error(message);
494                        break;                  
495                case WARN :
496                        apacheLogger.warn(message);
497                        break;                  
498                case INFO :
499                        apacheLogger.info(message);
500                        break;
501                case DEBUG :
502                        apacheLogger.debug(message);
503                        break;                  
504                case TRACE :
505                        apacheLogger.trace(message);
506                        break;  
507                }
508        }
509        protected void apache2Log(int level, String message, Exception e) {
510                switch (level) {
511                case FATAL :
512                        log4j2Logger.fatal(message);
513                        break;
514                case ERROR :
515                        log4j2Logger.error(message);
516                        break;                  
517                case WARN :
518                        log4j2Logger.warn(message);
519                        break;                  
520                case INFO :
521                        log4j2Logger.info(message);
522                        break;
523                case DEBUG :
524                        log4j2Logger.debug(message);
525                        break;                  
526                case TRACE :
527                        log4j2Logger.trace(message);
528                        break;  
529                }
530        }
531        protected void slf4jLog(int level, String message, Exception e) {
532                switch (level) {
533                case FATAL :
534                        slf4jLogger.error(message);
535                        break;
536                case ERROR :
537                        slf4jLogger.error(message);
538                        break;                  
539                case WARN :
540                        slf4jLogger.warn(message);
541                        break;                  
542                case INFO :
543                        slf4jLogger.info(message);
544                        break;
545                case DEBUG :
546                        slf4jLogger.debug(message);
547                        break;                  
548                case TRACE :
549                        slf4jLogger.trace(message);
550                        break;  
551                }
552        }
553
554        /**
555         * Helper method for fatal messages.
556         * @param string messages
557         * @param e exception
558         */
559        public void fatal(String string, Exception e) {
560                logException(FATAL, string, e);
561        }
562        /**
563         * Helper method for fatal messages.
564         * @param string message
565         */
566        public void fatal(String string) {
567                logException(FATAL, string, (Exception) null);
568        }
569        /**
570         * Helper method for fatal messages.
571         * @param strings messages
572         * @param e exception
573         */
574        public void fatal(List<String> strings, Exception e) {
575                logException(FATAL, strings, e);
576        }
577        /**
578         * Helper method for fatal messages.
579         * @param strings messages
580         */
581        public void fatal(List<String> strings) {
582                logException(FATAL, strings, (Exception) null);
583        }
584        /**
585         * Helper method for fatal messages.
586         * @param strings messages
587         * @param e exception
588         */
589        public void fatal(String[] strings, Exception e) {
590                List<String> list = new ArrayList<String>();
591                for (int i = 0; i < strings.length; i++) {
592                        list.add(strings[i]);
593                }
594                logException(FATAL, list, e);
595        }       
596        /**
597         * Helper method for fatal messages.
598         * @param strings messages
599         */
600        public void fatal(String[] strings) {
601                fatal(strings, (Exception) null);
602        }
603        /*
604         * Helper methods for error messages.
605         */
606        /**
607         * Helper method for error messages.
608         * @param string message
609         * @param e exception
610         */
611        public void error(String string, Exception e) {
612                logException(ERROR, string, e);
613        }
614        /**
615         * Helper method for error messages.
616         * @param string message
617         */
618        public void error(String string) {
619                logException(ERROR, string, (Exception) null);
620        }
621        /**
622         * Helper method for error messages.
623         * @param strings messages
624         * @param e exception
625         */
626        public void error(List<String> strings, Exception e) {
627                logException(ERROR, strings, e);
628        }
629        /**
630         * Helper method for error messages.
631         * @param strings messages
632         */
633        public void error(List<String> strings) {
634                logException(ERROR, strings, (Exception) null);
635        }
636        /**
637         * Helper method for error messages.
638         * @param strings messages
639         * @param e exception
640         */
641        public void error(String[] strings, Exception e) {
642                List<String> list = new ArrayList<String>();
643
644                for (int i = 0; i < strings.length; i++) {
645                        list.add(strings[i]);
646                }
647                logException(ERROR, list, e);
648        }
649        /**
650         * Helper method for error messages.
651         * @param strings messages
652         */
653        public void error (String[] strings) {
654                error(strings, (Exception) null);
655        }
656        /**
657         * Helper method for warn messages.
658         * @param string messages
659         * @param e exception
660         */
661        public void warn(String string, Exception e) {
662                logException(WARN, string, e);
663        }
664        /**
665         * Helper method for warn messages.
666         * @param string message
667         */
668        public void warn(String string) {
669                logException(WARN, string, (Exception) null);
670        }
671        /**
672         * Helper method for warn messages.
673         * @param strings messages
674         * @param e exception
675         */
676        public void warn(List<String> strings, Exception e) {
677                logException(WARN, strings, e);
678        }
679        /**
680         * Helper method for warn messages.
681         * @param strings messages
682         */
683        public void warn(List<String> strings) {
684                logException(WARN, strings, (Exception) null);
685        }
686        /**
687         * Helper method for warn messages.
688         * @param strings messages
689         * @param e exception
690         */
691        public void warn(String[] strings, Exception e) {
692                List<String> list = new ArrayList<String>();
693                for (int i = 0; i < strings.length; i++) {
694                        list.add(strings[i]);
695                }
696                logException(WARN, list, e);
697        }       
698        /**
699         * Helper method for warn messages.
700         * @param strings messages
701         */
702        public void warn(String[] strings) {
703                warn(strings, (Exception) null);
704        }
705        /**
706         * Helper method for info messages.
707         * @param string message
708         * @param e exception
709         */
710        public void info(String string, Exception e) {
711                logException(INFO, string, e);
712        }
713        /**
714         * Helper method for info messages.
715         * @param string message
716         */
717        public void info(String string) {
718                logException(INFO, string, (Exception) null);
719        }
720        /**
721         * Helper method for info messages.
722         * @param strings messages
723         * @param e exception
724         */
725        public void info(List<String> strings, Exception e) {
726                logException(INFO, strings, e);
727        }
728        /**
729         * Helper method for info messages.
730         * @param strings messages
731         */
732        public void info(List<String> strings) {
733                logException(INFO, strings, (Exception) null);
734        }
735        /**
736         * Helper method for info messages.
737         * @param strings messages
738         * @param e exception
739         */
740        public void info(String[] strings, Exception e) {
741                List<String> list = new ArrayList<String>();
742                for (int i = 0; i < strings.length; i++) {
743                        list.add(strings[i]);
744                }
745                logException(INFO, list, e);
746        }
747        /**
748         * Helper method for info messages.
749         * @param strings messages
750         */
751        public void info (String[] strings) {
752                info(strings, (Exception) null);
753        }
754        /**
755         * Helper method for debug messages.
756         * @param string messages
757         * @param e exception
758         */
759        public void debug(String string, Exception e) {
760                logException(DEBUG, string, e);
761        }
762        /**
763         * Helper method for debug messages.
764         * @param string message
765         */
766        public void debug(String string) {
767                logException(DEBUG, string, (Exception) null);
768        }
769        /**
770         * Helper method for debug messages.
771         * @param strings messages
772         * @param e exception
773         */
774        public void debug(List<String> strings, Exception e) {
775                logException(DEBUG, strings, e);
776        }
777        /**
778         * Helper method for debug messages.
779         * @param strings messages
780         */
781        public void debug(List<String> strings) {
782                logException(DEBUG, strings, (Exception) null);
783        }
784        /**
785         * Helper method for debug messages.
786         * @param strings messages
787         * @param e exception
788         */
789        public void debug(String[] strings, Exception e) {
790                List<String> list = new ArrayList<String>();
791                for (int i = 0; i < strings.length; i++) {
792                        list.add(strings[i]);
793                }
794                logException(DEBUG, list, e);
795        }       
796        /**
797         * Helper method for debug messages.
798         * @param strings messages
799         */
800        public void debug(String[] strings) {
801                debug(strings, (Exception) null);
802        }
803        /**
804         * Helper method for trace messages.
805         * @param string message
806         * @param e exception
807         */
808        public void trace(String string, Exception e) {
809                logException(TRACE, string, e);
810        }
811        /**
812         * Helper method for trace messages.
813         * @param string message
814         */
815        public void trace(String string) {
816                logException(TRACE, string, (Exception) null);
817        }
818        /**
819         * Helper method for trace messages.
820         * @param strings messages
821         * @param e exception
822         */
823        public void trace(List<String> strings, Exception e) {
824                logException(TRACE, strings, e);
825        }
826        /**
827         * Helper method for trace messages.
828         * @param strings messages
829         */
830        public void trace(List<String> strings) {
831                logException(TRACE, strings, (Exception) null);
832        }
833        /**
834         * Helper method for trace messages.
835         * @param strings messages
836         * @param e exception
837         */
838        public void trace(String[] strings, Exception e) {
839                List<String> list = new ArrayList<String>();
840                for (int i = 0; i < strings.length; i++) {
841                        list.add(strings[i]);
842                }
843                logException(TRACE, list, e);
844        }
845        /**
846         * Helper method for trace messages.
847         * @param strings messages
848         */
849        public void trace (String[] strings) {
850                trace(strings, (Exception) null);
851        }
852        protected List<String> splitLines(List<String> start) throws IOException {
853                return splitLines(start, 3);
854        }
855        public List<String> splitLines(List<String> start, int indent) throws IOException {
856                StringBuffer temp = new StringBuffer();
857                int size = indent;
858                if (size < 0) {
859                        size = 3;
860                }
861                for (int i = 0; i < size; i++) {
862                        temp.append(" ");
863                }
864                String prefix = temp.toString();
865                List<String> result = new ArrayList<String>();
866                if (start == null) { return result; }
867                Iterator<String> iter = start.iterator();
868                while (iter.hasNext()) {
869                        String preSplit = iter.next();
870                        LineNumberReader reader = new LineNumberReader(new StringReader(preSplit));
871                        while (true) {
872                                String line = reader.readLine();
873                                if (line == null) { break; }
874                                result.add(prefix + line);
875                        }
876                }
877                return result;
878        }
879        protected List<String> splitLines(String start) throws IOException {
880                List<String> result = new ArrayList<String>();
881                result.add(start);
882                return splitLines(result);
883        }
884        /**
885         * Internal debugging aid for printing list of strings.
886         * @param list list to be printed
887         * @param out destination for printing
888         */
889        protected void printList(List<String> list, PrintStream out) {
890                if (list == null ) { return; }
891                if (out == null) { return; }
892                Iterator<String> iter = list.iterator();
893                while (iter.hasNext()) {
894                        out.println("line: " + iter.next());
895                }
896        }
897        protected void printList(List<String> list) {
898                printList(list, System.out);
899        }
900        /**
901         * Demonstrates many of the features of the
902         * {@link ExceptionHelper} class.
903         * 
904         * @author Bradley Ross
905         *
906         */
907        protected class Tester implements Runnable {
908                protected ExceptionHelper helper = null;
909                public Tester(ExceptionHelper value) {
910                        helper = value;
911                }
912                public void run() {
913                        try {
914                                level1();
915                        } catch (Exception e) {
916                                helper.info("Trapping in method run", e);
917                        }
918                }
919                protected void level1() throws IOException {
920                        try {
921                                level2();
922                        } catch (Exception e) {
923                                helper.info("Trapping in method level1", e);
924
925                        }
926                }
927                protected void level2() throws IOException {
928                        try {
929                                level3();
930                        } catch (Exception e) {
931                                helper.info("Trap and throw in level 2 - level info", e);
932                                helper.warn("Trap and throw in level 2 - level warn", e);
933                        }
934                }
935                protected void level3() throws IOException {
936                        IOException  e = new IOException("Triggering IOException");
937                        throw e;
938                }
939        }
940        /**
941         * Test driver.
942         * 
943         * <p>Log4j or Slf4j must be set up separately so that this code will work.</p>
944         * 
945         * @param params - not used
946         */
947        public static void main(String[] params) {
948                /*
949                 * If the catalina.home Java system variable is not set,  
950                 * catalina.home will be set
951                 * to the home directory.
952                 */
953                Properties props = System.getProperties();
954                
955                if (!props.containsKey("catalina.home")) {
956                        System.setProperty("catalina.home", System.getProperty("user.home"));
957                }
958                System.out.println(System.getProperty("catalina.home"));
959                org.slf4j.Logger logger2 = org.slf4j.LoggerFactory.getLogger("test1");
960                org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("test3");
961        org.apache.logging.log4j.Logger logger3 = org.apache.logging.log4j.LogManager.getLogger("test4");
962                ExceptionHelper helper = new ExceptionHelper(logger);
963                /*
964                 * Test of splitting input lines using line feeds and carriage returns.
965                 */
966                try {
967                        System.out.println("Testing line splitters");
968                        StringBuilder test1 = new StringBuilder("abc\r\n");
969                        test1.append("def\n");
970                        test1.append("ghi\n");                  
971                        List<String> test2 = helper.splitLines(test1.toString());
972                        helper.printList(test2);
973                } catch (IOException e) {
974                        helper.error("IOException Error in splitLines", e);
975                }
976                /*
977                 * Testing with log4j
978                 */
979                Runnable run = helper.new Tester(helper);
980                helper.info("Starting test with log4j");
981                run.run();
982                /*
983                 * Starting test with slf4j
984                 */
985                ExceptionHelper helper2 = new ExceptionHelper(logger2);
986                helper2.info("Starting test with org.slf4j");
987                Runnable run2 = helper2.new Tester(helper2);
988                run2.run();
989                /*
990                 *  Starting test with log4j2
991                 */
992                ExceptionHelper helper3 = new ExceptionHelper(logger3);
993                helper3.info("Starting test with org.log4j2");
994                Runnable run3 = helper2.new Tester(helper2);
995                run3.run();             
996        }
997}