1 18 package org.objectweb.speedo.mapper.rdb; 19 20 import org.objectweb.jorm.api.PException; 21 import org.objectweb.jorm.api.PExceptionIO; 22 import org.objectweb.jorm.api.JormConfigurator; 23 import org.objectweb.jorm.mapper.rdb.lib.MapperJDBC; 24 import org.objectweb.jorm.mapper.rdb.lib.ConnectionSpecJDBC; 25 import org.objectweb.fractal.api.control.LifeCycleController; 26 import org.objectweb.fractal.api.control.BindingController; 27 import org.objectweb.util.monolog.api.LoggerFactory; 28 import org.objectweb.util.monolog.api.BasicLevel; 29 import org.objectweb.util.monolog.api.Logger; 30 import org.objectweb.util.monolog.wrapper.p6spy.P6SpyLogger; 31 import org.objectweb.speedo.api.ExceptionHelper; 32 import org.objectweb.speedo.mapper.rdb.JDBCConnectionHolder; 33 import org.objectweb.medor.eval.prefetch.lib.PrefetchCacheImpl; 34 import org.objectweb.perseus.pool.api.PoolMatchFactory; 35 import org.objectweb.perseus.pool.api.Pool; 36 import org.objectweb.perseus.pool.api.PoolException; 37 import org.objectweb.perseus.persistence.api.ConnectionHolderFactory; 38 import org.objectweb.perseus.persistence.api.ConnectionHolder; 39 import org.objectweb.perseus.persistence.api.PersistenceException; 40 41 import java.sql.DriverManager ; 42 import java.sql.Driver ; 43 import java.util.ArrayList ; 44 45 51 public class JDBCMapper 52 extends MapperJDBC 53 implements BindingController, LifeCycleController, 54 JDBCMapperAttributes, PoolMatchFactory, ConnectionHolderFactory { 55 56 public final static String POOL_BINDING = "pool"; 57 58 59 62 protected Pool connectionPool; 63 64 67 private String url; 68 69 73 private String userName; 74 75 79 private String password; 80 81 85 private String driverCN = null; 86 87 90 private boolean started = false; 91 92 95 private boolean poolConnection = false; 96 97 100 private ArrayList unpooledConnection; 101 102 private boolean checkConnectivityAtStartup = true; 103 104 public JDBCMapper() throws PException { 105 } 106 107 110 public ConnectionHolder createConnectionHolder() throws PersistenceException { 111 return new JDBCConnectionHolder(this, logger); 112 } 113 114 117 123 public Object createResource(Object hints) throws PoolException { 124 if (!started) { 125 startFc(); 126 } 127 Object connection = null; 128 try { 129 if (hints == null) { 130 connection = super.getConnection(); 131 } else { 132 connection = super.getConnection(hints); 133 } 134 } catch (PException e) { 135 throw new PoolException("Error during the allocation a new JDBC connection", e); 136 } 137 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 138 logger.log(BasicLevel.DEBUG, 139 "New JDBC connection allocated for the pool:" + connection); 140 } 141 return connection; 142 } 143 144 154 public boolean matchResource(Object pr, Object hints) { 155 return true; 156 } 157 158 public void destroyResource(Object resource) { 159 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 160 logger.log(BasicLevel.DEBUG, 161 "Destroy the JDBC connection of the pool:" + resource); 162 } 163 try { 164 super.closeConnection(resource); 165 } catch (PException e) { 166 if (logger != null) { 167 logger.log(BasicLevel.ERROR, 168 "ERROR during the closing of a connection of the pool:" 169 + resource, e); 170 } 171 } 172 } 173 174 177 public String getDriverClassName() { 178 return driverCN; 179 } 180 181 public void setDriverClassName(String dcn) { 182 driverCN = dcn; 183 } 184 185 public String getURL() { 186 return url; 187 } 188 189 public void setURL(String url) { 190 this.url = url; 191 } 192 193 public String getUserName() { 194 return userName; 195 } 196 197 public void setUserName(String userName) { 198 this.userName = userName; 199 } 200 201 public String getPassword() { 202 return password; 203 } 204 205 public void setPassword(String password) { 206 this.password = password; 207 } 208 209 public void setPoolConnection(boolean pc) { 210 poolConnection = pc; 211 if (poolConnection) { 212 unpooledConnection = new ArrayList (5); 213 } 214 } 215 216 public boolean getPoolConnection() { 217 return poolConnection; 218 } 219 220 221 224 public String [] listFc() { 225 return new String [] { 226 POOL_BINDING 227 }; 228 } 229 230 public Object lookupFc(String s) { 231 if (POOL_BINDING.equals(s)) { 232 return connectionPool; 233 } else { 234 return null; 235 } 236 } 237 238 public void bindFc(String s, Object o) { 239 if ("logger".equals(s)) { 240 logger = (Logger) o; 241 if (P6SpyLogger.logger == null) { 242 P6SpyLogger.logger = logger; 243 } 244 } else if ("monolog-factory".equals(s)) { 245 Logger l = logger; 246 setLoggerFactory((LoggerFactory) o); 247 if (l != null) { 248 logger = l; 249 } 250 P6SpyLogger.logger = getLoggerFactory() 251 .getLogger(logger.getName() + ".sql"); 252 } else if (POOL_BINDING.equals(s)) { 253 connectionPool = (Pool) o; 254 } 255 } 256 257 public void unbindFc(String s) { 258 if (POOL_BINDING.equals(s)) { 259 connectionPool = null; 260 } 261 } 262 263 266 public String getFcState() { 267 return started ? STARTED : STOPPED; 268 } 269 270 public void startFc() { 271 if (!started) { 272 if (logger == null) { 273 String msg = "No logger assigned on the component before the start."; 274 System.err.println(msg); 275 throw new RuntimeException (msg); 276 } 277 started = true; 278 P6SpyLogger.level = BasicLevel.DEBUG; 279 Object cf = getConnectionFactory(); 280 if (cf == null) { 281 try { 282 DriverManager.registerDriver((Driver ) 283 Class.forName(driverCN).newInstance()); 284 setConnectionFactory( 285 new ConnectionSpecJDBC(url, driverCN, userName, password)); 286 } catch (Exception e) { 287 logger.log(BasicLevel.ERROR, 288 "Impossible to configure the jdbc access: ", e); 289 throw new RuntimeException ( 290 "Impossible to configure the jdbc access: " 291 + ExceptionHelper.getNested(e).getMessage()); 292 } 293 } 294 if (checkConnectivityAtStartup) { 295 Object o = null; 296 try { 297 logger.log(BasicLevel.DEBUG, "try to fetch a connection"); 298 o = getConnection(); 299 } catch (Exception e) { 300 Exception ie = ExceptionHelper.getNested(e); 301 logger.log(BasicLevel.ERROR, 302 "Impossible to fetch a connection", ie); 303 throw new RuntimeException ( 304 "Impossible to fetch a connection: " 305 + ie.getMessage()); 306 } finally { 307 if (o != null) { 308 try { 309 closeConnection(o); 310 } catch (PException e) { 311 } 312 } 313 } 314 } 315 316 try { 317 JormConfigurator jc = getJormConfigurator(); 318 jc.setLoggerFactory(getLoggerFactory()); 319 PrefetchCacheImpl pc = new PrefetchCacheImpl( 320 getLoggerFactory().getLogger( 321 "org.objectweb.speedo.rt.query.prefetch")); 322 setPrefetchCache(pc); 323 start(); 324 } catch (PException e) { 325 throw new RuntimeException ( 326 "Impossible to configure the mapper: " 327 + ExceptionHelper.getNested(e).getMessage()); 328 } 329 } 330 } 331 332 public void stopFc() { 333 started = false; 334 } 335 336 337 340 343 public Object getConnection() throws PException { 344 if (poolConnection) { 345 try { 346 Object connection = connectionPool.getResource(null); 347 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 348 logger.log(BasicLevel.DEBUG, "Get a JDBC connection from the pool: " + connection); 349 } 350 return connection; 351 } catch (Exception e) { 352 throw new PExceptionIO(ExceptionHelper.getNested(e), 353 "Impossible to fetch a jdbc connection on driver"); 354 } 355 } else { 356 Object connection = super.getConnection(); 357 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 358 logger.log(BasicLevel.DEBUG, "JDBC connection allocated: " + connection); 359 } 360 return connection; 361 } 362 } 363 364 public Object getConnection(Object connectionContext, Object user) throws PException { 365 if (poolConnection) { 366 if (connectionContext == null) { 367 try { 368 Object connection = connectionPool.getResource(null, user); 369 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 370 logger.log(BasicLevel.DEBUG, "Get a JDBC connection from the pool: " + connection); 371 } 372 return connection; 373 } catch (Exception e) { 374 throw new PExceptionIO(ExceptionHelper.getNested(e), 375 "Impossible to fetch a jdbc connection on driver"); 376 } 377 } else { 378 Object connection = super.getConnection(connectionContext, user); 379 synchronized(unpooledConnection) { 380 unpooledConnection.add(connection); 381 } 382 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 383 logger.log(BasicLevel.DEBUG, 384 "JDBC connection allocated with context, context= " 385 + connectionContext + ", connection=" + connection); 386 } 387 return connection; 388 } 389 } else { 390 Object connection = super.getConnection(connectionContext, user); 391 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 392 logger.log(BasicLevel.DEBUG, "JDBC connection allocated: " + connection); 393 } 394 return connection; 395 } 396 } 397 398 403 public void closeConnection(Object conn) throws PException { 404 if (conn == null) { 405 return; 406 } 407 if (poolConnection) { 408 if (unpooledConnection != null) { 409 synchronized(unpooledConnection) { 410 if (unpooledConnection.remove(unpooledConnection)) { 411 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 412 logger.log(BasicLevel.DEBUG, "Closing the JDBC connection (context): " + conn); 413 } 414 return; 415 } } 417 } 418 try { 419 connectionPool.releaseResource(conn); 420 } catch (Exception e) { 421 throw new PExceptionIO(ExceptionHelper.getNested(e), 422 "Impossible to release a jdbc connection"); 423 } 424 } else { 425 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 426 logger.log(BasicLevel.DEBUG, "Closing the JDBC connection: " + conn); 427 } 428 super.closeConnection(conn); 429 } 430 } 431 public boolean getCheckConnectivityAtStartup() { 432 return this.checkConnectivityAtStartup; 433 } 434 public void setCheckConnectivityAtStartup(boolean b) { 435 checkConnectivityAtStartup = b; 436 437 } 438 } 439 | Popular Tags |