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    }