Package org.xmlBlaster.contrib.replication

Source Code of org.xmlBlaster.contrib.replication.SqlPrePostStatement

/*------------------------------------------------------------------------------
Name:      SqlPrePostStatement.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/

package org.xmlBlaster.contrib.replication;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.xmlBlaster.contrib.I_Info;
import org.xmlBlaster.contrib.InfoHelper;
import org.xmlBlaster.contrib.db.DbMetaHelper;
import org.xmlBlaster.contrib.db.I_DbPool;
import org.xmlBlaster.contrib.dbwriter.info.I_PrePostStatement;
import org.xmlBlaster.contrib.dbwriter.info.SqlDescription;
import org.xmlBlaster.contrib.dbwriter.info.SqlInfo;
import org.xmlBlaster.contrib.dbwriter.info.SqlRow;

/**
* SqlPrePostStatement allows the replication to execute a stored procedure before and / or
* after the operation on the replica (it is invoked as an optional plugin by the
* ReplicationWriter).
*
* @author <a href="mailto:michele@laghi.eu">Michele Laghi</a>
*/
public class SqlPrePostStatement implements I_PrePostStatement {
  
   private static Logger log = Logger.getLogger(SqlPrePostStatement.class.getName());
  
   private Map sqlInsertPre;
   private Map sqlUpdatePre;
   private Map sqlDeletePre;
  
   private Map sqlInsertPost;
   private Map sqlUpdatePost;
   private Map sqlDeletePost;
    
   public SqlPrePostStatement() {
   }

   private final boolean executeSqlCodeIfNeeded(Connection conn, Map map, String completeTableName) {
      if (map == null)
         return true;
      String sqlCode = (String)map.get(completeTableName);
      if (sqlCode == null)
         return true;
      CallableStatement cs = null;
      try {
         log.fine("Invoking '" + sqlCode + "'");
         cs = conn.prepareCall(sqlCode);
         cs.executeQuery();
      }
      catch (SQLException ex) {
         log.severe("An Exception occured when executing '" + sqlCode + "':" + ex.getMessage());
         ex.printStackTrace();
      }
      finally {
         if (cs != null) {
            try {
               cs.close();
            }
            catch (SQLException ex) {
               ex.printStackTrace();
            }
         }
      }
      return true;
   }
  
   public boolean preStatement(String operation, Connection conn, SqlInfo info, SqlDescription tableDescription, SqlRow currentRow) throws Exception {
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         return executeSqlCodeIfNeeded(conn, this.sqlInsertPre, tableDescription.getCompleteTableName());
      }
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         return executeSqlCodeIfNeeded(conn, this.sqlUpdatePre, tableDescription.getCompleteTableName());
      }
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         return executeSqlCodeIfNeeded(conn, this.sqlDeletePre, tableDescription.getCompleteTableName());
      }
      return true;
   }

   public void postStatement(String operation, Connection conn, SqlInfo info, SqlDescription tableDescription, SqlRow currentRow) throws Exception {
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         executeSqlCodeIfNeeded(conn, this.sqlInsertPost, tableDescription.getCompleteTableName());
      }
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         executeSqlCodeIfNeeded(conn, this.sqlUpdatePost, tableDescription.getCompleteTableName());
      }
      if (INSERT_ACTION.equalsIgnoreCase(operation)) {
         executeSqlCodeIfNeeded(conn, this.sqlDeletePost, tableDescription.getCompleteTableName());
      }
   }

   public Set getUsedPropertyKeys() {
      return null;
   }

   /**
    * Gets a map of all codes having as key the complete table name and as value
    * the callable statement to invoke (already correct for jdbc callableStatement
    * invocation).
    *
    * @param prefix
    * @param info
    * @param dbMetaHelper
    * @return
    */
   private Map getCodeMap(String prefix, I_Info info, DbMetaHelper dbMetaHelper) {
      Map map = InfoHelper.getPropertiesStartingWith(prefix, info, dbMetaHelper);
      log.info(prefix + " statements found '" + map.size() + "' times ");
      if (map.size() < 1)
         return null;
      Map ret = new HashMap();
      Iterator iter = map.keySet().iterator();
      while (iter.hasNext()) {
         Object key = iter.next();
         String val = (String)map.get(key);
         String sql = "{call " + val + "}";
         ret.put(key, sql);
      }
      return ret;
   }
  

   /**
    * Properties used are:
    * dbWriter.sqlPrePostStatement.sql.pre.insert.${SCHEMA}.${TABLE}
    * dbWriter.sqlPrePostStatement.sql.pre.update.${SCHEMA}.${TABLE}
    * dbWriter.sqlPrePostStatement.sql.pre.delete.${SCHEMA}.${TABLE}
    * dbWriter.sqlPrePostStatement.sql.post.insert.${SCHEMA}.${TABLE}
    * dbWriter.sqlPrePostStatement.sql.post.update.${SCHEMA}.${TABLE}
    * dbWriter.sqlPrePostStatement.sql.post.delete.${SCHEMA}.${TABLE}
    *
    */
   public void init(I_Info info) throws Exception {
      I_DbPool dbPool = (I_DbPool)info.getObject("db.pool");
      DbMetaHelper dbMetaHelper = null;
      if (dbPool != null) {
         dbMetaHelper = new DbMetaHelper(dbPool);
      }
      else
         log.warning("The database pool has not been registered ('db.pool')");
     
      this.sqlInsertPre = getCodeMap("dbWriter.sqlPrePostStatement.sql.pre.insert.", info, dbMetaHelper);
      this.sqlUpdatePre = getCodeMap("dbWriter.sqlPrePostStatement.sql.pre.update.", info, dbMetaHelper);
      this.sqlDeletePre = getCodeMap("dbWriter.sqlPrePostStatement.sql.pre.delete.", info, dbMetaHelper);

      this.sqlInsertPost = getCodeMap("dbWriter.sqlPrePostStatement.sql.post.insert.", info, dbMetaHelper);
      this.sqlUpdatePost = getCodeMap("dbWriter.sqlPrePostStatement.sql.post.update.", info, dbMetaHelper);
      this.sqlDeletePost = getCodeMap("dbWriter.sqlPrePostStatement.sql.post.delete.", info, dbMetaHelper);
   }

   public void shutdown() throws Exception {
      this.sqlInsertPre = null;
      this.sqlUpdatePre = null;
      this.sqlDeletePre = null;
      this.sqlInsertPost = null;
      this.sqlUpdatePost = null;
      this.sqlDeletePost = null;
   }
  
}
TOP

Related Classes of org.xmlBlaster.contrib.replication.SqlPrePostStatement

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.