1    
2    /*
3     * ====================================================================
4     * The Apache Software License, Version 1.1
5     *
6     * Copyright (c) 2002 The Apache Software Foundation.  All rights
7     * reserved.
8     *
9     * Redistribution and use in source and binary forms, with or without
10    * modification, are permitted provided that the following conditions
11    * are met:
12    *
13    * 1. Redistributions of source code must retain the above copyright
14    *    notice, this list of conditions and the following disclaimer.
15    *
16    * 2. Redistributions in binary form must reproduce the above copyright
17    *    notice, this list of conditions and the following disclaimer in
18    *    the documentation and/or other materials provided with the
19    *    distribution.
20    *
21    * 3. The end-user documentation included with the redistribution,
22    *    if any, must include the following acknowledgment:
23    *       "This product includes software developed by the
24    *        Apache Software Foundation (http://www.apache.org/)."
25    *    Alternately, this acknowledgment may appear in the software itself,
26    *    if and wherever such third-party acknowledgments normally appear.
27    *
28    * 4. The names "Apache" and "Apache Software Foundation" and
29    *    "Apache POI" must not be used to endorse or promote products
30    *    derived from this software without prior written permission. For
31    *    written permission, please contact apache@apache.org.
32    *
33    * 5. Products derived from this software may not be called "Apache",
34    *    "Apache POI", nor may "Apache" appear in their name, without
35    *    prior written permission of the Apache Software Foundation.
36    *
37    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48    * SUCH DAMAGE.
49    * ====================================================================
50    *
51    * This software consists of voluntary contributions made by many
52    * individuals on behalf of the Apache Software Foundation.  For more
53    * information on the Apache Software Foundation, please see
54    * <http://www.apache.org/>.
55    */
56   package org.apache.poi.util;
57   
58   import java.util.*;
59   
60   /**
61    * A logger class that strives to make it as easy as possible for
62    * developers to write log calls, while simultaneously making those
63    * calls as cheap as possible by performing lazy evaluation of the log
64    * message.<p>
65    *
66    * @author Marc Johnson (mjohnson at apache dot org)
67    * @author Glen Stampoultzis (glens at apache.org)
68    * @author Nicola Ken Barozzi (nicolaken at apache.org)
69    */
70   
71   public class POILogger
72   {
73   //    private Log             log   = null;
74       public static final int DEBUG = 1;
75       public static final int INFO  = 3;
76       public static final int WARN  = 5;
77       public static final int ERROR = 7;
78       public static final int FATAL = 9;
79   
80       /**
81        * package scope so it cannot be instantiated outside of the util
82        * package. You need a POILogger? Go to the POILogFactory for one
83        */
84   
85       POILogger()
86       {
87       }
88   
89       /**
90        * Log a message
91        *
92        * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
93        * @param obj1 The object to log.
94        */
95   
96       public void log(final int level, final Object obj1)
97       {
98           if (check(level))
99               System.out.println( obj1 );
100      }
101  
102      private boolean isDebugEnabled()
103      {
104          return System.getProperty("poi.logging") != null;
105      }
106  
107      private boolean isInfoEnabled()
108      {
109          return false;
110      }
111  
112      private boolean isWarnEnabled()
113      {
114          return System.getProperty("poi.logging") != null;
115      }
116  
117      private boolean isErrorEnabled()
118      {
119          return System.getProperty("poi.logging") != null;
120      }
121  
122      private boolean isFatalEnabled()
123      {
124          return System.getProperty("poi.logging") != null;
125      }
126  
127      /**
128       * Check if a logger is enabled to log at the specified level
129       *
130       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
131       */
132      public boolean check(final int level)
133      {
134          if(level==FATAL)
135          {
136            if(isFatalEnabled())
137            {
138              return true;
139            }
140          }
141          else if(level==ERROR)
142          {
143            if(isErrorEnabled())
144            {
145              return true;
146            }
147          }
148          else if(level==WARN)
149          {
150            if(isWarnEnabled())
151            {
152              return true;
153            }
154          }
155          else if(level==INFO)
156          {
157            if(isInfoEnabled())
158            {
159              return true;
160            }
161          }
162          else if(level==DEBUG)
163          {
164            if(isDebugEnabled())
165            {
166              return true;
167            }
168          }
169  
170          return false;
171  
172      }
173  
174      /**
175       * Log a message. Lazily appends Object parameters together.
176       *
177       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
178       * @param obj1 first object to place in the message
179       * @param obj2 second object to place in the message
180       */
181  
182      public void log(final int level, final Object obj1, final Object obj2)
183      {
184          if (check( level))
185          {
186              log(level, new StringBuffer(32).append(obj1).append(obj2));
187          }
188      }
189  
190      /**
191       * Log a message. Lazily appends Object parameters together.
192       *
193       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
194       * @param obj1 first Object to place in the message
195       * @param obj2 second Object to place in the message
196       * @param obj3 third Object to place in the message
197       */
198  
199      public void log(final int level, final Object obj1, final Object obj2,
200                      final Object obj3)
201      {
202          if (check( level))
203          {
204              log(level, new StringBuffer(48).append(obj1).append(obj2 ).append(obj3));
205          }
206      }
207  
208      /**
209       * Log a message. Lazily appends Object parameters together.
210       *
211       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
212       * @param obj1 first Object to place in the message
213       * @param obj2 second Object to place in the message
214       * @param obj3 third Object to place in the message
215       * @param obj4 fourth Object to place in the message
216       */
217  
218      public void log(final int level, final Object obj1, final Object obj2,
219                      final Object obj3, final Object obj4)
220      {
221          
222  
223          if (check( level))
224          {
225              log(level,
226                      new StringBuffer(64).append(obj1).append(obj2)
227                          .append(obj3).append(obj4));
228          }
229      }
230  
231      /**
232       * Log a message. Lazily appends Object parameters together.
233       *
234       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
235       * @param obj1 first Object to place in the message
236       * @param obj2 second Object to place in the message
237       * @param obj3 third Object to place in the message
238       * @param obj4 fourth Object to place in the message
239       * @param obj5 fifth Object to place in the message
240       */
241  
242      public void log(final int level, final Object obj1, final Object obj2,
243                      final Object obj3, final Object obj4, final Object obj5)
244      {
245          
246  
247          if (check( level))
248          {
249              log(level,
250                      new StringBuffer(80).append(obj1).append(obj2)
251                          .append(obj3).append(obj4).append(obj5));
252          }
253      }
254  
255      /**
256       * Log a message. Lazily appends Object parameters together.
257       *
258       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
259       * @param obj1 first Object to place in the message
260       * @param obj2 second Object to place in the message
261       * @param obj3 third Object to place in the message
262       * @param obj4 fourth Object to place in the message
263       * @param obj5 fifth Object to place in the message
264       * @param obj6 sixth Object to place in the message
265       */
266  
267      public void log(final int level, final Object obj1, final Object obj2,
268                      final Object obj3, final Object obj4, final Object obj5,
269                      final Object obj6)
270      {
271          
272  
273          if (check( level))
274          {
275              log(level ,
276                      new StringBuffer(96).append(obj1).append(obj2)
277                          .append(obj3).append(obj4).append(obj5).append(obj6));
278          }
279      }
280  
281      /**
282       * Log a message. Lazily appends Object parameters together.
283       *
284       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
285       * @param obj1 first Object to place in the message
286       * @param obj2 second Object to place in the message
287       * @param obj3 third Object to place in the message
288       * @param obj4 fourth Object to place in the message
289       * @param obj5 fifth Object to place in the message
290       * @param obj6 sixth Object to place in the message
291       * @param obj7 seventh Object to place in the message
292       */
293  
294      public void log(final int level, final Object obj1, final Object obj2,
295                      final Object obj3, final Object obj4, final Object obj5,
296                      final Object obj6, final Object obj7)
297      {
298          
299  
300          if (check( level))
301          {
302              log(level,
303                      new StringBuffer(112).append(obj1).append(obj2)
304                          .append(obj3).append(obj4).append(obj5).append(obj6)
305                          .append(obj7));
306          }
307      }
308  
309      /**
310       * Log a message. Lazily appends Object parameters together.
311       *
312       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
313       * @param obj1 first Object to place in the message
314       * @param obj2 second Object to place in the message
315       * @param obj3 third Object to place in the message
316       * @param obj4 fourth Object to place in the message
317       * @param obj5 fifth Object to place in the message
318       * @param obj6 sixth Object to place in the message
319       * @param obj7 seventh Object to place in the message
320       * @param obj8 eighth Object to place in the message
321       */
322  
323      public void log(final int level, final Object obj1, final Object obj2,
324                      final Object obj3, final Object obj4, final Object obj5,
325                      final Object obj6, final Object obj7, final Object obj8)
326      {
327          
328  
329          if (check( level))
330          {
331              log(level,
332                      new StringBuffer(128).append(obj1).append(obj2)
333                          .append(obj3).append(obj4).append(obj5).append(obj6)
334                          .append(obj7).append(obj8));
335          }
336      }
337  
338      /**
339       * Log a message
340       *
341       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
342       * @param obj1 The object to log.  This is converted to a string.
343       * @param exception An exception to be logged
344       */
345  
346      public void log(final int level, final Object obj1,
347                      final Throwable exception)
348      {
349          log(level , obj1, exception);
350      }
351  
352      /**
353       * Log a message. Lazily appends Object parameters together.
354       *
355       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
356       * @param obj1 first Object to place in the message
357       * @param obj2 second Object to place in the message
358       * @param exception An exception to be logged
359       */
360  
361      public void log(final int level, final Object obj1, final Object obj2,
362                      final Throwable exception)
363      {
364          
365  
366          if (check( level))
367          {
368              log(level, new StringBuffer(32).append(obj1).append(obj2),
369                      exception);
370          }
371      }
372  
373      /**
374       * Log a message. Lazily appends Object parameters together.
375       *
376       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
377       * @param obj1 first Object to place in the message
378       * @param obj2 second Object to place in the message
379       * @param obj3 third object to place in the message
380       * @param exception An error message to be logged
381       */
382  
383      public void log(final int level, final Object obj1, final Object obj2,
384                      final Object obj3, final Throwable exception)
385      {
386          
387  
388          if (check( level))
389          {
390              log(level, new StringBuffer(48).append(obj1).append(obj2)
391                  .append(obj3), exception);
392          }
393      }
394  
395      /**
396       * Log a message. Lazily appends Object parameters together.
397       *
398       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
399       * @param obj1 first Object to place in the message
400       * @param obj2 second Object to place in the message
401       * @param obj3 third object to place in the message
402       * @param obj4 fourth object to place in the message
403       * @param exception An exception to be logged
404       */
405  
406      public void log(final int level, final Object obj1, final Object obj2,
407                      final Object obj3, final Object obj4,
408                      final Throwable exception)
409      {
410          
411  
412          if (check( level))
413          {
414              log(level, new StringBuffer(64).append(obj1).append(obj2)
415                  .append(obj3).append(obj4), exception);
416          }
417      }
418  
419      /**
420       * Log a message. Lazily appends Object parameters together.
421       *
422       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
423       * @param obj1 first Object to place in the message
424       * @param obj2 second Object to place in the message
425       * @param obj3 third object to place in the message
426       * @param obj4 fourth object to place in the message
427       * @param obj5 fifth object to place in the message
428       * @param exception An exception to be logged
429       */
430  
431      public void log(final int level, final Object obj1, final Object obj2,
432                      final Object obj3, final Object obj4, final Object obj5,
433                      final Throwable exception)
434      {
435          
436  
437          if (check( level))
438          {
439              log(level, new StringBuffer(80).append(obj1).append(obj2)
440                  .append(obj3).append(obj4).append(obj5), exception);
441          }
442      }
443  
444      /**
445       * Log a message. Lazily appends Object parameters together.
446       *
447       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
448       * @param obj1 first Object to place in the message
449       * @param obj2 second Object to place in the message
450       * @param obj3 third object to place in the message
451       * @param obj4 fourth object to place in the message
452       * @param obj5 fifth object to place in the message
453       * @param obj6 sixth object to place in the message
454       * @param exception An exception to be logged
455       */
456  
457      public void log(final int level, final Object obj1, final Object obj2,
458                      final Object obj3, final Object obj4, final Object obj5,
459                      final Object obj6, final Throwable exception)
460      {
461          
462  
463          if (check( level))
464          {
465              log(level , new StringBuffer(96).append(obj1)
466                  .append(obj2).append(obj3).append(obj4).append(obj5)
467                  .append(obj6), exception);
468          }
469      }
470  
471      /**
472       * Log a message. Lazily appends Object parameters together.
473       *
474       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
475       * @param obj1 first Object to place in the message
476       * @param obj2 second Object to place in the message
477       * @param obj3 third object to place in the message
478       * @param obj4 fourth object to place in the message
479       * @param obj5 fifth object to place in the message
480       * @param obj6 sixth object to place in the message
481       * @param obj7 seventh object to place in the message
482       * @param exception An exception to be logged
483       */
484  
485      public void log(final int level, final Object obj1, final Object obj2,
486                      final Object obj3, final Object obj4, final Object obj5,
487                      final Object obj6, final Object obj7,
488                      final Throwable exception)
489      {
490          
491  
492          if (check( level))
493          {
494              log(level, new StringBuffer(112).append(obj1).append(obj2)
495                  .append(obj3).append(obj4).append(obj5).append(obj6)
496                  .append(obj7), exception);
497          }
498      }
499  
500      /**
501       * Log a message. Lazily appends Object parameters together.
502       *
503       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
504       * @param obj1 first Object to place in the message
505       * @param obj2 second Object to place in the message
506       * @param obj3 third object to place in the message
507       * @param obj4 fourth object to place in the message
508       * @param obj5 fifth object to place in the message
509       * @param obj6 sixth object to place in the message
510       * @param obj7 seventh object to place in the message
511       * @param obj8 eighth object to place in the message
512       * @param exception An exception to be logged
513       */
514  
515      public void log(final int level, final Object obj1, final Object obj2,
516                      final Object obj3, final Object obj4, final Object obj5,
517                      final Object obj6, final Object obj7, final Object obj8,
518                      final Throwable exception)
519      {
520          
521  
522          if (check( level))
523          {
524              log(level, new StringBuffer(128).append(obj1).append(obj2)
525                  .append(obj3).append(obj4).append(obj5).append(obj6)
526                  .append(obj7).append(obj8), exception);
527          }
528      }
529  
530      /**
531       * Logs a formated message. The message itself may contain %
532       * characters as place holders. This routine will attempt to match
533       * the placeholder by looking at the type of parameter passed to
534       * obj1.<p>
535       *
536       * If the parameter is an array, it traverses the array first and
537       * matches parameters sequentially against the array items.
538       * Otherwise the parameters after <code>message</code> are matched
539       * in order.<p>
540       *
541       * If the place holder matches against a number it is printed as a
542       * whole number. This can be overridden by specifying a precision
543       * in the form %n.m where n is the padding for the whole part and
544       * m is the number of decimal places to display. n can be excluded
545       * if desired. n and m may not be more than 9.<p>
546       *
547       * If the last parameter (after flattening) is a Throwable it is
548       * logged specially.
549       *
550       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
551       * @param message The message to log.
552       * @param obj1 The first object to match against.
553       */
554  
555      public void logFormatted(final int level, final String message,
556                               final Object obj1)
557      {
558          commonLogFormatted(level, message, new Object[]
559          {
560              obj1
561          });
562      }
563  
564      /**
565       * Logs a formated message. The message itself may contain %
566       * characters as place holders. This routine will attempt to match
567       * the placeholder by looking at the type of parameter passed to
568       * obj1.<p>
569       *
570       * If the parameter is an array, it traverses the array first and
571       * matches parameters sequentially against the array items.
572       * Otherwise the parameters after <code>message</code> are matched
573       * in order.<p>
574       *
575       * If the place holder matches against a number it is printed as a
576       * whole number. This can be overridden by specifying a precision
577       * in the form %n.m where n is the padding for the whole part and
578       * m is the number of decimal places to display. n can be excluded
579       * if desired. n and m may not be more than 9.<p>
580       *
581       * If the last parameter (after flattening) is a Throwable it is
582       * logged specially.
583       *
584       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
585       * @param message The message to log.
586       * @param obj1 The first object to match against.
587       * @param obj2 The second object to match against.
588       */
589  
590      public void logFormatted(final int level, final String message,
591                               final Object obj1, final Object obj2)
592      {
593          commonLogFormatted(level, message, new Object[]
594          {
595              obj1, obj2
596          });
597      }
598  
599      /**
600       * Logs a formated message. The message itself may contain %
601       * characters as place holders. This routine will attempt to match
602       * the placeholder by looking at the type of parameter passed to
603       * obj1.<p>
604       *
605       * If the parameter is an array, it traverses the array first and
606       * matches parameters sequentially against the array items.
607       * Otherwise the parameters after <code>message</code> are matched
608       * in order.<p>
609       *
610       * If the place holder matches against a number it is printed as a
611       * whole number. This can be overridden by specifying a precision
612       * in the form %n.m where n is the padding for the whole part and
613       * m is the number of decimal places to display. n can be excluded
614       * if desired. n and m may not be more than 9.<p>
615       *
616       * If the last parameter (after flattening) is a Throwable it is
617       * logged specially.
618       *
619       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
620       * @param message The message to log.
621       * @param obj1 The first object to match against.
622       * @param obj2 The second object to match against.
623       * @param obj3 The third object to match against.
624       */
625  
626      public void logFormatted(final int level, final String message,
627                               final Object obj1, final Object obj2,
628                               final Object obj3)
629      {
630          commonLogFormatted(level, message, new Object[]
631          {
632              obj1, obj2, obj3
633          });
634      }
635  
636      /**
637       * Logs a formated message. The message itself may contain %
638       * characters as place holders. This routine will attempt to match
639       * the placeholder by looking at the type of parameter passed to
640       * obj1.<p>
641       *
642       * If the parameter is an array, it traverses the array first and
643       * matches parameters sequentially against the array items.
644       * Otherwise the parameters after <code>message</code> are matched
645       * in order.<p>
646       *
647       * If the place holder matches against a number it is printed as a
648       * whole number. This can be overridden by specifying a precision
649       * in the form %n.m where n is the padding for the whole part and
650       * m is the number of decimal places to display. n can be excluded
651       * if desired. n and m may not be more than 9.<p>
652       *
653       * If the last parameter (after flattening) is a Throwable it is
654       * logged specially.
655       *
656       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
657       * @param message The message to log.
658       * @param obj1 The first object to match against.
659       * @param obj2 The second object to match against.
660       * @param obj3 The third object to match against.
661       * @param obj4 The forth object to match against.
662       */
663  
664      public void logFormatted(final int level, final String message,
665                               final Object obj1, final Object obj2,
666                               final Object obj3, final Object obj4)
667      {
668          commonLogFormatted(level, message, new Object[]
669          {
670              obj1, obj2, obj3, obj4
671          });
672      }
673  
674      private void commonLogFormatted(final int level, final String message,
675                                      final Object [] unflatParams)
676      {
677          
678  
679          if (check( level))
680          {
681              Object[] params = flattenArrays(unflatParams);
682  
683              if (params[ params.length - 1 ] instanceof Throwable)
684              {
685                  log(level, StringUtil.format(message, params),
686                      ( Throwable ) params[ params.length - 1 ]);
687              }
688              else
689              {
690                  log(level, StringUtil.format(message, params));
691              }
692          }
693      }
694  
695      /**
696       * Flattens any contained objects. Only tranverses one level deep.
697       */
698  
699      private Object [] flattenArrays(final Object [] objects)
700      {
701          List results = new ArrayList();
702  
703          for (int i = 0; i < objects.length; i++)
704          {
705              results.addAll(objectToObjectArray(objects[ i ]));
706          }
707          return ( Object [] ) results.toArray(new Object[ results.size() ]);
708      }
709  
710      private List objectToObjectArray(Object object)
711      {
712          List results = new ArrayList();
713  
714          if (object instanceof byte [])
715          {
716              byte[] array = ( byte [] ) object;
717  
718              for (int j = 0; j < array.length; j++)
719              {
720                  results.add(new Byte(array[ j ]));
721              }
722          }
723          if (object instanceof char [])
724          {
725              char[] array = ( char [] ) object;
726  
727              for (int j = 0; j < array.length; j++)
728              {
729                  results.add(new Character(array[ j ]));
730              }
731          }
732          else if (object instanceof short [])
733          {
734              short[] array = ( short [] ) object;
735  
736              for (int j = 0; j < array.length; j++)
737              {
738                  results.add(new Short(array[ j ]));
739              }
740          }
741          else if (object instanceof int [])
742          {
743              int[] array = ( int [] ) object;
744  
745              for (int j = 0; j < array.length; j++)
746              {
747                  results.add(new Integer(array[ j ]));
748              }
749          }
750          else if (object instanceof long [])
751          {
752              long[] array = ( long [] ) object;
753  
754              for (int j = 0; j < array.length; j++)
755              {
756                  results.add(new Long(array[ j ]));
757              }
758          }
759          else if (object instanceof float [])
760          {
761              float[] array = ( float [] ) object;
762  
763              for (int j = 0; j < array.length; j++)
764              {
765                  results.add(new Float(array[ j ]));
766              }
767          }
768          else if (object instanceof double [])
769          {
770              double[] array = ( double [] ) object;
771  
772              for (int j = 0; j < array.length; j++)
773              {
774                  results.add(new Double(array[ j ]));
775              }
776          }
777          else if (object instanceof Object [])
778          {
779              Object[] array = ( Object [] ) object;
780  
781              for (int j = 0; j < array.length; j++)
782              {
783                  results.add(array[ j ]);
784              }
785          }
786          else
787          {
788              results.add(object);
789          }
790          return results;
791      }
792  }   // end package scope class POILogger
793  
794