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