/* SocketHandler.java -- a class for publishing log messages to network sockets
   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., 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;


/**
 * A <code>SocketHandler</code> publishes log records to
 * a TCP/IP socket.
 *
 * <p><strong>Configuration:</strong> Values of the subsequent
 * <code>LogManager</code> properties are taken into consideration
 * when a <code>SocketHandler</code> is initialized.
 * If a property is not defined, or if it has an invalid
 * value, a default is taken without an exception being thrown.
 *
 * <ul>
 *
 * <li><code>java.util.SocketHandler.level</code> - specifies
 *     the initial severity level threshold. Default value:
 *     <code>Level.ALL</code>.</li>
 *
 * <li><code>java.util.SocketHandler.filter</code> - specifies
 *     the name of a Filter class. Default value: No Filter.</li>
 *
 * <li><code>java.util.SocketHandler.formatter</code> - specifies
 *     the name of a Formatter class. Default value:
 *     <code>java.util.logging.XMLFormatter</code>.</li>
 *
 * <li><code>java.util.SocketHandler.encoding</code> - specifies
 *     the name of the character encoding. Default value:
 *     the default platform encoding.</li>
 *
 * <li><code>java.util.SocketHandler.host</code> - specifies
 *     the name of the host to which records are published.
 *     There is no default value for this property; if it is
 *     not set, the SocketHandler constructor will throw
 *     an exception.</li>
 *
 * <li><code>java.util.SocketHandler.port</code> - specifies
 *     the TCP/IP port to which records are published.
 *     There is no default value for this property; if it is
 *     not set, the SocketHandler constructor will throw
 *     an exception.</li>
 *
 * </ul>
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class SocketHandler
  extends StreamHandler
{
  /**
   * Constructs a <code>SocketHandler</code> that publishes log
   * records to a TCP/IP socket.  Tthe initial configuration is
   * determined by the <code>LogManager</code> properties described
   * above.
   *
   * @throws java.io.IOException if the connection to the specified
   *         network host and port cannot be established.
   *
   * @throws java.lang.IllegalArgumentException if either the
   *         <code>java.util.logging.SocketHandler.host</code>
   *         or <code>java.util.logging.SocketHandler.port</code>
   *         LogManager properties is not defined, or specifies
   *         an invalid value.
   */
  public SocketHandler()
    throws java.io.IOException
  {
    this(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.host"),
	 getPortNumber());
  }

    
  /**
   * Constructs a <code>SocketHandler</code> that publishes log
   * records to a TCP/IP socket.  With the exception of the internet
   * host and port, the initial configuration is determined by the
   * <code>LogManager</code> properties described above.
   *
   * @param host the Internet host to which log records will be
   *        forwarded.
   *
   * @param port the port at the host which will accept a request
   *        for a TCP/IP connection.
   *
   * @throws java.io.IOException if the connection to the specified
   *         network host and port cannot be established.
   *
   * @throws java.lang.IllegalArgumentException if either
   *         <code>host</code> or <code>port</code> specify
   *         an invalid value.
   */
  public SocketHandler(String host, int port)
    throws java.io.IOException
  {
    super(createSocket(host, port),
	  "java.util.logging.SocketHandler",
	  /* default level */ Level.ALL,
	  /* formatter */ null,
	  /* default formatter */ XMLFormatter.class);
  }


  /**
   * Retrieves the port number from the java.util.logging.SocketHandler.port
   * LogManager property.
   *
   * @throws IllegalArgumentException if the property is not defined or
   *         does not specify an integer value.
   */
  private static int getPortNumber()
  {
    try {
      return Integer.parseInt(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.port"));
    } catch (Exception ex) {
      throw new IllegalArgumentException();
    }
  }


  /**
   * Creates an OutputStream for publishing log records to an Internet
   * host and port.  This private method is a helper for use by the
   * constructor of SocketHandler.
   *
   * @param host the Internet host to which log records will be
   *        forwarded.
   *
   * @param port the port at the host which will accept a request
   *        for a TCP/IP connection.
   *
   * @throws java.io.IOException if the connection to the specified
   *         network host and port cannot be established.
   *
   * @throws java.lang.IllegalArgumentException if either
   *         <code>host</code> or <code>port</code> specify
   *         an invalid value.
   */
  private static java.io.OutputStream createSocket(String host, int port)
    throws java.io.IOException, java.lang.IllegalArgumentException
  {
    java.net.Socket  socket;

    if ((host == null) || (port < 1))
      throw new IllegalArgumentException();

    socket = new java.net.Socket(host, port);

    socket.shutdownInput();

    /* The architecture of the logging framework provides replaceable
     * formatters.  Because these formatters perform their task by
     * returning one single String for each LogRecord to be formatted,
     * there is no need to buffer.
     */
    socket.setTcpNoDelay(true);

    return socket.getOutputStream();
  }


  /**
   * Publishes a <code>LogRecord</code> to the network socket,
   * provided the record passes all tests for being loggable.
   * In addition, all data that may have been buffered will
   * be forced to the network stream.
   *
   * <p>Most applications do not need to call this method directly.
   * Instead, they will use a {@link Logger} instance, which will
   * create LogRecords and distribute them to registered handlers.
   *
   * <p>In case of an I/O failure, the <code>ErrorManager</code>
   * of this <code>SocketHandler</code> will be informed, but the caller
   * of this method will not receive an exception.
   *
   * @param record the log event to be published.
   */
  public void publish(LogRecord record)
  {
    super.publish(record);
    flush();
  }
}
    
