Clover coverage report - Spice Netserve - 1.1-b3
Coverage timestamp: Tue Nov 30 2004 22:08:21 EET
file stats: LOC: 234   Methods: 12
NCLOC: 136   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractRequestHandler.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.handlers;
 9   
 10    import java.io.IOException;
 11    import java.net.Socket;
 12    import java.util.HashSet;
 13    import java.util.Set;
 14    import org.codehaus.spice.netserve.connection.RequestHandler;
 15   
 16    /**
 17    * Abstract base class for request handlers.
 18    *
 19    * @author Peter Donald
 20    * @version $Revision: 1.2 $ $Date: 2004/03/21 23:42:58 $
 21    */
 22    public abstract class AbstractRequestHandler
 23    implements RequestHandler
 24    {
 25    /**
 26    * The set of active requests.
 27    */
 28    private final Set m_activeRequests = new HashSet();
 29   
 30    /**
 31    * True if shutdown() has been called.
 32    */
 33    private boolean m_shutdown;
 34   
 35    /**
 36    * Handle a connection.
 37    *
 38    * @param socket the socket
 39    */
 40  27 public void handleConnection( Socket socket )
 41    {
 42  27 performRequest( socket );
 43    }
 44   
 45    /**
 46    * @see RequestHandler#shutdown
 47    */
 48  30 public void shutdown( final long timeout )
 49    {
 50  30 markAsShutdown();
 51  30 final Thread[] threads;
 52  30 synchronized( this )
 53    {
 54  30 threads = (Thread[])m_activeRequests.
 55    toArray( new Thread[ m_activeRequests.size() ] );
 56    }
 57  30 for( int i = 0; i < threads.length; i++ )
 58    {
 59  27 final Thread thread = threads[ i ];
 60  27 thread.interrupt();
 61    }
 62  30 final long now = System.currentTimeMillis();
 63  30 final long then = now + timeout;
 64   
 65  30 while( System.currentTimeMillis() < then || 0 == timeout )
 66    {
 67  47 synchronized( this )
 68    {
 69  47 if( 0 == m_activeRequests.size() )
 70    {
 71  21 return;
 72    }
 73  26 try
 74    {
 75  26 wait( timeout );
 76    }
 77    catch( final InterruptedException ie )
 78    {
 79    //Ignore
 80    }
 81    }
 82    }
 83    }
 84   
 85    /**
 86    * Mark request handler as shutdown.
 87    */
 88  39 protected void markAsShutdown()
 89    {
 90  39 m_shutdown = true;
 91    }
 92   
 93    /**
 94    * Return true if handler has been shutdown.
 95    *
 96    * @return true if handler has been shutdown.
 97    */
 98  18 protected boolean isShutdown()
 99    {
 100  18 return m_shutdown;
 101    }
 102   
 103    /**
 104    * Perform the request for socket by delegating to
 105    * underlying handler.
 106    *
 107    * @param socket the socket to handle
 108    */
 109  42 protected void performRequest( final Socket socket )
 110    {
 111  42 synchronized( this )
 112    {
 113  42 m_activeRequests.add( Thread.currentThread() );
 114    }
 115  42 setupThreadName( socket );
 116  42 try
 117    {
 118  42 doPerformRequest( socket );
 119    }
 120    catch( final Throwable t )
 121    {
 122  3 errorHandlingConnection( socket, t );
 123    }
 124    finally
 125    {
 126  33 endConnection( socket );
 127  33 synchronized( this )
 128    {
 129  33 m_activeRequests.remove( Thread.currentThread() );
 130  33 notifyAll();
 131    }
 132    }
 133    }
 134   
 135    /**
 136    * Method implemented to actually do the work.
 137    *
 138    * @param socket the socket
 139    * @throws Exception if an error occurs
 140    */
 141    protected abstract void doPerformRequest( Socket socket )
 142    throws Exception;
 143   
 144    /**
 145    * Setup the name of the thread.
 146    *
 147    * @param socket the socket associated with request
 148    */
 149  42 protected void setupThreadName( final Socket socket )
 150    {
 151  42 final String name = getThreadName( socket );
 152  42 Thread.currentThread().setName( name );
 153    }
 154   
 155    /**
 156    * End connection for socket.
 157    *
 158    * @param socket the socket
 159    */
 160  36 protected void endConnection( final Socket socket )
 161    {
 162  36 if( socket.isConnected() )
 163    {
 164  6 try
 165    {
 166  6 socket.close();
 167    }
 168    catch( final IOException ioe )
 169    {
 170  3 errorClosingConnection( socket, ioe );
 171    }
 172    }
 173    }
 174   
 175    /**
 176    * Create Runnable to perform the request.
 177    *
 178    * @param socket the socket to handle
 179    * @return thee runnable
 180    */
 181  15 protected Runnable createRunnable( final Socket socket )
 182    {
 183  15 return new Runnable()
 184    {
 185  12 public void run()
 186    {
 187  12 performRequest( socket );
 188    }
 189    };
 190    }
 191   
 192    /**
 193    * Return the name should be set for current thread.
 194    *
 195    * @param socket the socket being handled in thread
 196    * @return the thread name.
 197    */
 198  42 protected String getThreadName( final Socket socket )
 199    {
 200  42 if( socket.isConnected() )
 201    {
 202  3 return "RequestHandler for " +
 203    socket.getInetAddress().getHostAddress() + ":" +
 204    socket.getPort();
 205    }
 206    else
 207    {
 208  39 return "RequestHandler for " + socket;
 209    }
 210    }
 211   
 212    /**
 213    * Notify handler of an error handling socket.
 214    *
 215    * @param socket the socket
 216    * @param t the error
 217    */
 218  6 protected void errorHandlingConnection( final Socket socket,
 219    final Throwable t )
 220    {
 221    }
 222   
 223    /**
 224    * Notify handler of an error closing socket.
 225    *
 226    * @param socket the socket
 227    * @param t the error
 228    */
 229  3 protected void errorClosingConnection( final Socket socket,
 230    final Throwable t )
 231    {
 232  3 errorHandlingConnection( socket, t );
 233    }
 234    }