1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 package net.mlw.vlh.adapter.jdbc.dynabean.fix;
63
64 import java.io.Serializable;
65 import java.sql.ResultSet;
66 import java.sql.ResultSetMetaData;
67 import java.sql.SQLException;
68 import java.util.ArrayList;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Map;
72
73 import org.apache.commons.beanutils.DynaBean;
74 import org.apache.commons.beanutils.DynaClass;
75 import org.apache.commons.beanutils.DynaProperty;
76
77 /***
78 * <p>Provides common logic for JDBC implementations of {@link DynaClass}.</p>
79 *
80 * @author Craig R. McClanahan
81 * @author George Franciscus
82 * @version $Revision: 1.2 $ $Date: 2005/08/19 16:06:29 $
83 */
84
85 abstract class JDBCDynaClass implements DynaClass, Serializable {
86
87
88
89 /***
90 * <p>Flag defining whether column names should be lower cased when
91 * converted to property names.</p>
92 */
93 protected boolean lowerCase = true;
94
95 /***
96 * <p>Flag defining whether column names should be the column name
97 * or the column label.</p>
98 */
99 protected boolean useName = true;
100
101
102 /***
103 * <p>The set of dynamic properties that are part of this
104 * {@link DynaClass}.</p>
105 */
106 protected DynaProperty properties[] = null;
107
108 /***
109 * <p>The set of dynamic properties that are part of this
110 * {@link DynaClass}, keyed by the property name. Individual descriptor
111 * instances will be the same instances as those in the
112 * <code>properties</code> list.</p>
113 */
114 protected Map propertiesMap = new HashMap();
115
116
117
118 /***
119 * <p>Return the name of this DynaClass (analogous to the
120 * <code>getName()</code> method of <code>java.lang.Class</code), which
121 * allows the same <code>DynaClass</code> implementation class to support
122 * different dynamic classes, with different sets of properties.</p>
123 */
124 public String getName() {
125
126 return (this.getClass().getName());
127
128 }
129
130 /***
131 * <p>Return a property descriptor for the specified property, if it
132 * exists; otherwise, return <code>null</code>.</p>
133 *
134 * @param name Name of the dynamic property for which a descriptor
135 * is requested
136 *
137 * @exception IllegalArgumentException if no property name is specified
138 */
139 public DynaProperty getDynaProperty(String name) {
140
141 if (name == null) {
142 throw new IllegalArgumentException("No property name specified");
143 }
144 return ((DynaProperty) propertiesMap.get(name));
145
146 }
147
148 /***
149 * <p>Return an array of <code>ProperyDescriptors</code> for the properties
150 * currently defined in this DynaClass. If no properties are defined, a
151 * zero-length array will be returned.</p>
152 */
153 public DynaProperty[] getDynaProperties() {
154
155 return (properties);
156
157 }
158
159 /***
160 * <p>Instantiate and return a new DynaBean instance, associated
161 * with this DynaClass. <strong>NOTE</strong> - This operation is not
162 * supported, and throws an exception.</p>
163 *
164 * @exception IllegalAccessException if the Class or the appropriate
165 * constructor is not accessible
166 * @exception InstantiationException if this Class represents an abstract
167 * class, an array class, a primitive type, or void; or if instantiation
168 * fails for some other reason
169 */
170 public DynaBean newInstance()
171 throws IllegalAccessException, InstantiationException {
172
173 throw new UnsupportedOperationException("newInstance() not supported");
174
175 }
176
177 /***
178 * <p>Loads and returns the <code>Class</code> of the given name.
179 * By default, a load from the thread context class loader is attempted.
180 * If there is no such class loader, the class loader used to load this
181 * class will be utilized.</p>
182 *
183 * @exception SQLException if an exception was thrown trying to load
184 * the specified class
185 */
186 protected Class loadClass(String className) throws SQLException {
187
188 try {
189 ClassLoader cl = Thread.currentThread().getContextClassLoader();
190 if (cl == null) {
191 cl = this.getClass().getClassLoader();
192 }
193 return (cl.loadClass(className));
194 } catch (Exception e) {
195 throw new SQLException(
196 "Cannot load column class '" + className + "': " + e);
197 }
198
199 }
200
201 /***
202 * <p>Factory method to create a new DynaProperty for the given index
203 * into the result set metadata.</p>
204 *
205 * @param metadata is the result set metadata
206 * @param i is the column index in the metadata
207 * @return the newly created DynaProperty instance
208 */
209 protected DynaProperty createDynaProperty(
210 ResultSetMetaData metadata,
211 int i)
212 throws SQLException {
213
214 String name = ( useName ) ? metadata.getColumnName(i) : metadata.getColumnLabel(i);
215
216 if (lowerCase) {
217 name = name.toLowerCase();
218 }
219
220 String className = null;
221 try {
222 className = metadata.getColumnClassName(i);
223 } catch (SQLException e) {
224
225
226 }
227
228
229
230 Class clazz = Object.class;
231 if (className != null) {
232 clazz = loadClass(className);
233 }
234 return new DynaProperty(name, clazz);
235
236 }
237
238 /***
239 * <p>Introspect the metadata associated with our result set, and populate
240 * the <code>properties</code> and <code>propertiesMap</code> instance
241 * variables.</p>
242 *
243 * @param resultSet The <code>resultSet</code> whose metadata is to
244 * be introspected
245 *
246 * @exception SQLException if an error is encountered processing the
247 * result set metadata
248 */
249 protected void introspect(ResultSet resultSet) throws SQLException {
250
251
252 List list = new ArrayList();
253 ResultSetMetaData metadata = resultSet.getMetaData();
254 int n = metadata.getColumnCount();
255 for (int i = 1; i <= n; i++) {
256 DynaProperty dynaProperty = createDynaProperty(metadata, i);
257 if (dynaProperty != null) {
258 list.add(dynaProperty);
259 }
260 }
261
262
263 properties =
264 (DynaProperty[]) list.toArray(new DynaProperty[list.size()]);
265 for (int i = 0; i < properties.length; i++) {
266 propertiesMap.put(properties[i].getName(), properties[i]);
267 }
268
269 }
270
271 }