Coverage Report - net.admin4j.util.FixedSizeRollingList
 
Classes in this File Line Coverage Branch Coverage Complexity
FixedSizeRollingList
86%
46/53
65%
17/26
2.385
 
 1  
 /*
 2  
  * This software is licensed under the Apache License, Version 2.0
 3  
  * (the "License") agreement; you may not use this file except in compliance with
 4  
  * the License.  You may obtain a copy of the License at
 5  
  * 
 6  
  *      http://www.apache.org/licenses/LICENSE-2.0
 7  
  * 
 8  
  * Unless required by applicable law or agreed to in writing, software
 9  
  * distributed under the License is distributed on an "AS IS" BASIS,
 10  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11  
  * See the License for the specific language governing permissions and
 12  
  * limitations under the License.
 13  
  */
 14  
 package net.admin4j.util;
 15  
 
 16  
 import java.io.Serializable;
 17  
 import java.util.AbstractList;
 18  
 import java.util.Collection;
 19  
 
 20  
 import net.admin4j.deps.commons.lang3.Validate;
 21  
 
 22  
 /**
 23  
  * This is a rolling list with a defined maximum size.  As elements are added beyond
 24  
  * the maxSize, elements are removed from the front of the list.
 25  
  * @author D. Ashmore
 26  
  * @since 1.0.2
 27  
  */
 28  
 public class FixedSizeRollingList<E> extends AbstractList<E> implements Serializable {
 29  
     
 30  
     private static final long serialVersionUID = -6973689738559294580L;
 31  
 
 32  
     public static final int DEFAULT_MAX_SIZE=10;
 33  
     
 34  
     private Object[] elementData;
 35  
     private int maxSize;
 36  
     private int size;
 37  
     
 38  
     public FixedSizeRollingList() {
 39  6
         this(DEFAULT_MAX_SIZE);
 40  6
     }
 41  
     
 42  12
     public FixedSizeRollingList(int maxSize) {
 43  0
         Validate.isTrue(maxSize > 0, "Max Size must be greater than zero.  maxSize={}", maxSize);
 44  12
         this.maxSize = maxSize;
 45  12
         this.elementData = new Object[this.maxSize];
 46  12
         this.size = 0;
 47  12
     }
 48  
 
 49  
     @SuppressWarnings("unchecked")
 50  
     @Override
 51  
     public E get(int index) {
 52  273
         if (index >= size) {
 53  0
             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 54  
         }
 55  273
         return (E) elementData[index];
 56  
     }
 57  
 
 58  
     @Override
 59  
     public int size() {
 60  156
          return this.size;
 61  
     }
 62  
 
 63  
     /* (non-Javadoc)
 64  
      * @see java.util.AbstractList#set(int, java.lang.Object)
 65  
      */
 66  
     @Override
 67  
     public E set(int index, E element) {
 68  3
         E removed = this.get(index);
 69  3
         this.elementData[index] = element;
 70  3
         return removed;
 71  
     }
 72  
     
 73  
     /* (non-Javadoc)
 74  
      * @see java.util.AbstractList#add(java.lang.Object)
 75  
      */
 76  
     @Override
 77  
     public boolean add(E e) {
 78  189
         if (this.size == this.maxSize) {
 79  120
             this.remove(0);
 80  
         }
 81  189
         this.add(this.size, e);
 82  189
         return true;
 83  
     }
 84  
 
 85  
 
 86  
     /* (non-Javadoc)
 87  
      * @see java.util.AbstractList#add(int, java.lang.Object)
 88  
      */
 89  
     @Override
 90  
     public void add(int index, E element) {
 91  192
         this.maxRangeCheck(index);
 92  192
         if (index == this.size) {
 93  189
             this.elementData[size++] = element;
 94  
         }
 95  3
         else if (index < size) {
 96  3
             if (this.size == this.maxSize) {
 97  3
                 this.remove(this.size - 1);
 98  
             }
 99  
             
 100  3
             int numMoved = this.size - index;
 101  3
             System.arraycopy(this.elementData, index, this.elementData, index+1,
 102  
                              numMoved);
 103  3
             this.elementData[index] = element;
 104  3
             this.size++;
 105  3
         }
 106  
         else {
 107  0
             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 108  
         }
 109  192
     }
 110  
     
 111  
     /* (non-Javadoc)
 112  
      * @see java.util.AbstractCollection#addAll(java.util.Collection)
 113  
      */
 114  
     @Override
 115  
     public boolean addAll(Collection<? extends E> c) {
 116  
         Validate.notNull(c, "Null collection not allowed.");
 117  3
         if (c.isEmpty()) {
 118  0
             return true;
 119  
         }
 120  
         
 121  3
         for (E ele: c) {
 122  30
             this.add(ele);
 123  
         }
 124  3
         return super.addAll(c);
 125  
     }
 126  
     
 127  
     /* (non-Javadoc)
 128  
      * @see java.util.AbstractList#addAll(int, java.util.Collection)
 129  
      */
 130  
     @Override
 131  
     public boolean addAll(int index, Collection<? extends E> c) {
 132  
         Validate.notNull(c, "Null collection not allowed.");
 133  3
         if (c.isEmpty()) {
 134  0
             return true;
 135  
         }
 136  3
         if (this.size + c.size() > this.maxSize) {
 137  3
             throw new IndexOutOfBoundsException(outOfBoundsMsg(index) + ": No room to add collection of this at this index.");
 138  
         }
 139  0
         return true;
 140  
     }
 141  
 
 142  
     /* (non-Javadoc)
 143  
      * @see java.util.AbstractList#remove(int)
 144  
      */
 145  
     @Override
 146  
     public E remove(int index) {
 147  123
         E removed = this.get(index);
 148  123
         int numMoved = size - index - 1;
 149  123
         if (numMoved > 0) {
 150  120
             System.arraycopy(elementData, index+1, elementData, index,
 151  
                              numMoved);
 152  
         }
 153  123
         elementData[--size] = null;
 154  123
         return removed;
 155  
     }
 156  
 
 157  
     public int getMaxSize() {
 158  126
         return maxSize;
 159  
     }
 160  
     
 161  
     private void maxRangeCheck(int index) {
 162  192
         if (index >= this.maxSize || index > this.size)
 163  0
             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 164  192
     }
 165  
     
 166  
     /**
 167  
      * Constructs an IndexOutOfBoundsException detail message.
 168  
      * Of the many possible refactorings of the error handling code,
 169  
      * this "outlining" performs best with both server and client VMs.
 170  
      */
 171  
     private String outOfBoundsMsg(int index) {
 172  3
         return "Index: "+index+", Size: "+size;
 173  
     }
 174  
 
 175  
 }