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