/* XMLFormatter.java
   -- a class for formatting log messages into a standard XML format

Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.util.logging;

import java.util.Date;
import java.util.ResourceBundle;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;

/**
 * An <code>XMLFormatter</code> formats LogRecords into
 * a standard XML format.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class XMLFormatter
  extends Formatter
{
  /**
   * Constructs a new XMLFormatter.
   */
  public XMLFormatter()
  {
  }


  /**
   * The character sequence that is used to separate lines in the
   * generated XML stream. Somewhat surprisingly, the Sun J2SE 1.4
   * reference implementation always uses UNIX line endings, even on
   * platforms that have different line ending conventions (i.e.,
   * DOS). The GNU Classpath implementation does not replicates this
   * bug.
   *
   * See also the Sun bug parade, bug #4462871,
   * "java.util.logging.SimpleFormatter uses hard-coded line separator".
   */
  private static final String lineSep = SimpleFormatter.lineSep;

    
  /**
   * A DateFormat for emitting time in the ISO 8601 format.
   * Since the API specification of SimpleDateFormat does not talk
   * about its thread-safety, we cannot share a singleton instance.
   */
  private final SimpleDateFormat iso8601
    = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");


  /**
   * Appends a line consisting of indentation, opening element tag,
   * element content, closing element tag and line separator to
   * a StringBuffer, provided that the element content is
   * actually existing.
   *
   * @param buf the StringBuffer to which the line will be appended.
   *
   * @param indent the indentation level.
   *
   * @param tag the element tag name, for instance <code>method</code>.
   *
   * @param content the element content, or <code>null</code> to
   *        have no output whatsoever appended to <code>buf</code>.
   */
  private static final void appendTag(StringBuffer buf,
				      int indent,
				      String tag,
				      String content)
  {
    int i;

    if (content == null)
      return;

    for (i = 0; i < indent * 2; i++)
      buf.append(' ');

    buf.append("<");
    buf.append(tag);
    buf.append('>');

    /* Append the content, but escape for XML by replacing
     * '&', '<', '>' and all non-ASCII characters with
     * appropriate escape sequences.
     * The Sun J2SE 1.4 reference implementation does not
     * escape non-ASCII characters. This is a bug in their
     * implementation which has been reported in the Java
     * bug parade as bug number (FIXME: Insert number here).
     */
    for (i = 0; i < content.length(); i++)
    {
      char c = content.charAt(i);
      switch (c)
      {
      case '&':
	buf.append("&amp;");
	break;

      case '<':
	buf.append("&lt;");
	break;

      case '>':
	buf.append("&gt;");
	break;

      default:
	if (((c >= 0x20) && (c <= 0x7e))
	    || (c == /* line feed */ 10)
	    || (c == /* carriage return */ 13))
	  buf.append(c);
	else
	{
	  buf.append("&#");
	  buf.append((int) c);
	  buf.append(';');
	}
	break;
      } /* switch (c) */
    } /* for i */

    buf.append("</");
    buf.append(tag);
    buf.append(">");
    buf.append(lineSep);
  }


  /**
   * Appends a line consisting of indentation, opening element tag,
   * numeric element content, closing element tag and line separator
   * to a StringBuffer.
   *
   * @param buf the StringBuffer to which the line will be appended.
   *
   * @param indent the indentation level.
   *
   * @param tag the element tag name, for instance <code>method</code>.
   *
   * @param content the element content.
   */
  private static final void appendTag(StringBuffer buf,
				      int indent,
				      String tag,
				      long content)
  {
    appendTag(buf, indent, tag, Long.toString(content));
  }


  public String format(LogRecord record)
  {
    StringBuffer    buf = new StringBuffer(400);
    Level           level = record.getLevel();
    long            millis = record.getMillis();
    Object[]        params = record.getParameters();
    ResourceBundle  bundle = record.getResourceBundle();
    String          message;
    
    buf.append("<record>");
    buf.append(lineSep);
    
    
    appendTag(buf, 1, "date", iso8601.format(new Date(millis)));
    appendTag(buf, 1, "millis", record.getMillis());
    appendTag(buf, 1, "sequence", record.getSequenceNumber());
    appendTag(buf, 1, "logger", record.getLoggerName());

    if (level.isStandardLevel())
      appendTag(buf, 1, "level", level.toString());
    else
      appendTag(buf, 1, "level", level.intValue());

    appendTag(buf, 1, "class", record.getSourceClassName());
    appendTag(buf, 1, "method", record.getSourceMethodName());
    appendTag(buf, 1, "thread", record.getThreadID());

    /* The Sun J2SE 1.4 reference implementation does not emit the
     * message in localized form. This is in violation of the API
     * specification. The GNU Classpath implementation intentionally
     * replicates the buggy behavior of the Sun implementation, as
     * different log files might be a big nuisance to users.
     */
    try
    {
      record.setResourceBundle(null);
      message = formatMessage(record);
    }
    finally
    {
      record.setResourceBundle(bundle);
    }
    appendTag(buf, 1, "message", message);

    /* The Sun J2SE 1.4 reference implementation does not
     * emit key, catalog and param tags. This is in violation
     * of the API specification.  The Classpath implementation
     * intentionally replicates the buggy behavior of the
     * Sun implementation, as different log files might be
     * a big nuisance to users.
     *
     * FIXME: File a bug report with Sun. Insert bug number here.
     *
     *
     * key = record.getMessage();
     * if (key == null)
     *   key = "";
     *
     * if ((bundle != null) && !key.equals(message))
     * {
     *   appendTag(buf, 1, "key", key);
     *   appendTag(buf, 1, "catalog", record.getResourceBundleName());
     * }
     *
     * if (params != null)
     * {
     *   for (int i = 0; i < params.length; i++)
     *     appendTag(buf, 1, "param", params[i].toString());
     * }
     */

    /* FIXME: We have no way to obtain the stacktrace before free JVMs
     * support the corresponding method in java.lang.Throwable.  Well,
     * it would be possible to parse the output of printStackTrace,
     * but this would be pretty kludgy. Instead, we postpose the
     * implementation until Throwable has made progress.
     */
    Throwable thrown = record.getThrown();
    if (thrown != null)
    {
      buf.append("  <exception>");
      buf.append(lineSep);

      /* The API specification is not clear about what exactly
       * goes into the XML record for a thrown exception: It
       * could be the result of getMessage(), getLocalizedMessage(),
       * or toString(). Therefore, it was necessary to write a
       * Mauve testlet and run it with the Sun J2SE 1.4 reference
       * implementation. It turned out that the we need to call
       * toString().
       *
       * FIXME: File a bug report with Sun, asking for clearer
       * specs.
       */
      appendTag(buf, 2, "message", thrown.toString());

      /* FIXME: The Logging DTD specifies:
       *
       * <!ELEMENT exception (message?, frame+)>
       *
       * However, java.lang.Throwable.getStackTrace() is
       * allowed to return an empty array. So, what frame should
       * be emitted for an empty stack trace? We probably
       * should file a bug report with Sun, asking for the DTD
       * to be changed.
       */

      buf.append("  </exception>");
      buf.append(lineSep);
    }


    buf.append("</record>");
    buf.append(lineSep);

    return buf.toString();
  }


  /**
   * Returns a string that handlers are supposed to emit before
   * the first log record.  The base implementation returns an
   * empty string, but subclasses such as {@link XMLFormatter}
   * override this method in order to provide a suitable header.
   *
   * @return a string for the header.
   *
   * @param handler the handler which will prepend the returned
   *     string in front of the first log record.  This method
   *     will inspect certain properties of the handler, for
   *     example its encoding, in order to construct the header.
   */
  public String getHead(Handler h)
  {
    StringBuffer  buf;
    String        encoding;

    buf = new StringBuffer(80);
    buf.append("<?xml version=\"1.0\" encoding=\"");

    encoding = h.getEncoding();

    /* file.encoding is a system property with the Sun JVM, indicating
     * the platform-default file encoding. Unfortunately, the API
     * specification for java.lang.System.getProperties() does not
     * list this property.
     */
    if (encoding == null)
      encoding = System.getProperty("file.encoding");

    /* Since file.encoding is not listed with the API specification of
     * java.lang.System.getProperties(), there might be some VMs that
     * do not define this system property.  Therefore, we use UTF-8 as
     * a reasonable default. Please note that if the platform encoding
     * uses the same codepoints as US-ASCII for the US-ASCII character
     * set (e.g, 65 for A), it does not matter whether we emit the
     * wrong encoding into the XML header -- the GNU Classpath will
     * emit XML escape sequences like &#1234; for any non-ASCII
     * character.  Virtually all character encodings use the same code
     * points as US-ASCII for ASCII characters.  Probably, EBCDIC is
     * the only exception.
     */
    if (encoding == null)
      encoding = "UTF-8";
    
    /* On Windows XP localized for Swiss German (this is one of
     * my [Sascha Brawer's] test machines), the default encoding
     * has the canonical name "windows-1252". The "historical" name
     * of this encoding is "Cp1252" (see the Javadoc for the class
     * java.nio.charset.Charset for the distinction). Now, that class
     * does have a method for mapping historical to canonical encoding
     * names. However, if we used it here, we would be come dependent
     * on java.nio.*, which was only introduced with J2SE 1.4.
     * Thus, we do this little hack here. As soon as Classpath supports
     * java.nio.charset.CharSet, this hack should be replaced by
     * code that correctly canonicalizes the encoding name.
     */
    if ((encoding.length() > 2) && encoding.startsWith("Cp"))
      encoding = "windows-" + encoding.substring(2);

    buf.append(encoding);

    buf.append("\" standalone=\"no\"?>");
    buf.append(lineSep);

    /* SYSTEM is not a fully qualified URL so that validating
     * XML parsers do not need to connect to the Internet in
     * order to read in a log file.  See also the Sun Bug Parade,
     * bug #4372790, "Logging APIs: need to use relative URL for XML
     * doctype".
     */
    buf.append("<!DOCTYPE log SYSTEM \"logger.dtd\">");
    buf.append(lineSep);
    buf.append("<log>");
    buf.append(lineSep);

    return buf.toString();
  }


  public String getTail(Handler h)
  {
    return "</log>" + lineSep;
  }
}
