001 package railo.runtime.util; 002 003 import railo.runtime.PageContext; 004 import railo.runtime.exp.PageException; 005 import railo.runtime.op.Operator; 006 import railo.runtime.type.KeyImpl; 007 import railo.runtime.type.Query; 008 009 /** 010 * A Number Iterator Implementation to iterate from to 011 */ 012 public final class NumberIterator { 013 014 private int _from; 015 private int _to; 016 private int _current; 017 private int recordcount; 018 019 //private static int count=0; 020 021 /** 022 * constructor of the number iterator 023 * @param from iterate from 024 * @param to iterate to 025 * @param recordcount 026 */ 027 private NumberIterator(int from, int to, int recordcount) { 028 //railo.print.ln(count++); 029 init(from,to,recordcount); 030 } 031 private NumberIterator init(int from, int to, int recordcount) { 032 this._from=from; 033 this._current=from; 034 this._to=to; 035 this.recordcount=recordcount; 036 return this; 037 } 038 039 /** 040 * @return returns if there is a next value 041 */ 042 public boolean hasNext() { 043 return _current<_to; 044 } 045 public boolean hasNext(boolean useRecordcount) { 046 return _current<(useRecordcount?recordcount:_to); 047 } 048 049 /** 050 * @return increment and return new value 051 */ 052 public int next() { 053 return ++_current; 054 } 055 056 /** 057 * @return returns if there is a previous value 058 */ 059 public boolean hasPrevious() { 060 return _current>_from; 061 } 062 063 /** 064 * @return decrement and return new value 065 */ 066 public int previous() { 067 return --_current; 068 } 069 070 /** 071 * @return returns smallest possible value 072 */ 073 public int from() { 074 return _from; 075 } 076 077 /** 078 * @return returns greatest value 079 */ 080 public int to() { 081 return _to; 082 } 083 084 /** 085 * @return set value to first and return 086 */ 087 public int first() { 088 return _current=_from; 089 } 090 091 /** 092 * @return set value to last and return thid value 093 */ 094 public int last() { 095 return _current=_to; 096 } 097 /** 098 * @return returns current value 099 */ 100 public int current() { 101 return _current; 102 } 103 104 /** 105 * sets the current position 106 * @param current 107 */ 108 public void setCurrent(int current) { 109 _current=current; 110 } 111 112 /** 113 * @return is after last 114 */ 115 public boolean isAfterLast() { 116 return _current>_to; 117 } 118 /** 119 * @return is pointer on a valid position 120 */ 121 public boolean isValid() { 122 return _current>=_from && _current<=_to; 123 } 124 125 public boolean isValid(int current) { 126 _current=current; 127 return _current>=_from && _current<=_to; 128 } 129 130 131 132 133 private static NumberIterator[] iterators=new NumberIterator[]{ 134 new NumberIterator(1,1,1), 135 new NumberIterator(1,1,1), 136 new NumberIterator(1,1,1), 137 new NumberIterator(1,1,1), 138 new NumberIterator(1,1,1), 139 new NumberIterator(1,1,1), 140 new NumberIterator(1,1,1), 141 new NumberIterator(1,1,1), 142 new NumberIterator(1,1,1), 143 new NumberIterator(1,1,1) 144 }; 145 private static int pointer=0; 146 147 /** 148 * load a iterator 149 * @param from 150 * @param to iterate to 151 * @return NumberIterator 152 */ 153 private static NumberIterator _load(int from, int to) { 154 return _load(from, to, to); 155 } 156 private static NumberIterator _load(int from, int to, int recordcount) { 157 if(pointer>=iterators.length) return new NumberIterator(from,to,recordcount); 158 return iterators[pointer++].init(from,to,recordcount); 159 } 160 161 /** 162 * create a Number Iterator with value from and to 163 * @param from 164 * @param to 165 * @return NumberIterator 166 */ 167 public static synchronized NumberIterator load(double from, double to) { 168 return _load((int)from,(int)to,(int)to); 169 } 170 public static synchronized NumberIterator load(int from, int to) { 171 return _load(from,to,to); 172 } 173 174 /** 175 * create a Number Iterator with value from and to 176 * @param from 177 * @param to 178 * @param max 179 * @return NumberIterator 180 */ 181 public static synchronized NumberIterator load(double from, double to, double max) { 182 return loadMax((int)from, (int)to, (int)max); 183 } 184 185 public static synchronized NumberIterator loadMax(int from, int to, int max) { 186 return _load(from,((from+max-1<to)?from+max-1:to),to); 187 } 188 189 public static synchronized NumberIterator loadEnd(int from, int to, int end) { 190 return _load(from,((end<to)?end:to),to); 191 } 192 193 /** 194 * @param ni 195 * @param query 196 * @param groupName 197 * @param caseSensitive 198 * @return number iterator for group 199 * @throws PageException 200 */ 201 public static synchronized NumberIterator load(PageContext pc, NumberIterator ni, Query query, String groupName, boolean caseSensitive) throws PageException { 202 int startIndex=query.getCurrentrow(pc.getId()); 203 204 Object startValue=query.get(KeyImpl.init(groupName)); 205 while(ni.hasNext(true)) { 206 if(!Operator.equals(startValue,query.getAt(groupName,ni.next()),caseSensitive)) { 207 208 ni.previous(); 209 return _load(startIndex,ni.current()); 210 } 211 } 212 return _load(startIndex,ni.current()); 213 } 214 215 /** 216 * @param ni Iterator to release 217 */ 218 public static synchronized void release(NumberIterator ni) { 219 if(pointer>0) { 220 iterators[--pointer]=ni; 221 } 222 } 223 224 225 226 227 228 229 230 }