/* LogRecord.java --
   A class for the state associated with individual logging events
   Copyright (C) 2002, 2003, 2004  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 java.util.logging;

import java.util.ResourceBundle;


/**
 * A <code>LogRecord</code> contains the state for an individual
 * event to be logged.
 *
 * <p>As soon as a LogRecord instance has been handed over to the
 * logging framework, applications should not manipulate it anymore.
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class LogRecord
  implements java.io.Serializable
{
  /**
   * The severity level of this <code>LogRecord</code>.
   */
  private Level      level;


  /**
   * The sequence number of this <code>LogRecord</code>.
   */
  private long       sequenceNumber;


  /**
   * The name of the class that issued the logging request, or
   * <code>null</code> if this information could not be obtained.
   */
  private String     sourceClassName;


  /**
   * The name of the method that issued the logging request, or
   * <code>null</code> if this information could not be obtained.
   */
  private String sourceMethodName;


  /**
   * The message for this <code>LogRecord</code> before
   * any localization or formatting.
   */
  private String message;


  /**
   * An identifier for the thread in which this <code>LogRecord</code>
   * was created.  The identifier is not necessarily related to any
   * thread identifiers used by the operating system.
   */
  private int threadID;


  /**
   * The time when this <code>LogRecord</code> was created,
   * in milliseconds since the beginning of January 1, 1970.
   */
  private long millis;


  /**
   * The Throwable associated with this <code>LogRecord</code>, or
   * <code>null</code> if the logged event is not related to an
   * exception or error.
   */
  private Throwable thrown;


  /**
   * The name of the logger where this <code>LogRecord</code> has
   * originated, or <code>null</code> if this <code>LogRecord</code>
   * does not originate from a <code>Logger</code>.
   */
  private String  loggerName;


  /**
   * The name of the resource bundle used for localizing log messages,
   * or <code>null</code> if no bundle has been specified.
   */
  private String resourceBundleName;

  private transient Object[] parameters;

  private transient ResourceBundle bundle;


  /**
   * Constructs a <code>LogRecord</code> given a severity level and
   * an unlocalized message text.  In addition, the sequence number,
   * creation time (as returned by <code>getMillis()</code>) and
   * thread ID are assigned. All other properties are set to
   * <code>null</code>.
   *
   * @param level the severity level, for example <code>Level.WARNING</code>.
   *
   * @param message the message text (which will be used as key
   *                for looking up the localized message text
   *                if a resource bundle has been associated). 
   */
  public LogRecord(Level level, String message)
  {
    this.level = level;
    this.message = message;
    this.millis = System.currentTimeMillis();

    /* A subclass of java.lang.Thread could override hashCode(),
     * in which case the result would not be guaranteed anymore
     * to be unique among all threads.  While System.identityHashCode
     * is not necessarily unique either, it at least cannot be
     * overridden by user code.  However, is might be a good idea
     * to use something better for generating thread IDs.
     */
    this.threadID = System.identityHashCode(Thread.currentThread());

    sequenceNumber = allocateSeqNum();
  }


  /**
   * Determined with the serialver tool of the Sun J2SE 1.4.
   */
  static final long serialVersionUID = 5372048053134512534L;

  private void readObject(java.io.ObjectInputStream in)
    throws java.io.IOException, java.lang.ClassNotFoundException
  {
    in.defaultReadObject();

    /* We assume that future versions will be downwards compatible,
     * so we can ignore the versions.
     */
    byte majorVersion = in.readByte();
    byte minorVersion = in.readByte();

    int numParams = in.readInt();
    if (numParams >= 0)
    {
      parameters = new Object[numParams];
      for (int i = 0; i < numParams; i++)
	parameters[i] = in.readObject();
    }
  }


  /**
   * @serialData The default fields, followed by a major byte version
   * number, followed by a minor byte version number, followed by
   * information about the log record parameters.  If
   * <code>parameters</code> is <code>null</code>, the integer -1 is
   * written, otherwise the length of the <code>parameters</code>
   * array (which can be zero), followed by the result of calling
   * {@link Object#toString() toString()} on the parameter (or
   * <code>null</code> if the parameter is <code>null</code>).
   *
   * <p><strong>Specification Note:</strong> The Javadoc for the
   * Sun reference implementation does not specify the version
   * number. FIXME: Reverse-engineer the JDK and file a bug
   * report with Sun, asking for amendment of the specification.
   */
  private void writeObject(java.io.ObjectOutputStream out)
    throws java.io.IOException
  {
    out.defaultWriteObject();

    /* Major, minor version number: The Javadoc for J2SE1.4 does not
     * specify the values.
     */
    out.writeByte(0);
    out.writeByte(0);

    if (parameters == null)
      out.writeInt(-1);
    else
    {
      out.writeInt(parameters.length);
      for (int i = 0; i < parameters.length; i++)
      {
	if (parameters[i] == null)
	  out.writeObject(null);
	else
	  out.writeObject(parameters[i].toString());
      }
    }
  }


  /**
   * Returns the name of the logger where this <code>LogRecord</code>
   * has originated.
   *
   * @return the name of the source {@link Logger}, or
   *         <code>null</code> if this <code>LogRecord</code>
   *         does not originate from a <code>Logger</code>.
   */
  public String getLoggerName()
  {
    return loggerName;
  }


  /**
   * Sets the name of the logger where this <code>LogRecord</code>
   * has originated.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param name the name of the source logger, or <code>null</code> to
   *             indicate that this <code>LogRecord</code> does not
   *             originate from a <code>Logger</code>.
   */
  public void setLoggerName(String name)
  {
    loggerName = name;
  }


  /**
   * Returns the resource bundle that is used when the message
   * of this <code>LogRecord</code> needs to be localized.
   *
   * @return the resource bundle used for localization,
   *         or <code>null</code> if this message does not need
   *         to be localized.
   */
  public ResourceBundle getResourceBundle()
  {
    return bundle;
  }


  /**
   * Sets the resource bundle that is used when the message
   * of this <code>LogRecord</code> needs to be localized.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param bundle  the resource bundle to be used, or
   *                <code>null</code> to indicate that this
   *                message does not need to be localized.
   */
  public void setResourceBundle(ResourceBundle bundle)
  {
    this.bundle = bundle;

    /* FIXME: Is there a way to infer the name
     * of a resource bundle from a ResourceBundle object?
     */
    this.resourceBundleName = null;
  }


  /**
   * Returns the name of the resource bundle that is used when the
   * message of this <code>LogRecord</code> needs to be localized.
   *
   * @return the name of the resource bundle used for localization,
   *         or <code>null</code> if this message does not need
   *         to be localized.
   */
  public String getResourceBundleName()
  {
    return resourceBundleName;
  }


  /**
   * Sets the name of the resource bundle that is used when the
   * message of this <code>LogRecord</code> needs to be localized.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param name the name of the resource bundle to be used, or
   *             <code>null</code> to indicate that this message
   *             does not need to be localized.
   */
  public void setResourceBundleName(String name)
  {
    resourceBundleName = name;
    bundle = null;
    
    try
    {
      if (resourceBundleName != null)
	bundle = ResourceBundle.getBundle(resourceBundleName);
    }
    catch (java.util.MissingResourceException _)
    {
    }
  }


  /**
   * Returns the level of the LogRecord.
   *
   * <p>Applications should be aware of the possibility that the
   *  result is not necessarily one of the standard logging levels,
   *  since the logging framework allows to create custom subclasses
   *  of <code>java.util.logging.Level</code>.  Therefore, filters
   *  should perform checks like <code>theRecord.getLevel().intValue()
   *  == Level.INFO.intValue()</code> instead of <code>theRecord.getLevel()
   *  == Level.INFO</code>.
   */
  public Level getLevel()
  {
    return level;
  }


  /**
   * Sets the severity level of this <code>LogRecord</code> to a new
   * value.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param level the new severity level, for example
   *              <code>Level.WARNING</code>.
   */
  public void setLevel(Level level)
  {
    this.level = level;
  }


  /**
   * The last used sequence number for any LogRecord.
   */
  private static long lastSeqNum;


  /**
   * Allocates a sequence number for a new LogRecord.  This class
   * method is only called by the LogRecord constructor.
   */
  private static synchronized long allocateSeqNum()
  {
    lastSeqNum += 1;
    return lastSeqNum;
  }


  /**
   * Returns the sequence number of this <code>LogRecord</code>.
   */
  public long getSequenceNumber()
  {
    return sequenceNumber;
  }


  /**
   * Sets the sequence number of this <code>LogRecord</code> to a new
   * value.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param seqNum the new sequence number.
   */
  public void setSequenceNumber(long seqNum)
  {
    this.sequenceNumber = seqNum;
  }


  /**
   * Returns the name of the class where the event being logged
   * has had its origin.  This information can be passed as
   * parameter to some logging calls, and in certain cases, the
   * logging framework tries to determine an approximation
   * (which may or may not be accurate).
   * 
   * @return the name of the class that issued the logging request,
   *         or <code>null</code> if this information could not
   *         be obtained.
   */
  public String getSourceClassName()
  {
    if (sourceClassName != null)
      return sourceClassName;

    /*  FIXME: Should infer this information from the call stack. */
    return null;
  }


  /**
   * Sets the name of the class where the event being logged
   * has had its origin.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   * 
   * @param sourceClassName the name of the class that issued the
   *          logging request, or <code>null</code> to indicate that
   *          this information could not be obtained.
   */
  public void setSourceClassName(String sourceClassName)
  {
    this.sourceClassName = sourceClassName;
  }


  /**
   * Returns the name of the method where the event being logged
   * has had its origin.  This information can be passed as
   * parameter to some logging calls, and in certain cases, the
   * logging framework tries to determine an approximation
   * (which may or may not be accurate).
   * 
   * @return the name of the method that issued the logging request,
   *         or <code>null</code> if this information could not
   *         be obtained.
   */
  public String getSourceMethodName()
  {
    if (sourceMethodName != null)
      return sourceMethodName;

    /* FIXME: Should infer this information from the call stack. */
    return null;
  }


  /**
   * Sets the name of the method where the event being logged
   * has had its origin.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   * 
   * @param sourceMethodName the name of the method that issued the
   *          logging request, or <code>null</code> to indicate that
   *          this information could not be obtained.
   */
  public void setSourceMethodName(String sourceMethodName)
  {
    this.sourceMethodName = sourceMethodName;
  }


  /**
   * Returns the message for this <code>LogRecord</code> before
   * any localization or parameter substitution.
   *
   * <p>A {@link Logger} will try to localize the message
   * if a resource bundle has been associated with this
   * <code>LogRecord</code>.  In this case, the logger will call
   * <code>getMessage()</code> and use the result as the key
   * for looking up the localized message in the bundle.
   * If no bundle has been associated, or if the result of
   * <code>getMessage()</code> is not a valid key in the
   * bundle, the logger will use the raw message text as
   * returned by this method.
   *
   * @return the message text, or <code>null</code> if there
   *         is no message text.
   */
  public String getMessage()
  {
    return message;
  }


  /**
   * Sets the message for this <code>LogRecord</code>.
   *
   * <p>A <code>Logger</code> will try to localize the message
   * if a resource bundle has been associated with this
   * <code>LogRecord</code>.  In this case, the logger will call
   * <code>getMessage()</code> and use the result as the key
   * for looking up the localized message in the bundle.
   * If no bundle has been associated, or if the result of
   * <code>getMessage()</code> is not a valid key in the
   * bundle, the logger will use the raw message text as
   * returned by this method.
   *
   * <p>It is possible to set the message to either an empty String or
   * <code>null</code>, although this does not make the the message
   * very helpful to human users.
   *
   * @param message the message text (which will be used as key
   *                for looking up the localized message text
   *                if a resource bundle has been associated). 
   */
  public void setMessage(String message)
  {
    this.message = message;
  }


  /**
   * Returns the parameters to the log message.
   *
   * @return the parameters to the message, or <code>null</code> if
   *         the message has no parameters.
   */
  public Object[] getParameters()
  {
    return parameters;
  }


  /**
   * Sets the parameters to the log message.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param parameters the parameters to the message, or <code>null</code>
   *                   to indicate that the message has no parameters.
   */
  public void setParameters(Object[] parameters)
  {
    this.parameters = parameters;
  }


  /**
   * Returns an identifier for the thread in which this
   * <code>LogRecord</code> was created.  The identifier is not
   * necessarily related to any thread identifiers used by the
   * operating system.
   *
   * @return an identifier for the source thread.
   */
  public int getThreadID()
  {
    return threadID;
  }


  /**
   * Sets the identifier indicating in which thread this
   * <code>LogRecord</code> was created.  The identifier is not
   * necessarily related to any thread identifiers used by the
   * operating system.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param threadID the identifier for the source thread.
   */
  public void setThreadID(int threadID)
  {
    this.threadID = threadID;
  }


  /**
   * Returns the time when this <code>LogRecord</code> was created.
   *
   * @return the time of creation in milliseconds since the beginning
   *         of January 1, 1970.
   */
  public long getMillis()
  {
    return millis;
  }


  /**
   * Sets the time when this <code>LogRecord</code> was created.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param millis the time of creation in milliseconds since the
   *               beginning of January 1, 1970.
   */
  public void setMillis(long millis)
  {
    this.millis = millis;
  }


  /**
   * Returns the Throwable associated with this <code>LogRecord</code>,
   * or <code>null</code> if the logged event is not related to an exception
   * or error.
   */
  public Throwable getThrown()
  {
    return thrown;
  }


  /**
   * Associates this <code>LogRecord</code> with an exception or error.
   *
   * <p>As soon as a <code>LogRecord</code> has been handed over
   * to the logging framework, applications should not modify it
   * anymore.  Therefore, this method should only be called on
   * freshly constructed LogRecords.
   *
   * @param thrown the exception or error to associate with, or
   *               <code>null</code> if this <code>LogRecord</code>
   *               should be made unrelated to an exception or error.
   */
  public void setThrown(Throwable thrown)
  {
    this.thrown = thrown;
  }
}
