/* Simple1LineFormatter.java -- A simple 1-line logging formatter
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.classpath.debug;

import gnu.java.security.action.GetPropertyAction;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.AccessController;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

/**
 * A simple 1-line formatter to use instead of the 2-line SimpleFormatter used
 * by default in the JDK logging handlers.
 * <p>
 * The fixed format of this formatter is as follows:
 * <p>
 * <ol>
 *   <li>Date: As a yyyy-MM-dd string.</li>
 *   <li>Time: As a HH:mm:ss.SSSS Z string.</li>
 *   <li>Thread identifier, right-justified, and framed in an 11-digit field.</li>
 *   <li>Class name, without its package name, left-justified, and framed in a
 *   32-character field.</li>
 *   <li>Method name, left-justified, and framed in a 32-character field.</li>
 *   <li>Level name, left-justified, and framed in a 6-character field.</li>
 *   <li>User message and arguments.</li>
 *   <li>Platform-dependent line-separator.</li>
 *   <li>Optionally, if the log-record contains a thrown exception, that
 *   exception's stack trace is appended to the output.</li>
 * </ol>
 * <p>
 * Here is an example of the output generated by this formatter:
 * <p>
 * <pre>
 * 2006-02-27 21:59:12.0881 +1100 -1343151280 EncodedKeyFactory                engineGeneratePublic()           FINER - ENTRY java.security.spec.X509EncodedKeySpec@b00d7fc0
 * 2006-02-27 21:59:12.0887 +1100 -1343151280 EncodedKeyFactory                engineGeneratePublic()           FINE  - Exception in DSSPublicKey.valueOf(). Ignore
 * java.security.InvalidParameterException: Unexpected OID: 1.2.840.113549.1.1.1
 *    at gnu.java.security.key.dss.DSSKeyPairX509Codec.decodePublicKey (DSSKeyPairX509Codec.java:205)
 *    at gnu.java.security.key.dss.DSSPublicKey.valueOf (DSSPublicKey.java:136)
 *    at gnu.java.security.jce.sig.EncodedKeyFactory.engineGeneratePublic (EncodedKeyFactory.java:218)
 *    at java.security.KeyFactory.generatePublic (KeyFactory.java:219)
 *    at gnu.java.security.x509.X509Certificate.parse (X509Certificate.java:657)
 *    at gnu.java.security.x509.X509Certificate.<init> (X509Certificate.java:163)
 *    ...
 * 2006-02-27 21:59:12.0895 +1100 -1343151280 RSAKeyPairX509Codec              decodePublicKey()                FINER - ENTRY [B@b00d7fd0
 * 2006-02-27 21:59:12.0897 +1100 -1343151280 RSAKeyPairX509Codec              decodePublicKey()                FINER - RETURN gnu.java.security.key.rsa.GnuRSAPublicKey@b00fb940
 * </pre>
 */
public class Simple1LineFormatter
    extends Formatter
{
  private static final String DAT_PATTERN = "yyyy-MM-dd HH:mm:ss.SSSS Z ";
  private static final String THREAD_PATTERN = " #########0;-#########0";
  private static final String SPACES_32 = "                                ";
  private static final String SPACES_6 = "      ";
  private static final String LS = (String) AccessController.doPrivileged
    (new GetPropertyAction("line.separator"));
  private DateFormat dateFormat;
  private NumberFormat threadFormat;

  // default 0-arguments constructor

  public String format(LogRecord record)
  {
    if (dateFormat == null)
      dateFormat = new SimpleDateFormat(DAT_PATTERN);

    if (threadFormat == null)
      threadFormat = new DecimalFormat(THREAD_PATTERN);

    StringBuilder sb = new StringBuilder(180)
        .append(dateFormat.format(new Date(record.getMillis())))
        .append(threadFormat.format(record.getThreadID()))
        .append(" ");
    String s = record.getSourceClassName();
    if (s == null)
      sb.append(SPACES_32);
    else
      {
        s = s.trim();
        int i = s.lastIndexOf(".");
        if (i != - 1)
          s = s.substring(i + 1);

        s = (s + SPACES_32).substring(0, 32);
      }

    sb.append(s).append(" ");
    s = record.getSourceMethodName();
    if (s == null)
      sb.append(SPACES_32);
    else
      {
        s = s.trim();
        if (s.endsWith("()"))
          s = (s.trim() + SPACES_32).substring(0, 32);
        else
          s = (s.trim() + "()" + SPACES_32).substring(0, 32);
      }

    sb.append(s).append(" ");
    s = String.valueOf(record.getLevel());
    if (s == null)
      sb.append(SPACES_6);
    else
      s = (s.trim() + SPACES_6).substring(0, 6);

    sb.append(s).append(" - ").append(formatMessage(record)).append(LS);
    Throwable cause = record.getThrown();
    if (cause != null)
      {
        StringWriter sw = new StringWriter();
        cause.printStackTrace(new PrintWriter(sw, true));
        sb.append(sw.toString());
      }

    return sb.toString();
  }
}
