1 /***
2 * Copyright (c) 2003 held jointly by the individual authors.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 2.1 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 * > http://www.gnu.org/copyleft/lesser.html >
18 * http://www.opensource.org/licenses/lgpl-license.php
19 */
20 package net.mlw.vlh.adapter.hibernate3.util;
21
22 import java.math.BigDecimal;
23 import java.math.BigInteger;
24 import java.sql.Blob;
25 import java.sql.Clob;
26 import java.util.Calendar;
27 import java.util.Date;
28 import java.util.Locale;
29 import java.util.TimeZone;
30
31 import net.mlw.vlh.adapter.util.ObjectValidator;
32
33 import org.hibernate.HibernateException;
34 import org.hibernate.ScrollableResults;
35 import org.hibernate.type.Type;
36
37 /***
38 * The ScrollableResultsDecorator class enable or disable putting objects into a
39 * final ResultsSet, thus into a final valueList. To check validity it uses
40 * ObjectValidator's interface. This implementation ensures that the validation
41 * method is invoked only once per object.
42 *
43 * @todo Implement setRowNumber
44 * @author Andrej Zachar
45 * @version $Revision: 1.1 $ $Date: 2005/10/20 16:45:24 $
46 */
47 public class ScrollableResultsDecorator implements ScrollableResults
48 {
49
50 private static final int INITIAL_CAPACITY = 100;
51
52 private ScrollableResults _scrollableResults;
53
54 private ObjectValidator _validator;
55
56 private int _currentRow = -1;
57
58 private int[] _index;
59
60 private int _size;
61
62 private boolean _isComplete;
63
64 /***
65 * Default contructor of decorator;
66 */
67 public ScrollableResultsDecorator(ScrollableResults scrollableResults, ObjectValidator validator)
68 {
69 super();
70 setValidator(validator);
71 setScrollableResults(scrollableResults);
72 }
73
74 /***
75 * @see org.hibernate.ScrollableResults#beforeFirst()
76 */
77 public void beforeFirst() throws HibernateException
78 {
79 if (_scrollableResults.getRowNumber() >= 0)
80 {
81 _scrollableResults.beforeFirst();
82 }
83 _currentRow = -1;
84 }
85
86 /***
87 * @see org.hibernate.ScrollableResults#first()
88 */
89 public boolean first() throws HibernateException
90 {
91 return move(0);
92 }
93
94 /***
95 * @see org.hibernate.ScrollableResults#isFirst()
96 */
97 public boolean isFirst() throws HibernateException
98 {
99 return (_currentRow == 0);
100 }
101
102 /***
103 * @see org.hibernate.ScrollableResults#afterLast()
104 */
105 public void afterLast() throws HibernateException
106 {
107 if (_isComplete)
108 {
109
110 _scrollableResults.afterLast();
111 _currentRow = _size;
112 }
113 else
114 {
115 lastKnown();
116 while (nextValid())
117 ;
118 }
119 }
120
121 /***
122 * @see org.hibernate.ScrollableResults#last()
123 */
124 public boolean last() throws HibernateException
125 {
126 if (_isComplete)
127 {
128
129 return move(_size - 1);
130 }
131 else
132 {
133 afterLast();
134 return previous();
135 }
136 }
137
138 /***
139 * @see org.hibernate.ScrollableResults#isLast()
140 */
141 public boolean isLast() throws HibernateException
142 {
143 if (_isComplete)
144 {
145 return ((_currentRow + 1) == _size);
146 }
147 else
148 {
149 boolean result = next();
150 previous();
151 return result;
152 }
153 }
154
155 /***
156 * @see org.hibernate.ScrollableResults#next()
157 */
158 public boolean next() throws HibernateException
159 {
160 return move(_currentRow + 1);
161 }
162
163 /***
164 * @see org.hibernate.ScrollableResults#previous()
165 */
166 public boolean previous() throws HibernateException
167 {
168 return move(_currentRow - 1);
169 }
170
171 /***
172 * @see org.hibernate.ScrollableResults#scroll(int)
173 */
174 public boolean scroll(int i) throws HibernateException
175 {
176 if (i == 0)
177 {
178 return _scrollableResults.scroll(0);
179 }
180
181 return move(_currentRow + i);
182 }
183
184 /***
185 * @see org.hibernate.ScrollableResults#setRowNumber(int)
186 */
187 public boolean setRowNumber(int row) throws HibernateException
188 {
189 if (row >= 0)
190 {
191 return move(row);
192 }
193 else
194 {
195 if (!_isComplete)
196 {
197
198 afterLast();
199 }
200 return move(_size + row);
201 }
202 }
203
204 private boolean move(int row) throws HibernateException
205 {
206 if (row >= 0)
207 {
208 if (row < _size)
209 {
210 _currentRow = row;
211 int rowNumber = _index[_currentRow];
212 if (rowNumber != _scrollableResults.getRowNumber())
213 {
214 return _scrollableResults.setRowNumber(rowNumber);
215 }
216 else
217 {
218 return true;
219 }
220 }
221 else
222 {
223 if (_isComplete)
224 {
225 afterLast();
226 return false;
227 }
228 else
229 {
230 lastKnown();
231 boolean result = true;
232 while (result && (_currentRow < row))
233 {
234 result = nextValid();
235 }
236 return result;
237 }
238 }
239 }
240 else
241 {
242 beforeFirst();
243 return false;
244 }
245 }
246
247 private void lastKnown() throws HibernateException
248 {
249 if (_size > 0)
250 {
251 _currentRow = _size - 1;
252 int rowNumber = _index[_currentRow];
253 if (rowNumber != _scrollableResults.getRowNumber())
254 {
255 _scrollableResults.setRowNumber(_index[_currentRow]);
256 }
257 }
258 else
259 {
260 beforeFirst();
261 }
262 }
263
264 private boolean nextValid() throws HibernateException
265 {
266 boolean result;
267
268 do
269 {
270 result = _scrollableResults.next();
271 }
272 while (result && !_validator.isAcceptable(_scrollableResults.get(0)));
273
274 _currentRow++;
275
276 if (result)
277 {
278 _size = _currentRow + 1;
279 ensureCapacity(_size);
280 _index[_currentRow] = _scrollableResults.getRowNumber();
281 }
282 else
283 {
284 _isComplete = true;
285 }
286
287 return result;
288 }
289
290 private void ensureCapacity(int minCapacity)
291 {
292 int oldCapacity = _index.length;
293 if (minCapacity > oldCapacity)
294 {
295 int[] oldData = _index;
296 int newCapacity = (oldCapacity * 3) / 2 + 1;
297 if (newCapacity < minCapacity)
298 {
299 newCapacity = minCapacity;
300 }
301 _index = new int[newCapacity];
302 System.arraycopy(oldData, 0, _index, 0, oldCapacity);
303 }
304 }
305
306 /***
307 * @see org.hibernate.ScrollableResults#getRowNumber()
308 */
309 public int getRowNumber() throws HibernateException
310 {
311 return _currentRow;
312 }
313
314
315
316 /***
317 * @see org.hibernate.ScrollableResults#get()
318 */
319 public Object[] get() throws HibernateException
320 {
321 return _scrollableResults.get();
322 }
323
324 /***
325 * @see org.hibernate.ScrollableResults#get(int)
326 */
327 public Object get(int arg0) throws HibernateException
328 {
329 return _scrollableResults.get(arg0);
330 }
331
332 /***
333 * @see org.hibernate.ScrollableResults#close()
334 */
335 public void close() throws HibernateException
336 {
337 _scrollableResults.close();
338 }
339
340 /***
341 * @see org.hibernate.ScrollableResults#getBigDecimal(int)
342 */
343 public BigDecimal getBigDecimal(int arg0) throws HibernateException
344 {
345 return _scrollableResults.getBigDecimal(arg0);
346 }
347
348 /***
349 * @see org.hibernate.ScrollableResults#getBigInteger(int)
350 */
351 public BigInteger getBigInteger(int arg0) throws HibernateException
352 {
353 return _scrollableResults.getBigInteger(arg0);
354 }
355
356 /***
357 * @see org.hibernate.ScrollableResults#getBinary(int)
358 */
359 public byte[] getBinary(int arg0) throws HibernateException
360 {
361 return _scrollableResults.getBinary(arg0);
362 }
363
364 /***
365 * @see org.hibernate.ScrollableResults#getBlob(int)
366 */
367 public Blob getBlob(int arg0) throws HibernateException
368 {
369 return _scrollableResults.getBlob(arg0);
370 }
371
372 /***
373 * @see org.hibernate.ScrollableResults#getBoolean(int)
374 */
375 public Boolean getBoolean(int arg0) throws HibernateException
376 {
377 return _scrollableResults.getBoolean(arg0);
378 }
379
380 /***
381 * @see org.hibernate.ScrollableResults#getByte(int)
382 */
383 public Byte getByte(int arg0) throws HibernateException
384 {
385 return _scrollableResults.getByte(arg0);
386 }
387
388 /***
389 * @see org.hibernate.ScrollableResults#getCalendar(int)
390 */
391 public Calendar getCalendar(int arg0) throws HibernateException
392 {
393 return _scrollableResults.getCalendar(arg0);
394 }
395
396 /***
397 * @see org.hibernate.ScrollableResults#getClob(int)
398 */
399 public Clob getClob(int arg0) throws HibernateException
400 {
401 return _scrollableResults.getClob(arg0);
402 }
403
404 /***
405 * @see org.hibernate.ScrollableResults#getDate(int)
406 */
407 public Date getDate(int arg0) throws HibernateException
408 {
409 return _scrollableResults.getDate(arg0);
410 }
411
412 /***
413 * @see org.hibernate.ScrollableResults#getDouble(int)
414 */
415 public Double getDouble(int arg0) throws HibernateException
416 {
417 return _scrollableResults.getDouble(arg0);
418 }
419
420 /***
421 * @see org.hibernate.ScrollableResults#getFloat(int)
422 */
423 public Float getFloat(int arg0) throws HibernateException
424 {
425 return _scrollableResults.getFloat(arg0);
426 }
427
428 /***
429 * @see org.hibernate.ScrollableResults#getCharacter(int)
430 */
431 public Character getCharacter(int arg0) throws HibernateException
432 {
433 return _scrollableResults.getCharacter(arg0);
434 }
435
436 /***
437 * @see org.hibernate.ScrollableResults#getInteger(int)
438 */
439 public Integer getInteger(int arg0) throws HibernateException
440 {
441 return _scrollableResults.getInteger(arg0);
442 }
443
444 /***
445 * @see org.hibernate.ScrollableResults#getLocale(int)
446 */
447 public Locale getLocale(int arg0) throws HibernateException
448 {
449 return _scrollableResults.getLocale(arg0);
450 }
451
452 /***
453 * @see org.hibernate.ScrollableResults#getLong(int)
454 */
455 public Long getLong(int arg0) throws HibernateException
456 {
457 return _scrollableResults.getLong(arg0);
458 }
459
460 /***
461 * @see org.hibernate.ScrollableResults#getShort(int)
462 */
463 public Short getShort(int arg0) throws HibernateException
464 {
465 return _scrollableResults.getShort(arg0);
466 }
467
468 /***
469 * @see org.hibernate.ScrollableResults#getString(int)
470 */
471 public String getString(int arg0) throws HibernateException
472 {
473 return _scrollableResults.getString(arg0);
474 }
475
476 /***
477 * @see org.hibernate.ScrollableResults#getText(int)
478 */
479 public String getText(int arg0) throws HibernateException
480 {
481 return _scrollableResults.getString(arg0);
482 }
483
484 /***
485 * @see org.hibernate.ScrollableResults#getTimeZone(int)
486 */
487 public TimeZone getTimeZone(int arg0) throws HibernateException
488 {
489 return _scrollableResults.getTimeZone(arg0);
490 }
491
492 /***
493 * @see org.hibernate.ScrollableResults#getType(int)
494 */
495 public Type getType(int arg0)
496 {
497 return _scrollableResults.getType(arg0);
498 }
499
500
501
502 public void setScrollableResults(ScrollableResults scrollableResults)
503 {
504 _scrollableResults = scrollableResults;
505 reset();
506 }
507
508 public void setValidator(ObjectValidator validator)
509 {
510 _validator = validator;
511 }
512
513 private void reset()
514 {
515 _index = new int[INITIAL_CAPACITY];
516 _currentRow = -1;
517 _size = 0;
518 _isComplete = false;
519 }
520 }