Clover coverage report -
Coverage timestamp: Sun Oct 12 2003 22:57:21 PDT
file stats: LOC: 178   Methods: 6
NCLOC: 77   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
ClientWriter.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
 
 3   
 VRMoo Server - Virtual Reality Object Oriented MUD Server
 4   
 Copyright (C) 2001 - 2003  VRMoo Development Team
 5   
 
 6   
 
 7   
 This program is free software; you can redistribute it and/or modify
 8   
 it under the terms of the GNU General Public License as published by
 9   
 the Free Software Foundation; either version 2 of the License, or
 10   
 (at your option) any later version.
 11   
 
 12   
 This program is distributed in the hope that it will be useful,
 13   
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 14   
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15   
 GNU General Public License for more details.
 16   
 
 17   
 You should have received a copy of the GNU General Public License
 18   
 along with this program; if not, write to the Free Software
 19   
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 20   
 
 21   
 
 22   
 For information about VRMoo and its authors, please visit the website:
 23   
 http://www.vrmoo.org/
 24   
 
 25   
 */
 26   
 
 27   
 package org.vrmoo.server.client;
 28   
 
 29   
 import java.io.IOException;
 30   
 import java.io.OutputStream;
 31   
 import java.util.Vector;
 32   
 
 33   
 /**
 34   
  * The <code>ClientWriter</code> class is responsible for writing data to a
 35   
  * client socket connected to the server. This class is <code>Runnable</code>.
 36   
  * The constructor starts up a thread whose sole responsibility is to write data
 37   
  * to the client socket.
 38   
  *
 39   
  * @author Jeff Weston
 40   
  */
 41   
 public class ClientWriter
 42   
 {
 43   
     /**
 44   
      * The <code>OutputStream</code> attached to the client socket.
 45   
      */
 46   
     private OutputStream out;
 47   
 
 48   
     /**
 49   
      * The <code>ClientHandler</code> associated with this
 50   
      * <code>ClientWriter</code>.
 51   
      */
 52   
     private ClientHandler clientHandler;
 53   
 
 54   
     /**
 55   
      * The <code>Vector</code> of data we are waiting to send.
 56   
      */
 57   
     private Vector vectData;
 58   
 
 59   
     /**
 60   
      * The stop flag is set to false when running, true when we need to stop.
 61   
      */
 62   
     private boolean stopFlag = false;
 63   
 
 64   
     /**
 65   
      * Creates a thread whose sole responsibility is to write data to the
 66   
      * specified <code>OutputStream</code>
 67   
      *
 68   
      * @param streamOut       the <code>OutputStream</code> to write data to
 69   
      * @param clientHandler   the <code>ClientHandler</code> associated with
 70   
      *                          this writer
 71   
      */
 72  0
     public ClientWriter( OutputStream streamOut, ClientHandler clientHandler )
 73   
     {
 74  0
         out                = streamOut;
 75  0
         this.clientHandler = clientHandler;
 76  0
         vectData           = new Vector( );
 77  0
         String threadName  = "ClientWriter" + clientHandler.getClientID( );
 78   
 
 79  0
         new Thread( new Loop( ), threadName ).start( );
 80   
     }
 81   
 
 82   
     /**
 83   
      * This method is called when another object wants to queue up data to be
 84   
      * sent to the client socket. The data will be sent to the client in the
 85   
      * order it was received by this method.
 86   
      *
 87   
      * @param iData   the data to be queued up
 88   
      */
 89  0
     public synchronized void writeData( int iData )
 90   
     {
 91  0
         vectData.addElement( new Integer( iData ) );
 92  0
         notifyAll( );
 93   
     }
 94   
 
 95   
     /**
 96   
      * Specifies that the <code>ClientWriter</code> thread must stop by setting
 97   
      * the <code>stopFlag</code> to 1.
 98   
      */
 99  0
     public synchronized void stop( )
 100   
     {
 101  0
         stopFlag = true;
 102  0
         notifyAll( );
 103   
     }
 104   
 
 105   
     /**
 106   
      * This method is used internally to read the next byte of data from the
 107   
      * queue of data to be sent to the client.
 108   
      *
 109   
      * @return An <code>int</code> containing the next byte of data.
 110   
      */
 111  0
     private synchronized int readData( )
 112   
     {
 113  0
         Integer intData;
 114   
 
 115  0
         while ( vectData.isEmpty( ) )
 116   
         {
 117  0
             if ( checkStopFlag( ) )
 118   
             {
 119  0
                 return -1;
 120   
             }
 121  0
             try
 122   
             {
 123  0
                 wait( );
 124   
             }
 125   
             catch ( InterruptedException e )
 126   
             {
 127  0
                 e.printStackTrace( );
 128   
             }
 129   
         }
 130  0
         intData = ( Integer ) vectData.elementAt( 0 );
 131  0
         vectData.removeElementAt( 0 );
 132  0
         return intData.intValue( );
 133   
     }
 134   
 
 135   
     /**
 136   
      * Checks the <code>stopFlag</code> to see if we are supposed to stop.
 137   
      *
 138   
      * @return true if we are supposed to stop, otherwise return false
 139   
      */
 140  0
     private synchronized boolean checkStopFlag( )
 141   
     {
 142  0
         return stopFlag;
 143   
     }
 144   
 
 145   
     /**
 146   
      * Private inner class implementing Runnable to make this class thread-safe.
 147   
      * The thread that is started can only be called from the constructor.
 148   
      */
 149   
     private class Loop implements Runnable
 150   
     {
 151   
         /**
 152   
          * Continuously checks for data to be written to the
 153   
          * <code>OutputStream</code> and writes it out when available. This
 154   
          * method is called by the thread started from the constructor.
 155   
          */
 156  0
         public void run( )
 157   
         {
 158  0
             int iData;
 159   
 
 160  0
             try
 161   
             {
 162  0
                 while ( ! checkStopFlag( ) )
 163   
                 {
 164  0
                     iData = readData( );
 165  0
                     if ( iData >= 0 )
 166   
                     {
 167  0
                         out.write( iData );
 168   
                     }
 169   
                 }
 170   
             }
 171   
             catch ( IOException e )
 172   
             {
 173  0
                 clientHandler.clientDisconnected( );
 174   
             }
 175   
         }
 176   
     }
 177   
 }
 178