View Javadoc

1   /***
2    * License Agreement.
3    * 
4    * JSPA (POJO-SP)
5    * 
6    * Copyright (C) 2009 HRX Pty Ltd
7    * 
8    * This file is part of JSPA.
9    * 
10   * JSPA is free software: you can redistribute it and/or modify it under the
11   * terms of the GNU Lesser General Public License version 3 as published by the
12   * Free Software Foundation.
13   * 
14   * JSPA is distributed in the hope that it will be useful, but WITHOUT ANY
15   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16   * A PARTICULAR PURPOSE. See the Lesser General Public License for more details.
17   * 
18   * You should have received a copy of the GNU Lesser General Public License
19   * along with JSPA. If not, see <http://www.gnu.org/licenses/>.
20   */
21  package com.hrx.rasp.util.dao;
22  
23  import java.lang.reflect.Constructor;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.apache.log4j.Logger;
30  
31  import com.hrx.rasp.util.dao.exception.StoredProcedureProccessResultException;
32  import com.hrx.rasp.util.dao.metadata.MetadataHelper;
33  
34  /***
35   * The default implementation will return an ArrayList containing instances of
36   * the DAO that calls the JDBC Stored Procedure.
37   * 
38   * The default implementation is expected to be overwrite for any generic Store
39   * Procedure where the CURSOR will returns different data type than the DAO
40   * caller type.
41   * 
42   * When using this implementation the DAO implementation must implement a
43   * Constructor the has the same arguments and in the same order as the CURSOR
44   * record properties.
45   * 
46   * @author dan.stoica <dan.stoica@acslink.net.au>
47   * 
48   */
49  public class ClassConstructorResultSetProcessor<E> extends DefaultResultSetProcessor<E>
50  {
51  
52  	private static Logger log = Logger.getLogger(ClassConstructorResultSetProcessor.class);
53  
54  	@Override
55  	public List<E> create(ResultSet rs, Class<E> resultClass, boolean isSecret) throws SQLException, StoredProcedureProccessResultException
56  	{
57  		// Generate an ArrayList for results
58  		List<E> values = null;
59  
60  		try
61  		{
62  			Constructor<E> constuctor = findConstructor(rs, resultClass);
63  			if (constuctor != null)
64  			{
65  				values = new ArrayList<E>();
66  				// transform the record into Java Return Objects
67  				while (rs.next())
68  				{
69  					if (!isSecret && log.isTraceEnabled())
70  					{
71  						StoredProcUtility.dumpResultSetRecord(rs);
72  					}
73  					E value = MetadataHelper.createInstance(rs, constuctor);
74  					values.add(value);
75  				}
76  			}
77  			else
78  			{
79  				throw new StoredProcedureProccessResultException("Constructor not found for: " + resultClass.getName());
80  			}
81  		}
82  		catch (Exception e)
83  		{
84  			throw new StoredProcedureProccessResultException(e);
85  		}
86  		return values;
87  	}
88  
89  	@SuppressWarnings("unchecked")
90  	private Constructor<E> findConstructor(ResultSet rs, Class<E> resultClass) throws SQLException
91  	{
92  		Constructor<E>[] constrs = (Constructor<E>[]) resultClass.getConstructors();
93  
94  		Constructor<E> constuctor = findConstructorWithAnnotation(constrs);
95  		if (constuctor == null)
96  		{
97  			constuctor = findOtherConstructor(rs, constrs);
98  		}
99  		return constuctor;
100 	}
101 
102 	/***
103 	 * @param spMetaData
104 	 * @param returnType
105 	 * @throws SQLException
106 	 */
107 	private Constructor<E> findOtherConstructor(ResultSet rs, Constructor<E>[] constrs) throws SQLException
108 	{
109 		/*
110 		 * If no annotated constructor found, just try any available
111 		 * constructor.
112 		 */
113 		int colsCount = rs.getMetaData().getColumnCount();
114 
115 		for (Constructor<E> constr : constrs)
116 		{
117 			if (constr.getParameterTypes().length == colsCount)
118 			{
119 				return constr;
120 			}
121 		}
122 		return null;
123 	}
124 
125 }