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