1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.beanutils2.sql;
19
20 import java.sql.Date;
21 import java.sql.ResultSet;
22 import java.sql.ResultSetMetaData;
23 import java.sql.SQLException;
24 import java.sql.Time;
25 import java.sql.Timestamp;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31
32 import org.apache.commons.beanutils2.DynaBean;
33 import org.apache.commons.beanutils2.DynaClass;
34 import org.apache.commons.beanutils2.DynaProperty;
35
36
37
38
39
40
41 abstract class AbstractJdbcDynaClass implements DynaClass {
42
43
44
45
46 private Map<String, String> columnNameXref;
47
48
49
50
51
52
53 protected boolean lowerCase = true;
54
55
56
57
58
59
60 protected DynaProperty[] properties;
61
62
63
64
65
66
67
68 protected Map<String, DynaProperty> propertiesMap = new HashMap<>();
69
70
71
72
73
74 private boolean useColumnLabel;
75
76
77
78
79
80
81
82
83
84
85
86 protected DynaProperty createDynaProperty(final ResultSetMetaData metadata, final int i) throws SQLException {
87 String columnName = null;
88 if (useColumnLabel) {
89 columnName = metadata.getColumnLabel(i);
90 }
91 if (columnName == null || columnName.trim().isEmpty()) {
92 columnName = metadata.getColumnName(i);
93 }
94 final String name = lowerCase ? columnName.toLowerCase() : columnName;
95 if (!name.equals(columnName)) {
96 if (columnNameXref == null) {
97 columnNameXref = new HashMap<>();
98 }
99 columnNameXref.put(name, columnName);
100 }
101 String className = null;
102 try {
103 final int sqlType = metadata.getColumnType(i);
104 switch (sqlType) {
105 case java.sql.Types.DATE:
106 return new DynaProperty(name, java.sql.Date.class);
107 case java.sql.Types.TIMESTAMP:
108 return new DynaProperty(name, java.sql.Timestamp.class);
109 case java.sql.Types.TIME:
110 return new DynaProperty(name, java.sql.Time.class);
111 default:
112 className = metadata.getColumnClassName(i);
113 }
114 } catch (final SQLException e) {
115
116
117 }
118
119
120
121 Class<?> clazz = Object.class;
122 if (className != null) {
123 clazz = loadClass(className);
124 }
125 return new DynaProperty(name, clazz);
126 }
127
128
129
130
131
132
133
134 protected String getColumnName(final String name) {
135 if (columnNameXref != null && columnNameXref.containsKey(name)) {
136 return columnNameXref.get(name);
137 }
138 return name;
139 }
140
141
142
143
144
145
146
147 @Override
148 public DynaProperty[] getDynaProperties() {
149 return properties;
150 }
151
152
153
154
155
156
157
158
159
160 @Override
161 public DynaProperty getDynaProperty(final String name) {
162 return propertiesMap.get(Objects.requireNonNull(name, "name"));
163
164 }
165
166
167
168
169
170
171
172 @Override
173 public String getName() {
174 return this.getClass().getName();
175
176 }
177
178
179
180
181
182
183
184
185
186 protected Object getObject(final ResultSet resultSet, final String name) throws SQLException {
187 final DynaProperty property = getDynaProperty(name);
188 if (property == null) {
189 throw new IllegalArgumentException("Invalid name '" + name + "'");
190 }
191 final String columnName = getColumnName(name);
192 final Class<?> type = property.getType();
193
194
195 if (type.equals(Date.class)) {
196 return resultSet.getDate(columnName);
197 }
198
199
200 if (type.equals(Timestamp.class)) {
201 return resultSet.getTimestamp(columnName);
202 }
203
204
205 if (type.equals(Time.class)) {
206 return resultSet.getTime(columnName);
207 }
208
209 return resultSet.getObject(columnName);
210 }
211
212
213
214
215
216
217
218
219
220 protected void introspect(final ResultSet resultSet) throws SQLException {
221
222 final List<DynaProperty> list = new ArrayList<>();
223 final ResultSetMetaData metadata = resultSet.getMetaData();
224 final int n = metadata.getColumnCount();
225 for (int i = 1; i <= n; i++) {
226 final DynaProperty dynaProperty = createDynaProperty(metadata, i);
227 if (dynaProperty != null) {
228 list.add(dynaProperty);
229 }
230 }
231
232
233 properties = list.toArray(DynaProperty.EMPTY_ARRAY);
234 for (final DynaProperty property : properties) {
235 propertiesMap.put(property.getName(), property);
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248
249 protected Class<?> loadClass(final String className) throws SQLException {
250 try {
251 ClassLoader cl = Thread.currentThread().getContextClassLoader();
252 if (cl == null) {
253 cl = this.getClass().getClassLoader();
254 }
255
256 return Class.forName(className, false, cl);
257 } catch (final Exception e) {
258 throw new SQLException("Cannot load column class '" + className + "': " + e);
259 }
260 }
261
262
263
264
265
266
267
268
269
270
271
272 @Override
273 public DynaBean newInstance() throws IllegalAccessException, InstantiationException {
274 throw new UnsupportedOperationException("newInstance() not supported");
275 }
276
277
278
279
280
281
282 public void setUseColumnLabel(final boolean useColumnLabel) {
283 this.useColumnLabel = useColumnLabel;
284 }
285
286 }