001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License version 2
011: * as published by the Free Software Foundation.
012: *
013: * Resin Open Source is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
016: * of NON-INFRINGEMENT. See the GNU General Public License for more
017: * details.
018: *
019: * You should have received a copy of the GNU General Public License
020: * along with Resin Open Source; if not, write to the
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package javax.faces.model;
030:
031: import javax.faces.*;
032: import java.util.*;
033: import java.sql.*;
034:
035: public class ResultSetDataModel extends DataModel {
036: private ResultSet _rs;
037: private ResultSetMetaData _metaData;
038: private DataMap _map;
039: private int _rowIndex = -1;
040:
041: public ResultSetDataModel() {
042: }
043:
044: public ResultSetDataModel(ResultSet value) {
045: _rs = value;
046: setRowIndex(0);
047: }
048:
049: public int getRowCount() {
050: return -1;
051: }
052:
053: public Object getRowData() {
054: if (_rs == null)
055: return null;
056: else if (isRowAvailable()) {
057: if (_map == null)
058: _map = new DataMap(_rs, getMetaData());
059:
060: return _map;
061: } else
062: throw new IllegalArgumentException();
063: }
064:
065: public boolean isRowAvailable() {
066: try {
067: return _rs != null && _rs.absolute(getRowIndex() + 1);
068: } catch (SQLException e) {
069: throw new FacesException(e);
070: }
071: }
072:
073: public Object getWrappedData() {
074: return _rs;
075: }
076:
077: public void setWrappedData(Object data) {
078: _rs = (ResultSet) data;
079: _metaData = null;
080: _map = null;
081: setRowIndex(0);
082: }
083:
084: public int getRowIndex() {
085: return _rowIndex;
086: }
087:
088: public void setRowIndex(int index) {
089: if (_rs != null && index < -1)
090: throw new IllegalArgumentException("rowIndex '" + index
091: + "' cannot be less than -1.");
092:
093: DataModelListener[] listeners = getDataModelListeners();
094:
095: if (listeners.length > 0 && _rs != null && _rowIndex != index) {
096: DataModelEvent event = new DataModelEvent(this , index, _rs);
097:
098: for (int i = 0; i < listeners.length; i++) {
099: listeners[i].rowSelected(event);
100: }
101: }
102:
103: _rowIndex = index;
104: }
105:
106: private ResultSetMetaData getMetaData() {
107: try {
108: if (_metaData == null) {
109: _metaData = _rs.getMetaData();
110: }
111:
112: return _metaData;
113: } catch (SQLException e) {
114: throw new RuntimeException(e);
115: }
116: }
117:
118: static class DataMap extends AbstractMap<String, Object> {
119: private ResultSet _rs;
120: private ResultSetMetaData _metaData;
121: private int _columnCount;
122: private Set<String> _keySet;
123: private Set<Entry<String, Object>> _entrySet;
124:
125: DataMap(ResultSet resultSet, ResultSetMetaData metaData) {
126: _rs = resultSet;
127: _metaData = metaData;
128:
129: try {
130: _columnCount = _metaData.getColumnCount();
131: } catch (SQLException e) {
132: throw new RuntimeException(e);
133: }
134: }
135:
136: @Override
137: public Object get(Object key) {
138: int column = getColumn(String.valueOf(key));
139:
140: if (column < 0)
141: throw new IllegalArgumentException("'" + key
142: + "' is an unknown column");
143:
144: try {
145: return _rs.getObject(column + 1);
146: } catch (SQLException e) {
147: throw new RuntimeException(e);
148: }
149: }
150:
151: @Override
152: public Object remove(Object key) {
153: throw new UnsupportedOperationException();
154: }
155:
156: @Override
157: public void clear() {
158: throw new UnsupportedOperationException();
159: }
160:
161: public Set<String> keySet() {
162: if (_keySet == null)
163: _keySet = new DataMapKeySet(_metaData);
164:
165: return _keySet;
166: }
167:
168: public Collection<Object> values() {
169: return new DataMapValues(_rs, _columnCount);
170: }
171:
172: @Override
173: public boolean containsKey(Object v) {
174: String key = String.valueOf(v);
175:
176: return getColumn(key) >= 0;
177: }
178:
179: @Override
180: public Object put(String k, Object value) {
181: try {
182: String key = String.valueOf(k);
183:
184: int column = getColumn(key) + 1;
185:
186: if (column <= 0)
187: throw new IllegalArgumentException();
188:
189: _rs.updateObject(column, value);
190:
191: return null;
192: } catch (SQLException e) {
193: throw new RuntimeException(e);
194: } catch (RuntimeException e) {
195: throw e;
196: }
197: }
198:
199: public Set<Entry<String, Object>> entrySet() {
200: if (_entrySet == null)
201: _entrySet = new DataMapEntrySet(_rs, _metaData);
202:
203: return _entrySet;
204: }
205:
206: private int getColumn(String key) {
207: try {
208: for (int i = 0; i < _columnCount; i++) {
209: if (_metaData.getColumnName(i + 1)
210: .equalsIgnoreCase(key))
211: return i;
212: }
213:
214: return -1;
215: } catch (SQLException e) {
216: throw new RuntimeException(e);
217: }
218: }
219: }
220:
221: private static class DataMapKeySet extends AbstractSet<String> {
222: private ResultSetMetaData _metaData;
223: private int _columnCount;
224:
225: DataMapKeySet(ResultSetMetaData metaData) {
226: _metaData = metaData;
227:
228: try {
229: _columnCount = _metaData.getColumnCount();
230: } catch (SQLException e) {
231: throw new RuntimeException(e);
232: }
233: }
234:
235: public int size() {
236: return _columnCount;
237: }
238:
239: @Override
240: public boolean contains(Object v) {
241: try {
242: String key = String.valueOf(v);
243:
244: for (int i = 0; i < _columnCount; i++) {
245: if (_metaData.getColumnName(i + 1)
246: .equalsIgnoreCase(key))
247: return true;
248: }
249:
250: return false;
251: } catch (SQLException e) {
252: throw new RuntimeException(e);
253: }
254: }
255:
256: @Override
257: public boolean remove(Object key) {
258: throw new UnsupportedOperationException();
259: }
260:
261: public Iterator<String> iterator() {
262: ArrayList<String> keys = new ArrayList<String>();
263:
264: try {
265: for (int i = 0; i < _columnCount; i++) {
266: keys.add(_metaData.getColumnName(i + 1));
267: }
268:
269: return Collections.unmodifiableList(keys).iterator();
270: } catch (SQLException e) {
271: throw new RuntimeException(e);
272: }
273: }
274: }
275:
276: private static class DataMapValues extends AbstractCollection {
277: private ResultSet _rs;
278: private int _columnCount;
279:
280: DataMapValues(ResultSet rs, int columnCount) {
281: _rs = rs;
282: _columnCount = columnCount;
283: }
284:
285: public int size() {
286: return _columnCount;
287: }
288:
289: @Override
290: public boolean contains(Object v) {
291: try {
292: if (v == null)
293: return false;
294:
295: for (int i = 0; i < _columnCount; i++) {
296: if (v.equals(_rs.getObject(i + 1)))
297: return true;
298: }
299:
300: return false;
301: } catch (SQLException e) {
302: throw new RuntimeException(e);
303: }
304: }
305:
306: @Override
307: public boolean remove(Object key) {
308: throw new UnsupportedOperationException();
309: }
310:
311: public Iterator iterator() {
312: ArrayList values = new ArrayList();
313:
314: try {
315: for (int i = 0; i < _columnCount; i++) {
316: values.add(_rs.getObject(i + 1));
317: }
318:
319: return Collections.unmodifiableList(values).iterator();
320: } catch (SQLException e) {
321: throw new RuntimeException(e);
322: }
323: }
324: }
325:
326: private static class DataMapEntrySet extends
327: AbstractSet<Map.Entry<String, Object>> {
328: private ResultSet _rs;
329: private ResultSetMetaData _metaData;
330: private int _columnCount;
331: private int _index;
332:
333: DataMapEntrySet(ResultSet rs, ResultSetMetaData metaData) {
334: _rs = rs;
335: _metaData = metaData;
336:
337: try {
338: _columnCount = _metaData.getColumnCount();
339: } catch (SQLException e) {
340: throw new RuntimeException(e);
341: }
342: }
343:
344: public int size() {
345: return _columnCount;
346: }
347:
348: @Override
349: public boolean remove(Object key) {
350: throw new UnsupportedOperationException();
351: }
352:
353: public Iterator<Map.Entry<String, Object>> iterator() {
354: return new EntrySetIterator(_rs, _metaData, _columnCount);
355: }
356: }
357:
358: static class EntrySetIterator implements
359: Iterator<Map.Entry<String, Object>> {
360: private ResultSet _rs;
361: private ResultSetMetaData _metaData;
362: private Entry _entry = new Entry();
363: private int _count;
364: private int _index;
365:
366: EntrySetIterator(ResultSet rs, ResultSetMetaData metaData,
367: int count) {
368: _rs = rs;
369: _metaData = metaData;
370: _count = count;
371: }
372:
373: public boolean hasNext() {
374: return _index < _count;
375: }
376:
377: public Map.Entry<String, Object> next() {
378: if (_index++ < _count)
379: return _entry;
380: else
381: return null;
382: }
383:
384: public void remove() {
385: throw new UnsupportedOperationException();
386: }
387:
388: class Entry implements Map.Entry<String, Object> {
389: public String getKey() {
390: try {
391: return _metaData.getColumnName(_index);
392: } catch (SQLException e) {
393: throw new RuntimeException(e);
394: }
395: }
396:
397: public Object getValue() {
398: try {
399: return _rs.getObject(_index);
400: } catch (SQLException e) {
401: throw new RuntimeException(e);
402: }
403: }
404:
405: public Object setValue(Object value) {
406: try {
407: _rs.updateObject(_index, value);
408: } catch (SQLException e) {
409: throw new RuntimeException(e);
410: }
411:
412: return null;
413: }
414: }
415: }
416: }
|