Clover coverage report - groovy - 1.0-beta-6
Coverage timestamp: Thu Jul 15 2004 13:18:22 BST
file stats: LOC: 308   Methods: 25
NCLOC: 221   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ObjectRange.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  $Id: ObjectRange.java,v 1.11 2004/03/10 13:49:50 jstrachan Exp $
 3   
 
 4   
  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
 5   
 
 6   
  Redistribution and use of this software and associated documentation
 7   
  ("Software"), with or without modification, are permitted provided
 8   
  that the following conditions are met:
 9   
 
 10   
  1. Redistributions of source code must retain copyright
 11   
     statements and notices.  Redistributions must also contain a
 12   
     copy of this document.
 13   
 
 14   
  2. Redistributions in binary form must reproduce the
 15   
     above copyright notice, this list of conditions and the
 16   
     following disclaimer in the documentation and/or other
 17   
     materials provided with the distribution.
 18   
 
 19   
  3. The name "groovy" must not be used to endorse or promote
 20   
     products derived from this Software without prior written
 21   
     permission of The Codehaus.  For written permission,
 22   
     please contact info@codehaus.org.
 23   
 
 24   
  4. Products derived from this Software may not be called "groovy"
 25   
     nor may "groovy" appear in their names without prior written
 26   
     permission of The Codehaus. "groovy" is a registered
 27   
     trademark of The Codehaus.
 28   
 
 29   
  5. Due credit should be given to The Codehaus -
 30   
     http://groovy.codehaus.org/
 31   
 
 32   
  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 33   
  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 34   
  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 35   
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 36   
  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 37   
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 38   
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 39   
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 40   
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 41   
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 42   
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 43   
  OF THE POSSIBILITY OF SUCH DAMAGE.
 44   
 
 45   
  */
 46   
 package groovy.lang;
 47   
 
 48   
 import java.util.AbstractList;
 49   
 import java.util.Iterator;
 50   
 import java.util.List;
 51   
 
 52   
 import org.codehaus.groovy.runtime.InvokerHelper;
 53   
 import org.codehaus.groovy.runtime.IteratorClosureAdapter;
 54   
 
 55   
 /**
 56   
  * Represents an inclusive list of objects from a value to a value using
 57   
  * comparators
 58   
  * 
 59   
  * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 60   
  * @version $Revision: 1.11 $
 61   
  */
 62   
 public class ObjectRange extends AbstractList implements Range {
 63   
 
 64   
     private Comparable from;
 65   
     private Comparable to;
 66   
     private int size = -1;
 67   
     private final boolean reverse;
 68   
 
 69  0
     public ObjectRange(Comparable from, Comparable to) {
 70  0
         this.reverse = InvokerHelper.compareGreaterThan(from, to);
 71  0
         if (this.reverse) {
 72  0
             constructorHelper(to, from);
 73   
         } else {
 74  0
             constructorHelper(from, to);
 75   
         }
 76   
     }
 77   
 
 78  0
     public ObjectRange(Comparable from, Comparable to, boolean reverse) {
 79  0
         constructorHelper(from, to);
 80   
         
 81  0
         this.reverse = reverse;
 82   
     }
 83   
     
 84  0
     private void constructorHelper(Comparable from, Comparable to) {
 85  0
         if (from == null) {
 86  0
             throw new IllegalArgumentException("Must specify a non-null value for the 'from' index in a Range");
 87   
         }
 88  0
         if (to == null) {
 89  0
             throw new IllegalArgumentException("Must specify a non-null value for the 'to' index in a Range");
 90   
         }
 91  0
         if (from.getClass() == to.getClass()) {
 92  0
             this.from = from;
 93  0
             this.to = to;
 94   
         } else {
 95  0
             this.from = normaliseType(from);
 96  0
             this.to = normaliseType(to);
 97   
         }
 98   
     }
 99   
 
 100  0
     public int hashCode() {
 101   
         /** @todo should code this the Josh Bloch way */
 102  0
         return from.hashCode() ^ to.hashCode() + (reverse ? 1 : 0);
 103   
     }
 104   
 
 105  0
     public boolean equals(Object that) {
 106  0
         if (that instanceof ObjectRange) {
 107  0
             return equals((ObjectRange) that);
 108   
         }
 109  0
         else if (that instanceof List) {
 110  0
             return equals((List) that);
 111   
         }
 112  0
         return false;
 113   
     }
 114   
 
 115  0
     public boolean equals(ObjectRange that) {
 116  0
         return this.reverse == that.reverse
 117   
             && InvokerHelper.compareEqual(this.from, that.from)
 118   
             && InvokerHelper.compareEqual(this.to, that.to);
 119   
     }
 120   
 
 121  0
     public boolean equals(List that) {
 122  0
         int size = size();
 123  0
         if (that.size() == size) {
 124  0
             for (int i = 0; i < size; i++) {
 125  0
                 if (!InvokerHelper.compareEqual(get(i), that.get(i))) {
 126  0
                     return false;
 127   
                 }
 128   
             }
 129  0
             return true;
 130   
         }
 131  0
         return false;
 132   
     }
 133   
 
 134  0
     public Comparable getFrom() {
 135  0
         return from;
 136   
     }
 137   
 
 138  0
     public Comparable getTo() {
 139  0
         return to;
 140   
     }
 141   
 
 142  0
     public boolean isReverse() {
 143  0
         return reverse;
 144   
     }
 145   
 
 146  0
     public Object get(int index) {
 147  0
         if (index < 0) {
 148  0
             throw new IndexOutOfBoundsException("Index: " + index + " should not be negative");
 149   
         }
 150  0
         if (index >= size()) {
 151  0
             throw new IndexOutOfBoundsException("Index: " + index + " is too big for range: " + this);
 152   
         }
 153  0
         Object value = null;
 154  0
         if (reverse) {
 155  0
             value = to;
 156  0
             System.out.println("get(" + index + ")");
 157   
             
 158  0
             for (int i = 0; i < index; i++) {
 159  0
                 System.out.println("decrement: " + i + " value: " + value);
 160  0
                 value = decrement(value);
 161   
             }
 162   
         }
 163   
         else {
 164  0
             value = from;
 165  0
             for (int i = 0; i < index; i++) {
 166  0
                 value = increment(value);
 167   
             }
 168   
         }
 169  0
         return value;
 170   
     }
 171   
 
 172  0
     public Iterator iterator() {
 173  0
         return new Iterator() {
 174   
             int index = 0;
 175  0
             Object value = (reverse) ? to : from;
 176   
 
 177  0
             public boolean hasNext() {
 178  0
                 return index < size();
 179   
             }
 180   
 
 181  0
             public Object next() {
 182  0
                 if (index++ > 0) {
 183  0
                     if (index > size()) {
 184  0
                         value = null;
 185   
                     }
 186   
                     else {
 187  0
                         if (reverse) {
 188  0
                             value = decrement(value);
 189   
                         }
 190   
                         else {
 191  0
                             value = increment(value);
 192   
                         }
 193   
                     }
 194   
                 }
 195  0
                 return value;
 196   
             }
 197   
 
 198  0
             public void remove() {
 199  0
                 ObjectRange.this.remove(index);
 200   
             }
 201   
         };
 202   
     }
 203   
 
 204  0
     public int size() {
 205  0
         if (size == -1) {
 206   
             // lets lazily calculate the size
 207  0
             size = 0;
 208  0
             Object value = from;
 209  0
             while (to.compareTo(value) >= 0) {
 210  0
                 value = increment(value);
 211  0
                 size++;
 212   
             }
 213   
         }
 214  0
         return size;
 215   
     }
 216   
 
 217  0
     public List subList(int fromIndex, int toIndex) {
 218  0
         if (fromIndex < 0) {
 219  0
             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
 220   
         }
 221  0
         int size = size();
 222  0
         if (toIndex > size) {
 223  0
             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
 224   
         }
 225  0
         if (fromIndex > toIndex) {
 226  0
             throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
 227   
         }
 228  0
         if (--toIndex >= size) {
 229  0
             return new ObjectRange((Comparable) get(fromIndex), getTo(), reverse);
 230   
         }
 231   
         else {
 232  0
             return new ObjectRange((Comparable) get(fromIndex), (Comparable) get(toIndex), reverse);
 233   
         }
 234   
     }
 235   
 
 236  0
     public String toString() {
 237  0
         return (reverse) ? "" + to + ".." + from : "" + from + ".." + to;
 238   
     }
 239   
 
 240  0
     public String inspect() {
 241  0
         String toText = InvokerHelper.inspect(to);
 242  0
         String fromText = InvokerHelper.inspect(from);
 243  0
         return (reverse) ? "" + toText + ".." + fromText : "" + fromText + ".." + toText;
 244   
     }
 245   
 
 246  0
     public boolean contains(Comparable value) {
 247  0
         int result = from.compareTo(value);
 248  0
         if (result == 0) {
 249  0
             return true;
 250   
         }
 251  0
         return result < 0 && to.compareTo(value) >= 0;
 252   
     }
 253   
 
 254  0
     public void step(int step, Closure closure) {
 255  0
         if (reverse) {
 256  0
             step = -step;
 257   
         }
 258  0
         if (step >= 0) {
 259  0
             Comparable value = from;
 260  0
             while (value.compareTo(to) <= 0) {
 261  0
                 closure.call(value);
 262  0
                 for (int i = 0; i < step; i++) {
 263  0
                     value = (Comparable) increment(value);
 264   
                 }
 265   
             }
 266   
         }
 267   
         else {
 268  0
             step = -step;
 269  0
             Comparable value = to;
 270  0
             while (value.compareTo(from) >= 0) {
 271  0
                 closure.call(value);
 272  0
                 for (int i = 0; i < step; i++) {
 273  0
                     value = (Comparable) decrement(value);
 274   
                 }
 275   
             }
 276   
         }
 277   
     }
 278   
 
 279  0
     public List step(int step) {
 280  0
         IteratorClosureAdapter adapter = new IteratorClosureAdapter(this);
 281  0
         step(step, adapter);
 282  0
         return adapter.asList();
 283   
     }
 284   
 
 285  0
     protected Object increment(Object value) {
 286  0
         return InvokerHelper.invokeMethod(value, "next", null);
 287   
     }
 288   
 
 289  0
     protected Object decrement(Object value) {
 290  0
         return InvokerHelper.invokeMethod(value, "previous", null);
 291   
     }
 292   
     
 293  0
     private static Comparable normaliseType(final Comparable operand) {
 294  0
         if (operand instanceof Character) {
 295  0
             return new Integer(((Character)operand).charValue());
 296  0
         } else if (operand instanceof String) {
 297  0
         final String string = (String)operand;
 298   
         
 299  0
             if (string.length() == 1)
 300  0
                 return new Integer(string.charAt(0));
 301   
             else
 302  0
                 return string;
 303   
         } else {
 304  0
             return operand;
 305   
         }
 306   
     }
 307   
 }
 308