1 22 package org.jboss.ejb.plugins.cmp.jdbc.metadata; 23 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.Modifier ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Collection ; 31 32 import org.w3c.dom.Element ; 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 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 createJDBCQueryMetaData(QueryMetaData queryData) 60 throws DeploymentException 61 { 62 63 Method [] methods = getQueryMethods(queryData); 64 Map queries = new HashMap (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 createJDBCQueryMetaData(Element queryElement, 76 Map defaultValues, 77 JDBCReadAheadMetaData readAhead) throws DeploymentException 78 { 79 80 Method [] methods = getQueryMethods(queryElement); 82 83 Element readAheadElement = 85 MetaData.getOptionalChild(queryElement, "read-ahead"); 86 if(readAheadElement != null) 87 { 88 readAhead = new JDBCReadAheadMetaData(readAheadElement, readAhead); 89 } 90 91 Map queries = new HashMap (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 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 qlCompiler) 118 throws DeploymentException 119 { 120 121 if(jdbcQueryMetaData instanceof JDBCRawSqlQueryMetaData) 123 { 124 return new JDBCRawSqlQueryMetaData(jdbcQueryMetaData.getMethod(), qlCompiler, false); 125 } 126 127 if(jdbcQueryMetaData instanceof JDBCJBossQLQueryMetaData) 129 { 130 return new JDBCJBossQLQueryMetaData( 131 (JDBCJBossQLQueryMetaData) jdbcQueryMetaData, 132 readAhead, qlCompiler, false 133 ); 134 } 135 136 if(jdbcQueryMetaData instanceof JDBCDynamicQLQueryMetaData) 138 { 139 return new JDBCDynamicQLQueryMetaData( 140 (JDBCDynamicQLQueryMetaData) jdbcQueryMetaData, 141 readAhead, qlCompiler, false 142 ); 143 } 144 145 if(jdbcQueryMetaData instanceof JDBCDeclaredQueryMetaData) 147 { 148 return new JDBCDeclaredQueryMetaData( 149 (JDBCDeclaredQueryMetaData) jdbcQueryMetaData, 150 readAhead, qlCompiler, false 151 ); 152 } 153 154 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 queryElement, 172 Method method, 173 JDBCReadAheadMetaData readAhead) 174 throws DeploymentException 175 { 176 final Class qlCompiler = JDBCQueryManager.getQLCompiler(queryElement, entity); 177 final boolean isResultTypeMappingLocal = (jdbcQueryMetaData == null ? 178 false : jdbcQueryMetaData.isResultTypeMappingLocal()); 179 180 final boolean lazyResultSetLoading = Collection .class.isAssignableFrom(method.getReturnType()) && 181 MetaData.getOptionalChildBooleanContent(queryElement, "lazy-resultset-loading"); 182 183 Element rawSql = MetaData.getOptionalChild(queryElement, "raw-sql"); 185 if(rawSql != null) 186 { 187 return new JDBCRawSqlQueryMetaData(method, qlCompiler, lazyResultSetLoading); 188 } 189 190 Element 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 Element dynamicQL = MetaData.getOptionalChild(queryElement, "dynamic-ql"); 207 if(dynamicQL != null) 208 { 209 return new JDBCDynamicQLQueryMetaData(isResultTypeMappingLocal, method, readAhead, qlCompiler, lazyResultSetLoading); 210 } 211 212 Element 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 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 [] getQueryMethods(Element queryElement) 240 throws DeploymentException 241 { 242 Element queryMethod = MetaData.getUniqueChild(queryElement, "query-method"); 244 245 String methodName = 247 MetaData.getUniqueChildContent(queryMethod, "method-name"); 248 249 ArrayList methodParams = new ArrayList (); 251 Element methodParamsElement = 252 MetaData.getUniqueChild(queryMethod, "method-params"); 253 Iterator iterator = 254 MetaData.getChildrenByTagName(methodParamsElement, "method-param"); 255 while(iterator.hasNext()) 256 { 257 methodParams.add(MetaData.getElementContent((Element ) iterator.next())); 258 } 259 260 try 261 { 262 Class [] parameters = Classes.convertToJavaClasses(methodParams.iterator(), entity.getClassLoader()); 263 264 return getQueryMethods(methodName, parameters); 265 } 266 catch(ClassNotFoundException cnfe) 267 { 268 throw new DeploymentException(cnfe.getMessage()); 269 } 270 271 } 272 273 private Method [] getQueryMethods(QueryMetaData queryData) 274 throws DeploymentException 275 { 276 String methodName = queryData.getMethodName(); 277 278 try 279 { 280 Class [] parameters = Classes.convertToJavaClasses(queryData.getMethodParams(), entity.getClassLoader()); 281 282 return getQueryMethods(methodName, parameters); 283 } 284 catch(ClassNotFoundException cnfe) 285 { 286 throw new DeploymentException(cnfe.getMessage()); 287 } 288 } 289 290 private Method [] getQueryMethods(String methodName, 291 Class parameters[]) throws DeploymentException 292 { 293 294 ArrayList methods = new ArrayList (2); 296 if(methodName.startsWith("ejbSelect")) 297 { 298 Method method = getQueryMethod(methodName, parameters, entity.getEntityClass()); 300 if(method != null) 301 { 302 methods.add(method); 303 } 304 } 305 else 306 { 307 Class homeClass = entity.getHomeClass(); 309 if(homeClass != null) 310 { 311 Method method = getQueryMethod(methodName, parameters, homeClass); 312 if(method != null) 313 { 314 methods.add(method); 315 } 316 } 317 Class localHomeClass = entity.getLocalHomeClass(); 319 if(localHomeClass != null) 320 { 321 Method 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 sb = new StringBuffer (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 []) methods.toArray(new Method [methods.size()]); 346 } 347 348 private static Method getQueryMethod(String queryName, 349 Class [] parameters, 350 Class clazz) 351 { 352 353 try 354 { 355 Method method = clazz.getMethod(queryName, parameters); 356 357 if(Modifier.isAbstract(method.getModifiers())) 360 { 361 return method; 362 } 363 } 364 catch(NoSuchMethodException e) 365 { 366 } 368 return null; 369 } 370 371 } 372 | Popular Tags |