/*
 * $Id: XMLLogger.html,v 1.2 2003/09/01 20:28:03 suhrin Exp $
 
 * Copyright (c) 1999-2003 Gnome Ltd. All Rights Reserved.
 
 * This software is the confidential and proprietary information of
 * Gnome Ltd. You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with Gnome Ltd.
 */

package SK.gnome.dwarf.sample;

import java.util.Date;
import java.io.PrintWriter;
import java.io.CharArrayWriter;

import SK.gnome.dwarf.*;
import SK.gnome.dwarf.log.LogLevel;
import SK.gnome.dwarf.log.FileLogger;

/**
 * The XML file logger.
 *
 <p>This logger writes the log messages to a XML file. The DTD for the XML document
 * is as follows:
 <pre>
 *&lt;!ELEMENT log (message?,error?)&gt;
 *&lt;!ATTLIST log time CDATA
 *              level CDATA
 *              facility CDATA&gt;
 *
 *&lt;!ELEMENT message (#PCDATA)&gt;
 *
 *&lt;!ELEMENT error (#PCDATA)&gt;
 *&lt;!ATTLIST error class CDATA #REQUIRED&gt;
 </pre>
 *
 <p>The character encoding of the XML document may be specified via the {@link #setEncoding(String)}
 * method. By default, is uses the <tt>"UTF-8"</tt> encoding, which is suitable for most cases.
 */

public class XMLLogger extends FileLogger

  /**
   * Creates new <tt>FileLogger</tt>.
   *
   <p>The {@link #encoding} protected field is initialized to default <tt>"UTF-8"</tt>
   * character encoding. It may be changed via the {@link #setEncoding(String)} method.
   */

  public XMLLogger(String name)
  super(name);
    encoding = "UTF-8";  // default, but may be changed via setEncoding(String)
  }
  
  /**
   * Initializes the service.
   *
   <p>It calls the superclass' initialization method and then writes the XML header
   * to the output file.
   */

  public void init(Server parentthrows ServiceException
  super.init(parent);

    if (file.length() == 0)
    out.println("<?xml version='1.0' encoding='" + encoding + "'?>");
      out.println("<!DOCTYPE log SYSTEM 'file:lib/xmlLogger.dtd'>");
      out.println();
    }
  }

  protected void write(long time, String facility, LogLevel level, String message, Throwable error)
  StringBuffer sb = new StringBuffer("<log");

    if (dateTime)
      sb.append(" time='").append(dateTimeFormat.format(new Date(time))).append("'");

    if (extendedInfo)
      sb.append(" level='").append(level).append("' facility='").append(facility).append("'");
    sb.append(">");

    // note also that we use <![CDATA[...]]> declaration to prevent problems caused by the
    // XML special characters 

    if (message != null)
      sb.append("<message><![CDATA[").append(message).append("]]></message>");

    // CharArrayWriter is used to convert the exception stack trace to a String because
    // we need to preserve the original Unicode strings. The output PrintStream will then
    // convert them transparently according to the desired encoding.

    if (error != null)
    CharArrayWriter out = new CharArrayWriter();
      PrintWriter writer = new PrintWriter(out, true);
      error.printStackTrace(writer);
      sb.append("<error class='").append(error.getClass().getName()).append("'><![CDATA[");
      sb.append(out.toString()).append("]]></error>");
    }

    sb.append("</log>");
    out.println(sb);
  }    
}