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 public Scroller(int entries, int from, int limit, int count) { 44 calculate(entries,from,limit,count); 45 } 46 47 48 public Scroller() { 49 } 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 public static int FROM = 1; 66 67 68 /** 69 * The starting point for the current query [FROM]. 70 */ 71 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 this.from = from; 80 } 81 82 83 /** 84 * Return from. 85 * @return The form value. 86 */ 87 public int getFrom() { 88 return(this.from); 89 } 90 91 92 /** 93 * The ending point for the current query [1]. 94 */ 95 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 this.thru = thru; 104 } 105 106 107 /** 108 * Return thru. 109 * @return The form value. 110 */ 111 public int getThru() { 112 return(this.thru); 113 } 114 115 116 /** 117 * The starting point to use for a "backward" query. 118 */ 119 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 this.prev = prev; 128 } 129 130 131 /** 132 * Return prev. 133 * @return The prev value. 134 */ 135 public int getPrev() { 136 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 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 this.next = next; 154 } 155 156 157 /** 158 * Return next. 159 * @return The next value. 160 */ 161 public int getNext() { 162 return(this.next); 163 } 164 165 166 /** 167 * The maximum number of entries to fetch at a time 168 * [Integer.MAX_VALUE]. 169 */ 170 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 this.limit = limit; 179 } 180 181 182 /** 183 * Return limit. 184 * @return The limit value. 185 */ 186 public int getLimit() { 187 return(this.limit); 188 } 189 190 191 /** 192 * The actual number of entries to fetch (eg length or limit). 193 */ 194 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 this.entries = entries; 203 } 204 205 206 /** 207 * Return entries. 208 * @return The entries value. 209 */ 210 public int getEntries() { 211 return(this.entries); 212 } 213 214 215 /** 216 * The maximum number of entries available (the SQL count). 217 * 218 */ 219 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 this.count = count; 228 } 229 230 231 /** 232 * Return count. 233 * @return The count value. 234 */ 235 public int getCount() { 236 return(this.count); 237 } 238 239 240 /** 241 * Field for the parameters property [java.util.HashMap]. 242 */ 243 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 this.parameters = parameters; 252 } 253 254 255 /** 256 * Return parameters. 257 * @return The parameters value. 258 */ 259 public Map getParameters() { 260 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 getParameters().put(key,value); 271 } 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 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 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 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 int from = getFrom(); 318 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 int limit = getLimit(); 329 330 if ((0==thru) || (0==limit)) return 1; 331 332 double page = (thru / limit) + (thru % limit == 0 ? 0 : 1); 333 334 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 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 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 int limit = getLimit(); 365 366 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 int from = getFrom(); 379 int limit = getLimit(); 380 int entries = getEntries(); 381 int count = getCount(); 382 383 // Calculate "next" relative to starting point; or wrap to beginning. 384 int thru = (from + entries) - 1 ; if (thru < 1) thru = 1; 385 386 // Calculate "previous" relative to starting point, but don't go negative 387 int prev = from - limit; if (prev < 1) prev = 1; 388 389 // Calculate "next" relative to starting point; or wrap to beginning. 390 int next = from + entries; if (next > count) next = 1; 391 392 setPrev(prev); 393 setNext(next); 394 setThru(thru); 395 } 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 setEntries(entries); 408 calculate(); 409 } 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 if ((from<1) || (from>count)) from = 1; 423 424 setLimit(limit); 425 setCount(count); 426 setFrom(from); 427 calculate(entries); 428 } 429 430 } // end Scroller