Package modelet.model

Source Code of modelet.model.DefaultModel

package modelet.model;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

import javax.sql.DataSource;

import modelet.context.SessionContext;
import modelet.entity.AppEntity;
import modelet.entity.Entity;
import modelet.entity.SystemIncrementEntity;
import modelet.entity.TxnMode;
import modelet.model.dataroller.DataRoller;
import modelet.model.dataroller.EntityDataRoller;
import modelet.model.dataroller.MapDataRoller;
import modelet.model.paging.DefaultPageContainer;
import modelet.model.paging.PageContainer;
import modelet.model.paging.PagingElement;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Primary;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component("defaultModel")
@Transactional(readOnly = true)
@Primary
public class DefaultModel implements Model {

  private static final Log LOG = LogFactory.getLog(DefaultModel.class);
  private static final Logger EXP_LOG = Logger.getLogger("exceptionLog");
 
  private DataSource dataSource;
  private JdbcTemplate jdbcTemplate;

  private boolean txnSuccessful = true;
  private String txnErrorStack = null;
  private boolean swallowException = false;
 
  public boolean isSwallowException() {
    return swallowException;
  }
 
  public void setSwallowException(boolean swallowException) {
    this.swallowException = swallowException;
  }

  public String getTxnErrorStack() {
    return txnErrorStack;
  }

  private void setTxnErrorStack(String txnErrorStack) {
    this.txnErrorStack = txnErrorStack;
  }

  public boolean isTxnSuccessful() {
    return txnSuccessful;
  }

  private void setTxnSuccessful(boolean txnSuccessful) {
    this.txnSuccessful = txnSuccessful;
  }

  @Transactional(readOnly = false)
  public <E extends Entity> void save(List<E> entities) throws ModelException {
   
    for (E e : entities) {
      save(e);
    }
  }
 
  @Transactional(readOnly = false)
  public int save(Entity entity) throws ModelException {
   
    TxnMode txnMode = entity.getTxnMode();
    if (txnMode == null)
      throw new ModelException("Please assign action type(insert, update, delete) before persist entity to database.");
   
    int returnCode = 0;
    entity.beforeSave();
    if (txnMode.equals(TxnMode.INSERT))
      returnCode = insert(entity);
    else if (txnMode.equals(TxnMode.UPDATE))
      returnCode = update(entity);
    else if (txnMode.equals(TxnMode.DELETE))
      returnCode = delete(entity);
   
    entity.afterSave();
    return returnCode;
  }

  private int insert(final Entity entity) {

    int returnCode = 0;
    final StatementSet stmtSet = ModelUtil.buildPreparedCreateStatement(entity);
    try {
      if (entity instanceof SystemIncrementEntity) {
        returnCode = jdbcTemplate.update(stmtSet.getSql(), stmtSet.getParams());
      }
      else if (entity.getId() != null) {
        returnCode = executeStatementSet(stmtSet);
      }
      else {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        returnCode = jdbcTemplate.update(new PreparedStatementCreator() {
 
          public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
           
            LOG.info("Model INFO :" + stmtSet.getSql() + " param : " + Arrays.toString(stmtSet.getParams()));
            PreparedStatement ps = connection.prepareStatement(stmtSet.getSql(), new String[] { "id" });
            appendParam(ps, stmtSet.getParams());
            return ps;
          }
        }, keyHolder);
 
        long keyValue = keyHolder.getKey().longValue();
        entity.setId(keyValue);
      }
      LOG.info("INSERT returnCode : [" + returnCode + "]");
      entity.setTxnMode(TxnMode.UPDATE);
     
    }
    catch (DataAccessException e) {
      e.printStackTrace();
      setTxnSuccessful(false);
      logSqlError(e, stmtSet.getSql(), stmtSet.getParams());
      logExceptionStack(e);
      throw new ModelException("Error occured while inserting data!", e);
    }
    return returnCode;
  }
 
  private int update(Entity entity) {
   
    StatementSet stmtSet = ModelUtil.buildPreparedUpdateStatement(entity);
    return executeStatementSet(stmtSet);
  }
 
  private int executeStatementSet(StatementSet stmtSet) {
   
    int returnCode = 0;
    try {
      LOG.info("Model INFO :" + stmtSet.getSql() + " param : " + Arrays.toString(stmtSet.getParams()));
      returnCode = jdbcTemplate.update(stmtSet.getSql(), stmtSet.getParams());
      LOG.info("UPDATE returnCode : [" + returnCode + "]");
    }
    catch (DataAccessException e) {
      e.printStackTrace();
      setTxnSuccessful(false);
      logSqlError(e, stmtSet.getSql(), stmtSet.getParams());
      logExceptionStack(e);
      throw new ModelException("Error occured while updaeing data!", e);
    }
    return returnCode;
  }
 
  private int delete(Entity entity) {
   
    int returnCode = 0;
    String sql = ModelUtil.buildDeleteStatement(entity);
    try {
      returnCode = jdbcTemplate.update(sql);
      LOG.info("DELETE returnCode : [" + returnCode + "]");
    }
    catch (DataAccessException e) {
      e.printStackTrace();
      setTxnSuccessful(false);
      logSqlError(e, sql);
      logExceptionStack(e);
      throw new ModelException("Error occured while updaeing data!", e);
    }
    return returnCode;
  }
 
  public <E extends Entity> E findOne(String sql, Object[] params, Class<E> clazz) {
 
    try {
      E entity = (E) Class.forName(clazz.getName()).newInstance();
      List<E> entities = find(sql, params, clazz);
      if (entities != null && entities.size() > 0) {
        entity = entities.get(0);
      }
      return entity;
    } catch (Exception e) {
      throw new ModelException("Can not create instance of " + clazz.getName(), e);
    }
  }
 
  @SuppressWarnings("unchecked")
  public List<Map<String, Object>> find(String sql, Object[] params) {
   
    RowMapper rowMapper = new RowMapper() {
     
      public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
       
        MapDataRoller roller = new MapDataRoller();
        Map<String, Object> row = roller.rollSingleRow(rs);
        return row;
      }
     
    };
    convertParams(params);
    List<Map<String, Object>> entities = jdbcTemplate.query(sql, params, rowMapper);
    return entities;
   
