Source code: org/enableit/db/daf/jdbc/JdbcDaf.java
1 package org.enableit.db.daf.jdbc;
2
3 // Java imports
4 import java.beans.PropertyDescriptor ;
5 import java.sql.Connection ;
6 import java.util.ArrayList ;
7 import java.util.Date ;
8 import java.util.Iterator ;
9 import java.util.List ;
10 import java.util.Map ;
11
12 // Apache commons imports
13 import org.apache.commons.beanutils.PropertyUtils ;
14
15 // Log4J Imports
16 import org.apache.log4j.Category;
17
18 // My imports
19 import org.enableit.db.ConnectionFactory ;
20 import org.enableit.db.DatabaseProxy ;
21 import org.enableit.db.DataSourceProxy ;
22 import org.enableit.db.DBException ;
23 import org.enableit.db.DBFilter ;
24 import org.enableit.db.DBUtils ;
25 import org.enableit.db.SqlEncoder ;
26 import org.enableit.db.daf.ComparableBean ;
27 import org.enableit.db.daf.NotPersistedException ;
28 import org.enableit.db.daf.QueryException ;
29 import org.enableit.db.daf.conf.ProviderDetails ;
30
31 /**
32 * Implementation of <code>DataAbstractionFacade</code>
33 * backed by JDBC calls.
34 * <br>
35 * Since this class requires no additional metadata file to
36 * map Bean properties to database columns, it must rely on a
37 * naming convention in order to construct the correct SQL.
38 * It is expected that this restriction will be acceptable for
39 * applications where UI and function is more important than
40 * database design, and where there is no existing database.
41 * <br>
42 * The convention is as follows:
43 * <ul>
44 * <li>Bean name must be <TableName>Bean e.g. for a table named Task, bean name must be TaskBean.
45 * <li>The database key column must be named <TableName>Id, except that the initial will be lower case.
46 * <li>Bean properties must have the same name as the database columns they are stored in.
47 * <li>Normal JavaBean conventions apply to accessor and mutator method names.
48 * </ul>
49 *
50 * @author default
51 */
52 public class JdbcDaf implements org.enableit.db.daf.DataAbstractionFacade
53 {
54 /**
55 * Construct and configure a new instance.
56 */
57 public JdbcDaf (ProviderDetails pd)
58 {
59 // prefer Datasource, look for that 1st
60 if (pd.getJdbc().getDatasource()!=null) {
61 dataSourceName = pd.getJdbc().getDatasource() ;
62 } else {
63 /*
64 * if neither datasource nor driver has been configured,
65 * Castor will have already thrown exception
66 */
67 driverClass = pd.getJdbc().getDriver().getDriverClass() ;
68 password = pd.getJdbc().getDriver().getPassword() ;
69 url = pd.getJdbc().getDriver().getUrl() ;
70 username = pd.getJdbc().getDriver().getUsername() ;
71 }
72 }
73
74 /*
75 * Interface methods
76 */
77
78 /**
79 * Test if the bean exists in the configured data store.
80 * <p>
81 * If the bean implements <code>org.enableit.db.daf.ComparableBean</code>
82 * then the Persistent datastore will be queried for an entry that matches
83 * just those properties defined by the <code>getEqualityPropertyList</code>.
84 * Otherwise every accessible property will be used in the query.
85 *
86 * @param bean
87 */
88 public boolean exists (Object bean)
89 throws QueryException
90 {
91 logger.info("METHOD_ENTRY: exists");
92
93 boolean exists = false ;
94
95 try {
96 String sql = null ;
97 if (bean instanceof ComparableBean) {
98 List equalityProps = ((ComparableBean)bean).getEqualityPropertyList() ;
99 sql = getFindSql(bean, equalityProps) ;
100 } else {
101 sql = getFindSql(bean) ;
102 }
103
104 // Do the query
105 List results = null ;
106 if (dataSourceName==null) {
107 Connection conn = ConnectionFactory.getConnection(
108 driverClass, url, username, password) ;
109 results = DatabaseProxy.executeQuery( conn, sql ) ;
110 conn.close() ;
111 } else {
112 results = DataSourceProxy.executeQuery( dataSourceName, sql ) ;
113 }
114
115 if (results.size()>=1) {
116 exists = true ;
117 }
118 } catch (DBException e) {
119 // will be already logged; rethrow, exception page will have to explain
120 throw new QueryException("Failed attempt to execute query on " +
121 getTableName(bean), e) ;
122 } catch (java.sql.SQLException e) {
123 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
124 throw new QueryException(e.getMessage(), e) ;
125 }
126
127 logger.info("METHOD_ENTRY: exists");
128 logger.info("... with params exists=" + exists) ;
129 return exists ;
130 }
131
132 /**
133 * Create a persistent copy of the received JavaBean.
134 *
135 * @param bean
136 * @returns Persisted copy of JavaBean.
137 */
138 public Object create (Object bean)
139 throws NotPersistedException
140 {
141 String tableName = getTableName(bean) ;
142 String keyColumn = getKeyColumn(tableName) ;
143
144 try {
145 // Get the next id to be used
146 Long id = new Long(DBUtils.getNextId(tableName, false)) ;
147 PropertyUtils.setProperty(bean, keyColumn, id) ;
148
149 // Construct the SQL expression
150 String sql = getInsertSql(bean, tableName) ;
151
152 // Do the insert
153 if (dataSourceName==null) {
154 Connection conn = ConnectionFactory.getConnection(
155 driverClass, url, username, password) ;
156 DatabaseProxy.executeUpdate( conn, sql ) ;
157 conn.close() ;
158 } else {
159 DataSourceProxy.executeUpdate( dataSourceName, sql ) ;
160 }
161 } catch (DBException dbe) {
162 // will be already logged; rethrow, exception page will have to explain
163 throw new NotPersistedException("Failed attempt to add new " + tableName, dbe) ;
164 } catch (java.sql.SQLException e) {
165 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
166 throw new NotPersistedException(e.getMessage(), e) ;
167 } catch (java.lang.IllegalAccessException e) {
168 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
169 throw new NotPersistedException(e.getMessage(), e) ;
170 } catch (java.lang.IllegalArgumentException e) {
171 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
172 throw new NotPersistedException(e.getMessage(), e) ;
173 } catch (java.lang.reflect.InvocationTargetException e) {
174 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
175 throw new NotPersistedException(e.getMessage(), e) ;
176 } catch (java.lang.NoSuchMethodException e) {
177 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
178 throw new NotPersistedException(e.getMessage(), e) ;
179 }
180
181 return bean;
182 }
183
184 /** @param bean */
185 public Object modify (Object bean)
186 throws NotPersistedException
187 {
188 String tableName = getTableName(bean) ;
189 String keyColumn = getKeyColumn(tableName) ;
190
191 try {
192 // Construct the SQL expression
193 String sql = getUpdateSql(bean, tableName, keyColumn) ;
194
195 // Do the update
196 if (dataSourceName==null) {
197 Connection conn = ConnectionFactory.getConnection(
198 driverClass, url, username, password) ;
199 DatabaseProxy.executeUpdate( conn, sql ) ;
200 conn.close() ;
201 } else {
202 DataSourceProxy.executeUpdate( dataSourceName, sql ) ;
203 }
204 } catch (DBException dbe) {
205 // will be already logged; rethrow, exception page will have to explain
206 throw new NotPersistedException("Failed attempt to update " + tableName, dbe) ;
207 } catch (java.sql.SQLException e) {
208 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
209 throw new NotPersistedException(e.getMessage(), e) ;
210 }
211
212 return bean;
213 }
214
215 /** @param bean */
216 public Object remove (Object bean)
217 throws NotPersistedException
218 {
219 String tableName = getTableName(bean) ;
220 String keyColumn = getKeyColumn(tableName) ;
221
222 try {
223 // Construct the SQL expression
224 String sql = getDeleteSql(bean, tableName, keyColumn) ;
225
226 // Do the delete
227 if (dataSourceName==null) {
228 Connection conn = ConnectionFactory.getConnection(
229 driverClass, url, username, password) ;
230 DatabaseProxy.executeUpdate( conn, sql ) ;
231 conn.close() ;
232 } else {
233 DataSourceProxy.executeUpdate( dataSourceName, sql ) ;
234 }
235 } catch (DBException dbe) {
236 // will be already logged; rethrow, exception page will have to explain
237 throw new NotPersistedException("Failed attempt to remove " + tableName, dbe) ;
238 } catch (java.sql.SQLException e) {
239 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
240 throw new NotPersistedException(e.getMessage(), e) ;
241 }
242
243 return bean;
244 }
245
246 /**
247 * Load a JavaBean from the data store.
248 *
249 * @param bean
250 * JavaBean with the key column populated.
251 *
252 * @return
253 * A JavaBean of the same type populated with the values found in
254 * the data store for the key supplied.
255 */
256 public Object load (Object bean)
257 throws QueryException
258 {
259 String tableName = getTableName(bean) ;
260 String keyColumn = getKeyColumn(tableName) ;
261
262 try {
263 // Construct the SQL expression
264 String sql = getSelectSql(bean, tableName, keyColumn) ;
265
266 // Do the select
267 List results = null ;
268 if (dataSourceName==null) {
269 Connection conn = ConnectionFactory.getConnection(
270 driverClass, url, username, password) ;
271 results = DatabaseProxy.executeQuery( conn, sql ) ;
272 conn.close() ;
273 } else {
274 results = DataSourceProxy.executeQuery( dataSourceName, sql ) ;
275 }
276 DBUtils.populateBean(bean, (Map)results.get(0)) ;
277 } catch (DBException dbe) {
278 // will be already logged; rethrow, exception page will have to explain
279 throw new QueryException("Failed attempt to load " + tableName, dbe) ;
280 } catch (java.sql.SQLException e) {
281 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
282 throw new QueryException(e.getMessage(), e) ;
283 }
284
285 return bean;
286 }
287
288
289 /*
290 * Implementation helper methods
291 */
292
293 /**
294 * Return a connection to the database.
295 * <p>
296 * Using this method allows pooling of connections.
297 */
298 protected Connection getPooledConnection()
299 {
300 return null ;
301 }
302
303 /**
304 * Returns the name of the table derived from the Bean name
305 * according to conventions. TODO detail conventions.
306 */
307 protected String getTableName(Object bean)
308 {
309 logger.info("METHOD_ENTRY: getTableName");
310
311 String temp = bean.getClass().getName() ;
312 temp = temp.substring(temp.lastIndexOf('.')+1, temp.length()-4) ;
313
314 logger.info("METHOD_EXIT: getTableName");
315 logger.info("... with params table name=" + temp) ;
316 return temp ;
317 }
318
319
320 protected String getKeyColumn(String tableName)
321 {
322 logger.info("METHOD_ENTRY: getKeyColumn");
323
324 String keyColumn = tableName.substring(0,1).toLowerCase() +
325 tableName.substring(1) + "Id" ;
326
327 logger.info("METHOD_EXIT: getKeyColumn");
328 logger.info("... with params keyColumn =" + keyColumn) ;
329 return keyColumn ;
330 }
331
332 /**
333 * Return the SQL to find a bean.
334 */
335 protected String getFindSql(Object bean)
336 throws QueryException
337 {
338 logger.info("METHOD_ENTRY: getFindSql");
339 StringBuffer sql = new StringBuffer() ;
340 try {
341 sql.append("SELECT * FROM ") ;
342 sql.append(getTableName(bean)) ;
343 sql.append(" ") ;
344
345 ArrayList filters = new ArrayList() ;
346 PropertyDescriptor[] descriptors =
347 PropertyUtils.getPropertyDescriptors(bean) ;
348 for ( int i=0 ; i<descriptors.length ; i++ ) {
349 // This is a bit of a hack, not sure what other descriptors may need to be excluded...
350 if (!descriptors[i].getName().equals("class")) {
351 Object value =
352 PropertyUtils.getProperty(bean, descriptors[i].getName()) ;
353
354 StringBuffer filterValue = new StringBuffer() ;
355 // DBUtils adds the quotes as necessary
356 if (value instanceof java.util.Date) {
357 filterValue.append(new java.sql.Date(((Date)value).getTime())) ;
358 } else if (value instanceof java.lang.Number) {
359 filterValue.append(value) ;
360 } else {
361 filterValue.append( value==null ? null : SqlEncoder.encode(value.toString()) ) ;
362 }
363
364 DBFilter filter = new DBFilter(descriptors[i].getName(),
365 filterValue.toString()) ;
366 filters.add(filter) ;
367 }
368 }
369 sql = DBUtils.addFilters(sql, filters) ;
370 } catch (java.lang.IllegalAccessException e) {
371 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
372 throw new QueryException(e.getMessage(), e) ;
373 } catch (java.lang.IllegalArgumentException e) {
374 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
375 throw new QueryException(e.getMessage(), e) ;
376 } catch (java.lang.reflect.InvocationTargetException e) {
377 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
378 throw new QueryException(e.getMessage(), e) ;
379 } catch (java.lang.NoSuchMethodException e) {
380 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
381 throw new QueryException(e.getMessage(), e) ;
382 }
383
384 logger.info("METHOD_EXIT: getFindSql");
385 logger.info("... with params sql =" + sql) ;
386 return sql.toString() ;
387 }
388
389 /**
390 * Return the SQL to find a bean.
391 */
392 protected String getFindSql(Object bean, List equalityProps)
393 throws QueryException
394 {
395 logger.info("METHOD_ENTRY: getFindSql");
396
397 StringBuffer sql = new StringBuffer() ;
398 try {
399 sql.append("SELECT * FROM ") ;
400 sql.append(getTableName(bean)) ;
401 sql.append(" ") ;
402
403 ArrayList filters = new ArrayList() ;
404 for ( Iterator i=equalityProps.iterator() ; i.hasNext() ; ) {
405 String propName = (String)i.next() ;
406 Object value = null ;
407 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean) ;
408
409 for (int j=0 ; j<descriptors.length ; j++ ) {
410 if (descriptors[j].getName().equals(propName)) {
411 value = PropertyUtils.getProperty(bean, propName) ;
412 break ;
413 }
414 }
415
416 StringBuffer filterValue = new StringBuffer() ;
417 // DBUtils adds the quotes as necessary
418 if (value instanceof java.util.Date) {
419 filterValue.append(new java.sql.Date(((Date)value).getTime())) ;
420 } else if (value instanceof java.lang.Number) {
421 filterValue.append(value) ;
422 } else {
423 filterValue.append( value==null ? null : SqlEncoder.encode(value.toString()) ) ;
424 }
425
426 DBFilter filter = new DBFilter(propName, filterValue.toString()) ;
427 filters.add(filter) ;
428 }
429 sql = DBUtils.addFilters(sql, filters) ;
430 } catch (java.lang.IllegalAccessException e) {
431 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
432 throw new QueryException(e.getMessage(), e) ;
433 } catch (java.lang.IllegalArgumentException e) {
434 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
435 throw new QueryException(e.getMessage(), e) ;
436 } catch (java.lang.reflect.InvocationTargetException e) {
437 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
438 throw new QueryException(e.getMessage(), e) ;
439 } catch (java.lang.NoSuchMethodException e) {
440 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
441 throw new QueryException(e.getMessage(), e) ;
442 }
443
444 logger.info("METHOD_EXIT: getFindSql");
445 logger.info("... with params sql=" + sql) ;
446 return sql.toString() ;
447 }
448
449
450 /**
451 * Returns SQL to do an insert, providing that naming
452 * convention has been observed.
453 */
454 protected String getInsertSql (Object bean, String tableName)
455 throws NotPersistedException
456 {
457 // No caching of Bean Descriptors is done here as PropertyUtils handles it already.
458 logger.info("METHOD_ENTRY: getInsertSql");
459
460 StringBuffer sql = new StringBuffer("INSERT INTO " + tableName);
461 sql.append(" (") ;
462 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean) ;
463
464 // add the column names
465 for (int i=0 ; i<descriptors.length ; i++ ) {
466 // This is a bit of a hack, not sure what other descriptors may need to be excluded...
467 if (!descriptors[i].getName().equals("class") &&
468 !descriptors[i].getName().equals("equalityPropertyList")) {
469 sql.append(descriptors[i].getName()) ;
470 sql.append(",") ;
471 }
472 }
473
474 sql = new StringBuffer(sql.substring(0,sql.length()-1)) ;
475 sql.append(") VALUES (") ;
476
477 // add the column values
478 for (int i=0 ; i<descriptors.length ; i++ ) {
479 // This is a bit of a hack, not sure what other descriptors may need to be excluded...
480 if (!descriptors[i].getName().equals("class") &&
481 !descriptors[i].getName().equals("equalityPropertyList")) {
482 Object value = null ;
483 try {
484 value = PropertyUtils.getProperty(bean, descriptors[i].getName()) ;
485 } catch (java.lang.IllegalAccessException e) {
486 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
487 throw new NotPersistedException(e.getMessage(), e) ;
488 } catch (java.lang.IllegalArgumentException e) {
489 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
490 throw new NotPersistedException(e.getMessage(), e) ;
491 } catch (java.lang.reflect.InvocationTargetException e) {
492 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
493 throw new NotPersistedException(e.getMessage(), e) ;
494 } catch (java.lang.NoSuchMethodException e) {
495 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
496 throw new NotPersistedException(e.getMessage(), e) ;
497 }
498 //Object value = descriptors[i].getValue(descriptors[i].getName()) ;
499 if (value instanceof java.util.Date) {
500 sql.append("'") ;
501 sql.append(new java.sql.Date(((Date)value).getTime())) ;
502 sql.append("'") ;
503 } else if (value instanceof java.lang.Number) {
504 sql.append(value) ;
505 } else if (value==null) {
506 sql.append( value ) ;
507 } else {
508 sql.append("'") ;
509 sql.append( SqlEncoder.encode(value.toString()) ) ;
510 sql.append("'") ;
511 }
512
513 sql.append(",") ;
514 }
515 }
516
517 sql = new StringBuffer(sql.substring(0,sql.length()-1)) ;
518 sql.append(")") ;
519
520 logger.info("METHOD_EXIT: getInsertSql");
521 logger.info("... with params sql=" + sql) ;
522 return sql.toString() ;
523 }
524
525 /**
526 * Returns SQL to do an update, providing that naming
527 * convention has been observed.
528 */
529 protected String getUpdateSql (Object bean, String tableName, String keyColumn)
530 throws NotPersistedException
531 {
532 // No caching of Bean Descriptors is done here as PropertyUtils handles it already.
533 logger.info("METHOD_ENTRY: getUpdateSql");
534
535 StringBuffer sql = new StringBuffer("UPDATE " + tableName);
536 sql.append(" SET ") ;
537 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean) ;
538
539 // add the column names
540 for (int i=0 ; i<descriptors.length ; i++ ) {
541 // This is a bit of a hack, not sure what other descriptors may need to be excluded...
542 if (!descriptors[i].getName().equals("class")&&
543 !descriptors[i].getName().equals("equalityPropertyList")) {
544 sql.append(descriptors[i].getName()) ;
545 sql.append("=") ;
546
547 Object value = null ;
548 try {
549 value = PropertyUtils.getProperty(bean, descriptors[i].getName()) ;
550 } catch (java.lang.IllegalAccessException e) {
551 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
552 throw new NotPersistedException(e.getMessage(), e) ;
553 } catch (java.lang.IllegalArgumentException e) {
554 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
555 throw new NotPersistedException(e.getMessage(), e) ;
556 } catch (java.lang.reflect.InvocationTargetException e) {
557 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
558 throw new NotPersistedException(e.getMessage(), e) ;
559 } catch (java.lang.NoSuchMethodException e) {
560 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
561 throw new NotPersistedException(e.getMessage(), e) ;
562 }
563 //Object value = descriptors[i].getValue(descriptors[i].getName()) ;
564 if (value instanceof java.util.Date) {
565 sql.append("'") ;
566 sql.append(new java.sql.Date(((Date)value).getTime())) ;
567 sql.append("'") ;
568 } else if (value instanceof java.lang.Number) {
569 sql.append(value) ;
570 } else if (value==null) {
571 sql.append( value ) ;
572 } else {
573 sql.append("'") ;
574 sql.append( SqlEncoder.encode(value.toString()) ) ;
575 sql.append("'") ;
576 }
577
578 if (i+1<descriptors.length) {
579 sql.append(",") ;
580 }
581 }
582 }
583
584 sql.append(" WHERE ") ;
585 sql.append(keyColumn) ;
586 sql.append("=") ;
587
588 try {
589 sql.append(PropertyUtils.getProperty(bean, keyColumn)) ;
590 } catch (java.lang.IllegalAccessException e) {
591 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
592 throw new NotPersistedException(e.getMessage(), e) ;
593 } catch (java.lang.IllegalArgumentException e) {
594 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
595 throw new NotPersistedException(e.getMessage(), e) ;
596 } catch (java.lang.reflect.InvocationTargetException e) {
597 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
598 throw new NotPersistedException(e.getMessage(), e) ;
599 } catch (java.lang.NoSuchMethodException e) {
600 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
601 throw new NotPersistedException(e.getMessage(), e) ;
602 }
603
604 logger.info("METHOD_EXIT: getUpdateSql");
605 logger.info("... with params sql=" + sql) ;
606 return sql.toString() ;
607 }
608
609 /**
610 * Returns SQL to do a delete, providing that naming
611 * convention has been observed.
612 */
613 protected String getDeleteSql (Object bean, String tableName, String keyColumn)
614 throws NotPersistedException
615 {
616 // No caching of Bean Descriptors is done here as PropertyUtils handles it already.
617 logger.info("METHOD_ENTRY: getDeleteSql");
618
619 StringBuffer sql = new StringBuffer("DELETE FROM " + tableName);
620 sql.append(" WHERE ") ;
621 sql.append(keyColumn) ;
622 sql.append("=") ;
623 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean) ;
624
625 try {
626 sql.append(PropertyUtils.getProperty(bean, keyColumn)) ;
627 } catch (java.lang.IllegalAccessException e) {
628 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
629 throw new NotPersistedException(e.getMessage(), e) ;
630 } catch (java.lang.IllegalArgumentException e) {
631 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
632 throw new NotPersistedException(e.getMessage(), e) ;
633 } catch (java.lang.reflect.InvocationTargetException e) {
634 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
635 throw new NotPersistedException(e.getMessage(), e) ;
636 } catch (java.lang.NoSuchMethodException e) {
637 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
638 throw new NotPersistedException(e.getMessage(), e) ;
639 }
640
641 logger.info("METHOD_EXIT: getDeleteSql");
642 logger.info("... with params sql=" + sql) ;
643 return sql.toString() ;
644 }
645
646 /**
647 * Returns SQL to do a select, providing that naming
648 * convention has been observed.
649 */
650 protected String getSelectSql (Object bean, String tableName, String keyColumn)
651 throws QueryException
652 {
653 // No caching of Bean Descriptors is done here as PropertyUtils handles it already.
654 logger.info("METHOD_ENTRY: getSelectSql");
655
656 StringBuffer sql = new StringBuffer("SELECT * FROM " + tableName);
657 sql.append(" WHERE ") ;
658 sql.append(keyColumn) ;
659 sql.append("=") ;
660 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean) ;
661
662 try {
663 sql.append(PropertyUtils.getProperty(bean, keyColumn)) ;
664 } catch (java.lang.IllegalAccessException e) {
665 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
666 throw new QueryException(e.getMessage(), e) ;
667 } catch (java.lang.IllegalArgumentException e) {
668 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
669 throw new QueryException(e.getMessage(), e) ;
670 } catch (java.lang.reflect.InvocationTargetException e) {
671 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
672 throw new QueryException(e.getMessage(), e) ;
673 } catch (java.lang.NoSuchMethodException e) {
674 logger.error(e.getClass().getName() + ":" + e.getMessage()) ;
675 throw new QueryException(e.getMessage(), e) ;
676 }
677
678 logger.info("METHOD_EXIT: getSelectSql");
679 logger.info("... with params sql=" + sql) ;
680 return sql.toString() ;
681 }
682
683 /*
684 * Member properties
685 */
686 /**
687 * The Log4J <code>Category</code> doing the logging.
688 */
689 protected static Category logger = Category.getInstance(JdbcDaf.class);
690
691 protected String dataSourceName ;
692 protected String driverClass ;
693 protected String url ;
694 protected String username ;
695 protected String password ;
696 }