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 interface 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 abstract class POILogger
72   {
73   
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        * @param log the object that does the real work of logging
85        */
86       POILogger()
87       {}
88       
89       abstract public void initialize(final String cat);
90       
91       abstract public void log(final int level, final Object obj1);
92   
93       /**
94        * Check if a logger is enabled to log at the specified level
95        *
96        * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
97        * @param obj1 The logger to check.
98        */
99       abstract public boolean check(final int level);
100  
101      /**
102       * Log a message. Lazily appends Object parameters together.
103       *
104       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
105       * @param obj1 first object to place in the message
106       * @param obj2 second object to place in the message
107       */
108  
109     /**
110       * Log a message. Lazily appends Object parameters together.
111       *
112       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
113       * @param obj1 first object to place in the message
114       * @param obj2 second object to place in the message
115       */
116  
117      public void log(final int level, final Object obj1, final Object obj2)
118      {
119          if (check(level))
120          {
121              log(level, new StringBuffer(32).append(obj1).append(obj2));
122          }
123      }
124  
125      /**
126       * Log a message. Lazily appends Object parameters together.
127       *
128       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
129       * @param obj1 first Object to place in the message
130       * @param obj2 second Object to place in the message
131       * @param obj3 third Object to place in the message
132       */
133  
134      public void log(final int level, final Object obj1, final Object obj2,
135                      final Object obj3)
136      {
137          
138  
139          if (check(level))
140          {
141              log(level,
142                      new StringBuffer(48).append(obj1).append(obj2)
143                          .append(obj3));
144          }
145      }
146  
147      /**
148       * Log a message. Lazily appends Object parameters together.
149       *
150       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
151       * @param obj1 first Object to place in the message
152       * @param obj2 second Object to place in the message
153       * @param obj3 third Object to place in the message
154       * @param obj4 fourth Object to place in the message
155       */
156  
157      public void log(final int level, final Object obj1, final Object obj2,
158                      final Object obj3, final Object obj4)
159      {
160          
161  
162          if (check(level))
163          {
164              log(level,
165                      new StringBuffer(64).append(obj1).append(obj2)
166                          .append(obj3).append(obj4));
167          }
168      }
169  
170      /**
171       * Log a message. Lazily appends Object parameters together.
172       *
173       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
174       * @param obj1 first Object to place in the message
175       * @param obj2 second Object to place in the message
176       * @param obj3 third Object to place in the message
177       * @param obj4 fourth Object to place in the message
178       * @param obj5 fifth Object to place in the message
179       */
180  
181      public void log(final int level, final Object obj1, final Object obj2,
182                      final Object obj3, final Object obj4, final Object obj5)
183      {
184          
185  
186          if (check(level))
187          {
188              log(level,
189                      new StringBuffer(80).append(obj1).append(obj2)
190                          .append(obj3).append(obj4).append(obj5));
191          }
192      }
193  
194      /**
195       * Log a message. Lazily appends Object parameters together.
196       *
197       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
198       * @param obj1 first Object to place in the message
199       * @param obj2 second Object to place in the message
200       * @param obj3 third Object to place in the message
201       * @param obj4 fourth Object to place in the message
202       * @param obj5 fifth Object to place in the message
203       * @param obj6 sixth Object to place in the message
204       */
205  
206      public void log(final int level, final Object obj1, final Object obj2,
207                      final Object obj3, final Object obj4, final Object obj5,
208                      final Object obj6)
209      {
210          
211  
212          if (check(level))
213          {
214              log(level ,
215                      new StringBuffer(96).append(obj1).append(obj2)
216                          .append(obj3).append(obj4).append(obj5).append(obj6));
217          }
218      }
219  
220      /**
221       * Log a message. Lazily appends Object parameters together.
222       *
223       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
224       * @param obj1 first Object to place in the message
225       * @param obj2 second Object to place in the message
226       * @param obj3 third Object to place in the message
227       * @param obj4 fourth Object to place in the message
228       * @param obj5 fifth Object to place in the message
229       * @param obj6 sixth Object to place in the message
230       * @param obj7 seventh Object to place in the message
231       */
232  
233      public void log(final int level, final Object obj1, final Object obj2,
234                      final Object obj3, final Object obj4, final Object obj5,
235                      final Object obj6, final Object obj7)
236      {
237          
238  
239          if (check(level))
240          {
241              log(level,
242                      new StringBuffer(112).append(obj1).append(obj2)
243                          .append(obj3).append(obj4).append(obj5).append(obj6)
244                          .append(obj7));
245          }
246      }
247  
248      /**
249       * Log a message. Lazily appends Object parameters together.
250       *
251       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
252       * @param obj1 first Object to place in the message
253       * @param obj2 second Object to place in the message
254       * @param obj3 third Object to place in the message
255       * @param obj4 fourth Object to place in the message
256       * @param obj5 fifth Object to place in the message
257       * @param obj6 sixth Object to place in the message
258       * @param obj7 seventh Object to place in the message
259       * @param obj8 eighth Object to place in the message
260       */
261  
262      public void log(final int level, final Object obj1, final Object obj2,
263                      final Object obj3, final Object obj4, final Object obj5,
264                      final Object obj6, final Object obj7, final Object obj8)
265      {
266          
267  
268          if (check(level))
269          {
270              log(level,
271                      new StringBuffer(128).append(obj1).append(obj2)
272                          .append(obj3).append(obj4).append(obj5).append(obj6)
273                          .append(obj7).append(obj8));
274          }
275      }
276  
277      /**
278       * Log a message
279       *
280       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
281       * @param obj1 The object to log.  This is converted to a string.
282       * @param exception An exception to be logged
283       */
284  
285      public void log(final int level, final Object obj1,
286                      final Throwable exception)
287      {
288          log(level , obj1, exception);
289      }
290  
291      /**
292       * Log a message. Lazily appends Object parameters together.
293       *
294       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
295       * @param obj1 first Object to place in the message
296       * @param obj2 second Object to place in the message
297       * @param exception An exception to be logged
298       */
299  
300      public void log(final int level, final Object obj1, final Object obj2,
301                      final Throwable exception)
302      {
303          
304  
305          if (check(level))
306          {
307              log(level, new StringBuffer(32).append(obj1).append(obj2),
308                      exception);
309          }
310      }
311  
312      /**
313       * Log a message. Lazily appends Object parameters together.
314       *
315       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
316       * @param obj1 first Object to place in the message
317       * @param obj2 second Object to place in the message
318       * @param obj3 third object to place in the message
319       * @param exception An error message to be logged
320       */
321  
322      public void log(final int level, final Object obj1, final Object obj2,
323                      final Object obj3, final Throwable exception)
324      {
325          
326  
327          if (check(level))
328          {
329              log(level, new StringBuffer(48).append(obj1).append(obj2)
330                  .append(obj3), exception);
331          }
332      }
333  
334      /**
335       * Log a message. Lazily appends Object parameters together.
336       *
337       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
338       * @param obj1 first Object to place in the message
339       * @param obj2 second Object to place in the message
340       * @param obj3 third object to place in the message
341       * @param obj4 fourth object to place in the message
342       * @param exception An exception to be logged
343       */
344  
345      public void log(final int level, final Object obj1, final Object obj2,
346                      final Object obj3, final Object obj4,
347                      final Throwable exception)
348      {
349          
350  
351          if (check(level))
352          {
353              log(level, new StringBuffer(64).append(obj1).append(obj2)
354                  .append(obj3).append(obj4), exception);
355          }
356      }
357  
358      /**
359       * Log a message. Lazily appends Object parameters together.
360       *
361       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
362       * @param obj1 first Object to place in the message
363       * @param obj2 second Object to place in the message
364       * @param obj3 third object to place in the message
365       * @param obj4 fourth object to place in the message
366       * @param obj5 fifth object to place in the message
367       * @param exception An exception to be logged
368       */
369  
370      public void log(final int level, final Object obj1, final Object obj2,
371                      final Object obj3, final Object obj4, final Object obj5,
372                      final Throwable exception)
373      {
374          
375  
376          if (check(level))
377          {
378              log(level, new StringBuffer(80).append(obj1).append(obj2)
379                  .append(obj3).append(obj4).append(obj5), exception);
380          }
381      }
382  
383      /**
384       * Log a message. Lazily appends Object parameters together.
385       *
386       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
387       * @param obj1 first Object to place in the message
388       * @param obj2 second Object to place in the message
389       * @param obj3 third object to place in the message
390       * @param obj4 fourth object to place in the message
391       * @param obj5 fifth object to place in the message
392       * @param obj6 sixth object to place in the message
393       * @param exception An exception to be logged
394       */
395  
396      public void log(final int level, final Object obj1, final Object obj2,
397                      final Object obj3, final Object obj4, final Object obj5,
398                      final Object obj6, final Throwable exception)
399      {
400          
401  
402          if (check(level))
403          {
404              log(level , new StringBuffer(96).append(obj1)
405                  .append(obj2).append(obj3).append(obj4).append(obj5)
406                  .append(obj6), exception);
407          }
408      }
409  
410      /**
411       * Log a message. Lazily appends Object parameters together.
412       *
413       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
414       * @param obj1 first Object to place in the message
415       * @param obj2 second Object to place in the message
416       * @param obj3 third object to place in the message
417       * @param obj4 fourth object to place in the message
418       * @param obj5 fifth object to place in the message
419       * @param obj6 sixth object to place in the message
420       * @param obj7 seventh object to place in the message
421       * @param exception An exception to be logged
422       */
423  
424      public void log(final int level, final Object obj1, final Object obj2,
425                      final Object obj3, final Object obj4, final Object obj5,
426                      final Object obj6, final Object obj7,
427                      final Throwable exception)
428      {
429          
430  
431          if (check(level))
432          {
433              log(level, new StringBuffer(112).append(obj1).append(obj2)
434                  .append(obj3).append(obj4).append(obj5).append(obj6)
435                  .append(obj7), exception);
436          }
437      }
438  
439      /**
440       * Log a message. Lazily appends Object parameters together.
441       *
442       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
443       * @param obj1 first Object to place in the message
444       * @param obj2 second Object to place in the message
445       * @param obj3 third object to place in the message
446       * @param obj4 fourth object to place in the message
447       * @param obj5 fifth object to place in the message
448       * @param obj6 sixth object to place in the message
449       * @param obj7 seventh object to place in the message
450       * @param obj8 eighth object to place in the message
451       * @param exception An exception to be logged
452       */
453  
454      public void log(final int level, final Object obj1, final Object obj2,
455                      final Object obj3, final Object obj4, final Object obj5,
456                      final Object obj6, final Object obj7, final Object obj8,
457                      final Throwable exception)
458      {
459          
460  
461          if (check(level))
462          {
463              log(level, new StringBuffer(128).append(obj1).append(obj2)
464                  .append(obj3).append(obj4).append(obj5).append(obj6)
465                  .append(obj7).append(obj8), exception);
466          }
467      }
468  
469      /**
470       * Logs a formated message. The message itself may contain %
471       * characters as place holders. This routine will attempt to match
472       * the placeholder by looking at the type of parameter passed to
473       * obj1.<p>
474       *
475       * If the parameter is an array, it traverses the array first and
476       * matches parameters sequentially against the array items.
477       * Otherwise the parameters after <code>message</code> are matched
478       * in order.<p>
479       *
480       * If the place holder matches against a number it is printed as a
481       * whole number. This can be overridden by specifying a precision
482       * in the form %n.m where n is the padding for the whole part and
483       * m is the number of decimal places to display. n can be excluded
484       * if desired. n and m may not be more than 9.<p>
485       *
486       * If the last parameter (after flattening) is a Throwable it is
487       * logged specially.
488       *
489       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
490       * @param message The message to log.
491       * @param obj1 The first object to match against.
492       */
493  
494      public void logFormatted(final int level, final String message,
495                               final Object obj1)
496      {
497          commonLogFormatted(level, message, new Object[]
498          {
499              obj1
500          });
501      }
502  
503      /**
504       * Logs a formated message. The message itself may contain %
505       * characters as place holders. This routine will attempt to match
506       * the placeholder by looking at the type of parameter passed to
507       * obj1.<p>
508       *
509       * If the parameter is an array, it traverses the array first and
510       * matches parameters sequentially against the array items.
511       * Otherwise the parameters after <code>message</code> are matched
512       * in order.<p>
513       *
514       * If the place holder matches against a number it is printed as a
515       * whole number. This can be overridden by specifying a precision
516       * in the form %n.m where n is the padding for the whole part and
517       * m is the number of decimal places to display. n can be excluded
518       * if desired. n and m may not be more than 9.<p>
519       *
520       * If the last parameter (after flattening) is a Throwable it is
521       * logged specially.
522       *
523       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
524       * @param message The message to log.
525       * @param obj1 The first object to match against.
526       * @param obj2 The second object to match against.
527       */
528  
529      public void logFormatted(final int level, final String message,
530                               final Object obj1, final Object obj2)
531      {
532          commonLogFormatted(level, message, new Object[]
533          {
534              obj1, obj2
535          });
536      }
537  
538      /**
539       * Logs a formated message. The message itself may contain %
540       * characters as place holders. This routine will attempt to match
541       * the placeholder by looking at the type of parameter passed to
542       * obj1.<p>
543       *
544       * If the parameter is an array, it traverses the array first and
545       * matches parameters sequentially against the array items.
546       * Otherwise the parameters after <code>message</code> are matched
547       * in order.<p>
548       *
549       * If the place holder matches against a number it is printed as a
550       * whole number. This can be overridden by specifying a precision
551       * in the form %n.m where n is the padding for the whole part and
552       * m is the number of decimal places to display. n can be excluded
553       * if desired. n and m may not be more than 9.<p>
554       *
555       * If the last parameter (after flattening) is a Throwable it is
556       * logged specially.
557       *
558       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
559       * @param message The message to log.
560       * @param obj1 The first object to match against.
561       * @param obj2 The second object to match against.
562       * @param obj3 The third object to match against.
563       */
564  
565      public void logFormatted(final int level, final String message,
566                               final Object obj1, final Object obj2,
567                               final Object obj3)
568      {
569          commonLogFormatted(level, message, new Object[]
570          {
571              obj1, obj2, obj3
572          });
573      }
574  
575      /**
576       * Logs a formated message. The message itself may contain %
577       * characters as place holders. This routine will attempt to match
578       * the placeholder by looking at the type of parameter passed to
579       * obj1.<p>
580       *
581       * If the parameter is an array, it traverses the array first and
582       * matches parameters sequentially against the array items.
583       * Otherwise the parameters after <code>message</code> are matched
584       * in order.<p>
585       *
586       * If the place holder matches against a number it is printed as a
587       * whole number. This can be overridden by specifying a precision
588       * in the form %n.m where n is the padding for the whole part and
589       * m is the number of decimal places to display. n can be excluded
590       * if desired. n and m may not be more than 9.<p>
591       *
592       * If the last parameter (after flattening) is a Throwable it is
593       * logged specially.
594       *
595       * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
596       * @param message The message to log.
597       * @param obj1 The first object to match against.
598       * @param obj2 The second object to match against.
599       * @param obj3 The third object to match against.
600       * @param obj4 The forth object to match against.
601       */
602  
603      public void logFormatted(final int level, final String message,
604                               final Object obj1, final Object obj2,
605                               final Object obj3, final Object obj4)
606      {
607          commonLogFormatted(level, message, new Object[]
608          {
609              obj1, obj2, obj3, obj4
610          });
611      }                             
612  
613      private void commonLogFormatted(final int level, final String message,
614                                      final Object [] unflatParams)
615      {
616          
617  
618          if (check(level))
619          {
620              Object[] params = flattenArrays(unflatParams);
621  
622              if (params[ params.length - 1 ] instanceof Throwable)
623              {
624                  log(level, StringUtil.format(message, params),
625                      ( Throwable ) params[ params.length - 1 ]);
626              }
627              else
628              {
629                  log(level, StringUtil.format(message, params));
630              }
631          }
632      }
633  
634      /**
635       * Flattens any contained objects. Only tranverses one level deep.
636       */
637  
638      private Object [] flattenArrays(final Object [] objects)
639      {
640          List results = new ArrayList();
641  
642          for (int i = 0; i < objects.length; i++)
643          {
644              results.addAll(objectToObjectArray(objects[ i ]));
645          }
646          return ( Object [] ) results.toArray(new Object[ results.size() ]);
647      }
648  
649      private List objectToObjectArray(Object object)
650      {
651          List results = new ArrayList();
652  
653          if (object instanceof byte [])
654          {
655              byte[] array = ( byte [] ) object;
656  
657              for (int j = 0; j < array.length; j++)
658              {
659                  results.add(new Byte(array[ j ]));
660              }
661          }
662          if (object instanceof char [])
663          {
664              char[] array = ( char [] ) object;
665  
666              for (int j = 0; j < array.length; j++)
667              {
668                  results.add(new Character(array[ j ]));
669              }
670          }
671          else if (object instanceof short [])
672          {
673              short[] array = ( short [] ) object;
674  
675              for (int j = 0; j < array.length; j++)
676              {
677                  results.add(new Short(array[ j ]));
678              }
679          }
680          else if (object instanceof int [])
681          {
682              int[] array = ( int [] ) object;
683  
684              for (int j = 0; j < array.length; j++)
685              {
686                  results.add(new Integer(array[ j ]));
687              }
688          }
689          else if (object instanceof long [])
690          {
691              long[] array = ( long [] ) object;
692  
693              for (int j = 0; j < array.length; j++)
694              {
695                  results.add(new Long(array[ j ]));
696              }
697          }
698          else if (object instanceof float [])
699          {
700              float[] array = ( float [] ) object;
701  
702              for (int j = 0; j < array.length; j++)
703              {
704                  results.add(new Float(array[ j ]));
705              }
706          }
707          else if (object instanceof double [])
708          {
709              double[] array = ( double [] ) object;
710  
711              for (int j = 0; j < array.length; j++)
712              {
713                  results.add(new Double(array[ j ]));
714              }
715          }
716          else if (object instanceof Object [])
717          {
718              Object[] array = ( Object [] ) object;
719  
720              for (int j = 0; j < array.length; j++)
721              {
722                  results.add(array[ j ]);
723              }
724          }
725          else
726          {
727              results.add(object);
728          }
729          return results;
730      }
731                                   
732  }   // end package scope abstract class POILogger
733  
734