KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc > metadata > JDBCQueryMetaDataFactory


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc.metadata;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.Modifier JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Collection JavaDoc;
31
32 import org.w3c.dom.Element JavaDoc;
33
34 import org.jboss.deployment.DeploymentException;
35 import org.jboss.metadata.MetaData;
36 import org.jboss.metadata.QueryMetaData;
37 import org.jboss.util.Classes;
38 import org.jboss.ejb.plugins.cmp.jdbc.JDBCQueryManager;
39 import org.jboss.logging.Logger;
40
41 /**
42  * JDBCQueryMetaDataFactory constructs a JDBCQueryMetaData object based
43  * on the query specifiection type.
44  *
45  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
46  * @version $Revision: 41923 $
47  */

48 public class JDBCQueryMetaDataFactory
49 {
50    private static final Logger log = Logger.getLogger(JDBCQueryMetaDataFactory.class);
51
52    private JDBCEntityMetaData entity;
53
54    public JDBCQueryMetaDataFactory(JDBCEntityMetaData entity)
55    {
56       this.entity = entity;
57    }
58
59    public Map JavaDoc createJDBCQueryMetaData(QueryMetaData queryData)
60       throws DeploymentException
61    {
62
63       Method JavaDoc[] methods = getQueryMethods(queryData);
64       Map JavaDoc queries = new HashMap JavaDoc(methods.length);
65       for(int i = 0; i < methods.length; i++)
66       {
67          queries.put(
68             methods[i],
69             new JDBCQlQueryMetaData(queryData, methods[i], entity.getQLCompiler(), false)
70          );
71       }
72       return queries;
73    }
74
75    public Map JavaDoc createJDBCQueryMetaData(Element JavaDoc queryElement,
76                                       Map JavaDoc defaultValues,
77                                       JDBCReadAheadMetaData readAhead) throws DeploymentException
78    {
79
80       // get the query methods
81
Method JavaDoc[] methods = getQueryMethods(queryElement);
82
83       // read-ahead
84
Element JavaDoc readAheadElement =
85          MetaData.getOptionalChild(queryElement, "read-ahead");
86       if(readAheadElement != null)
87       {
88          readAhead = new JDBCReadAheadMetaData(readAheadElement, readAhead);
89       }
90
91       Map JavaDoc queries = new HashMap JavaDoc(methods.length);
92       for(int i = 0; i < methods.length; i++)
93       {
94          JDBCQueryMetaData defaultValue =
95             (JDBCQueryMetaData) defaultValues.get(methods[i]);
96
97          if(defaultValue == null && !entity.isCMP1x() && !methods[i].getName().equals("findByPrimaryKey"))
98          {
99             //throw new DeploymentException("Unknown query method : " + methods[i]);
100
log.warn("The query method is not defined in ejb-jar.xml: " + methods[i]);
101          }
102
103          JDBCQueryMetaData jdbcQueryData = createJDBCQueryMetaData(
104             defaultValue,
105             queryElement,
106             methods[i],
107             readAhead
108          );
109
110          queries.put(methods[i], jdbcQueryData);
111       }
112       return queries;
113    }
114
115    public static JDBCQueryMetaData createJDBCQueryMetaData(JDBCQueryMetaData jdbcQueryMetaData,
116                                                            JDBCReadAheadMetaData readAhead,
117                                                            Class JavaDoc qlCompiler)
118       throws DeploymentException
119    {
120
121       // RAW-SQL
122
if(jdbcQueryMetaData instanceof JDBCRawSqlQueryMetaData)
123       {
124          return new JDBCRawSqlQueryMetaData(jdbcQueryMetaData.getMethod(), qlCompiler, false);
125       }
126
127       // JBOSS-QL
128
if(jdbcQueryMetaData instanceof JDBCJBossQLQueryMetaData)
129       {
130          return new JDBCJBossQLQueryMetaData(
131             (JDBCJBossQLQueryMetaData) jdbcQueryMetaData,
132             readAhead, qlCompiler, false
133          );
134       }
135
136       // DYNAMIC-SQL
137
if(jdbcQueryMetaData instanceof JDBCDynamicQLQueryMetaData)
138       {
139          return new JDBCDynamicQLQueryMetaData(
140             (JDBCDynamicQLQueryMetaData) jdbcQueryMetaData,
141             readAhead, qlCompiler, false
142          );
143       }
144
145       // DECLARED-SQL
146
if(jdbcQueryMetaData instanceof JDBCDeclaredQueryMetaData)
147       {
148          return new JDBCDeclaredQueryMetaData(
149             (JDBCDeclaredQueryMetaData) jdbcQueryMetaData,
150             readAhead, qlCompiler, false
151          );
152       }
153
154       // EJB-QL: default
155
if(jdbcQueryMetaData instanceof JDBCQlQueryMetaData)
156       {
157          return new JDBCQlQueryMetaData(
158             (JDBCQlQueryMetaData) jdbcQueryMetaData,
159             readAhead, qlCompiler, false
160          );
161       }
162
163       throw new DeploymentException(
164          "Error in query specification for method " +
165          jdbcQueryMetaData.getMethod().getName()
166       );
167    }
168
169
170    private JDBCQueryMetaData createJDBCQueryMetaData(JDBCQueryMetaData jdbcQueryMetaData,
171                                                      Element JavaDoc queryElement,
172                                                      Method JavaDoc method,
173                                                      JDBCReadAheadMetaData readAhead)
174       throws DeploymentException
175    {
176       final Class JavaDoc qlCompiler = JDBCQueryManager.getQLCompiler(queryElement, entity);
177       final boolean isResultTypeMappingLocal = (jdbcQueryMetaData == null ?
178          false : jdbcQueryMetaData.isResultTypeMappingLocal());
179
180       final boolean lazyResultSetLoading = Collection JavaDoc.class.isAssignableFrom(method.getReturnType()) &&
181          MetaData.getOptionalChildBooleanContent(queryElement, "lazy-resultset-loading");
182
183       // RAW-SQL
184
Element JavaDoc rawSql = MetaData.getOptionalChild(queryElement, "raw-sql");
185       if(rawSql != null)
186       {
187          return new JDBCRawSqlQueryMetaData(method, qlCompiler, lazyResultSetLoading);
188       }
189
190       // JBOSS-QL
191
Element JavaDoc jbossQL =
192          MetaData.getOptionalChild(queryElement, "jboss-ql");
193       if(jbossQL != null)
194       {
195          return new JDBCJBossQLQueryMetaData(
196             isResultTypeMappingLocal,
197             jbossQL,
198             method,
199             readAhead,
200             qlCompiler,
201             lazyResultSetLoading
202          );
203       }
204
205       // DYNAMIC-SQL
206
Element JavaDoc dynamicQL = MetaData.getOptionalChild(queryElement, "dynamic-ql");
207       if(dynamicQL != null)
208       {
209          return new JDBCDynamicQLQueryMetaData(isResultTypeMappingLocal, method, readAhead, qlCompiler, lazyResultSetLoading);
210       }
211
212       // DECLARED-SQL
213
Element JavaDoc delcaredSql = MetaData.getOptionalChild(queryElement, "declared-sql");
214       if(delcaredSql != null)
215       {
216          return new JDBCDeclaredQueryMetaData(
217             isResultTypeMappingLocal,
218             delcaredSql,
219             method,
220             readAhead,
221             qlCompiler,
222             lazyResultSetLoading
223          );
224       }
225
226       // EJB-QL: default
227
if(jdbcQueryMetaData instanceof JDBCQlQueryMetaData)
228       {
229          return new JDBCQlQueryMetaData(
230             (JDBCQlQueryMetaData) jdbcQueryMetaData,
231             method,
232             readAhead
233          );
234       }
235
236       throw new DeploymentException("Error in query specification for method " + method.getName());
237    }
238
239    private Method JavaDoc[] getQueryMethods(Element JavaDoc queryElement)
240       throws DeploymentException
241    {
242       // query-method sub-element
243
Element JavaDoc queryMethod = MetaData.getUniqueChild(queryElement, "query-method");
244
245       // method name
246
String JavaDoc methodName =
247          MetaData.getUniqueChildContent(queryMethod, "method-name");
248
249       // method params
250
ArrayList JavaDoc methodParams = new ArrayList JavaDoc();
251       Element JavaDoc methodParamsElement =
252          MetaData.getUniqueChild(queryMethod, "method-params");
253       Iterator JavaDoc iterator =
254          MetaData.getChildrenByTagName(methodParamsElement, "method-param");
255       while(iterator.hasNext())
256       {
257          methodParams.add(MetaData.getElementContent((Element JavaDoc) iterator.next()));
258       }
259
260       try
261       {
262          Class JavaDoc[] parameters = Classes.convertToJavaClasses(methodParams.iterator(), entity.getClassLoader());
263
264          return getQueryMethods(methodName, parameters);
265       }
266       catch(ClassNotFoundException JavaDoc cnfe)
267       {
268          throw new DeploymentException(cnfe.getMessage());
269       }
270
271    }
272
273    private Method JavaDoc[] getQueryMethods(QueryMetaData queryData)
274       throws DeploymentException
275    {
276       String JavaDoc methodName = queryData.getMethodName();
277
278       try
279       {
280          Class JavaDoc[] parameters = Classes.convertToJavaClasses(queryData.getMethodParams(), entity.getClassLoader());
281
282          return getQueryMethods(methodName, parameters);
283       }
284       catch(ClassNotFoundException JavaDoc cnfe)
285       {
286          throw new DeploymentException(cnfe.getMessage());
287       }
288    }
289
290    private Method JavaDoc[] getQueryMethods(String JavaDoc methodName,
291                                     Class JavaDoc parameters[]) throws DeploymentException
292    {
293
294       // find the query and load the xml
295
ArrayList JavaDoc methods = new ArrayList JavaDoc(2);
296       if(methodName.startsWith("ejbSelect"))
297       {
298          // bean method
299
Method JavaDoc method = getQueryMethod(methodName, parameters, entity.getEntityClass());
300          if(method != null)
301          {
302             methods.add(method);
303          }
304       }
305       else
306       {
307          // remote home
308
Class JavaDoc homeClass = entity.getHomeClass();
309          if(homeClass != null)
310          {
311             Method JavaDoc method = getQueryMethod(methodName, parameters, homeClass);
312             if(method != null)
313             {
314                methods.add(method);
315             }
316          }
317          // local home
318
Class JavaDoc localHomeClass = entity.getLocalHomeClass();
319          if(localHomeClass != null)
320          {
321             Method JavaDoc method = getQueryMethod(methodName, parameters, localHomeClass);
322             if(method != null)
323             {
324                methods.add(method);
325             }
326          }
327       }
328
329       if(methods.size() == 0)
330       {
331          StringBuffer JavaDoc sb = new StringBuffer JavaDoc(300);
332          sb.append("Query method not found: ")
333             .append(methodName).append('(');
334          for(int i = 0; i < parameters.length; i++)
335          {
336             if(i > 0)
337             {
338                sb.append(',');
339             }
340             sb.append(parameters[i].getName());
341          }
342          sb.append(')');
343          throw new DeploymentException(sb.toString());
344       }
345       return (Method JavaDoc[]) methods.toArray(new Method JavaDoc[methods.size()]);
346    }
347
348    private static Method JavaDoc getQueryMethod(String JavaDoc queryName,
349                                         Class JavaDoc[] parameters,
350                                         Class JavaDoc clazz)
351    {
352
353       try
354       {
355          Method JavaDoc method = clazz.getMethod(queryName, parameters);
356
357          // is the method abstract?
358
// (remember interface methods are always abstract)
359
if(Modifier.isAbstract(method.getModifiers()))
360          {
361             return method;
362          }
363       }
364       catch(NoSuchMethodException JavaDoc e)
365       {
366          // that's cool
367
}
368       return null;
369    }
370
371 }
372
Popular Tags