Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Scroller |
|
| 1.2;1.2 |
1 | /* | |
2 | * Copyright 2001,2004 The Apache Software Foundation. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package org.apache.commons.scaffold.util; | |
18 | ||
19 | ||
20 | import java.util.Map; | |
21 | ||
22 | import org.apache.commons.scaffold.text.ConvertUtils; | |
23 | ||
24 | ||
25 | /** | |
26 | * Scroller tracks the coordinates needed to manage | |
27 | * flipping through a result list using | |
28 | * LIMIT and OFFSET clauses (or the equivalent). | |
29 | * | |
30 | * Scrolls through entries using a range (10 to 20 of 50) | |
31 | * but does not support paging per se goto page 3 (or entry 30)), | |
32 | * though that would be an easy enhancement. | |
33 | * | |
34 | * @author James Klicman <james@jsptags.com> | |
35 | * @author Ted Husted | |
36 | * @author WXXI Public Broadcasting Council | |
37 | * @author OK State DEQ | |
38 | * @version $Revision: 155464 $ $Date: 2005-02-26 13:26:54 +0000 (Sat, 26 Feb 2005) $ | |
39 | */ | |
40 | public class Scroller { | |
41 | ||
42 | ||
43 | 0 | public Scroller(int entries, int from, int limit, int count) { |
44 | 0 | calculate(entries,from,limit,count); |
45 | 0 | } |
46 | ||
47 | ||
48 | 0 | public Scroller() { |
49 | 0 | } |
50 | ||
51 | ||
52 | /** | |
53 | * The maximum to return with a scrolling list. | |
54 | */ | |
55 | public static final int SCROLL_ROWS = 20; | |
56 | ||
57 | ||
58 | // ---------------------------------------------------------------- Properties | |
59 | ||
60 | ||
61 | /** | |
62 | * The default starting point [1]. | |
63 | * The value is for the convenience of SQL, which is one-based. | |
64 | */ | |
65 | 0 | public static int FROM = 1; |
66 | ||
67 | ||
68 | /** | |
69 | * The starting point for the current query [FROM]. | |
70 | */ | |
71 | 0 | protected int from = FROM; |
72 | ||
73 | ||
74 | /** | |
75 | * Set from. | |
76 | * @param from The new from value. | |
77 | */ | |
78 | public void setFrom(int from) { | |
79 | 0 | this.from = from; |
80 | 0 | } |
81 | ||
82 | ||
83 | /** | |
84 | * Return from. | |
85 | * @return The form value. | |
86 | */ | |
87 | public int getFrom() { | |
88 | 0 | return(this.from); |
89 | } | |
90 | ||
91 | ||
92 | /** | |
93 | * The ending point for the current query [1]. | |
94 | */ | |
95 | 0 | protected int thru = 1; |
96 | ||
97 | ||
98 | /** | |
99 | * Set thru. | |
100 | * @param thru The new thru value. | |
101 | */ | |
102 | public void setThru(int thru) { | |
103 | 0 | this.thru = thru; |
104 | 0 | } |
105 | ||
106 | ||
107 | /** | |
108 | * Return thru. | |
109 | * @return The form value. | |
110 | */ | |
111 | public int getThru() { | |
112 | 0 | return(this.thru); |
113 | } | |
114 | ||
115 | ||
116 | /** | |
117 | * The starting point to use for a "backward" query. | |
118 | */ | |
119 | 0 | protected int prev = 1; |
120 | ||
121 | ||
122 | /** | |
123 | * Set prev. | |
124 | * @param prev The new prev value. | |
125 | */ | |
126 | public void setPrev(int prev) { | |
127 | 0 | this.prev = prev; |
128 | 0 | } |
129 | ||
130 | ||
131 | /** | |
132 | * Return prev. | |
133 | * @return The prev value. | |
134 | */ | |
135 | public int getPrev() { | |
136 | 0 | return(this.prev); |
137 | } | |
138 | ||
139 | ||
140 | /** | |
141 | * The starting point to use with a "forward" query. | |
142 | * This should always be a valid value. | |
143 | * | |
144 | */ | |
145 | 0 | protected int next = 1; |
146 | ||
147 | ||
148 | /** | |
149 | * Set next. | |
150 | * @param next The new next value. | |
151 | */ | |
152 | public void setNext(int next) { | |
153 | 0 | this.next = next; |
154 | 0 | } |
155 | ||
156 | ||
157 | /** | |
158 | * Return next. | |
159 | * @return The next value. | |
160 | */ | |
161 | public int getNext() { | |
162 | 0 | return(this.next); |
163 | } | |
164 | ||
165 | ||
166 | /** | |
167 | * The maximum number of entries to fetch at a time | |
168 | * [Integer.MAX_VALUE]. | |
169 | */ | |
170 | 0 | protected int limit = Integer.MAX_VALUE; |
171 | ||
172 | ||
173 | /** | |
174 | * Set limit. | |
175 | * @param limit The new limit value. | |
176 | */ | |
177 | public void setLimit(int limit) { | |
178 | 0 | this.limit = limit; |
179 | 0 | } |
180 | ||
181 | ||
182 | /** | |
183 | * Return limit. | |
184 | * @return The limit value. | |
185 | */ | |
186 | public int getLimit() { | |
187 | 0 | return(this.limit); |
188 | } | |
189 | ||
190 | ||
191 | /** | |
192 | * The actual number of entries to fetch (eg length or limit). | |
193 | */ | |
194 | 0 | protected int entries = 0; |
195 | ||
196 | ||
197 | /** | |
198 | * Set entries | |
199 | * @param entries The new entries value. | |
200 | */ | |
201 | public void setEntries(int entries) { | |
202 | 0 | this.entries = entries; |
203 | 0 | } |
204 | ||
205 | ||
206 | /** | |
207 | * Return entries. | |
208 | * @return The entries value. | |
209 | */ | |
210 | public int getEntries() { | |
211 | 0 | return(this.entries); |
212 | } | |
213 | ||
214 | ||
215 | /** | |
216 | * The maximum number of entries available (the SQL count). | |
217 | * | |
218 | */ | |
219 | 0 | protected int count = 0; |
220 | ||
221 | ||
222 | /** | |
223 | * Set count | |
224 | * @param count The new count value. | |
225 | */ | |
226 | public void setCount(int count) { | |
227 | 0 | this.count = count; |
228 | 0 | } |
229 | ||
230 | ||
231 | /** | |
232 | * Return count. | |
233 | * @return The count value. | |
234 | */ | |
235 | public int getCount() { | |
236 | 0 | return(this.count); |
237 | } | |
238 | ||
239 | ||
240 | /** | |
241 | * Field for the parameters property [java.util.HashMap]. | |
242 | */ | |
243 | 0 | protected Map parameters = new java.util.HashMap(); |
244 | ||
245 | ||
246 | /** | |
247 | * Set parameters | |
248 | * @param parameters The new parameters value. | |
249 | */ | |
250 | public void setParameters(Map parameters) { | |
251 | 0 | this.parameters = parameters; |
252 | 0 | } |
253 | ||
254 | ||
255 | /** | |
256 | * Return parameters. | |
257 | * @return The parameters value. | |
258 | */ | |
259 | public Map getParameters() { | |
260 | 0 | return(this.parameters); |
261 | } | |
262 | ||
263 | ||
264 | /** | |
265 | * Set a parameter | |
266 | * @param key The parameter name | |
267 | * @param value The parameter value | |
268 | */ | |
269 | public void putParameter(String key, String value) { | |
270 | 0 | getParameters().put(key,value); |
271 | 0 | } |
272 | ||
273 | ||
274 | /** | |
275 | * Set a parameter | |
276 | * @param key The parameter name | |
277 | * @param value The parameter value | |
278 | */ | |
279 | public boolean isParameters() { | |
280 | 0 | return (!getParameters().isEmpty()); |
281 | } | |
282 | ||
283 | ||
284 | /** | |
285 | * Return parameters as a query string for use with a URI. | |
286 | * @return query string | |
287 | */ | |
288 | public String getQueryString(String uri) { | |
289 | ||
290 | 0 | return ConvertUtils.addParams(uri,getParameters()); |
291 | ||
292 | } | |
293 | ||
294 | ||
295 | /** | |
296 | * Return parameters as a series of hidden HTML fields. | |
297 | * @return parameters as a series of hidden HTML fields. | |
298 | */ | |
299 | public String getHiddenFields() { | |
300 | ||
301 | 0 | return ConvertUtils.renderHiddenFields(getParameters()); |
302 | ||
303 | } | |
304 | ||
305 | ||
306 | // ------------------------------------------------------------ Public Methods | |
307 | ||
308 | ||
309 | /** | |
310 | * The database offset for the current query [0]. | |
311 | * | |
312 | * Convenience method to return one less than from | |
313 | * | |
314 | * @return The offset for this query | |
315 | */ | |
316 | public int getOffset() { | |
317 | 0 | int from = getFrom(); |
318 | 0 | return(--from); |
319 | } | |
320 | ||
321 | ||
322 | /** | |
323 | * Return page number for given entry. | |
324 | * @return The number of pages | |
325 | */ | |
326 | public int getPage(int thru) { | |
327 | ||
328 | 0 | int limit = getLimit(); |
329 | ||
330 | 0 | if ((0==thru) || (0==limit)) return 1; |
331 | ||
332 | 0 | double page = (thru / limit) + (thru % limit == 0 ? 0 : 1); |
333 | ||
334 | 0 | return new Double(page).intValue(); |
335 | } | |
336 | ||
337 | ||
338 | /** | |
339 | * Return current page number | |
340 | * @return The number of pages | |
341 | */ | |
342 | public int getPage() { | |
343 | ||
344 | 0 | return getPage(getThru()); |
345 | } | |
346 | ||
347 | ||
348 | /** | |
349 | * Return number of pages. | |
350 | * @return The number of pages | |
351 | */ | |
352 | public int getPages() { | |
353 | ||
354 | 0 | return getPage(getCount()); |
355 | } | |
356 | ||
357 | ||
358 | /** | |
359 | * Return first entry for given page. | |
360 | * @return first entry for given page | |
361 | */ | |
362 | public int getOffsetForPage(int page) { | |
363 | ||
364 | 0 | int limit = getLimit(); |
365 | ||
366 | 0 | return ((page*limit)-limit)+1; |
367 | } | |
368 | ||
369 | ||
370 | /** | |
371 | * Calculate the new property values | |
372 | * using a bean that has already had count and limit set. | |
373 | * | |
374 | * @param from The first absolute row | |
375 | */ | |
376 | public void calculate() { | |
377 | ||
378 | 0 | int from = getFrom(); |
379 | 0 | int limit = getLimit(); |
380 | 0 | int entries = getEntries(); |
381 | 0 | int count = getCount(); |
382 | ||
383 | // Calculate "next" relative to starting point; or wrap to beginning. | |
384 | 0 | int thru = (from + entries) - 1 ; if (thru < 1) thru = 1; |
385 | ||
386 | // Calculate "previous" relative to starting point, but don't go negative | |
387 | 0 | int prev = from - limit; if (prev < 1) prev = 1; |
388 | ||
389 | // Calculate "next" relative to starting point; or wrap to beginning. | |
390 | 0 | int next = from + entries; if (next > count) next = 1; |
391 | ||
392 | 0 | setPrev(prev); |
393 | 0 | setNext(next); |
394 | 0 | setThru(thru); |
395 | 0 | } |
396 | ||
397 | ||
398 | ||
399 | /** | |
400 | * Calculate the new property values | |
401 | * using a bean that has already had count and limit set. | |
402 | * | |
403 | * @param from The first absolute row | |
404 | */ | |
405 | public void calculate(int entries) { | |
406 | ||
407 | 0 | setEntries(entries); |
408 | 0 | calculate(); |
409 | 0 | } |
410 | ||
411 | ||
412 | /** | |
413 | * Calculate the new property values. | |
414 | * | |
415 | * @param entries The number of matches in this set | |
416 | * @param from The first absolute row in this set | |
417 | * @param count How many rows in the complete set | |
418 | * @param limit The maximum rows in a subset page | |
419 | */ | |
420 | public void calculate(int entries, int from, int count, int limit) { | |
421 | ||
422 | 0 | if ((from<1) || (from>count)) from = 1; |
423 | ||
424 | 0 | setLimit(limit); |
425 | 0 | setCount(count); |
426 | 0 | setFrom(from); |
427 | 0 | calculate(entries); |
428 | 0 | } |
429 | ||
430 | } // end Scroller |