/* ServerSocket.java -- Class for implementing server side sockets
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 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 java.net;

import gnu.java.net.PlainSocketImpl;

import java.io.IOException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.ServerSocketChannel;


/* Written using on-line Java Platform 1.2 API Specification.
 * Status:  I believe all methods are implemented.
 */

/**
 * This class models server side sockets.  The basic model is that the
 * server socket is created and bound to some well known port.  It then
 * listens for and accepts connections.  At that point the client and
 * server sockets are ready to communicate with one another utilizing
 * whatever application layer protocol they desire.
 *
 * As with the <code>Socket</code> class, most instance methods of this class
 * simply redirect their calls to an implementation class.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner (bothner@cygnus.com)
 */
public class ServerSocket
{
  /**
   * This is the user defined SocketImplFactory, if one is supplied
   */
  private static SocketImplFactory factory;

  /**
   * This is the SocketImp object to which most instance methods in this
   * class are redirected
   */
  private SocketImpl impl;

  /**
   * We need to retain the local address even after the socket is closed.
   */
  private InetSocketAddress local;

  /*
   * This constructor is only used by java.nio.
   */

  // FIXME: Workaround a bug in gcj.
  //ServerSocket (PlainSocketImpl impl) throws IOException
  ServerSocket(SocketImpl impl) throws IOException
  {
    if (impl == null)
      throw new NullPointerException("impl may not be null");

    this.impl = impl;
    this.impl.create(true);
  }

  /*
   * This method is only used by java.nio.
   */

  // FIXME: Workaround a bug in gcj.
  //PlainSocketImpl getImpl()
  SocketImpl getImpl()
  {
    return impl;
  }

  /**
   * Constructor that simply sets the implementation.
   *
   * @exception IOException If an error occurs
   *
   * @specnote This constructor is public since JDK 1.4
   */
  public ServerSocket() throws IOException
  {
    if (factory != null)
      impl = factory.createSocketImpl();
    else
      impl = new PlainSocketImpl();

    impl.create(true);
  }

  /**
   * Creates a server socket and binds it to the specified port.  If the
   * port number is 0, a random free port will be chosen.  The pending
   * connection queue on this socket will be set to 50.
   *
   * @param port The port number to bind to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   */
  public ServerSocket(int port) throws IOException
  {
    this(port, 50);
  }

  /**
   * Creates a server socket and binds it to the specified port.  If the
   * port number is 0, a random free port will be chosen.  The pending
   * connection queue on this socket will be set to the value passed as
   * arg2.
   *
   * @param port The port number to bind to
   * @param backlog The length of the pending connection queue
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   */
  public ServerSocket(int port, int backlog) throws IOException
  {
    this(port, backlog, null);
  }

  /**
   * Creates a server socket and binds it to the specified port.  If the
   * port number is 0, a random free port will be chosen.  The pending
   * connection queue on this socket will be set to the value passed as
   * backlog.  The third argument specifies a particular local address to
   * bind t or null to bind to all local address.
   *
   * @param port The port number to bind to
   * @param backlog The length of the pending connection queue
   * @param bindAddr The address to bind to, or null to bind to all addresses
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   *
   * @since 1.1
   */
  public ServerSocket(int port, int backlog, InetAddress bindAddr)
    throws IOException
  {
    this();

    // bind/listen socket
    bind(new InetSocketAddress(bindAddr, port), backlog);
  }

  /**
   * Binds the server socket to a specified socket address
   *
   * @param endpoint The socket address to bind to
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   *
   * @since 1.4
   */
  public void bind(SocketAddress endpoint) throws IOException
  {
    bind(endpoint, 50);
  }

  /**
   * Binds the server socket to a specified socket address
   *
   * @param endpoint The socket address to bind to
   * @param backlog The length of the pending connection queue
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   *
   * @since 1.4
   */
  public void bind(SocketAddress endpoint, int backlog)
    throws IOException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    if (! (endpoint instanceof InetSocketAddress))
      throw new IllegalArgumentException("Address type not supported");

