1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.common.util;
21  
22  import java.io.PrintWriter;
23  import java.io.StringWriter;
24  import java.text.MessageFormat;
25  import java.util.Date;
26  import java.util.logging.Formatter;
27  import java.util.logging.LogManager;
28  import java.util.logging.LogRecord;
29  import java.util.logging.Logger;
30  
31  /**
32   * Formats a log entry by pattern.
33   * 
34   * <ul>
35   * <li>{0} is the Date</li>
36   * <li>{1} is the name of the logger</li>
37   * <li>{2} is the level of the record</li>
38   * <li>{3} is the message</li>
39   * <li>{4} is the throwable</li>
40   * <li>{5} is the class name (typically the same as the logger's name)</li>
41   * <li>{6} is the method name</li>
42   * <li>{7} is the line number</li>
43   * <li>{8} is the system supplied new line</li>
44   * </ul>
45   * 
46   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
47   * @author DM Smith
48   * @author Joe Walker
49   */
50  public class PatternFormatter extends Formatter {
51      /**
52       * Format the given LogRecord.
53       * 
54       * @param record
55       *            the log record to be formatted.
56       * @return a formatted log record
57       */
58      @Override
59      public synchronized String format(LogRecord record) {
60          // Minimize memory allocations here.
61          dat.setTime(record.getMillis());
62          String throwable = "";
63          if (record.getThrown() != null) {
64              StringWriter sw = new StringWriter();
65              PrintWriter pw = new PrintWriter(sw);
66              record.getThrown().printStackTrace(pw);
67              pw.close();
68              throwable = sw.toString();
69          }
70  
71          String format = LogManager.getLogManager().getProperty(PatternFormatter.class.getName() + ".format");
72          String loggerName = record.getLoggerName();
73          Logger logger = LogManager.getLogManager().getLogger(loggerName);
74  
75          for (Logger aLogger = logger; aLogger != null; aLogger = aLogger.getParent()) {
76              String property = null;
77              String aLoggerName = aLogger.getName();
78  
79              if (aLoggerName != null) {
80                  property = LogManager.getLogManager().getProperty(aLoggerName + ".format");
81              }
82  
83              if (property != null) {
84                  format = property;
85                  break;
86              }
87          }
88  
89          if (format == null) {
90              format = DEFAULT_FORMAT;
91          }
92  
93          return MessageFormat.format(format,
94                  dat, // 0
95                  record.getLoggerName(), // 1
96                  record.getLevel().getLocalizedName(), // 2
97                  formatMessage(record), // 3
98                  throwable, // 4
99                  record.getSourceClassName(), // 5
100                 record.getSourceMethodName(), // 6
101                 Long.valueOf(record.getSequenceNumber()), // 7
102                 lineSeparator // 8
103         );
104     }
105 
106     private Date dat = new Date();
107     private static final String DEFAULT_FORMAT = "{1}({2}): {3}{8} {4}";
108 
109     // Line separator string. This is the value of the line.separator
110     // property at the moment that the PatternFormatter was created.
111     private String lineSeparator = System.getProperty("line.separator", "\r\n");
112 }
113