1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.model;
20
21 import javax.faces.FacesException;
22 import java.sql.ResultSet;
23 import java.sql.ResultSetMetaData;
24 import java.sql.SQLException;
25 import java.util.AbstractCollection;
26 import java.util.AbstractSet;
27 import java.util.Collection;
28 import java.util.Comparator;
29 import java.util.Iterator;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33
34
35
36
37
38
39
40
41 public class ResultSetDataModel extends DataModel<Map<String,Object>>
42 {
43
44
45 private int _currentIndex = -1;
46
47
48
49
50 private ResultSet _resultSet = null;
51
52
53
54
55 private ResultSetMetaData _resultSetMetadata = null;
56
57
58
59
60 private boolean _currentRowUpdated = false;
61
62
63 public ResultSetDataModel()
64 {
65 this(null);
66 }
67
68 public ResultSetDataModel(ResultSet resultSet)
69 {
70
71 super();
72 setWrappedData(resultSet);
73
74 }
75
76
77
78
79 @Override
80 public int getRowCount()
81 {
82 return -1;
83 }
84
85
86
87
88
89 @Override
90 public Map<String,Object> getRowData()
91 {
92 if (_resultSet == null)
93 {
94 return null;
95 }
96 else if (!isRowAvailable())
97 {
98 throw new IllegalArgumentException(
99 "the requested row is not available in the ResultSet - you have scrolled beyond the end.");
100 }
101
102 try
103 {
104 return new WrapResultSetMap(String.CASE_INSENSITIVE_ORDER);
105 }
106 catch (SQLException e)
107 {
108 throw new FacesException(e);
109 }
110 }
111
112 @Override
113 public int getRowIndex()
114 {
115 return _currentIndex;
116 }
117
118 @Override
119 public Object getWrappedData()
120 {
121 return _resultSet;
122 }
123
124 @Override
125 public boolean isRowAvailable()
126 {
127 if (_resultSet == null)
128 {
129 return false;
130 }
131 else if (_currentIndex < 0)
132 {
133 return false;
134 }
135
136 try
137 {
138 return _resultSet.absolute(_currentIndex + 1);
139 }
140 catch (SQLException e)
141 {
142 throw new FacesException(e);
143 }
144 }
145
146 @Override
147 public void setRowIndex(int rowIndex)
148 {
149 if (rowIndex < -1)
150 {
151 throw new IllegalArgumentException("you cannot set the rowIndex to anything less than 0");
152 }
153
154
155 if (_currentRowUpdated && _resultSet != null)
156 {
157 try
158 {
159 if (!_resultSet.rowDeleted())
160 {
161 _resultSet.updateRow();
162 }
163
164 setCurrentRowUpdated(false);
165 }
166 catch (SQLException e)
167 {
168 throw new FacesException(e);
169 }
170 }
171
172 int old = _currentIndex;
173 _currentIndex = rowIndex;
174
175
176
177 if (_resultSet == null)
178 {
179 return;
180 }
181
182
183 DataModelListener[] listeners = getDataModelListeners();
184
185 if ((old != _currentIndex) && (listeners != null))
186 {
187 Object rowData = null;
188
189 if (isRowAvailable())
190 {
191 rowData = getRowData();
192 }
193
194 DataModelEvent event = new DataModelEvent(this, _currentIndex, rowData);
195
196 int n = listeners.length;
197
198 for (int i = 0; i < n; i++)
199 {
200 if (listeners[i] != null)
201 {
202 listeners[i].rowSelected(event);
203 }
204 }
205 }
206 }
207
208 @Override
209 public void setWrappedData(Object data)
210 {
211 if (data == null)
212 {
213 _resultSetMetadata = null;
214 _resultSet = null;
215 setRowIndex(-1);
216 }
217 else
218 {
219 _resultSetMetadata = null;
220 _resultSet = (ResultSet) data;
221 _currentIndex = -1;
222 setRowIndex(0);
223 }
224 }
225
226 private ResultSetMetaData getResultSetMetadata()
227 {
228 if (_resultSetMetadata == null)
229 {
230 try
231 {
232 _resultSetMetadata = _resultSet.getMetaData();
233 }
234 catch (SQLException e)
235 {
236 throw new FacesException(e);
237 }
238 }
239
240 return _resultSetMetadata;
241 }
242
243 private void setCurrentRowUpdated(boolean currentRowUpdated)
244 {
245 _currentRowUpdated = currentRowUpdated;
246 }
247
248
249
250
251
252
253 private class WrapResultSetMap extends TreeMap<String, Object>
254 {
255 private static final long serialVersionUID = -4321143404567038922L;
256 private int _currentIndex;
257
258 public WrapResultSetMap(Comparator<String> comparator) throws SQLException
259 {
260 super(comparator);
261
262 _currentIndex = ResultSetDataModel.this._currentIndex;
263
264 _resultSet.absolute(_currentIndex + 1);
265
266 int columnCount = getResultSetMetadata().getColumnCount();
267
268 for (int i = 1; i <= columnCount; i++)
269 {
270 super.put(getResultSetMetadata().getColumnName(i), getResultSetMetadata().getColumnName(i));
271 }
272 }
273
274 @Override
275 public void clear()
276 {
277 throw new UnsupportedOperationException("It is not allowed to remove from this map");
278 }
279
280 @Override
281 public boolean containsValue(Object value)
282 {
283
284
285 for (Map.Entry<String, Object> entry : entrySet())
286 {
287 if (value != null && value.equals(entry.getValue()))
288 {
289 return true;
290 }
291 else if (value == null && entry.getValue() == null)
292 {
293 return true;
294 }
295 }
296
297 return false;
298 }
299
300 @Override
301 public Set<Map.Entry<String, Object>> entrySet()
302 {
303 return new WrapResultSetEntries(this);
304 }
305
306 @Override
307 public Object get(Object key)
308 {
309 if (!containsKey(key))
310 {
311 return null;
312 }
313
314 return basicGet(key);
315 }
316
317 private Object basicGet(Object key)
318 {
319 try
320 {
321 _resultSet.absolute(_currentIndex + 1);
322
323 return _resultSet.getObject((String) getUnderlyingKey(key));
324
325 }
326 catch (SQLException e)
327 {
328 throw new FacesException(e);
329 }
330 }
331
332 @Override
333 public Set<String> keySet()
334 {
335 return new WrapResultSetKeys(this);
336 }
337
338 @Override
339 public Object put(String key, Object value)
340 {
341 if (!containsKey(key))
342 {
343 throw new IllegalArgumentException("underlying result set does not provide this key");
344 }
345
346 try
347 {
348 _resultSet.absolute(_currentIndex + 1);
349
350 Object oldValue = _resultSet.getObject((String) getUnderlyingKey(key));
351
352 if (oldValue == null ? value == null : oldValue.equals(value))
353 {
354 return oldValue;
355 }
356
357 _resultSet.updateObject((String) getUnderlyingKey(key), value);
358
359 setCurrentRowUpdated(true);
360
361 return oldValue;
362 }
363 catch (SQLException e)
364 {
365 throw new FacesException(e);
366 }
367 }
368
369 @Override
370 public void putAll(Map<? extends String, ?> map)
371 {
372 for (Map.Entry<? extends String, ?> entry : map.entrySet())
373 {
374 put(entry.getKey(), entry.getValue());
375 }
376 }
377
378 @Override
379 public Object remove(Object key)
380 {
381 throw new UnsupportedOperationException("It is not allowed to remove entries from this set.");
382 }
383
384 @Override
385 public Collection<Object> values()
386 {
387 return new WrapResultSetValues(this);
388 }
389
390 Object getUnderlyingKey(Object key)
391 {
392 return super.get(key);
393 }
394
395 Iterator<String> getUnderlyingKeys()
396 {
397 return super.keySet().iterator();
398 }
399
400 }
401
402 private static class WrapResultSetEntries extends AbstractSet<Map.Entry<String, Object>>
403 {
404 private WrapResultSetMap _wrapMap;
405
406 public WrapResultSetEntries(WrapResultSetMap wrapMap)
407 {
408 _wrapMap = wrapMap;
409 }
410
411 @Override
412 public boolean add(Map.Entry<String, Object> o)
413 {
414 throw new UnsupportedOperationException("it is not allowed to add to this set");
415 }
416
417 @Override
418 public boolean addAll(Collection<? extends Map.Entry<String, Object>> c)
419 {
420 throw new UnsupportedOperationException("it is not allowed to add to this set");
421 }
422
423 @Override
424 public void clear()
425 {
426 throw new UnsupportedOperationException("it is not allowed to remove from this set");
427 }
428
429 @Override
430 public boolean contains(Object o)
431 {
432 if (o == null)
433 {
434 throw new NullPointerException();
435 }
436 if (!(o instanceof Map.Entry))
437 {
438 return false;
439 }
440
441 Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
442 Object key = e.getKey();
443
444 if (!_wrapMap.containsKey(key))
445 {
446 return false;
447 }
448
449 Object value = e.getValue();
450 Object cmpValue = _wrapMap.get(key);
451
452 return value == null ? cmpValue == null : value.equals(cmpValue);
453 }
454
455 @Override
456 public boolean isEmpty()
457 {
458 return _wrapMap.isEmpty();
459 }
460
461 @Override
462 public Iterator<Map.Entry<String, Object>> iterator()
463 {
464 return new WrapResultSetEntriesIterator(_wrapMap);
465 }
466
467 @Override
468 public boolean remove(Object o)
469 {
470 throw new UnsupportedOperationException("it is not allowed to remove from this set");
471 }
472
473 @Override
474 public boolean removeAll(Collection<?> c)
475 {
476 throw new UnsupportedOperationException("it is not allowed to remove from this set");
477 }
478
479 @Override
480 public boolean retainAll(Collection<?> c)
481 {
482 throw new UnsupportedOperationException("it is not allowed to remove from this set");
483 }
484
485 @Override
486 public int size()
487 {
488 return _wrapMap.size();
489 }
490 }
491
492 private static class WrapResultSetEntriesIterator implements Iterator<Map.Entry<String, Object>>
493 {
494
495 private WrapResultSetMap _wrapMap = null;
496 private Iterator<String> _keyIterator = null;
497
498 public WrapResultSetEntriesIterator(WrapResultSetMap wrapMap)
499 {
500 _wrapMap = wrapMap;
501 _keyIterator = _wrapMap.keySet().iterator();
502 }
503
504 public boolean hasNext()
505 {
506 return _keyIterator.hasNext();
507 }
508
509 public Map.Entry<String, Object> next()
510 {
511 return new WrapResultSetEntry(_wrapMap, _keyIterator.next());
512 }
513
514 public void remove()
515 {
516 throw new UnsupportedOperationException("It is not allowed to remove from this iterator");
517 }
518
519 }
520
521 private static class WrapResultSetEntry implements Map.Entry<String, Object>
522 {
523
524 private WrapResultSetMap _wrapMap;
525 private String _entryKey;
526
527 public WrapResultSetEntry(WrapResultSetMap wrapMap, String entryKey)
528 {
529 _wrapMap = wrapMap;
530 _entryKey = entryKey;
531 }
532
533 @Override
534 public boolean equals(Object o)
535 {
536 if (o == null)
537 {
538 return false;
539 }
540
541 if (!(o instanceof Map.Entry))
542 {
543 return false;
544 }
545
546 Map.Entry<?, ?> cmpEntry = (Map.Entry<?, ?>) o;
547
548 if (_entryKey == null ? cmpEntry.getKey() != null : !_entryKey.equals(cmpEntry.getKey()))
549 {
550 return false;
551 }
552
553 Object value = _wrapMap.get(_entryKey);
554 Object cmpValue = cmpEntry.getValue();
555
556 return value == null ? cmpValue != null : value.equals(cmpValue);
557 }
558
559 public String getKey()
560 {
561 return _entryKey;
562 }
563
564 public Object getValue()
565 {
566 return _wrapMap.get(_entryKey);
567 }
568
569 @Override
570 public int hashCode()
571 {
572 int result;
573 result = (_entryKey != null ? _entryKey.hashCode() : 0);
574 result = 29 * result + (_wrapMap.get(_entryKey) != null ? _wrapMap.get(_entryKey).hashCode() : 0);
575 return result;
576 }
577
578 public Object setValue(Object value)
579 {
580 Object oldValue = _wrapMap.get(_entryKey);
581 _wrapMap.put(_entryKey, value);
582 return oldValue;
583 }
584 }
585
586 private static class WrapResultSetKeys extends AbstractSet<String>
587 {
588 private WrapResultSetMap _wrapMap;
589
590 public WrapResultSetKeys(WrapResultSetMap wrapMap)
591 {
592 _wrapMap = wrapMap;
593 }
594
595 @Override
596 public boolean add(String o)
597 {
598 throw new UnsupportedOperationException("It is not allowed to add to this set");
599 }
600
601 @Override
602 public boolean addAll(Collection<? extends String> c)
603 {
604 throw new UnsupportedOperationException("It is not allowed to add to this set");
605 }
606
607 @Override
608 public void clear()
609 {
610 throw new UnsupportedOperationException("It is not allowed to remove from this set");
611 }
612
613 @Override
614 public boolean contains(Object obj)
615 {
616 return _wrapMap.containsKey(obj);
617 }
618
619 @Override
620 public boolean isEmpty()
621 {
622 return _wrapMap.isEmpty();
623 }
624
625 @Override
626 public Iterator<String> iterator()
627 {
628 return new WrapResultSetKeysIterator(_wrapMap);
629 }
630
631 @Override
632 public boolean remove(Object o)
633 {
634 throw new UnsupportedOperationException("It is not allowed to remove from this set");
635 }
636
637 @Override
638 public boolean removeAll(Collection<?> c)
639 {
640 throw new UnsupportedOperationException("It is not allowed to remove from this set");
641 }
642
643 @Override
644 public boolean retainAll(Collection<?> c)
645 {
646 throw new UnsupportedOperationException("It is not allowed to remove from this set");
647 }
648
649 @Override
650 public int size()
651 {
652 return _wrapMap.size();
653 }
654 }
655
656 private static class WrapResultSetKeysIterator implements Iterator<String>
657 {
658 private Iterator<String> _keyIterator = null;
659
660 public WrapResultSetKeysIterator(WrapResultSetMap map)
661 {
662 _keyIterator = map.getUnderlyingKeys();
663 }
664
665 public boolean hasNext()
666 {
667 return _keyIterator.hasNext();
668 }
669
670 public String next()
671 {
672 return _keyIterator.next();
673 }
674
675 public void remove()
676 {
677 throw new UnsupportedOperationException("it is not allowed to remove from this iterator");
678 }
679
680 }
681
682 private static class WrapResultSetValues extends AbstractCollection<Object>
683 {
684 private WrapResultSetMap _wrapMap;
685
686 public WrapResultSetValues(WrapResultSetMap wrapMap)
687 {
688 _wrapMap = wrapMap;
689 }
690
691 @Override
692 public boolean add(Object o)
693 {
694 throw new UnsupportedOperationException("it is not allowed to add to this collection");
695 }
696
697 @Override
698 public boolean addAll(Collection<?> c)
699 {
700 throw new UnsupportedOperationException("it is not allowed to add to this collection");
701 }
702
703 @Override
704 public void clear()
705 {
706 throw new UnsupportedOperationException("it is not allowed to remove from this collection");
707 }
708
709 @Override
710 public boolean contains(Object value)
711 {
712 return _wrapMap.containsValue(value);
713 }
714
715 @Override
716 public Iterator<Object> iterator()
717 {
718 return new WrapResultSetValuesIterator(_wrapMap);
719 }
720
721 @Override
722 public boolean remove(Object o)
723 {
724 throw new UnsupportedOperationException();
725 }
726
727 @Override
728 public boolean removeAll(Collection<?> c)
729 {
730 throw new UnsupportedOperationException("it is not allowed to remove from this collection");
731 }
732
733 @Override
734 public boolean retainAll(Collection<?> c)
735 {
736 throw new UnsupportedOperationException("it is not allowed to remove from this collection");
737 }
738
739 @Override
740 public int size()
741 {
742 return _wrapMap.size();
743 }
744
745 }
746
747 private static class WrapResultSetValuesIterator implements Iterator<Object>
748 {
749
750 private WrapResultSetMap _wrapMap;
751 private Iterator<String> _keyIterator;
752
753 public WrapResultSetValuesIterator(WrapResultSetMap wrapMap)
754 {
755 _wrapMap = wrapMap;
756 _keyIterator = _wrapMap.keySet().iterator();
757 }
758
759 public boolean hasNext()
760 {
761 return _keyIterator.hasNext();
762 }
763
764 public Object next()
765 {
766 return _wrapMap.get(_keyIterator.next());
767 }
768
769 public void remove()
770 {
771 throw new UnsupportedOperationException("it is not allowed to remove from this map");
772 }
773
774 }
775
776 }