    InetSocketAddress tmp = (InetSocketAddress) endpoint;

    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkListen(tmp.getPort());

    InetAddress addr = tmp.getAddress();

    // Initialize addr with 0.0.0.0.
    if (addr == null)
      addr = InetAddress.ANY_IF;

    try
      {
	impl.bind(addr, tmp.getPort());
	impl.listen(backlog);
	local = new InetSocketAddress(
            (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR),
            impl.getLocalPort());
      }
    catch (IOException exception)
      {
	close();
	throw exception;
      }
    catch (RuntimeException exception)
      {
	close();
	throw exception;
      }
    catch (Error error)
      {
	close();
	throw error;
      }
  }

  /**
   * This method returns the local address to which this socket is bound
   *
   * @return The socket's local address
   */
  public InetAddress getInetAddress()
  {
    if (local == null)
      return null;

    return local.getAddress();
  }

  /**
   * This method returns the local port number to which this socket is bound
   *
   * @return The socket's port number
   */
  public int getLocalPort()
  {
    if (local == null)
      return -1;

    return local.getPort();
  }

  /**
   * Returns the local socket address
   *
   * @return the local socket address, null if not bound
   * 
   * @since 1.4
   */
  public SocketAddress getLocalSocketAddress()
  {
    return local;
  }

  /**
   * Accepts a new connection and returns a connected <code>Socket</code>
   * instance representing that connection.  This method will block until a
   * connection is available.
   *
   * @return socket object for the just accepted connection
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   * @exception IllegalBlockingModeException If this socket has an associated
   * channel, and the channel is in non-blocking mode
   * @exception SocketTimeoutException If a timeout was previously set with
   * setSoTimeout and the timeout has been reached
   */
  public Socket accept() throws IOException
  {
    Socket socket = new Socket();

    try
      {
	implAccept(socket);
      }
    catch (IOException e)
      {
	try
	  {
	    socket.close();
	  }
	catch (IOException e2)
	  {
	    // Ignore.
	  }

	throw e;
      }

    return socket;
  }

  /**
   * This protected method is used to help subclasses override
   * <code>ServerSocket.accept()</code>.  The passed in socket will be
   * connected when this method returns.
   *
   * @param socket The socket that is used for the accepted connection
   *
   * @exception IOException If an error occurs
   * @exception IllegalBlockingModeException If this socket has an associated
   * channel, and the channel is in non-blocking mode
   *
   * @since 1.1
   */
  protected final void implAccept(Socket socket) throws IOException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    // FIXME: Add a security check to make sure we're allowed to 
    // connect to the remote host.

    // The Sun spec says that if we have an associated channel and
    // it is in non-blocking mode, we throw an IllegalBlockingModeException.
    // However, in our implementation if the channel itself initiated this
    // operation, then we must honor it regardless of its blocking mode.
    if (getChannel() != null && ! getChannel().isBlocking()
        && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
      throw new IllegalBlockingModeException();

    impl.accept(socket.impl);
    socket.implCreated = true;
    socket.bound = true;
  }

  /**
   * Closes this socket and stops listening for connections
   *
   * @exception IOException If an error occurs
   */
  public void close() throws IOException
  {
    if (isClosed())
      return;

    impl.close();
    impl = null;

    if (getChannel() != null)
      getChannel().close();
  }

  /**
   * Returns the unique <code>ServerSocketChannel</code> object
   * associated with this socket, if any.
   *
   * <p>The socket only has a <code>ServerSocketChannel</code> if its created
   * by <code>ServerSocketChannel.open()</code>.</p>
   *
   * @return the associated socket channel, null if none exists
   * 
   * @since 1.4
   */
  public ServerSocketChannel getChannel()
  {
    return null;
  }

  /**
   * Returns true when the socket is bound, otherwise false
   *
   * @return true if socket is bound, false otherwise
   * 
   * @since 1.4
   */
  public boolean isBound()
  {
    return local != null;
  }

  /**
   * Returns true if the socket is closed, otherwise false
   *
   * @return true if socket is closed, false otherwise
   * 
   * @since 1.4
   */
  public boolean isClosed()
  {
    return impl == null;
  }

  /**
   * Sets the value of SO_TIMEOUT.  A value of 0 implies that SO_TIMEOUT is
   * disabled (ie, operations never time out).  This is the number of
   * milliseconds a socket operation can block before an
   * InterruptedIOException is thrown.
   *
   * @param timeout The new SO_TIMEOUT value
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.1
   */
  public void setSoTimeout(int timeout) throws SocketException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    if (timeout < 0)
      throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");

    impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  }

  /**
   * Retrieves the current value of the SO_TIMEOUT setting.  A value of 0
   * implies that SO_TIMEOUT is disabled (ie, operations never time out).
   * This is the number of milliseconds a socket operation can block before
   * an InterruptedIOException is thrown.
   *
   * @return The value of SO_TIMEOUT
   *
   * @exception IOException If an error occurs
   *
   * @since 1.1
   */
  public int getSoTimeout() throws IOException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);

    if (! (timeout instanceof Integer))
      throw new IOException("Internal Error");

    return ((Integer) timeout).intValue();
  }

  /**
   * Enables/Disables the SO_REUSEADDR option
   *
   * @param on true if SO_REUSEADDR should be enabled, false otherwise
   * 
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public void setReuseAddress(boolean on) throws SocketException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
  }

  /**
   * Checks if the SO_REUSEADDR option is enabled
   *
   * @return true if SO_REUSEADDR is set, false otherwise
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public boolean getReuseAddress() throws SocketException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);

    if (! (reuseaddr instanceof Boolean))
      throw new SocketException("Internal Error");

    return ((Boolean) reuseaddr).booleanValue();
  }

  /**
   * This method sets the value for the system level socket option
   * SO_RCVBUF to the specified value.  Note that valid values for this
   * option are specific to a given operating system.
   *
   * @param size The new receive buffer size.
   *
   * @exception SocketException If an error occurs or Socket is not connected
   * @exception IllegalArgumentException If size is 0 or negative
   *
   * @since 1.4
   */
  public void setReceiveBufferSize(int size) throws SocketException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    if (size <= 0)
      throw new IllegalArgumentException("SO_RCVBUF value must be > 0");

    impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  }

  /**
   * This method returns the value of the system level socket option
   * SO_RCVBUF, which is used by the operating system to tune buffer
   * sizes for data transfers.
   *
   * @return The receive buffer size.
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.4
   */
  public int getReceiveBufferSize() throws SocketException
  {
    if (isClosed())
      throw new SocketException("ServerSocket is closed");

    Object buf = impl.getOption(SocketOptions.SO_RCVBUF);

    if (! (buf instanceof Integer))
      throw new SocketException("Internal Error: Unexpected type");

    return ((Integer) buf).intValue();
  }

  /**
   * Returns the value of this socket as a <code>String</code>.
   *
   * @return This socket represented as a <code>String</code>.
   */
  public String toString()
  {
    if (! isBound())
      return "ServerSocket[unbound]";

    return ("ServerSocket[addr=" + getInetAddress() + ",port="
           + impl.getPort() + ",localport=" + impl.getLocalPort() + "]");
  }

  /**
   * Sets the <code>SocketImplFactory</code> for all
   * <code>ServerSocket</code>'s.  This may only be done
   * once per virtual machine.  Subsequent attempts will generate an
   * exception.  Note that a <code>SecurityManager</code> check is made prior
   * to setting the factory.  If insufficient privileges exist to set the
   * factory, an exception will be thrown
   *
   * @param fac the factory to set
   *
   * @exception SecurityException If this operation is not allowed by the
   * <code>SecurityManager</code>.
   * @exception SocketException If the factory object is already defined
   * @exception IOException If any other error occurs
   */
  public static synchronized void setSocketFactory(SocketImplFactory fac)
    throws IOException
  {
    factory = fac;
  }
}
