001// Copyright 2006 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.commons.util; 016 017import java.util.Iterator; 018 019/** 020 * Represents a sequence of integer values, either ascending or descending. The sequence is always inclusive (of the 021 * finish value). 022 */ 023public final class IntegerRange implements Iterable<Integer> 024{ 025 private final int start; 026 027 private final int finish; 028 029 private class RangeIterator implements Iterator<Integer> 030 { 031 private final int increment; 032 033 private int value = start; 034 035 private boolean hasNext = true; 036 037 RangeIterator() 038 { 039 increment = start < finish ? +1 : -1; 040 } 041 042 public boolean hasNext() 043 { 044 return hasNext; 045 } 046 047 public Integer next() 048 { 049 if (!hasNext) throw new IllegalStateException(); 050 051 int result = value; 052 053 hasNext = value != finish; 054 055 value += increment; 056 057 return result; 058 } 059 060 public void remove() 061 { 062 throw new UnsupportedOperationException(); 063 } 064 065 } 066 067 public IntegerRange(final int start, final int finish) 068 { 069 this.start = start; 070 this.finish = finish; 071 } 072 073 public int getFinish() 074 { 075 return finish; 076 } 077 078 public int getStart() 079 { 080 return start; 081 } 082 083 @Override 084 public String toString() 085 { 086 return String.format("%d..%d", start, finish); 087 } 088 089 /** 090 * The main puprose of a range object is to produce an Iterator. Since IntegerRange is iterable, it is useful with 091 * the Tapestry Loop component, but also with the Java for loop! 092 */ 093 public Iterator<Integer> iterator() 094 { 095 return new RangeIterator(); 096 } 097 098 @Override 099 public int hashCode() 100 { 101 final int PRIME = 31; 102 103 int result = PRIME + finish; 104 105 result = PRIME * result + start; 106 107 return result; 108 } 109 110 /** 111 * Returns true if the other object is an IntegerRange with the same start and finish values. 112 */ 113 @Override 114 public boolean equals(Object obj) 115 { 116 if (this == obj) return true; 117 if (obj == null) return false; 118 if (getClass() != obj.getClass()) return false; 119 final IntegerRange other = (IntegerRange) obj; 120 if (finish != other.finish) return false; 121 122 return start == other.start; 123 } 124 125}