Clover Coverage Report - perfectjpattern(Aggregated)
Coverage timestamp: Sat Feb 28 2009 14:35:07 CET
../../../../../img/srcFileCovDistChart9.png 84% of files have more coverage
44   313   21   4.89
20   160   0.48   9
9     2.33  
1    
24% of code in this file is excluded from these metrics.
 
  SpringGenericDao       Line # 42 44 24% 21 12 83.6% 0.8356164
 
  (3)
 
1    //----------------------------------------------------------------------
2    //
3    // PerfectJPattern: "Design patterns are good but components are better!"
4    // SpringGenericDao.java Copyright (c) 2009 Giovanni Azua Garcia
5    // bravegag@hotmail.com
6    //
7    // This program is free software; you can redistribute it and/or
8    // modify it under the terms of the GNU General Public License
9    // as published by the Free Software Foundation; either version 3
10    // of the License, or (at your option) any later version.
11    //
12    // This program is distributed in the hope that it will be useful,
13    // but WITHOUT ANY WARRANTY; without even the implied warranty of
14    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15    // GNU General Public License for more details.
16    //
17    // You should have received a copy of the GNU General Public License
18    // along with this program; if not, see <http://www.gnu.org/licenses/>.
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    * Spring-based implementation of {@link IGenericDao}
34    *
35    * @param <Id> Identification type
36    * @param <Element> Element type
37    *
38    * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
39    * @version $ $Date: Nov 5, 2008 11:40:00 AM $
40    */
41    public
 
42    class SpringGenericDao<Id extends Serializable, Element>
43    extends HibernateGenericDao<Id, Element>
44    implements IFinderExecutor<Element>
45    {
46    //------------------------------------------------------------------------
47    // public
48    //------------------------------------------------------------------------
49    /**
50    * {@inheritDoc}
51    */
 
52  3 toggle @SuppressWarnings("unchecked")
53    public List<Element>
54    execute(Method aMethod, Object... anArguments)
55    {
56  3 final Query myQuery = prepareQuery(aMethod, anArguments);
57   
58  3 return myQuery.list();
59    }
60   
61    //------------------------------------------------------------------------
62    /**
63    * Returns the namingStrategy
64    *
65    * @return the namingStrategy
66    */
 
67  3 toggle public final IFinderNamingStrategy
68    getNamingStrategy()
69    {
70  3 return theNamingStrategy;
71    }
72   
73    //------------------------------------------------------------------------
74    /**
75    * Sets the namingStrategy
76    *
77    * @param aNamingStrategy the namingStrategy to set
78    */
 
79  2 toggle public final void
80    setNamingStrategy(IFinderNamingStrategy aNamingStrategy)
81    {
82  2 theNamingStrategy = aNamingStrategy;
83    }
84   
85    //------------------------------------------------------------------------
86    /**
87    * Returns the argumentTypeResolver
88    *
89    * @return the argumentTypeResolver
90    */
 
91  5 toggle public final IArgumentTypeResolver
92    getArgumentTypeResolver()
93    {
94  5 return theArgumentTypeResolver;
95    }
96   
97    //------------------------------------------------------------------------
98    /**
99    * Sets the argumentTypeResolver
100    *
101    * @param anArgumentTypeResolver the argumentTypeResolver to set
102    */
 
103  0 toggle public final void
104    setArgumentTypeResolver(IArgumentTypeResolver anArgumentTypeResolver)
105    {
106  0 theArgumentTypeResolver = anArgumentTypeResolver;
107    }
108   
109    //------------------------------------------------------------------------
110    // protected
111    //------------------------------------------------------------------------
112    /**
113    * Constructs a {@link SpringGenericReadOnlyDao} instance from the
114    * persistent class type and the {@link ISessionStrategy} that creates
115    * {@link Session} instances and the {@link ITransactionStrategy} that
116    * creates {@link Transaction} instances
117    *
118    * @param aPersistentClass The persistent Java Bean class
119    * @param aSessionStrategy Strategy that creates Sessions
120    * @param aTransactionStrategy Strategy that creates Transaction
121    * @throws IllegalArgumentException 'aPersistentClass' must not be null
122    * @throws IllegalArgumentException 'aPersistentClass' must be a class type
123    * @throws IllegalArgumentException 'aDaoSessionStrategy' must not be null
124    * @throws IllegalArgumentException 'aDaoTransactionStrategy' must not be
125    * null
126    */
 
127  2 toggle protected
128    SpringGenericDao(Class<Element> aPersistentClass,
129    ISessionStrategy aSessionStrategy,
130    ITransactionStrategy aTransactionStrategy)
131    {
132  2 super(aPersistentClass, aSessionStrategy, aTransactionStrategy);
133    }
134   
135    //------------------------------------------------------------------------
136    // private
137    //------------------------------------------------------------------------
 
138  3 toggle 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  3 final String myQueryName = getNamingStrategy().getQueryName(
145    getPersistentClass(), aMethod);
146   
147  3 final Query myQuery = getActualSession().getNamedQuery(myQueryName);
148   
149  3 String[] myQueryParameters = myQuery.getNamedParameters();
150  3 if (myQueryParameters.length == 0)
151    {
152  1 setPositionalParams(myQuery, anArguments);
153    }
154    else
155    {
156  2 Annotation myAnnotation = null;
157  2 final int myNumberOfAnnotations = aMethod.getAnnotations().length;
158  2 for (int i = 0; i < myNumberOfAnnotations; ++i)
159    {
160  2 if (aMethod.getAnnotations()[i] instanceof QueryParameters)
161    {
162  2 myAnnotation = aMethod.getAnnotations()[i];
163   
164  2 break;
165    }
166    }
167   
168    assert myAnnotation != null : "'" + aMethod.getName() +
169    "' does not include the required QueryParameters annotation";
170   
171  2 String[] myAnnotatedParameters = ((QueryParameters)
172    myAnnotation).names();
173   
174  2 final int myNumberOfAnnotated = myAnnotatedParameters.length;
175  2 final int myNumberOfParameters = myQueryParameters.length;
176   
177    assert myNumberOfAnnotated == myNumberOfParameters : "Arguments " +
178    "mismatch, all query parameters must be annotated";
179   
180   
181  2 setNamedParams(myQuery, anArguments, myQueryParameters,
182    myAnnotatedParameters);
183    }
184   
185  3 return myQuery;
186    }
187   
188    //------------------------------------------------------------------------
189    /**
190    * Assigns the parameters according to their order in the finder method
191    * signature. This method is called when the query parameters are defined
192    * as ? and not named.
193    *
194    * @param aNamedQuery The Hibernate named query defined in the mapping
195    * @param aMethodArguments The finder method argument values
196    */
 
