Package org.objectweb.speedo.mapper.rdb

Source Code of org.objectweb.speedo.mapper.rdb.JDBCMapper

/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.objectweb.speedo.mapper.rdb;

import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PExceptionIO;
import org.objectweb.jorm.api.JormConfigurator;
import org.objectweb.jorm.mapper.rdb.lib.MapperJDBC;
import org.objectweb.jorm.mapper.rdb.lib.ConnectionSpecJDBC;
import org.objectweb.fractal.api.control.LifeCycleController;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.util.monolog.api.LoggerFactory;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.wrapper.p6spy.P6SpyLogger;
import org.objectweb.speedo.api.ExceptionHelper;
import org.objectweb.speedo.mapper.rdb.JDBCConnectionHolder;
import org.objectweb.medor.eval.prefetch.lib.PrefetchCacheImpl;
import org.objectweb.perseus.pool.api.PoolMatchFactory;
import org.objectweb.perseus.pool.api.Pool;
import org.objectweb.perseus.pool.api.PoolException;
import org.objectweb.perseus.persistence.api.ConnectionHolderFactory;
import org.objectweb.perseus.persistence.api.ConnectionHolder;
import org.objectweb.perseus.persistence.api.PersistenceException;

import java.sql.DriverManager;
import java.sql.Driver;
import java.util.ArrayList;

