001: package net.sourceforge.squirrel_sql.fw.datasetviewer;
002:
003: /*
004: * Copyright (C) 2001-2004 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import java.lang.reflect.Method;
022: import java.sql.ResultSet;
023: import java.sql.ResultSetMetaData;
024: import java.sql.SQLException;
025: import java.util.ArrayList;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030:
031: import net.sourceforge.squirrel_sql.fw.util.IMessageHandler;
032: import net.sourceforge.squirrel_sql.fw.util.StringManager;
033: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
034: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
035: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
036:
037: public class ResultSetMetaDataDataSet implements IDataSet {
038:
039: private static final StringManager s_stringMgr = StringManagerFactory
040: .getStringManager(ResultSetMetaDataDataSet.class);
041:
042: private interface i18n {
043: String UNSUPPORTED = "<Unsupported>";
044: // i18n[resultSetMentaDataSet.propName=Property Name]
045: String NAME_COLUMN = s_stringMgr
046: .getString("resultSetMentaDataSet.propName");
047: // String NULL = "<null>";
048: // i18n[resultSetMentaDataSet.val=Value]
049: String VALUE_COLUMN = s_stringMgr
050: .getString("resultSetMentaDataSet.val");
051: }
052:
053: /** Logger for this class. */
054: private static ILogger s_log = LoggerController
055: .createLogger(ResultSetMetaDataDataSet.class);
056:
057: private DataSetDefinition _dsDef;
058: private boolean[] _propertyMethodIndicators;
059: private Iterator<Object[]> _rowsIter;
060: private Object[] _row;
061:
062: /**
063: * Data. Each element is an array of String objects representing a column from
064: * the result set metadata.
065: */
066: private List<Object[]> _data = new ArrayList<Object[]>();
067:
068: /**
069: * Collection of method names that are considered to the
070: * "properties" of the <TT>ResultSetMetaData</TT> class.
071: */
072: private static final Map<String, Object> s_propNames = new HashMap<String, Object>();
073:
074: static {
075: s_propNames.put("getCatalogName", null);
076: s_propNames.put("getColumnClassName", null);
077: s_propNames.put("getColumnDisplaySize", null);
078: s_propNames.put("getColumnLabel", null);
079: s_propNames.put("getColumnName", null);
080: s_propNames.put("getColumnType", null);
081: s_propNames.put("getColumnTypeName", null);
082: s_propNames.put("getPrecision", null);
083: s_propNames.put("getScale", null);
084: s_propNames.put("getSchemaName", null);
085: s_propNames.put("getTableName", null);
086: s_propNames.put("isAutoIncrement", null);
087: s_propNames.put("isCaseSensitive", null);
088: s_propNames.put("isCurrency", null);
089: s_propNames.put("isDefinitelyWritable", null);
090: s_propNames.put("isNullable", null);
091: s_propNames.put("isReadOnly", null);
092: s_propNames.put("isSearchable", null);
093: s_propNames.put("isSigned", null);
094: s_propNames.put("isWritable", null);
095: }
096:
097: public ResultSetMetaDataDataSet(ResultSet rs)
098: throws IllegalArgumentException, DataSetException {
099: this (getMetaDataFromResultSet(rs));
100: }
101:
102: public ResultSetMetaDataDataSet(ResultSetMetaData md)
103: throws IllegalArgumentException, DataSetException {
104: super ();
105: setResultSetMetaData(md);
106: }
107:
108: public synchronized void setResultSetMetaData(ResultSetMetaData md)
109: throws DataSetException {
110: _dsDef = new DataSetDefinition(createColumnDefinitions());
111: load(md);
112: }
113:
114: public final int getColumnCount() {
115: return _dsDef.getColumnDefinitions().length;
116: }
117:
118: public DataSetDefinition getDataSetDefinition() {
119: return _dsDef;
120: }
121:
122: public synchronized boolean next(IMessageHandler msgHandler)
123: throws DataSetException {
124: if (_rowsIter.hasNext()) {
125: _row = _rowsIter.next();
126: } else {
127: _row = null;
128: }
129: return _row != null;
130: }
131:
132: public synchronized Object get(int columnIndex) {
133: return _row[columnIndex];
134: }
135:
136: private ColumnDisplayDefinition[] createColumnDefinitions() {
137: final Method[] methods = ResultSetMetaData.class.getMethods();
138: _propertyMethodIndicators = new boolean[methods.length];
139: final List<ColumnDisplayDefinition> colDefs = new ArrayList<ColumnDisplayDefinition>();
140: for (int i = 0; i < methods.length; ++i) {
141: if (isPropertyMethod(methods[i])) {
142: colDefs.add(new ColumnDisplayDefinition(200, methods[i]
143: .getName()));
144: _propertyMethodIndicators[i] = true;
145: } else {
146: _propertyMethodIndicators[i] = false;
147: }
148: }
149: return colDefs.toArray(new ColumnDisplayDefinition[colDefs
150: .size()]);
151: }
152:
153: private void load(ResultSetMetaData md) throws DataSetException {
154: try {
155: final Method[] methods = ResultSetMetaData.class
156: .getMethods();
157: final ArrayList<Object> line = new ArrayList<Object>();
158: for (int metaIdx = 1, metaLimit = md.getColumnCount() + 1; metaIdx < metaLimit; ++metaIdx) {
159: Object[] methodParms = new Object[] { Integer
160: .valueOf(metaIdx), };
161: line.clear();
162: line.ensureCapacity(methods.length);
163: for (int methodIdx = 0; methodIdx < methods.length; ++methodIdx) {
164: try {
165:
166: if (_propertyMethodIndicators[methodIdx]) {
167: Object obj = executeGetter(md,
168: methods[methodIdx], methodParms);
169: line.add(obj);// != null ? obj.toString() : i18n.NULL);
170: }
171: } catch (Throwable th) {
172: line.add("<Error>");
173: s_log
174: .error("Error reading column metadata",
175: th);
176: }
177:
178: }
179:
180: _data.add(line.toArray(new Object[line.size()]));
181: }
182:
183: _rowsIter = _data.iterator();
184: } catch (SQLException ex) {
185: s_log.error("Error occured processing result set", ex);
186: throw new DataSetException(ex);
187: }
188: }
189:
190: /**
191: * A valid method for a property in <TT>ResultSetMetaData</TT> is one that
192: * has a non-void ouput and takes a single integer parameter (the column index).
193: *
194: * @return <TT>true</TT> if method is a property getter else <TT>false</TT>.
195: */
196: protected boolean isPropertyMethod(Method method) {
197: return s_propNames.containsKey(method.getName());
198: // return method.getParameterTypes().length == 1
199: // && method.getParameterTypes()[0] == int.class
200: // && method.getReturnType() != Void.TYPE;
201: }
202:
203: protected Object executeGetter(Object bean, Method getter,
204: Object[] parms) {
205: try {
206: return getter.invoke(bean, parms);
207: } catch (Throwable th) {
208: return i18n.UNSUPPORTED;
209: }
210: }
211:
212: private static ResultSetMetaData getMetaDataFromResultSet(
213: ResultSet rs) throws IllegalArgumentException,
214: DataSetException {
215: if (rs == null) {
216: throw new IllegalArgumentException("Null ResultSet passed");
217: }
218: try {
219: return rs.getMetaData();
220: } catch (SQLException ex) {
221: throw new DataSetException(ex);
222: }
223: }
224: }
|