Coverage Report - org.mule.transport.tcp.protocols.DirectProtocol
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectProtocol
96%
25/26
94%
15/16
2
 
 1  
 /*
 2  
  * $Id: DirectProtocol.java 10489 2008-01-23 17:53:38Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.tcp.protocols;
 12  
 
 13  
 import java.io.IOException;
 14  
 import java.io.InputStream;
 15  
 import java.text.MessageFormat;
 16  
 
 17  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 18  
 import org.apache.commons.logging.Log;
 19  
 import org.apache.commons.logging.LogFactory;
 20  
 
 21  
 /**
 22  
  * The DirectProtocol class is an application level tcp protocol that does nothing.
 23  
  * The socket is read until no more bytes are (momentarily) available
 24  
  * (previously the transfer buffer also had to be full on the previous read, which made
 25  
  * stronger requirements on the underlying network).  On slow networks
 26  
  * {@link org.mule.transport.tcp.protocols.EOFProtocol} and
 27  
  * {@link org.mule.transport.tcp.protocols.LengthProtocol} may be more reliable.
 28  
  *
 29  
  * <p>Writing simply writes the data to the socket.</p>
 30  
  */
 31  
 public class DirectProtocol extends AbstractByteProtocol
 32  
 {
 33  
 
 34  
     protected static final int UNLIMITED = -1;
 35  
 
 36  2
     private static final Log logger = LogFactory.getLog(DirectProtocol.class);
 37  
     private static final int DEFAULT_BUFFER_SIZE = 8192;
 38  
     
 39  
     protected int bufferSize;
 40  
 
 41  
     public DirectProtocol()
 42  
     {
 43  44
         this(STREAM_OK, DEFAULT_BUFFER_SIZE);
 44  44
     }
 45  
 
 46  
     public DirectProtocol(boolean streamOk, int bufferSize)
 47  
     {
 48  388
         super(streamOk);
 49  388
         this.bufferSize = bufferSize;
 50  388
     }
 51  
 
 52  
     public Object read(InputStream is) throws IOException
 53  
     {
 54  2721
         return read(is, UNLIMITED);
 55  
     }
 56  
 
 57  
     public Object read(InputStream is, int limit) throws IOException
 58  
     {
 59  
         // this can grow on repeated reads
 60  3224
         ByteArrayOutputStream baos = new ByteArrayOutputStream(bufferSize);
 61  
         
 62  
         try
 63  
         {
 64  3224
             byte[] buffer = new byte[bufferSize];
 65  
             int len;
 66  3224
             int remain = remaining(limit, limit, 0);
 67  
             boolean repeat;
 68  
             do
 69  
             {
 70  
 
 71  4589
                 len = copy(is, buffer, baos, remain);
 72  4589
                 remain = remaining(limit, remain, len);
 73  4589
                 repeat = EOF != len && remain > 0 && isRepeat(len, is.available());
 74  
 
 75  4589
                 if (logger.isDebugEnabled())
 76  
                 {
 77  0
                     logger.debug(MessageFormat.format(
 78  
                             "len/limit/repeat: {0}/{1}/{2}",
 79  
                             new Object[] {new Integer(len), new Integer(limit), Boolean.valueOf(repeat)}));
 80  
                 }
 81  
             }
 82  4589
             while (repeat);
 83  
         }
 84  
         finally
 85  
         {
 86  3224
             baos.flush();
 87  3224
             baos.close();
 88  3223
         }
 89  3223
         return nullEmptyArray(baos.toByteArray());
 90  
     }
 91  
 
 92  
     protected int remaining(int limit, int remain, int len)
 93  
     {
 94  7813
         if (UNLIMITED == limit)
 95  
         {
 96  6789
             return bufferSize;
 97  
         }
 98  1024
         else if (EOF != len)
 99  
         {
 100  958
             return remain - len;
 101  
         }
 102  
         else
 103  
         {
 104  65
             return remain;
 105  
         }
 106  
     }
 107  
 
 108  
     /**
 109  
      * Decide whether to repeat transfer.  This implementation does so if
 110  
      * more data are available.  Note that previously, while documented as such,
 111  
      * there was also the additional requirement that the previous transfer
 112  
      * completely used the transfer buffer.
 113  
      *
 114  
      * @param len Amount transferred last call (-1 on EOF or socket error)
 115  
      * @param available Amount available
 116  
      * @return true if the transfer should continue
 117  
      */
 118  
     protected boolean isRepeat(int len, int available)
 119  
     {
 120  
         // previous logic - less reliable on slow networks
 121  
 //        return len == bufferSize && available > 0;
 122  
         
 123  38
         return available > 0;
 124  
     }
 125  
 
 126  
 }