Coverage Report - palmed.edit.text.Cache

Classes in this Package Line Coverage Branch Coverage Complexity
Cache
48% 
70% 
2,667

 1  
 /**
 2  
  * Redistribution  and use  in source  and binary  forms, with  or without
 3  
  * modification, are permitted provided  that the following conditions are
 4  
  * met :
 5  
  *
 6  
  * . Redistributions  of  source  code  must  retain  the  above copyright
 7  
  *   notice, this list of conditions and the following disclaimer.
 8  
  *
 9  
  * . Redistributions in  binary form  must reproduce  the above  copyright
 10  
  *   notice, this list of conditions  and the following disclaimer in  the
 11  
  *   documentation and/or other materials provided with the distribution.
 12  
  *
 13  
  * . The name of the author may not be used to endorse or promote products
 14  
  *   derived from this software without specific prior written permission.
 15  
  *
 16  
  * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
 17  
  * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
 18  
  * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
 19  
  * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
 20  
  * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
 21  
  * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
 22  
  * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
 23  
  * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
 24  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 25  
  * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
 26  
  * POSSIBILITY OF SUCH DAMAGE.
 27  
  *
 28  
  * $Id$
 29  
  */
 30  
 
 31  
 package palmed.edit.text;
 32  
 
 33  
 import java.io.IOException;
 34  
 import java.io.InputStream;
 35  
 import java.io.OutputStream;
 36  
 import java.util.Enumeration;
 37  
 import java.util.NoSuchElementException;
 38  
 import java.util.Vector;
 39  
 import palmed.io.IRecord;
 40  
 import palmed.io.IRecordFactory;
 41  
 
 42  
 /**
 43  
  * This class implements a cache based on records.
 44  
  *
 45  
  * @author Mathieu Champlon
 46  
  * @version $Revision$ $Date$
 47  
  */
 48  
 public final class Cache implements ICache
 49  
 {
 50  
     /**
 51  
      * The record factory.
 52  
      */
 53  
     private final IRecordFactory factory_;
 54  
     /**
 55  
      * The maximum number of elements in cache at a time.
 56  
      */
 57  
     private final int threshold_;
 58  
     /**
 59  
      * The cachable elements.
 60  
      */
 61  
     private final Vector elements_;
 62  
     /**
 63  
      * The records of the cachable elements.
 64  
      */
 65  
     private final Vector records_;
 66  
     /**
 67  
      * The elements in cache.
 68  
      */
 69  
     private final Vector awake_;
 70  
 
 71  
     /**
 72  
      * Create a cache.
 73  
      *
 74  
      * @param factory the record factory
 75  
      * @param threshold the maximum number of elements in cache at a time
 76  
      */
 77  
     public Cache( final IRecordFactory factory, final int threshold )
 78  25
     {
 79  25
         if( factory == null )
 80  0
             throw new IllegalArgumentException( "parameter 'factory' is null" );
 81  25
         if( threshold <= 0 )
 82  0
             throw new IllegalArgumentException( "parameter 'threshold' must be > 0" );
 83  25
         factory_ = factory;
 84  25
         threshold_ = threshold;
 85  25
         awake_ = new Vector();
 86  25
         records_ = new Vector();
 87  25
         elements_ = new Vector();
 88  25
     }
 89  
 
 90  
     /**
 91  
      * {@inheritDoc}
 92  
      */
 93  
     public Enumeration elements()
 94  
     {
 95  0
         return elements_.elements();
 96  
     }
 97  
 
 98  
     /**
 99  
      * {@inheritDoc}
 100  
      */
 101  
     public void add( final ICachable cachable )
 102  
     {
 103  30
         if( cachable == null )
 104  0
             throw new IllegalArgumentException( "parameter 'cachable' is null" );
 105  30
         elements_.addElement( cachable );
 106  30
         records_.addElement( factory_.createRecord( cachable ) );
 107  30
         awake_.addElement( cachable );
 108  30
         sleep();
 109  30
     }
 110  
 
 111  
     /**
 112  
      * {@inheritDoc}
 113  
      */
 114  
     public void wake( final ICachable cachable )
 115  
     {
 116  10
         if( cachable == null )
 117  0
             return;
 118  10
         if( !awake_.removeElement( cachable ) )
 119  
         {
 120  5
             final int index = elements_.indexOf( cachable );
 121  5
             if( index == -1 )
 122  5
                 throw new NoSuchElementException();
 123  0
             final IRecord record = (IRecord)records_.elementAt( index );
 124  0
             record.restore();
 125  
         }
 126  5
         awake_.addElement( cachable );
 127  5
         sleep();
 128  5
     }
 129  
 
 130  
     private void sleep()
 131  
     {
 132  35
         if( awake_.size() > threshold_ )
 133  
         {
 134  5
             final ICachable cachable = (ICachable)awake_.firstElement();
 135  5
             awake_.removeElementAt( 0 );
 136  5
             final int index = elements_.indexOf( cachable );
 137  5
             ((IRecord)records_.elementAt( index )).persist();
 138  5
             cachable.sleep();
 139  
         }
 140  35
     }
 141  
 
 142  
     /**
 143  
      * {@inheritDoc}
 144  
      */
 145  
     public void clear()
 146  
     {
 147  0
         elements_.removeAllElements();
 148  0
         awake_.removeAllElements();
 149  0
         records_.removeAllElements();
 150  0
     }
 151  
 
 152  
     /**
 153  
      * {@inheritDoc}
 154  
      */
 155  
     public void unmarshall( final InputStream stream ) throws IOException
 156  
     {
 157  0
         clear();
 158  
         do
 159  
         {
 160  0
             final ICachable cachable = new Chunk( this );
 161  0
             final IRecord record = factory_.createRecord( cachable );
 162  0
             record.unmarshall( stream );
 163  0
             elements_.addElement( cachable );
 164  0
             records_.addElement( record );
 165  0
             wake( cachable );
 166  
         }
 167  0
         while( stream.available() > 0 );
 168  0
     }
 169  
 
 170  
     /**
 171  
      * {@inheritDoc}
 172  
      */
 173  
     public void marshall( final OutputStream stream ) throws IOException
 174  
     {
 175  0
         final Enumeration records = records_.elements();
 176  0
         while( records.hasMoreElements() )
 177  
         {
 178  0
             final IRecord record = (IRecord)records.nextElement();
 179  0
             record.persist();
 180  0
             record.marshall( stream );
 181  0
         }
 182  0
     }
 183  
 
 184  
     /**
 185  
      * {@inheritDoc}
 186  
      */
 187  
     public void delete()
 188  
     {
 189  0
         final Enumeration records = records_.elements();
 190  0
         while( records.hasMoreElements() )
 191  0
             ((IRecord)records.nextElement()).delete();
 192  0
         clear();
 193  0
     }
 194  
 }