Package org.jdbf.engine.keygen

Source Code of org.jdbf.engine.keygen.KeyKeeper

/*

* 09/01/2003 - 21:29:27

*

* $RCSfile: KeyKeeper.java,v $ - JdbF Object Relational mapping system

* Copyright (C) 2002 JDBF Development Team

*

* http://jdbf.sourceforge.net

*

* This program 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 program 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 program; if not, write to the Free Software

* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/



/*



$Id: KeyKeeper.java,v 1.7 2004/05/20 22:40:02 gmartone Exp $



*/



package org.jdbf.engine.keygen;

  
import java.sql.*;
import java.util.logging.Logger;
import java.util.logging.Level;

import org.jdbf.castor.Messages;
import org.jdbf.engine.mapping.*;
import org.jdbf.engine.sql.SqlInterface;



/**

*<code>KeyKeeper</code> provides generated keys
*for HighLow keyGenerator

*

* The method is similar to the one called Key-Values by Scott Ambler

* in <a href="http://www.Ambysoft.com/mappingObjects.pdf">Mapping

* Objects to Relational Databases</a>.

* With this method, there's a multi-row table which has three columns,

* one for the identifier for the table name, one for the identifier for the key table

* and another for the next key value for that table.

*

* @author Giovanni Martone

* @version $Revision: 1.7 $

* last changed by $Author: gmartone $

*

*/

public class KeyKeeper {

   
  /**
   * Class name
   */
    private static final String CLASS_NAME = "org.jdbf.engine.keygen.KeyKeeper";



    /**

     * Represents the sql type for high value

     */

    private static int DATA_TYPE = Types.VARCHAR;

   

   

    /**

     * Represents the progressive to add the high forn new insert operation

     */

    private static int PROGRESSIVE = 1;

   

   

    /**

     * Represents the tyoe of column of high value

     */

    private int columnType = -1;



   

    /**

     * The key is generated for this table.

     */

    private String tableName;



   

    /**

     * Indicates if KeyKeeper is used

     */

    private boolean isUsed = false;

       

   

    /**

     * The high value is combined with the low value to

     * produce the key.

     */

    private HighLowMap hiloMap;





    /**

     * SqlInterface object

     */

    private SqlInterface sqlInterface;



   

    /**

     * Logger object

     */

    private Logger logger;



                   

    /**

     * Creates the object given table name,given hiloMap
     * and current sqlInterface

     *

     * @param tableName

     * @param hiloMap
     * @param sqlInterface

     */

    public KeyKeeper (String tableName,HighLowMap hiloMap,
              SqlInterface sqlInterface){

    logger = Logger.getLogger(CLASS_NAME);
    this.tableName = tableName;
    this.hiloMap = hiloMap;
    this.sqlInterface = sqlInterface;

    }



       

    /**

     * Obtains a block of available keys
     * from the key-values table.

     *

     * @param conn java.sql.Connection

     * @param vendor name of database vendor

     * @return HighLowMap the value beyond the block of available keys,

     * @exception KeyGenerationException if an error occurs

     */

    private HighLowMap fetchHigh(Connection conn,String vendor)

        throws KeyGenerationException{

 

    logger.log(Level.INFO,Messages.message("KeyKeeper.fetchHigh"));

    /*
      * HighLowMap holds three things: 
      * 1) name of the table used to store two columns.
      * 2) column name for identifier  for table name and
      * 3) column name for the next key for that table.
      */
    StringBuffer condition = new StringBuffer(32);   
    condition.append(hiloMap.getTableColumn()).append("=?");

    String sql = sqlInterface.getSelectStatement(hiloMap.getTable(),
                           "*",
                           condition.toString()
                    );

    logger.log(Level.FINEST,Messages.format("KeyKeeper.highLowQuery",
                                    sql,tableName));

 
    ResultSet rs = null;
    PreparedStatement pstmt = null;

    try{       

      // First get column type of key.

      if (columnType == -1) {
        columnType = getColumnType(conn,
                       hiloMap.getTable(),
                          hiloMap.getKeyColumn());

      }

   
      if (columnType != DATA_TYPE){         
        logger.throwing(CLASS_NAME,"fetchHigh()",
                new KeyGenerationException(
                  Messages.format("mapping.keyGenWrongType",
                   new Integer(columnType),getClass())
               ));
              
        throw new KeyGenerationException(
            Messages.format("mapping.keyGenWrongType",
            new Integer(columnType),getClass()))
      }

      pstmt = conn.prepareStatement(sql);
      pstmt.setString(1,tableName);

      rs = pstmt.executeQuery();

      //Get the high and low values and creates the key
      //then updates the low values adding to last low the
      //value of PROGRESSIVE variable and update the table
      //that contains the highlow
      if (rs.next()) {

        hiloMap.setHigh(rs.getString(2));
        hiloMap.setLow(rs.getObject(3));
      }
      else{
        logger.throwing(CLASS_NAME,"fetchHigh()",
              new KeyGenerationException("mapping.MissingDataKeyGen",
              hiloMap.getTable(),tableName)

             );
            
             throw new KeyGenerationException("mapping.MissingDataKeyGen",
            hiloMap.getTable(),tableName);
      }
    }
    catch (SQLException excep) {

      logger.throwing(CLASS_NAME,"fetchHigh()",
          new KeyGenerationException(excep));
     
      throw new KeyGenerationException(excep);
    }
    finally {
      try {
        if (rs != null)
          rs.close();
        if (pstmt != null) {
          pstmt.close();
        }
        pstmt = null;
      }
      catch (SQLException excep) {
        logger.throwing(CLASS_NAME,"fetchHigh()",
            new KeyGenerationException(excep));
           
        throw new KeyGenerationException(excep);
      }
    }
    logger.log(Level.FINEST,hiloMap.toString());
    logger.log(Level.INFO,Messages.message("KeyKeeper.fetchedHigh"));
    return hiloMap;
    }

 
    /**

     * Return column's type fo column specified in column parameter.

     *

     * @param conn

     * @param table name of table

     * @param column name of column

     * @return type of dataType specified in int

     * @throws SQLException if error occurs

     * @throws KeyGenerationException if error occurs

     *

     */

