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
84
85
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
102
103
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
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
131
132
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
149
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
159
160
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
170
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
181
182
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
215
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
226
227
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 }