1 22 package org.jboss.ejb.plugins.cmp.jdbc; 23 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.Constructor ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import javax.ejb.FinderException ; 30 31 import org.jboss.deployment.DeploymentException; 32 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge; 33 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCAutomaticQueryMetaData; 34 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData; 35 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCDeclaredQueryMetaData; 36 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCDynamicQLQueryMetaData; 37 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCJBossQLQueryMetaData; 38 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQlQueryMetaData; 39 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData; 40 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData; 41 import org.jboss.ejb.plugins.cmp.ejbql.Catalog; 42 import org.jboss.logging.Logger; 43 import org.jboss.metadata.MetaData; 44 import org.w3c.dom.Element ; 45 46 57 public final class JDBCQueryManager 58 { 59 private static final String FIND_BY_PK = "findByPrimaryKey"; 60 private static final String EJB_FIND = "ejbFind"; 61 private static final String FIND_ALL = "findAll"; 62 private static final String FIND_BY = "findBy"; 63 64 private final Map knownQueries = new HashMap (); 65 private final JDBCStoreManager manager; 66 67 public JDBCQueryManager(JDBCStoreManager manager) 68 { 69 this.manager = manager; 70 } 71 72 public static final Class getQLCompiler(Element query, JDBCEntityMetaData entity) 73 throws DeploymentException 74 { 75 String compiler = MetaData.getOptionalChildContent(query, "ql-compiler"); 76 Class impl; 77 78 if(compiler == null || compiler.trim().length() == 0) 79 { 80 impl = entity.getQLCompiler(); 81 } 82 else 83 { 84 try 85 { 86 impl = TCLAction.UTIL.getContextClassLoader().loadClass(compiler); 87 } 88 catch(ClassNotFoundException e) 89 { 90 throw new DeploymentException("Failed to load compiler implementation: " + compiler); 91 } 92 } 93 return impl; 94 } 95 96 public static final QLCompiler getInstance(Class impl, Catalog catalog) 97 throws DeploymentException 98 { 99 if(impl == null) 100 { 101 throw new DeploymentException("ql-compiler is not specified."); 102 } 103 104 final Constructor constructor; 105 try 106 { 107 constructor = impl.getConstructor(new Class []{Catalog.class}); 108 } 109 catch(NoSuchMethodException e) 110 { 111 throw new DeploymentException("Compiler class does not have a constructor which takes " + Catalog.class.getName()); 112 } 113 114 try 115 { 116 return (QLCompiler)constructor.newInstance(new Object []{catalog}); 117 } 118 catch(Exception e) 119 { 120 throw new DeploymentException("Failed to create an instance of " + impl.getName() + ": " + e.getMessage(), e); 121 } 122 } 123 124 public JDBCQueryCommand getQueryCommand(Method queryMethod) 125 throws FinderException 126 { 127 JDBCQueryCommand queryCommand = (JDBCQueryCommand)knownQueries.get(queryMethod); 128 129 if(queryCommand == null) 130 { 131 throw new FinderException ("Unknown query: " + queryMethod); 132 } 133 return queryCommand; 134 } 135 136 public void start() throws DeploymentException 137 { 138 Logger log = Logger.getLogger( 139 this.getClass().getName() + 140 "." + 141 manager.getMetaData().getName()); 142 143 JDBCCommandFactory factory = manager.getCommandFactory(); 144 145 Class homeClass = manager.getContainer().getHomeClass(); 146 Class localHomeClass = manager.getContainer().getLocalHomeClass(); 147 148 JDBCEntityBridge entity = (JDBCEntityBridge) manager.getEntityBridge(); 152 if(homeClass != null) 153 { 154 try 155 { 156 Method method = homeClass.getMethod(FIND_BY_PK, new Class []{entity.getPrimaryKeyClass()}); 158 159 JDBCQueryMetaData findByPKMD = manager.getMetaData().getQueryMetaDataForMethod(method); 160 JDBCReadAheadMetaData readAhead = (findByPKMD == null ? 161 entity.getMetaData().getReadAhead() : findByPKMD.getReadAhead()); 162 163 JDBCQueryMetaData q = new JDBCAutomaticQueryMetaData( 165 method, 166 readAhead, 167 entity.getMetaData().getQLCompiler(), 168 false 169 ); 170 knownQueries.put(method, factory.createFindByPrimaryKeyQuery(q)); 171 172 if(log.isDebugEnabled()) 173 log.debug("Added findByPrimaryKey query command for home interface"); 174 } catch(NoSuchMethodException e) 175 { 176 throw new DeploymentException("Home interface does not have a findByPrimaryKey method"); 177 } 178 } 179 180 if(localHomeClass != null) 181 { 182 183 Method method; 184 try 185 { 186 method = localHomeClass.getMethod(FIND_BY_PK, new Class [] { entity.getPrimaryKeyClass() }); 188 } catch(NoSuchMethodException e) 189 { 190 throw new DeploymentException("Local home interface does " + 191 "not have the method findByPrimaryKey(" + 192 entity.getPrimaryKeyClass().getName() + ")"); 193 } 194 195 JDBCQueryMetaData findByPKMD = manager.getMetaData().getQueryMetaDataForMethod(method); 197 JDBCReadAheadMetaData readAhead = (findByPKMD == null ? 198 entity.getMetaData().getReadAhead() : findByPKMD.getReadAhead()); 199 JDBCQueryMetaData q = new JDBCAutomaticQueryMetaData(method, readAhead, entity.getMetaData().getQLCompiler(), false); 200 knownQueries.put(method, factory.createFindByPrimaryKeyQuery(q)); 201 202 if(log.isDebugEnabled()) 203 log.debug("Added findByPrimaryKey query command for local home interface"); 204 } 205 206 Class ejbClass = manager.getMetaData().getEntityClass(); 210 211 Method [] customMethods = ejbClass.getMethods(); 212 for (int i = 0; i < customMethods.length; i++) 213 { 214 Method m = customMethods[i]; 215 String methodName = m.getName(); 216 if(methodName.startsWith(EJB_FIND)) 217 { 218 String interfaceName = 'f' + methodName.substring(4); 219 220 if(homeClass != null) 221 { 222 try 223 { 224 Method interfaceMethod = homeClass.getMethod( 226 interfaceName, 227 m.getParameterTypes()); 228 229 knownQueries.put(interfaceMethod, new JDBCCustomFinderQuery(manager, m)); 231 232 if(log.isDebugEnabled()) 233 log.debug("Added custom finder " + methodName + " on home interface"); 234 } catch(NoSuchMethodException e) 235 { 236 } 238 } 239 240 if(localHomeClass != null) 241 { 242 try 243 { 244 Method interfaceMethod = localHomeClass.getMethod( 246 interfaceName, 247 m.getParameterTypes()); 248 249 knownQueries.put(interfaceMethod, new JDBCCustomFinderQuery(manager, m)); 251 252 if(log.isDebugEnabled()) 253 log.debug("Added custom finder " + methodName + " on local home interface"); 254 } catch(NoSuchMethodException e) 255 { 256 } 258 } 259 } 260 } 261 262 Iterator definedFinders = manager.getMetaData().getQueries().iterator(); 266 while(definedFinders.hasNext()) 267 { 268 JDBCQueryMetaData q = (JDBCQueryMetaData)definedFinders.next(); 269 270 if(!knownQueries.containsKey(q.getMethod()) ) 271 { 272 if(q instanceof JDBCJBossQLQueryMetaData) 273 { 274 knownQueries.put(q.getMethod(), factory.createJBossQLQuery(q)); 275 276 } else if(q instanceof JDBCDynamicQLQueryMetaData) 277 { 278 knownQueries.put(q.getMethod(), factory.createDynamicQLQuery(q)); 279 280 } else if(q instanceof JDBCDeclaredQueryMetaData) 281 { 282 knownQueries.put(q.getMethod(), factory.createDeclaredSQLQuery(q)); 283 284 } else if(q instanceof JDBCQlQueryMetaData) 285 { 286 knownQueries.put(q.getMethod(), factory.createEJBQLQuery(q)); 287 } 288 } 289 } 290 291 if(homeClass != null) 295 { 296 addAutomaticFinders(manager, homeClass.getMethods(), log); 297 } 298 299 if(localHomeClass != null) 300 { 301 addAutomaticFinders(manager, localHomeClass.getMethods(), log); 302 } 303 } 304 305 public void clear() 306 { 307 this.knownQueries.clear(); 308 } 309 310 private void addAutomaticFinders( 311 JDBCStoreManager manager, 312 Method [] homeMethods, 313 Logger log) throws DeploymentException 314 { 315 316 JDBCCommandFactory factory = manager.getCommandFactory(); 317 JDBCEntityBridge entity = (JDBCEntityBridge) manager.getEntityBridge(); 318 for (int i = 0; i < homeMethods.length; i++) 319 { 320 Method method = homeMethods[i]; 321 322 if(!knownQueries.containsKey(method)) 323 { 324 String name = method.getName(); 325 if(name.equals(FIND_ALL)) 326 { 327 JDBCQueryMetaData q = new JDBCAutomaticQueryMetaData( 328 method, 329 entity.getMetaData().getReadAhead(), 330 entity.getMetaData().getQLCompiler(), false 331 ); 332 knownQueries.put(method, factory.createFindAllQuery(q)); 333 } 334 else if(name.startsWith(FIND_BY) && !name.equals(FIND_BY_PK)) 335 { 336 try 337 { 338 JDBCQueryMetaData q = new JDBCAutomaticQueryMetaData( 339 method, 340 entity.getMetaData().getReadAhead(), 341 entity.getMetaData().getQLCompiler(), false); 342 knownQueries.put(method, factory.createFindByQuery(q)); 343 } catch (IllegalArgumentException e) 344 { 345 log.debug("Could not create the finder " + name + 346 ", because no matching CMP field was found."); 347 } 348 } 349 } 350 } 351 } 352 } 353 | Popular Tags |