    private final int getColumnType(Connection conn, String table, String column)

    throws SQLException, KeyGenerationException{

   

    logger.log(Level.INFO,Messages.message("KeyKeeper.getColumnType"));
 
    ResultSet rs = null;
 
    int dataType = -1;
 
    try {
 
        // Using meta data because many DBMS can not
 
        // pre-compile statements.
 
        DatabaseMetaData dmd = conn.getMetaData();
 
        rs = dmd.getColumns(null , null, table, column);
 
 
 
        synchronized (this) {
 
            if (rs.next()) {
 
             dataType =  rs.getInt("DATA_TYPE");
 
          logger.log(Level.FINEST,Messages.message("dataType: " + dataType));
 
          return dataType;
 
      }
 
      logger.throwing(CLASS_NAME,"getColumnType()",
 
            new KeyGenerationException("mapping.checkKeyGen",
 
                getClass().getName()
 
            ));
      throw new KeyGenerationException("mapping.checkKeyGen",
                       getClass().getName());
        }
 
    } 
    finally{
 
        if (rs != null) {
 
        rs.close();
 
        rs = null;
 
        }
 
        logger.log(Level.INFO,Messages.message("KeyKeeper.getColumnTypeFinish"));
 
        return dataType;
 
    }

    }

 

 

    /**

     * Returns the next generated key.

     *

     * @param conn database connections for the key-values table

     * @param vendor name of database vendor

     * @return Object the generated key

     * @exception KeyGenerationException if an error occurs

     */

    public synchronized Object nextKey(Connection conn,String vendor)
    throws KeyGenerationException{



    logger.log(Level.INFO,Messages.message("KeyKeeper.nextKey"));
 
   
 
    Object key = null;
 
   
 
    if (!isUsed){   
 
        hiloMap = fetchHigh(conn,vendor);
 
        isUsed = true;
 
          }     
 
    int  low = Integer.parseInt(hiloMap.getLow().toString());
 
    int iLow = low + PROGRESSIVE;
 
    String cKey = hiloMap.getHigh() + String.valueOf(iLow);
 
          key = (cKey);
 
   
 
    logger.log(Level.FINEST,Messages.format("KeeyKeeper.highLowKey",key));
 
   
 
    Object sLow = (String.valueOf(iLow));
 
    hiloMap.setLow(sLow);
 
    updateLow(conn,hiloMap);
 
 
 
    logger.log(Level.INFO,Messages.message("KeyKeeper.nextKeyFinished"));
 
    return key;

    }





    /**

     * Updates in table where keyGenerators are mapped the new low value specified

     * in table.

     *

     * @param conn,
     * @param hiloMap HighLowMap object.

     * @return row number of rows affected.

     * @throws KeyGenerationException if occurs

     */

    private int updateLow(Connection conn, HighLowMap hiloMap) throws KeyGenerationException{

       

    logger.log(Level.INFO,Messages.message("KeyKeeper.updateLow"));
 
    int row = 0;
 
    PreparedStatement pstmt = null;
 
    SqlInterface sqlInterface = new SqlInterface();
 
    StringBuffer condition = new StringBuffer(32);
 
    condition.append(hiloMap.getTableColumn()).append("=?");
 
    condition.append(" " + SqlInterface.AND  + hiloMap.getKeyColumn() + "=?");
 
 
 
    String setNewValue = hiloMap.getNextColumn() + "=" + hiloMap.getLow().toString();
 
 
 
    //Updates value
 
    String sql = sqlInterface.getUpdateStatement(hiloMap.getTable(),setNewValue,
 
                condition.toString());
 
   
 
    Object[] params = {sql,tableName,hiloMap.getHigh()};
 
    logger.log(Level.FINEST,Messages.format("KeeyKeeper.updateLowQuery",params));
 
 
 
    try{
 
        pstmt = conn.prepareStatement(sql);
 
        pstmt.setString(1,tableName);
 
        pstmt.setString(2,hiloMap.getHigh());
 
        row = pstmt.executeUpdate();
 
          }
 
    catch(SQLException excep){
 
        logger.throwing(CLASS_NAME,"updateLow()",
                  new KeyGenerationException(excep));
      throw new KeyGenerationException(excep);
    }
 
    finally{
 
        try{
 
        if(pstmt != null)
 
            pstmt.close();     
 
        pstmt = null;
 
        }
        catch(SQLException ex){
 
        logger.throwing(CLASS_NAME,"updateLow()",
                    new KeyGenerationException(ex));
        throw new KeyGenerationException(ex);
        }
 
    }
 
    logger.log(Level.INFO,Messages.message("KeyKeeper.updatedLow"));
 
    return row;

    }

}



/*

  $Log: KeyKeeper.java,v $
  Revision 1.7  2004/05/20 22:40:02  gmartone
  Changed for task 99073 (Coverage Javadocs)

  Revision 1.6  2004/04/19 23:48:59  gmartone
  changed type of Exception thrown in all methods from MappingException to KeyGenerationException

  Revision 1.5  2004/04/05 22:06:31  gmartone
  *** empty log message ***




*/

 
TOP

Related Classes of org.jdbf.engine.keygen.KeyKeeper

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.