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.sql.Connection;
24  import java.sql.SQLException;
25  import java.util.List;
26  
27  import javax.sql.DataSource;
28  
29  import org.apache.log4j.Logger;
30  
31  import com.hrx.rasp.util.dao.annotations.DAO;
32  import com.hrx.rasp.util.dao.annotations.Operation;
33  import com.hrx.rasp.util.dao.exception.InvalidStoredProcedureException;
34  import com.hrx.rasp.util.dao.exception.OperationNotSupportedException;
35  import com.hrx.rasp.util.dao.exception.RecordNotFoundException;
36  import com.hrx.rasp.util.dao.exception.StoredProcedureException;
37  import com.hrx.rasp.util.dao.exception.StoredProcedurePrepareException;
38  import com.hrx.rasp.util.dao.exception.StoredProcedureProccessResultException;
39  import com.hrx.rasp.util.dao.jdbc.DataSourceImpl;
40  import com.hrx.rasp.util.dao.metadata.MetadataProcessor;
41  import com.hrx.rasp.util.dao.metadata.StoredProcMetaDataImpl;
42  import com.hrx.rasp.util.dao.operation.CommandFactory;
43  import com.hrx.rasp.util.dao.operation.DAOCommand;
44  import com.hrx.rasp.util.dao.operation.OperationType;
45  
46  /***
47   * 
48   * DAOManager default implementation
49   * 
50   * @author dan.stoica <dan.stoica@acslink.net.au>
51   * 
52   */
53  @SuppressWarnings("unchecked")
54  public class DAOManagerImpl implements DAOManager
55  {
56  	private static Logger log = Logger.getLogger(DAOManagerImpl.class);
57  
58  	private final CommandFactory cmdFactory;
59  
60  	private MetadataProcessor metaDataProcessor = new MetadataProcessor();
61  
62  	private StoredProcMetaDataImpl spMetaData = new StoredProcMetaDataImpl();
63  
64  	public DAOManagerImpl(Connection conn)
65  	{
66  		this(new DataSourceImpl(conn));
67  	}
68  
69  	/***
70  	 * @param DataSource
71  	 */
72  	public DAOManagerImpl(DataSource ds)
73  	{
74  		this.cmdFactory = new CommandFactory(ds);
75  	}
76  
77  	public DAOManagerImpl(final CommandFactory cmdFactory)
78  	{
79  		this.cmdFactory = cmdFactory;
80  	}
81  
82  	/*
83  	 * (non-Javadoc)
84  	 * 
85  	 * @see com.hrx.rasp.util.dao.DAOManager#create(T)
86  	 */
87  	public <T> T create(final T daoBean) throws StoredProcedureException, SQLException, StoredProcedurePrepareException,
88  					InvalidStoredProcedureException, StoredProcedureProccessResultException
89  	{
90  		Operation operation = getOperation(OperationType.CREATE, daoBean);
91  		prepare(operation, 1, 2);
92  
93  		metaDataProcessor.process(spMetaData, operation, daoBean);
94  
95  		DAOCommand cmd = cmdFactory.getCommand(OperationType.CREATE, spMetaData, daoBean);
96  		T ret = (T) cmd.execute();
97  		return ret;
98  	}
99  
100 	/*
101 	 * (non-Javadoc)
102 	 * 
103 	 * @see com.hrx.rasp.util.dao.DAOManager#delete(java.lang.Object)
104 	 */
105 	public void delete(final Object daoBean) throws SQLException, StoredProcedureException, StoredProcedurePrepareException,
106 					StoredProcedureProccessResultException, InvalidStoredProcedureException
107 	{
108 		Operation operation = getOperation(OperationType.DELETE, daoBean);
109 
110 		prepare(operation, 1, 2);
111 
112 		metaDataProcessor.process(spMetaData, operation, daoBean);
113 
114 		if (spMetaData.getPrimaryKeyParameters().size() <= 0)
115 		{
116 			throw new InvalidStoredProcedureException("Primary key requierd for stored procedure name:" + operation.name() + " in Java entity:"
117 							+ daoBean.getClass().getName());
118 		}
119 
120 		// the delete is using just the Primary key parameters
121 		spMetaData.getInParameters().clear();
122 		spMetaData.getInOutParameters().clear();
123 		spMetaData.getOutParameters().clear();
124 
125 		DAOCommand cmd = cmdFactory.getCommand(OperationType.DELETE, spMetaData, daoBean);
126 		cmd.execute();
127 	}
128 
129 	/*
130 	 * (non-Javadoc)
131 	 * 
132 	 * @see com.hrx.rasp.util.dao.DAOManager#update(T)
133 	 */
134 	public <T> void update(final T daoBean) throws StoredProcedurePrepareException, SQLException, StoredProcedureException,
135 					InvalidStoredProcedureException, StoredProcedureProccessResultException
136 	{
137 		Operation operation = getOperation(OperationType.UPDATE, daoBean);
138 
139 		prepare(operation, 1, 2);
140 		metaDataProcessor.process(spMetaData, operation, daoBean);
141 
142 		if (spMetaData.getPrimaryKeyParameters().size() <= 0)
143 		{
144 			throw new InvalidStoredProcedureException("Primary key requierd for stored procedure name:" + operation.name() + " in Java entity:"
145 							+ daoBean.getClass().getName());
146 		}
147 
148 		// ignore any INOUT and OUT parameters;
149 		// we are using the primary key and IN parameters
150 		spMetaData.getOutParameters().clear();
151 		spMetaData.getInOutParameters().clear();
152 
153 		DAOCommand cmd = cmdFactory.getCommand(OperationType.UPDATE, spMetaData, daoBean);
154 		cmd.execute();
155 	}
156 
157 	/*
158 	 * (non-Javadoc)
159 	 * 
160 	 * @see com.hrx.rasp.util.dao.DAOManager#find(java.lang.Object)
161 	 */
162 	public <T> T find(final T daoWithPk) throws SQLException, StoredProcedureException, StoredProcedurePrepareException,
163 					StoredProcedureProccessResultException, InvalidStoredProcedureException
164 	{
165 		Operation operation = getOperation(OperationType.FIND, daoWithPk);
166 		prepare(operation, 1, 2);
167 		metaDataProcessor.process(spMetaData, operation, daoWithPk);
168 
169 		// The find StoredProc is using just Pk and out parameters
170 		// Any other parameters will be ignored
171 		spMetaData.getInParameters().clear();
172 		spMetaData.getInOutParameters().clear();
173 
174 		DAOCommand cmd = cmdFactory.getCommand(OperationType.FIND, spMetaData, daoWithPk);
175 		T daoBean = (T) cmd.execute();
176 		return daoBean;
177 	}
178 
179 	/*
180 	 * (non-Javadoc)
181 	 * 
182 	 * @see com.hrx.rasp.util.dao.DAOManager#select(T)
183 	 */
184 	public <T> List<T> select(final T daoBean) throws SQLException, StoredProcedureException, RecordNotFoundException,
185 					StoredProcedurePrepareException, StoredProcedureProccessResultException, InvalidStoredProcedureException
186 	{
187 		return select(daoBean, 1, 0);
188 	}
189 
190 	public <T> List<T> select(T daoBean, int startPosition, int maxResult) throws SQLException, StoredProcedureException, RecordNotFoundException,
191 					StoredProcedurePrepareException, StoredProcedureProccessResultException, InvalidStoredProcedureException
192 	{
193 		Class<T> clazz = (Class<T>) daoBean.getClass();
194 		return select(daoBean, clazz);
195 	}
196 
197 	public <T> List<T> select(final Object daoBean, Class<T> returnType) throws SQLException, StoredProcedureException, RecordNotFoundException,
198 					StoredProcedurePrepareException, StoredProcedureProccessResultException, InvalidStoredProcedureException
199 	{
200 		return select(daoBean, returnType, 0, 0);
201 	}
202 
203 	public <T> List<T> select(Object daoBean, Class<T> returnType, int startPosition, int maxResult) throws SQLException, StoredProcedureException,
204 					StoredProcedurePrepareException, StoredProcedureProccessResultException, InvalidStoredProcedureException
205 	{
206 		Operation operation = getOperation(OperationType.SELECT, daoBean);
207 
208 		prepare(operation, 2, 3);
209 		spMetaData.setMaxResult(maxResult);
210 		spMetaData.setStartPosition(startPosition);
211 
212 		metaDataProcessor.process(spMetaData, operation, daoBean, returnType);
213 
214 		// The find StoredProc is using just Pk and IN parameters
215 		// Any other parameters will be ignored
216 		spMetaData.getOutParameters().clear();
217 		spMetaData.getInOutParameters().clear();
218 
219 		DAOCommand cmd = cmdFactory.getCommand(OperationType.SELECT, spMetaData, daoBean);
220 		List<T> beans = (List<T>) cmd.execute();
221 		return beans;
222 	}
223 
224 	/*
225 	 * (non-Javadoc)
226 	 * 
227 	 * @see com.hrx.rasp.util.dao.DAOManager#execute(java.lang.Object)
228 	 */
229 	public <T> T execute(T daoBean) throws StoredProcedureException, SQLException, StoredProcedurePrepareException, OperationNotSupportedException,
230 					InvalidStoredProcedureException, StoredProcedureProccessResultException
231 	{
232 		return execute(daoBean, 1, 0);
233 	}
234 
235 	public <T> T execute(T daoBean, int startPosition, int maxResult) throws StoredProcedureException, SQLException, StoredProcedurePrepareException,
236 					OperationNotSupportedException, InvalidStoredProcedureException, StoredProcedureProccessResultException
237 	{
238 		log.debug("Call Generic Stored procedure or Generic function starts.");
239 
240 		DAO spm = daoBean.getClass().getAnnotation(DAO.class);
241 		if (spm == null)
242 		{
243 			throw new InvalidStoredProcedureException(MetadataProcessor.DAO_ANNOTATION_NOT_FOUND);
244 		}
245 		DAOCommand cmd = null;
246 		Operation operation = null;
247 		for (Operation oper : spm.value())
248 		{
249 			if (oper.type().equals(OperationType.GENERIC_STORED_PROCEDURE))
250 			{
251 				operation = oper;
252 				cmd = cmdFactory.getCommand(OperationType.GENERIC_STORED_PROCEDURE, spMetaData, daoBean);
253 				break;
254 			}
255 			if (oper.type().equals(OperationType.GENERIC_FUNCTION))
256 			{
257 				operation = oper;
258 				cmd = cmdFactory.getCommand(OperationType.GENERIC_FUNCTION, spMetaData, daoBean);
259 				break;
260 			}
261 		}
262 		if (operation == null)
263 		{
264 			throw new InvalidStoredProcedureException(daoBean.getClass().getName());
265 		}
266 
267 		spMetaData.prepare(operation, operation.errorCodeIndex(), operation.errorMessageIndex());
268 		metaDataProcessor.process(this.spMetaData, operation, daoBean);
269 
270 		spMetaData.setMaxResult(maxResult);
271 		spMetaData.setStartPosition(startPosition);
272 
273 		T bean = (T) cmd.execute();
274 		log.debug("End Generic Stored procedure call");
275 		return bean;
276 	}
277 
278 	/***
279 	 * @return the spMetaData
280 	 */
281 	protected StoredProcMetaDataImpl getSpMetaData()
282 	{
283 		return spMetaData;
284 	}
285 
286 	protected void setSpMetaData(StoredProcMetaDataImpl metadata)
287 	{
288 		spMetaData = metadata;
289 	}
290 	
291 	private Operation getOperation(OperationType type, Object dao) throws InvalidStoredProcedureException
292 	{
293 		spMetaData.startTimer();
294 		Class<?> daoClass = dao.getClass();
295 
296 		DAO spm = daoClass.getAnnotation(DAO.class);
297 		if (spm == null)
298 		{
299 			throw new InvalidStoredProcedureException(MetadataProcessor.DAO_ANNOTATION_NOT_FOUND);
300 		}
301 
302 		for (Operation oper : spm.value())
303 		{
304 			if (oper.type().equals(type))
305 			{
306 				return oper;
307 			}
308 		}
309 		throw new OperationNotSupportedException();
310 
311 	}
312 
313 	protected final int getErrorIndex(int index, int defaultIndex)
314 	{
315 		return (index > 0) ? index : defaultIndex;
316 	}
317 
318 	private void prepare(Operation operation, int defaultCodeIndex, int defaultMessageIndex)
319 	{
320 		spMetaData.prepare(operation, getErrorIndex(operation.errorCodeIndex(), defaultCodeIndex), getErrorIndex(operation.errorMessageIndex(),
321 						defaultMessageIndex));
322 	}
323 }