//    MapListHandler rsHandler = new MapListHandler();
//    List<Map<String, Object>> entities = new ArrayList<Map<String, Object>>();
//    try {
//      convertDateIn(params);
//      entities = (List<Map<String, Object>>) getQueryRunner().query(sql, params, rsHandler);
//    }
//    catch (SQLException e) {
//      e.printStackTrace();
//      logSqlError(e, sql, params);
//      logExceptionStack(e);
//    }
//    return entities;
  }
 
  @SuppressWarnings("unchecked")
  public <E extends Entity> List<E> find(String sql, Object[] params, final Class<E> clazz) {
   
    RowMapper rowMapper = new RowMapper() {
     
      public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
       
        EntityDataRoller<E> roller = new EntityDataRoller<E>(clazz);
        E e = roller.rollSingleRow(rs);
//        e.setTxnMode(TxnMode.UPDATE);
        return e;
      }
     
    };
    convertParams(params);
    List<E> entities = jdbcTemplate.query(sql, params, rowMapper);
    return entities;
   
//    ResultSetHandler rsHandler = new BeanListHandler(clazz);
//    List<E> entities = new ArrayList<E>(0);
//    try {
//      convertDateIn(params);
//      entities = (List<E>) getQueryRunner().query(sql, params, rsHandler);
//      for (Entity e: entities) {
//        e.setTxnMode(TxnMode.UPDATE);
//      }
//    }
//    catch (SQLException e) {
//      e.printStackTrace();
//      logSqlError(e, sql, params);
//      logExceptionStack(e);
//    }
//    return entities;
  }

  public PageContainer<SortedMap<String, Object>> findWithPaging(String sql, Object[] params, final PagingElement pagingElement) throws ModelException {
   
    PageContainer<SortedMap<String, Object>> pageContainer = null;
    try {
     
      RstHandler<PageContainer<SortedMap<String, Object>>> rstHandler = new RstHandler<PageContainer<SortedMap<String, Object>>>() {

        @SuppressWarnings("unchecked")
        @Override
        PageContainer<SortedMap<String, Object>> handleRst(ResultSet rst) {
         
          final PageContainer<SortedMap<String, Object>> pageContainer = new DefaultPageContainer<SortedMap<String,Object>>();
          DataRoller dataRoller = new MapDataRoller(pageContainer);
          dataRoller.roll(rst, pagingElement);
          return pageContainer;
        }
       
      };
     
      pageContainer = executeSql(sql, params, rstHandler);
    }
    catch (SQLException e) {
      EXP_LOG.error("Fail to execute query: " + sql + " param : " + Arrays.toString(params), e);
      throw new ModelException("Fail to execute query", e);
    }
    return pageContainer;
  }

  public PageContainer<SortedMap<String, Object>> findWithPaging(String sql, Object[] params, final int page, final int rowsPerPage) throws ModelException {
   
    PageContainer<SortedMap<String, Object>> pageContainer = null;
    try {
     
      RstHandler<PageContainer<SortedMap<String, Object>>> rstHandler = new RstHandler<PageContainer<SortedMap<String, Object>>>() {

        @SuppressWarnings("unchecked")
        @Override
        PageContainer<SortedMap<String, Object>> handleRst(ResultSet rst) {
         
          final PageContainer<SortedMap<String, Object>> pageContainer = new DefaultPageContainer<SortedMap<String,Object>>();
          DataRoller dataRoller = new MapDataRoller(pageContainer);
          dataRoller.roll(rst, page, rowsPerPage);
          return pageContainer;
        }
       
      };
     
      pageContainer = executeSql(sql, params, rstHandler);
    }
    catch (SQLException e) {
      EXP_LOG.error("Fail to execute query: " + sql + " param : " + Arrays.toString(params), e);
      throw new ModelException("Fail to execute query", e);
    }
    return pageContainer;
  }
 
  public <E extends Entity> PageContainer<E> findWithPaging(String sql, Object[] params, final Class<E> clazz, final PagingElement pagingElement) throws ModelException {
   
    PageContainer<E> pageContainer = new DefaultPageContainer<E>();
    try {
      RstHandler<PageContainer<E>> rstHandler = new RstHandler<PageContainer<E>>() {

        @SuppressWarnings("unchecked")
        @Override
        PageContainer<E> handleRst(ResultSet rst) {
         
          final PageContainer<E> pageContainer = new DefaultPageContainer<E>();
          DataRoller dataRoller = new EntityDataRoller<E>(clazz, pageContainer);
          dataRoller.roll(rst, pagingElement);
          return pageContainer;
        }
       
      };
     
      pageContainer = executeSql(sql, params, rstHandler);
    }
    catch (SQLException e) {
      EXP_LOG.error("Fail to execute query: " + sql + " param : " + Arrays.toString(params), e);
      throw new TransactionRollbackedException("Fail to execute query", e);
    }
    return pageContainer;
  }

  public <E extends Entity> PageContainer<E> findWithPaging(String sql, Object[] params, final Class<E> clazz, final int page, final int rowsPerPage) throws ModelException {
   
    PageContainer<E> pageContainer = new DefaultPageContainer<E>();
    try {
      RstHandler<PageContainer<E>> rstHandler = new RstHandler<PageContainer<E>>() {

        @SuppressWarnings("unchecked")
        @Override
        PageContainer<E> handleRst(ResultSet rst) {
         
          final PageContainer<E> pageContainer = new DefaultPageContainer<E>();
          DataRoller dataRoller = new EntityDataRoller<E>(clazz, pageContainer);
          dataRoller.roll(rst, page, rowsPerPage);
          return pageContainer;
        }
       
      };
     
      pageContainer = executeSql(sql, params, rstHandler);
    }
    catch (SQLException e) {
      EXP_LOG.error("Fail to execute query: " + sql + " param : " + Arrays.toString(params), e);
      throw new TransactionRollbackedException("Fail to execute query", e);
    }
    return pageContainer;
  }
 
  public <T extends Entity> T getEntityById(Long id, String tableName, Class<T> clazz) {
   
    if (id == null) {
      id = 0L;
    }

    StringBuffer sql = new StringBuffer();
    sql.append(" select * from ").append(tableName).append(" where id=?");
    Object[] params = {id};
    T rs = findOne(sql.toString(), params, clazz);
    return rs;
  }
 
 
  public Map<String, Object> getEntityMapById(Long id, String tableName) {
   
    if (id == null) {
      id = 0L;
    }

    Map<String, Object> entityMap = new HashMap<String, Object>();
    StringBuffer sql = new StringBuffer();
    sql.append(" select * from ").append(tableName).append(" where id=?");
    Object[] params = {id};
    List<Map<String, Object>> rs = find(sql.toString(), params);
    if (rs.size() > 0) {
      entityMap = rs.get(0);
    }
    return entityMap;
  }
 
  @Transactional(readOnly=false)
  public int executeSql(String sql, Object[] params) throws ModelException {
   
    int count = 0;
    try {
      convertParams(params);
//      for (int i=0; params != null && (i<params.length); i++) {
//        Object obj = params[i];
//        if (obj instanceof Date) {
//          obj = new Timestamp(((Date)obj).getTime());
//          params[i] = obj;
//        }
//        else if (obj.getClass().isEnum()) {
//          obj = obj.toString();
//          params[i] = obj;
//        }
//      }
      LOG.info("Model INFO :" + sql + " param : " + Arrays.toString(params));
      count = jdbcTemplate.update(sql, params);
      LOG.info("sql execution return count : [" + count + "]");
    }
    catch (DataAccessException e) {
      EXP_LOG.error("Fail to execute statement: " + sql + " param : " + Arrays.toString(params), e);
      throw new ModelException("Fail to execute update sql", e);
    }
    return count;
  }
 
  //_Resource(name = "defaultDataSource")
  @Autowired
  public void setDataSource(@Qualifier("defaultDataSource") DataSource dataSource) {
    this.dataSource = dataSource;
  }
 
  //_Resource(name = "jdbcTemplate")
  @Autowired
  public void setJdbcTemplate(@Qualifier("jdbcTemplate") JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }
 
  protected DataSource getDataSource() {
    return dataSource;
  }

  protected JdbcTemplate getJdbcTemplate() {
    return jdbcTemplate;
  }

  private <A> A executeSql(String sql, Object[] params, RstHandler<A> handler) throws SQLException  {
   
    A rs = null;
    Connection cnct = getDataSource().getConnection();
    try {
      PreparedStatement stmt = cnct.prepareStatement(sql);
      convertParams(params);
      for (int i=0; params != null && (i<params.length); i++) {
        stmt.setObject(i+1, params[i]);
      }
      ResultSet rst = stmt.executeQuery();
      rs = handler.handleRst(rst);
      rst.close();
      stmt.close();
    }
    catch (SQLException e) {
      e.printStackTrace();
      throw e;
    }
    finally {
      cnct.close();
    }
    return rs;
  }
 
  private void convertParams(Object[] params) {
 
    for (int i=0; params != null && (i<params.length); i++) {
      Object obj = params[i];
      if (obj instanceof Date) {
        obj = new Timestamp(((Date)obj).getTime());
        params[i] = obj;
      }
      else if (obj instanceof Boolean) {
        if (((Boolean)obj).booleanValue())
          params[i] = "1"; //true
        else
          params[i] = "0"; //false
      }
      else if (obj.getClass().isEnum()) {
        obj = obj.toString();
        params[i] = obj;
      }
    }
  }
 
  abstract class RstHandler<A> {
    abstract A handleRst(ResultSet rst);
  }
 
  private void appendParam(PreparedStatement ps, Object param[]) throws SQLException {

    int i = 1;
    for (Object value : param) {
      if (value == null)
        ps.setNull(i, java.sql.Types.NULL);
      else if (value instanceof String)
        ps.setString(i, (String) value);
      else if (value instanceof Integer)
        ps.setInt(i, (Integer) value);
      else if (value instanceof Long)
        ps.setLong(i, (Long) value);
      else if (value instanceof BigDecimal)
        ps.setBigDecimal(i, (BigDecimal) value);
      else if (value instanceof Timestamp)
        ps.setTimestamp(i, (Timestamp) value);
      else
        ps.setObject(i, value);
      i++;
    }
  }
 
  private Object[] convertDateIn(Object[] params) {
   
    for (int i=0; params != null && (i<params.length); i++) {
      Object obj = params[i];
      if (obj instanceof Date) {
        obj = new Timestamp(((Date)obj).getTime());
        params[i] = obj;
      }
    }
    return params;
  }
 
  private void logSqlError(Exception e, String sql, Object... params) {
   
    StringBuffer paramsContent = new StringBuffer();
    for (int i=0; i<params.length; i++) {
      Object aparam = params[i];
      if (aparam == null)
        aparam = "[null]";
      paramsContent.append(aparam.toString()).append("  ");
    }
    EXP_LOG.error("Fail to execute: " + sql + ", params: " + paramsContent.toString(), e);
  }
 
  private void logExceptionStack(Exception e) {
   
    StringBuffer content = new StringBuffer();
    StackTraceElement[] trace = e.getStackTrace();
    if (trace != null) {
      for (int i=0; i<trace.length; i++) {
        content.append(trace[i].getClassName() + " : " + trace[i].getMethodName() + " : " + trace[i].getLineNumber()).append("\n");
      }
    }
    setTxnErrorStack(content.toString());
  }

}
TOP

Related Classes of modelet.model.DefaultModel

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.