Clover coverage report - Spice Netserve - 1.1-b3
Coverage timestamp: Tue Nov 30 2004 22:08:21 EET
file stats: LOC: 216   Methods: 9
NCLOC: 106   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultAcceptorManager.java 100% 100% 100% 100%
coverage
 1    /*
 2    * Copyright (C) The Spice Group. All rights reserved.
 3    *
 4    * This software is published under the terms of the Spice
 5    * Software License version 1.1, a copy of which has been included
 6    * with this distribution in the LICENSE.txt file.
 7    */
 8    package org.codehaus.spice.netserve.connection.impl;
 9   
 10    import java.net.ServerSocket;
 11    import java.util.Hashtable;
 12    import java.util.Map;
 13    import org.codehaus.spice.netserve.connection.RequestHandler;
 14    import org.codehaus.spice.netserve.connection.SocketAcceptorManager;
 15    import org.codehaus.spice.netserve.connection.impl.AcceptorConfig;
 16    import org.codehaus.spice.netserve.connection.impl.AcceptorMonitor;
 17    import org.codehaus.spice.netserve.connection.impl.ConnectionAcceptor;
 18   
 19    /**
 20    * Default implementation of SocketAcceptorManager that uses
 21    * a thread per acceptor approach.
 22    *
 23    * <p>Note that on some OS/JVM combinations <tt>soTimeout</tt> must
 24    * be set to non-0 value or else the ServerSocket will never get out
 25    * of accept() system call and we wont be able to shutdown the server
 26    * socket properly. However it can introduce performance problems if
 27    * constantly timing out. </p>
 28    *
 29    * @author Peter Donald
 30    * @author Mauro Talevi
 31    * @version $Revision: 1.3 $ $Date: 2004/03/21 23:42:59 $
 32    */
 33    public class DefaultAcceptorManager
 34    implements SocketAcceptorManager
 35    {
 36    /**
 37    * The map of name->acceptor.
 38    */
 39    private final Map m_acceptors = new Hashtable();
 40   
 41    /**
 42    * The monitor that receives notifications of Connection events
 43    */
 44    private AcceptorMonitor m_monitor = NullAcceptorMonitor.MONITOR;
 45   
 46    /**
 47    * Value that we are to set SO_TIMEOUT to if the user
 48    * has not already set the timeout. Defaults to 1000 (1s timeout).
 49    */
 50    private int m_soTimeout = 1000;
 51   
 52    /**
 53    * Set to the number of milliseconds that we will wait
 54    * for a connection to shutdown gracefully. Defaults to 0
 55    * which indicates indefinite wait.
 56    */
 57    private int m_shutdownTimeout;
 58   
 59    /**
 60    * Set the AcceptorMonitor that receives events when changes occur.
 61    *
 62    * @param monitor the AcceptorMonitor that receives events when
 63    * changes occur.
 64    */
 65  24 public void setMonitor( final AcceptorMonitor monitor )
 66    {
 67  24 m_monitor = monitor;
 68    }
 69   
 70    /**
 71    * Set the value that we are to set SO_TIMEOUT to if the user
 72    * has not already set the timeout. Defaults to 1000 (1s timeout).
 73    *
 74    * @param soTimeout the timeout value
 75    */
 76  12 public void setSoTimeout( final int soTimeout )
 77    {
 78  12 m_soTimeout = soTimeout;
 79    }
 80   
 81    /**
 82    * Set timeout for shutting down handlers.
 83    * The timeout defaults to 0 which means wait indefinetly.
 84    *
 85    * @param shutdownTimeout the timeout
 86    */
 87  15 public void setShutdownTimeout( final int shutdownTimeout )
 88    {
 89  15 m_shutdownTimeout = shutdownTimeout;
 90    }
 91   
 92    /**
 93    * Return the shutdownTimeout.
 94    *
 95    * @return the shutdownTimeout
 96    */
 97  33 protected int getShutdownTimeout()
 98    {
 99  33 return m_shutdownTimeout;
 100    }
 101   
 102    /**
 103    * Dispose the ConnectionManager which involves shutting down all
 104    * the connected acceptors.
 105    */
 106  24 public void shutdownAcceptors()
 107    {
 108  24 final String[] names;
 109  24 synchronized( m_acceptors )
 110    {
 111  24 names = (String[])m_acceptors.keySet().toArray( new String[ 0 ] );
 112    }
 113  24 for( int i = 0; i < names.length; i++ )
 114    {
 115  6 disconnect( names[ i ] );
 116    }
 117    }
 118   
 119    /**
 120    * Start accepting connections from a socket and passing connections
 121    * to specified handler.
 122    *
 123    * @param name the name of connection. This serves as a key used to
 124    * shutdown acceptor.
 125    * @param socket the ServerSocket from which connections are accepted
 126    * @throws java.lang.Exception if unable to initiate connection management. This could
 127    * be due to the key already being used for another acceptor,
 128    * the serversocket being closed, the handler being null etc.
 129    */
 130  27 public void connect( final String name,
 131    final ServerSocket socket,
 132    final RequestHandler handler )
 133    throws Exception
 134    {
 135  27 if( null == name )
 136    {
 137  3 throw new NullPointerException( "name" );
 138    }
 139  24 if( null == socket )
 140    {
 141  3 throw new NullPointerException( "socket" );
 142    }
 143  21 if( null == handler )
 144    {
 145  3 throw new NullPointerException( "handler" );
 146    }
 147   
 148  18 if( 0 == socket.getSoTimeout() )
 149    {
 150  15 socket.setSoTimeout( m_soTimeout );
 151    }
 152   
 153  18 final ConnectionAcceptor acceptor;
 154  18 synchronized( m_acceptors )
 155    {
 156  18 if( isConnected( name ) )
 157    {
 158  3 final String message =
 159    "Connection already exists with name " + name;
 160  3 throw new IllegalArgumentException( message );
 161    }
 162   
 163  15 final AcceptorConfig config = new AcceptorConfig( name, socket, handler );
 164  15 acceptor = new ConnectionAcceptor( config, getMonitor() );
 165  15 m_acceptors.put( name, acceptor );
 166    }
 167   
 168  15 final Thread thread =
 169    new Thread( acceptor, "Acceptor[" + name + "]" );
 170  15 thread.start();
 171  15 while( !acceptor.hasStarted() )
 172    {
 173  11 Thread.sleep( 5 );
 174    }
 175    }
 176   
 177    /**
 178    * Return true if acceptor with specified name exists.
 179    *
 180    * @param name the name
 181    * @return true if acceptor with specified name exists.
 182    */
 183  63 public boolean isConnected( final String name )
 184    {
 185  63 return m_acceptors.containsKey( name );
 186    }
 187   
 188    /**
 189    * This shuts down the acceptor and the associated ServerSocket.
 190    *
 191    * @param name the name of connection
 192    * @throws java.lang.IllegalArgumentException if no connection with specified name
 193    */
 194  18 public void disconnect( final String name )
 195    {
 196  18 final ConnectionAcceptor acceptor =
 197    (ConnectionAcceptor)m_acceptors.remove( name );
 198  18 if( null == acceptor )
 199    {
 200  3 final String message = "No connection with name " + name;
 201  3 throw new IllegalArgumentException( message );
 202    }
 203   
 204  15 acceptor.close( getShutdownTimeout() );
 205    }
 206   
 207    /**
 208    * Return the monitor used by manager.
 209    *
 210    * @return the monitor used by manager.
 211    */
 212  33 protected AcceptorMonitor getMonitor()
 213    {
 214  33 return m_monitor;
 215    }
 216    }