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 126 127 128 private static NumberIterator[] iterators=new NumberIterator[]{ 129 new NumberIterator(1,1,1), 130 new NumberIterator(1,1,1), 131 new NumberIterator(1,1,1), 132 new NumberIterator(1,1,1), 133 new NumberIterator(1,1,1), 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 }; 140 private static int pointer=0; 141 142 /** 143 * load a iterator 144 * @param from 145 * @param to iterate to 146 * @return NumberIterator 147 */ 148 private static NumberIterator _load(int from, int to) { 149 return _load(from, to, to); 150 } 151 private static NumberIterator _load(int from, int to, int recordcount) { 152 if(pointer>=iterators.length) return new NumberIterator(from,to,recordcount); 153 return iterators[pointer++].init(from,to,recordcount); 154 } 155 156 /** 157 * create a Number Iterator with value from and to 158 * @param from 159 * @param to 160 * @return NumberIterator 161 */ 162 public static synchronized NumberIterator load(double from, double to) { 163 return _load((int)from,(int)to,(int)to); 164 } 165 166 /** 167 * create a Number Iterator with value from and to 168 * @param from 169 * @param to 170 * @param max 171 * @return NumberIterator 172 */ 173 public static synchronized NumberIterator load(double from, double to, double max) { 174 return _load((int)from,(int)((from+max-1<to)?from+max-1:to),(int)to); 175 } 176 177 /** 178 * @param ni 179 * @param query 180 * @param groupName 181 * @param caseSensitive 182 * @return number iterator for group 183 * @throws PageException 184 */ 185 public static synchronized NumberIterator load(PageContext pc, NumberIterator ni, Query query, String groupName, boolean caseSensitive) throws PageException { 186 int startIndex=query.getCurrentrow(); 187 // FUTURE int startIndex=query.getCurrentrow(pc.getId()); 188 189 Object startValue=query.get(KeyImpl.init(groupName)); 190 // FUTURE Object startValue=query.get(pc,KeyImpl.init(groupName)); 191 while(ni.hasNext(true)) { 192 if(!Operator.equals(startValue,query.getAt(groupName,ni.next()),caseSensitive)) { 193 ni.previous(); 194 return _load(startIndex,ni.current()); 195 } 196 } 197 return _load(startIndex,ni.current()); 198 } 199 200 /** 201 * @param ni Iterator to release 202 */ 203 public static synchronized void release(NumberIterator ni) { 204 if(pointer>0) { 205 iterators[--pointer]=ni; 206 } 207 } 208 209 210 211 212 213 214 215 }