1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.perfectjpattern.jee.integration.dao;
22
23 import java.io.*;
24 import java.lang.annotation.*;
25 import java.lang.reflect.*;
26 import java.util.*;
27
28 import org.hibernate.*;
29 import org.hibernate.type.Type;
30 import org.perfectjpattern.jee.api.integration.dao.*;
31
32
33
34
35
36
37
38
39
40
41 public
42 class SpringGenericDao<Id extends Serializable, Element>
43 extends HibernateGenericDao<Id, Element>
44 implements IFinderExecutor<Element>
45 {
46
47
48
49
50
51
52 @SuppressWarnings("unchecked")
53 public List<Element>
54 execute(Method aMethod, Object... anArguments)
55 {
56 final Query myQuery = prepareQuery(aMethod, anArguments);
57
58 return myQuery.list();
59 }
60
61
62
63
64
65
66
67 public final IFinderNamingStrategy
68 getNamingStrategy()
69 {
70 return theNamingStrategy;
71 }
72
73
74
75
76
77
78
79 public final void
80 setNamingStrategy(IFinderNamingStrategy aNamingStrategy)
81 {
82 theNamingStrategy = aNamingStrategy;
83 }
84
85
86
87
88
89
90
91 public final IArgumentTypeResolver
92 getArgumentTypeResolver()
93 {
94 return theArgumentTypeResolver;
95 }
96
97
98
99
100
101
102
103 public final void
104 setArgumentTypeResolver(IArgumentTypeResolver anArgumentTypeResolver)
105 {
106 theArgumentTypeResolver = anArgumentTypeResolver;
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 protected
128 SpringGenericDao(Class<Element> aPersistentClass,
129 ISessionStrategy aSessionStrategy,
130 ITransactionStrategy aTransactionStrategy)
131 {
132 super(aPersistentClass, aSessionStrategy, aTransactionStrategy);
133 }
134
135
136
137
138 private Query
139 prepareQuery(Method aMethod, Object... anArguments)
140 {
141 assert aMethod != null : "'aMethod' must not be null";
142 assert anArguments != null : "'anArguments' must not be null";
143
144 final String myQueryName = getNamingStrategy().getQueryName(
145 getPersistentClass(), aMethod);
146
147 final Query myQuery = getActualSession().getNamedQuery(myQueryName);
148
149 String[] myQueryParameters = myQuery.getNamedParameters();
150 if (myQueryParameters.length == 0)
151 {
152 setPositionalParams(myQuery, anArguments);
153 }
154 else
155 {
156 Annotation myAnnotation = null;
157 final int myNumberOfAnnotations = aMethod.getAnnotations().length;
158 for (int i = 0; i < myNumberOfAnnotations; ++i)
159 {
160 if (aMethod.getAnnotations()[i] instanceof QueryParameters)
161 {
162 myAnnotation = aMethod.getAnnotations()[i];
163
164 break;
165 }
166 }
167
168 assert myAnnotation != null : "'" + aMethod.getName() +
169 "' does not include the required QueryParameters annotation";
170
171 String[] myAnnotatedParameters = ((QueryParameters)
172 myAnnotation).names();
173
174 final int myNumberOfAnnotated = myAnnotatedParameters.length;
175 final int myNumberOfParameters = myQueryParameters.length;
176
177 assert myNumberOfAnnotated == myNumberOfParameters : "Arguments " +
178 "mismatch, all query parameters must be annotated";
179
180
181 setNamedParams(myQuery, anArguments, myQueryParameters,
182 myAnnotatedParameters);
183 }
184
185 return myQuery;
186 }
187
188
189
190
191
192
193
194
195
196
197 private void
198 setPositionalParams(Query aNamedQuery, Object[] aMethodArguments)
199 {
200 assert aNamedQuery != null : "'aNamedQuery' must not be null";
201 assert aMethodArguments != null : "'anArguments' must not be null";
202
203
204 for (int i = 0; i < aMethodArguments.length; i++)
205 {
206 Object myArgument = aMethodArguments[i];
207
208 Type myArgumentType = getArgumentTypeResolver().getArgumentType(
209 myArgument);
210
211 if (myArgumentType != null)
212 {
213 aNamedQuery.setParameter(i, myArgument, myArgumentType);
214 }
215 else
216 {
217 aNamedQuery.setParameter(i, myArgument);
218 }
219 }
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 private void
240 setNamedParams(Query aNamedQuery, Object[] aMethodArguments,
241 String[] aQueryParameters, String[] aMethodParameters)
242 {
243 assert aNamedQuery != null : "'aNamedQuery' must not be null";
244 assert aMethodArguments != null : "'anArguments' must not be null";
245 assert aQueryParameters != null : "'aNamedParameters' must not be null";
246 assert aMethodParameters != null :
247 "'anOrderedArgumentNames' must not be null";
248
249 if (aMethodArguments.length != aQueryParameters.length ||
250 aQueryParameters.length != aMethodParameters.length)
251 {
252 throw new IllegalAccessError("Mismatching number of arguments");
253 }
254
255
256 Map<String, Object> myArgumentsMap = new HashMap<String, Object>();
257 final int myNumberOfParameters = aMethodArguments.length;
258 for (int i = 0; i < myNumberOfParameters; i++)
259 {
260 myArgumentsMap.put(aMethodParameters[i], aMethodArguments[i]);
261 }
262
263
264 for (String myQueryParameter : aQueryParameters)
265 {
266
267 Object myArgument = null;
268 if (myArgumentsMap.containsKey(myQueryParameter))
269 {
270 myArgument = myArgumentsMap.get(myQueryParameter);
271 }
272
273 assert myArgument != null : "Query parameter '" +
274 myQueryParameter + "' was not found, check for misspelling";
275
276 Type myArgumentType = getArgumentTypeResolver().getArgumentType(
277 myArgument);
278
279 if (myArgumentType != null)
280 {
281 aNamedQuery.setParameter(myQueryParameter, myArgument,
282 myArgumentType);
283 }
284 else
285 {
286 if (myArgument instanceof Collection)
287 {
288 aNamedQuery.setParameterList(myQueryParameter,
289 (Collection<?>) myArgument);
290 }
291 else
292 {
293 aNamedQuery.setParameter(myQueryParameter, myArgument);
294 }
295 }
296 }
297 }
298
299
300
301
302
303
304
305 private IFinderNamingStrategy theNamingStrategy =
306 new SimpleFinderNamingStrategy();
307
308
309
310
311 private IArgumentTypeResolver theArgumentTypeResolver =
312 new SimpleArgumentTypeResolver();
313 }