/**
* A JDBC mapper component able to pool the JDBC connection in non managed
* environnement.
*
* @author S.Chassande-Barrioz
*/
public class JDBCMapper
    extends MapperJDBC
    implements BindingController, LifeCycleController,
    JDBCMapperAttributes, PoolMatchFactory, ConnectionHolderFactory {

  public final static String POOL_BINDING = "pool";


  /**
   * The pool of JDBC connection.
   */
  protected Pool connectionPool;

  /**
   * The database url. This field is null when a Datasource is used.
   */
  private String url;

  /**
   * The user name to access the database. This field is null when a
   * Datasource is used.
   */
    private String userName;

  /**
   * The user passwor to access the database. This field is null when a
   * Datasource is used.
   */
    private String password;

  /**
   * The class name of the JDBC driver. This field is null when a
   * Datasource is used.
   */
    private String driverCN = null;

  /**
   * Indicates if the component is started;
   */
    private boolean started = false;

  /**
   * Indicates if JDBC connection must be pool or not.
   */
  private boolean poolConnection = false;

  /**
   * Contains the connection allocated for a particular user, in a pooled mode
   */
  private ArrayList unpooledConnection;

  private boolean checkConnectivityAtStartup = true;

    public JDBCMapper() throws PException {
    }

  // IMPLEMENTATION OF THE ConnectionHolderFactory INTERFACE //
  //---------------------------------------------------------//

  public ConnectionHolder createConnectionHolder() throws PersistenceException {
    return new JDBCConnectionHolder(this, logger);
  }

  // IMPLEMENTATION OF THE PoolMatchFactory INTERFACE //
  //--------------------------------------------------//

  /**
   * <b>createResource</b> creates a new PoolResource.
   * @param hints  The "properties" that the created PoolResource should
   *        conform to.
   * @return    The created PoolResource.
   */
  public Object createResource(Object hints) throws PoolException {
    if (!started) {
      startFc();
    }
    Object connection = null;
    try {
      if (hints == null) {
        connection = super.getConnection();
      } else {
        connection = super.getConnection(hints);
      }
    } catch (PException e) {
      throw new PoolException("Error during the allocation a new JDBC connection", e);
    }
    if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG,
          "New JDBC connection allocated for the pool:" + connection);
    }
    return connection;
  }

  /**
   * <b>matchResource</b> tests if a given resource of a Pool matches with
   * the hints passed with the Pool getResource method.
   * @param pr  The PoolResource to test its matching with some
   *        "properties" specified by hints.
   * @param hints  The "properties" that the PoolResource specified by pr
   *        should match.
   * @return    <b>true</b> if the pr PoolResource matches the hints
   *        "properties".
   */
  public boolean matchResource(Object pr, Object hints) {
    return true;
  }

  public void destroyResource(Object resource) {
    if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG,
          "Destroy the JDBC connection of the pool:" + resource);
    }
    try {
      super.closeConnection(resource);
    } catch (PException e) {
      if (logger != null) {
        logger.log(BasicLevel.ERROR,
            "ERROR during the closing of a connection of the pool:"
            + resource, e);
      }
    }
  }

    // IMPLEMENTATION OF THE JDBCMapperAttributes INTERFACE //
    //------------------------------------------------------//

    public String getDriverClassName() {
        return driverCN;
    }

    public void setDriverClassName(String dcn) {
        driverCN = dcn;
    }

    public String getURL() {
        return url;
    }

    public void setURL(String url) {
        this.url = url;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

  public void setPoolConnection(boolean pc) {
    poolConnection = pc;
    if (poolConnection) {
      unpooledConnection = new ArrayList(5);
    }
  }

  public boolean getPoolConnection() {
    return poolConnection;
  }


    // IMPLEMENTATION OF THE UserBindingController INTERFACE //
    //-------------------------------------------------------//

    public String[] listFc() {
        return new String[] {
            POOL_BINDING
        };
    }

    public Object lookupFc(String s) {
    if (POOL_BINDING.equals(s)) {
      return connectionPool;
    } else {
          return null;
    }
    }

    public void bindFc(String s, Object o) {
        if ("logger".equals(s)) {
            logger = (Logger) o;
      if (P6SpyLogger.logger == null) {
        P6SpyLogger.logger = logger;
      }
    } else if ("monolog-factory".equals(s)) {
      Logger l = logger;
            setLoggerFactory((LoggerFactory) o);
      if (l != null) {
        logger = l;
      }
      P6SpyLogger.logger = getLoggerFactory()
          .getLogger(logger.getName() + ".sql");
    } else if (POOL_BINDING.equals(s)) {
      connectionPool = (Pool) o;
    }
    }

    public void unbindFc(String s) {
    if (POOL_BINDING.equals(s)) {
      connectionPool = null;
    }
    }

    // IMPLEMENTATION OF THE LifeCycleController INTERFACE //
    //-----------------------------------------------------//

    public String getFcState() {
        return started ? STARTED : STOPPED;
    }

    public void startFc() {
        if (!started) {
      if (logger == null) {
        String msg = "No logger assigned on the component before the start.";
        System.err.println(msg);
        throw new RuntimeException(msg);
      }
      started = true;
            P6SpyLogger.level = BasicLevel.DEBUG;
            Object cf = getConnectionFactory();
            if (cf == null) {
                try {
                    DriverManager.registerDriver((Driver)
                                Class.forName(driverCN).newInstance());
                    setConnectionFactory(
                            new ConnectionSpecJDBC(url, driverCN, userName, password));
                } catch (Exception e) {
          logger.log(BasicLevel.ERROR,
              "Impossible to configure the jdbc access: ", e);
                    throw new RuntimeException(
                            "Impossible to configure the jdbc access: "
                            + ExceptionHelper.getNested(e).getMessage());
                }
            }
            if (checkConnectivityAtStartup) {
              Object o = null;
              try {
                  logger.log(BasicLevel.DEBUG, "try to fetch a connection");
                  o = getConnection();
              } catch (Exception e) {
                  Exception ie = ExceptionHelper.getNested(e);
                  logger.log(BasicLevel.ERROR,
                          "Impossible to fetch a connection", ie);
                  throw new RuntimeException(
                          "Impossible to fetch a connection: "
                          + ie.getMessage());
              } finally {
                  if (o != null)  {
                      try {
                          closeConnection(o);
                      } catch (PException e) {
                      }
                  }
              }
            }

            try {
                JormConfigurator jc = getJormConfigurator();
                jc.setLoggerFactory(getLoggerFactory());
                PrefetchCacheImpl pc = new PrefetchCacheImpl(
            getLoggerFactory().getLogger(
                "org.objectweb.speedo.rt.query.prefetch"));
        setPrefetchCache(pc);
                start();
            } catch (PException e) {
                throw new RuntimeException(
                        "Impossible to configure the mapper: "
                        + ExceptionHelper.getNested(e).getMessage());
            }
        }
    }

    public void stopFc() {
        started = false;
    }


  // IMPLEMENTATION OF THE PMapper INTERFACE //
  //-----------------------------------------//

  /**
   * The pool is used to fetch a connection.
   */
  public Object getConnection() throws PException {
    if (poolConnection) {
      try {
        Object connection = connectionPool.getResource(null);
        if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
          logger.log(BasicLevel.DEBUG, "Get a JDBC connection from the pool: " + connection);
        }
        return connection;
      } catch (Exception e) {
        throw new PExceptionIO(ExceptionHelper.getNested(e),
            "Impossible to fetch a jdbc connection on driver");
      }
    } else {
      Object connection = super.getConnection();
      if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "JDBC connection allocated: " + connection);
      }
      return connection;
    }
  }

  public Object getConnection(Object connectionContext, Object user) throws PException {
    if (poolConnection) {
      if (connectionContext == null) {
        try {
          Object connection = connectionPool.getResource(null, user);
          if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "Get a JDBC connection from the pool: " + connection);
          }
          return connection;
        } catch (Exception e) {
          throw new PExceptionIO(ExceptionHelper.getNested(e),
              "Impossible to fetch a jdbc connection on driver");
        }
      } else {
        Object connection = super.getConnection(connectionContext, user);
        synchronized(unpooledConnection) {
          unpooledConnection.add(connection);
        }
        if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
          logger.log(BasicLevel.DEBUG,
              "JDBC connection allocated with context, context= "
              + connectionContext + ", connection=" + connection);
        }
        return connection;
      }
    } else {
      Object connection = super.getConnection(connectionContext, user);
      if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "JDBC connection allocated: " + connection);
      }
      return connection;
    }
  }

  /**
   * The connection is release into the pool
   * @param conn
   * @throws org.objectweb.jorm.api.PException
   */
  public void closeConnection(Object conn) throws PException {
    if (conn == null) {
      return;
    }
    if (poolConnection) {
      if (unpooledConnection != null) {
        synchronized(unpooledConnection) {
          if (unpooledConnection.remove(unpooledConnection)) {
            if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
              logger.log(BasicLevel.DEBUG, "Closing the JDBC connection (context): " + conn);
            }
            return;
          } //else the connection has not been found
        }
      }
      try {
        connectionPool.releaseResource(conn);
      } catch (Exception e) {
        throw new PExceptionIO(ExceptionHelper.getNested(e),
            "Impossible to release a jdbc connection");
      }
    } else {
      if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "Closing the JDBC connection: " + conn);
      }
      super.closeConnection(conn);
    }
  }
    public boolean getCheckConnectivityAtStartup() {
        return this.checkConnectivityAtStartup;
    }
    public void setCheckConnectivityAtStartup(boolean b) {
        checkConnectivityAtStartup = b;

    }
}
TOP

Related Classes of org.objectweb.speedo.mapper.rdb.JDBCMapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.