197  1 toggle 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    // set parameter
204  2 for (int i = 0; i < aMethodArguments.length; i++)
205    {
206  1 Object myArgument = aMethodArguments[i];
207   
208  1 Type myArgumentType = getArgumentTypeResolver().getArgumentType(
209    myArgument);
210   
211  1 if (myArgumentType != null)
212    {
213  0 aNamedQuery.setParameter(i, myArgument, myArgumentType);
214    }
215    else
216    {
217  1 aNamedQuery.setParameter(i, myArgument);
218    }
219    }
220    }
221   
222    //------------------------------------------------------------------------
223    /**
224    * Assigns the parameters of the interface finder method to the named
225    * query. The parameters are assigned based on the name of the finder
226    * method arguments to match those of the named query. The arguments
227    * are not assumed to be in any specific order but will be matched
228    * according to the name. In case that there is a mismatch i.e. missing
229    * or outstanding parameter in either side a {@link IllegalAccessError}
230    * will be thrown.
231    *
232    * @param aNamedQuery The Hibernate named query defined in the mapping
233    * @param aMethodArguments The finder method argument values
234    * @param aQueryParameters The named query parameter place holders
235    * @param aMethodParameters The ordered parameter names as defined in
236    * the finder method signature
237    * @throws IllegalAccessError "Mismatching number of arguments"
238    */
 
239  2 toggle 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  2 if (aMethodArguments.length != aQueryParameters.length ||
250    aQueryParameters.length != aMethodParameters.length)
251    {
252    throw new IllegalAccessError("Mismatching number of arguments");
253    }
254   
255    // populate a Map of Method parameter values keyed by parameter name
256  2 Map<String, Object> myArgumentsMap = new HashMap<String, Object>();
257  2 final int myNumberOfParameters = aMethodArguments.length;
258  6 for (int i = 0; i < myNumberOfParameters; i++)
259    {
260  4 myArgumentsMap.put(aMethodParameters[i], aMethodArguments[i]);
261    }
262   
263    // finally assign the parameters
264  2 for (String myQueryParameter : aQueryParameters)
265    {
266    // do the parameter matching taking into account naming conventions
267  4 Object myArgument = null;
268  4 if (myArgumentsMap.containsKey(myQueryParameter))
269    {
270  4 myArgument = myArgumentsMap.get(myQueryParameter);
271    }
272   
273    assert myArgument != null : "Query parameter '" +
274    myQueryParameter + "' was not found, check for misspelling";
275   
276  4 Type myArgumentType = getArgumentTypeResolver().getArgumentType(
277    myArgument);
278   
279  4 if (myArgumentType != null)
280    {
281  0 aNamedQuery.setParameter(myQueryParameter, myArgument,
282    myArgumentType);
283    }
284    else
285    {
286  4 if (myArgument instanceof Collection)
287    {
288  0 aNamedQuery.setParameterList(myQueryParameter,
289    (Collection<?>) myArgument);
290    }
291    else
292    {
293  4 aNamedQuery.setParameter(myQueryParameter, myArgument);
294    }
295    }
296    }
297    }
298   
299    //------------------------------------------------------------------------
300    // members
301    //------------------------------------------------------------------------
302    /**
303    * Defines an strategy for discovering the finder methods
304    */
305    private IFinderNamingStrategy theNamingStrategy =
306    new SimpleFinderNamingStrategy();
307   
308    /**
309    * Provides ability to map instances to their corresponding type
310    */
311    private IArgumentTypeResolver theArgumentTypeResolver =
312    new SimpleArgumentTypeResolver();
313    }