Package org.uengine.util.dao

Source Code of org.uengine.util.dao.AbstractGenericDAO

package org.uengine.util.dao;

import sun.jdbc.rowset.CachedRowSet;

import javax.naming.InitialContext;
import java.lang.reflect.*;

import javax.sql.*;

import org.uengine.kernel.UEngineException;
import org.uengine.persistence.dao.DAOFactory;
import org.uengine.processmanager.ProcessManagerBean;
import org.uengine.processmanager.ProcessTransactionContext;
import org.uengine.util.ForLoop;

import java.sql.*;
import java.util.*;
import java.util.Date;


/**
* Generic DAO
*
* @author <a href="mailto:ghbpark@hanwha.co.kr">Sungsoo Park</a>, Jinyoung Jang
* @version $Id: AbstractGenericDAO.java,v 1.33 2010/04/08 01:27:21 allbegray Exp $
*/
public abstract class AbstractGenericDAO implements InvocationHandler, IDAO {
  private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; 
//  protected boolean isAutoCommit = true;
 
  protected boolean isConnective = false;
    public boolean isConnective() {
      return isConnective;
    }
    public void setConnective(boolean isConnective) {
      this.isConnective = isConnective;
    }
   
  private boolean isDirty = false;
 
  private boolean isUpdateOnlyWhenDirty = true;
    protected boolean updateOnlyWhenDirty() {
      return isUpdateOnlyWhenDirty;
    }
    public void setUpdateOnlyWhenDirty(boolean isUpdateOnlyWhenDirty) {
      this.isUpdateOnlyWhenDirty = isUpdateOnlyWhenDirty;
    }
   
    protected CachedRowSet rowSet = null;
   
    private ConnectionFactory connectionFactory;
    public ConnectionFactory getConnectionFactory() {
      return connectionFactory;
    }
    public void setConnectionFactory(ConnectionFactory factory) {
      if(factory==null) throw new RuntimeException(new UEngineException("ConnectionFactory should not be null."));
     
      connectionFactory = factory;
    }
   
    //private HashMap propertyMap;
  protected HashMap cache;
    protected HashMap outFieldMap;
    protected HashMap modifiedFieldMap;
   
    protected boolean isBatchUpdate = false;
   
    String sqlStmt;
    public String getSqlStmt() {
      return sqlStmt;
    }
    public void setSqlStmt(String sqlStmt) {
      this.sqlStmt = sqlStmt;
    }

  String tableName;
    public String getTableName() {
      return tableName;
    }
    public void setTableName(String tableName) {
      this.tableName = tableName;
    }
   
  String keyField;
    public String getKeyField() {
      return keyField;
    }
    public void setKeyField(String keyField) {
      this.keyField = keyField;
    }

   
  Class daoClass;

  HashMap propertyTypes;
    public HashMap getPropertyTypes() {
      return propertyTypes;
    }


//  HashMap isOptional;
 
  boolean autoSQLGeneration;
    public boolean isAutoSQLGeneration() {
      return autoSQLGeneration;
    }
    public void setAutoSQLGeneration(boolean autoSQLGeneration) {
      this.autoSQLGeneration = autoSQLGeneration;
   

  protected AbstractGenericDAO(Class daoClass, boolean isConnective) throws Exception{
    initialize(daoClass, isConnective);
 


    /**
     * JNDI �̸��� Retrive�� '�� ����� �Բ� Ŀ�ؼ� �غ�
     *
     * @param jndiName
     * @param statement
     * @throws DAOException
     */
   
  protected AbstractGenericDAO(final String jndiName, boolean isConnective, String sqlStmt, Class daoClass) throws Exception {
    this(
      new ConnectionFactory(){
        public Connection getConnection() throws Exception{
          InitialContext ctx = null;
          ctx = new InitialContext();
          DataSource ds = (javax.sql.DataSource) ctx.lookup(jndiName);
          return ds.getConnection();
        }
      },
      isConnective,
      sqlStmt, daoClass
    );   
  }
 
//  protected AbstractGenericDAO(TransactionContext tc, String sqlStmt, Class daoClass)  throws Exception {
//    this(
//      new TransactionContextConnectionFactoryAdapter(tc),
//      false,
//      sqlStmt, daoClass
//    );
//    this.tc = tc;
//  }   

//  protected AbstractGenericDAO(final Connection conn, boolean isConnective, String sqlStmt, Class daoClass)  throws Exception {
//    this(
//      new ConnectionFactory(){
//        public Connection getConnection() throws Exception{
//          return conn;
//        }
//      },
//      isConnective,
//      sqlStmt, daoClass
//    );
//  }   

  protected AbstractGenericDAO(ConnectionFactory con, boolean isConnective, String sqlStmt, Class daoClass) throws Exception {
    initialize(con, isConnective, sqlStmt, daoClass);
  }
 
  protected void initialize(ConnectionFactory cf, boolean isConnective, String sqlStmt, Class daoClass)
    throws Exception {
   
    setConnectionFactory(cf);
     
/*    propertyMap = new HashMap();{
      String[] splits = statement.split("?");
      for(int i=0; i<splits.length; i++){
        String token = splits[i];
       
        String splits2[] = token.split(" ");           
        String propertyName = splits2[0];
       
        propertyMap.put(propertyName.toUpperCase(), new Integer(i));
      }
    }*/
//    this.outFieldMap = new HashMap();   
//    this.cache = new HashMap();
   
//    this.selectSqlStmt = selectSqlStmt;
//    this.insertSqlStmt = insertSqlStmt;
//    this.updateSqlStmt = updateSqlStmt;
   
//    this.actualSelectSqlStmt = getActualSqlStmt(selectSqlStmt);
//    this.actualInsertSqlStmt = getActualSqlStmt(insertSqlStmt);
//    this.actualUpdateSqlStmt = getActualSqlStmt(updateSqlStmt);
   
//    this.daoClass = daoClass;
//    Method[] methods = daoClass.getMethods();
//    propertyTypes = new HashMap(methods.length);
//    for(int i=0; i<methods.length; i++){
//      String propName = methods[i].getName();
//     
//      if(propName.startsWith("get")){
//        propName = propName.substring(3).toUpperCase();
//        propertyTypes.put(propName, methods[i].getReturnType());
//      }
//    }
    setStatement(sqlStmt);
    initialize(daoClass, isConnective);
  }

 
  protected void initialize(Class daoClass, boolean isConnective) throws Exception {
//    this.isAutoCommit = isAutoCommit;
    this.isConnective = isConnective;
   
//    if ( isAutoCommit ) isConnective = false;
   
    this.outFieldMap = new HashMap();   
    this.cache = new HashMap();
   
    this.daoClass = daoClass;
    Method[] methods = daoClass.getMethods();
    propertyTypes = new HashMap(methods.length);
    for(int i=0; i<methods.length; i++){
      String propName = methods[i].getName();
     
      if(propName.startsWith("get") && methods[i].getParameterTypes().length == 0){
       
        try{
          propName = propName.substring(3);
          daoClass.getMethod("set" + propName, new Class[]{methods[i].getReturnType()});

          propName = propName.toUpperCase();
          propertyTypes.put(propName, methods[i].getReturnType());
        }catch(Exception e){
          //ignore if there's no setter having same property naming convention.
        }
       
      }
    }
  }
 
  public void select() throws Exception {
   
    if(sqlStmt == null && isAutoSQLGeneration()){
      createSelectSql();
    }
   
    rowSet = null;
    //TODO: need to be cached
   
    PreparedStatement pstmt = null;
    Connection con = getConnectionFactory().getConnection();
    try{
      if(con == null) throw new UEngineException("Connection is null");
     
      pstmt = con.prepareStatement(getActualSqlStmt(getStatement()));
   
      lateBindProperties(getStatement(), pstmt);
      rowSet = new CachedRowSet();
//      ResultSet rs = pstmt.executeQuery();
//      rs.next();
      rowSet.populate(pstmt.executeQuery());
      rowSet.beforeFirst();
     
      isDirty = false;
     
    }catch(Exception e){
      throw new UEngineException("Error when to try sql [" + getStatement() + "] ", e);
    }finally{
      try{pstmt.close();}catch(Exception e){}
      if ( !isConnective ) {
        checkOkToCloseConnection();
        try{con.close();}catch(Exception e){}
      }
     
    }   
  }
 
  private void checkOkToCloseConnection() throws Exception{
    if(getConnectionFactory() instanceof ProcessTransactionContext){
      ProcessManagerBean pm = ((ProcessTransactionContext)getConnectionFactory()).getProcessManager();
      if(!pm.isManagedTransaction()) throw new UEngineException("This thread tries to close any of connection in uEngine-managed transaction.");
    }
  }
 
  public void createInsertSql() throws Exception{
    final StringBuffer sql_KeyNames = new StringBuffer();
    final StringBuffer sql_ValuePlaceHolders = new StringBuffer();
   
    if(rowSet==null){  // fetch ���� sql��: cache���� �Էµ� ���� ���뿡 ��� ������.
      ForLoop loopForCacheKeys = new ForLoop(){
        String sep = "";

        public void logic(Object target) {
          String propertyName = (String)target;
         
          sql_KeyNames.append(sep + propertyName);
          sql_ValuePlaceHolders.append(sep + "?" + propertyName);
         
          sep =", ";
        }
       
      };
     
      loopForCacheKeys.run(cache.keySet());
      sqlStmt = "insert into " + getTableName() + "("+ sql_KeyNames +") values (" + sql_ValuePlaceHolders + ")";

    }else{        // fetch ���� ��Ȱ��� dao�� insert�� ��Ÿ�����Ϳ��� ã�ƿͼ� ������
      String sep = "";
      ResultSetMetaData rsMetaData = rowSet.getMetaData();
      for(int i=1; i<=rsMetaData.getColumnCount(); i++){
        String propertyName = rsMetaData.getColumnName(i);
       
        sql_KeyNames.append(sep + propertyName);
        sql_ValuePlaceHolders.append(sep + "?" + propertyName);
       
        sep =", ";
      }

      sqlStmt = "insert into " + getTableName() + "("+ sql_KeyNames +") values (" + sql_ValuePlaceHolders + ")";

         adjustMetaDataIfFetched();
    }
   
  }
 
  public int insert() throws Exception {
    if(sqlStmt == null && isAutoSQLGeneration()){
      createInsertSql();
    }
   
    return update();
  }

  private static Hashtable typeMappingHT = new Hashtable();
  static{
    typeMappingHT.put(Integer.valueOf(Types.VARCHAR),   String.class);
    typeMappingHT.put(Integer.valueOf(Types.INTEGER),   Number.class);
    typeMappingHT.put(Integer.valueOf(2),         Number.class);
    typeMappingHT.put(Integer.valueOf(Types.DATE),    Date.class);
    typeMappingHT.put(Integer.valueOf(Types.BOOLEAN),  Boolean.class);
  }
  protected void adjustMetaDataIfFetched() throws Exception{
    if(rowSet==null) return;
   
    ResultSetMetaData rsMetaData = rowSet.getMetaData();
    for(int i=1; i<=rsMetaData.getColumnCount(); i++){
      String propertyName = rsMetaData.getColumnName(i);
      int type = rsMetaData.getColumnType(i);

      Class propertyCls = (Class)typeMappingHT.get(Integer.valueOf(type));
      if(propertyCls!=null)
        propertyTypes.put(propertyName, propertyCls);
    }
  }
 
  public int update(String sqlStmt) throws Exception
    setStatement(sqlStmt);
    return update();
  }
 
 
  private int batchCount = 0;
    public int getBatchCount() {
      return batchCount;
    }

  private PreparedStatement pstmtForBatch = null;
  private Connection connForBatch = null;
 
  public void addBatch() throws Exception {
    isBatchUpdate = true;
    if ( batchCount == 0 ) {
//      if ( getConnectionFactory() == null )
//        setConnectionFactory(new ConnectionFactory());
      connForBatch = getConnectionFactory().getConnection();
      pstmtForBatch = connForBatch.prepareStatement(getActualSqlStmt(getStatement()));
    }
    lateBindProperties(getStatement(), pstmtForBatch);
    pstmtForBatch.addBatch();
    batchCount++;
  }
 
  public int[] updateBatch() throws Exception {
    try{
      if ( batchCount > 0 ) {
        return pstmtForBatch.executeBatch();
      } else {
        int[] btc = new int[0];
        return btc;
      }
    }catch(Exception e){
      throw new UEngineException("Error when to try sql [" + getStatement() + "] ", e);
     
    }finally{
      try{pstmtForBatch.close();}catch(Exception e){}
      if ( !isConnective ) {
        checkOkToCloseConnection();
        try{connForBatch.close();}catch(Exception e){}
      }
    }     
  }
 
 
  public void createUpdateSql() throws Exception{
    final StringBuffer sql_SetPairs = new StringBuffer();

    if(getTableName()==null || getKeyField()==null)
      throw new UEngineException("Although Update query is set to be build automatically, the table name or key field is not set.");
   
    if(rowSet==null){
     
      ForLoop loopForCacheKeys = new ForLoop(){
        String sep = "";

        public void logic(Object target) {
          String propertyName = (String)target;
         
          if(modifiedFieldMap!=null && !modifiedFieldMap.containsKey(propertyName)) return;

          sql_SetPairs.append(sep + propertyName + "=?" + propertyName);
         
          sep =", ";
        }
       
      };
     
      loopForCacheKeys.run(cache.keySet());
      sqlStmt = "update " + getTableName() + " set "+ sql_SetPairs +" where " + getKeyField() + "=?" + getKeyField();

    }else{        // fetch ���� ��Ȱ��� dao�� insert�� ��Ÿ�����Ϳ��� ã�ƿͼ� ������
      String sep = "";
      ResultSetMetaData rsMetaData = rowSet.getMetaData();
      for(int i=1; i<=rsMetaData.getColumnCount(); i++){
        String propertyName = rsMetaData.getColumnName(i);       
       
        if(propertyName.equalsIgnoreCase(getKeyField()) || modifiedFieldMap!=null && !modifiedFieldMap.containsKey(propertyName)) continue;
       
        sql_SetPairs.append(sep + propertyName + "=?" + propertyName);       
        sep =", ";
      }

      sqlStmt = "update " + getTableName() + " set "+ sql_SetPairs +" where " + getKeyField() + "=?" + getKeyField();

      if(sql_SetPairs.length() == 0)
        sqlStmt = null;
     
         adjustMetaDataIfFetched();
    }
  }
 
  public void createSelectSql() throws Exception{
    sqlStmt = "select * from " + getTableName() + " where " + getKeyField() + "=?" + getKeyField();
  }
 
  public int update() throws Exception {
    if(sqlStmt == null && isAutoSQLGeneration()){
      createUpdateSql();
    }
   
    if(sqlStmt == null || updateOnlyWhenDirty() && !isDirty) return 0;
     
//    if ( tc != null ) tc.setHasDML(true);
//    if ( getConnectionFactory() == null )
//      setConnectionFactory(new ConnectionFactory());
   
    //rowSet = null;

    //TODO: need to be cached
    Connection con = getConnectionFactory().getConnection();
    PreparedStatement pstmt = null;
   
    try{
//      System.out.println("getStatement() : " + getStatement());
     
      pstmt = con.prepareStatement(getActualSqlStmt(getStatement()));
     
      lateBindProperties(getStatement(), pstmt);
      int rowAffected = pstmt.executeUpdate();
     
      return rowAffected;
    }catch(Exception e){
      throw new UEngineException("Error when to try sql [" + getStatement() + "] ", e);
    }finally{
      try{pstmt.close();}catch(Exception e){}
      if ( !isConnective ) {
        checkOkToCloseConnection();
        try{con.close();}catch(Exception e){}
      }
    }   
  } 
 
 
  public int call() throws Exception {
    CallableStatement cstmt = null;   
    Connection con = getConnectionFactory().getConnection();
    try{
      rowSet = null;
   
      cstmt = con.prepareCall(getActualSqlStmt(getStatement()));
   
      lateBindProperties(getStatement(), cstmt);
      int rowAffected = cstmt.executeUpdate();
   
      for(Iterator iter = outFieldMap.keySet().iterator(); iter.hasNext();){
        String fieldName = (String)iter.next();
        int order = ((Integer)outFieldMap.get(fieldName)).intValue();
        Object value = cstmt.getObject(order);
//        Array array = cstmt.getArray("");
        cache.put(fieldName.toUpperCase(), value);
      }
   
      return rowAffected;     
    }catch(Exception e){
      throw e;
    }finally{
      try{cstmt.close();}catch(Exception e){}
      if ( !isConnective ) {
        checkOkToCloseConnection();
        try{con.close();}catch(Exception e){}
      }
    }   
  }
 
//  public boolean absolute(int row) throws Exception {
//    if(rowSet==null)
//      throw new Exception("This DAO is not selected yet.");
//
//    return rowSet.absolute(row);
//  }

//  public int getRow() throws Exception {
//    if(rowSet==null)
//      throw new Exception("This DAO is not selected yet.");
//
//    return rowSet.getRow();
//  }

  public void beforeFirst() throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    rowSet.beforeFirst();
  }

  public boolean previous() throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");
    return rowSet.previous();
  }   

    public boolean next() throws Exception {
      if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");
     
    return rowSet.next();
    }

  public void afterLast() throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");
     
      rowSet.afterLast();
  }
   
  public boolean last() throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");
     
    return rowSet.last();
  }
       
   
    public boolean first() throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return rowSet.first();
    }
   
    public boolean absolute(int pos) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return rowSet.absolute(pos);
    }   

    public int size() {
    if(rowSet==null)
      throw new RuntimeException("This DAO is not selected yet.");

        return rowSet.size();
    }
   
  public String getString(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return rowSet.getString(key);
  }
  public Integer getInt(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");
    return Integer.valueOf(rowSet.getInt(key));
  }
  public Long getLong(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return Long.valueOf(rowSet.getLong(key));   
  }
  public Boolean getBoolean(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return Boolean.valueOf(rowSet.getBoolean(key));     
  }
 
  public Date getDate(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return rowSet.getDate(key);        
  }

  public Timestamp getTimestamp(String key) throws Exception {
    if(rowSet==null)
      throw new Exception("This DAO is not selected yet.");

    return rowSet.getTimestamp(key);        
  }

  protected void lateBindProperties(String statement, PreparedStatement pStmt) throws Exception{
    getActualSqlStmt(statement, pStmt);     
  }
 
  protected String getActualSqlStmt(String statement) throws Exception{
    return getActualSqlStmt(statement, null);
  }

    protected String getActualSqlStmt(String statement, PreparedStatement pstmt) throws Exception{
     
      if(statement==null) return null;
     
       StringBuffer realSql=new StringBuffer();
     
    String[] splits = statement.split("\\?");
           
    if(splits.length>0)
      realSql.append(splits[0]);
     
    outFieldMap.clear();

    if(splits.length>1){
      for(int i=1; i<splits.length; i++){
        String token = splits[i];
   
        String splits2[] = token.split("[ ,);]");           
        String propertyNamePart = splits2[0];
        String propertyName = propertyNamePart.trim();
        boolean isOut = false;
       
        if(propertyNamePart.startsWith("*")){
          isOut = true;
          propertyName = propertyNamePart.substring(1);
         
          outFieldMap.put(propertyName.toUpperCase(), Integer.valueOf(i));
        }
           
        token = token.replaceFirst((isOut ? "\\*" : "") + propertyName, "\\?");     
        realSql.append(token);
       
///System.out.println("\n\n ===================== real sql =========================\n  " + realSql);
       
        if (pstmt != null) {
          propertyName = propertyName.toUpperCase();
         
          Object value;
          if (rowSet != null)
            value = rowSet.getObject(propertyName);
          else
            value = cache.get(propertyName);
         
          Class type = (Class) propertyTypes.get(propertyName);
         
//          if ( tc != null && tc.getThreadId() != null && tc.isHasDML() ) {
//            apprLogger.warn("sql update value : " + value);
//          }         
         
          boolean failToFindInMethods = false;
         
          if (type == null)
            failToFindInMethods = true;
          if (type == null && value != null)
            type = value.getClass();
         
          if (isOut) {
            CallableStatement cstmt = (CallableStatement) pstmt;
            if (type == String.class) {
              cstmt.registerOutParameter(i, Types.VARCHAR);
            } else if (Number.class.isAssignableFrom(type)) {
              cstmt.registerOutParameter(i, Types.BIGINT);
            } else if (type == java.util.Date.class) {
              cstmt.registerOutParameter(i, Types.DATE);
            }
          } else {
            try{                       
              if (type == String.class) {
                pstmt.setString(i, (String) value);
              } else if (type != null && Number.class.isAssignableFrom(type)) {
                if (value != null) {
                  Number numberValue;
                  if (value instanceof Boolean) {
                    numberValue = Long.valueOf(((Boolean)value).booleanValue() ? 1 : 0);
                  } else {
                    if (value instanceof String)
                    try {
                      value = Long.valueOf((String)value);
                    } catch (Exception e) {
                    }
                   
                    numberValue = (Number)value;
                  }
             
                  pstmt.setLong(i, numberValue.longValue());
                } else
                  pstmt.setNull(i, Types.BIGINT);
               
              } else if (type != null && java.util.Date.class.isAssignableFrom(type)) {
                if (value != null) {
                  java.util.Date dateValue = (java.util.Date)value;
           
                  long timeInMS = dateValue.getTime();
                  value = new Timestamp(timeInMS);              
                }
             
                pstmt.setTimestamp(i, (Timestamp)value);                         
              } else if ( type != null && (Boolean.class.isAssignableFrom(type) || boolean.class == type)) {
                Boolean booleanValue = Boolean.valueOf(false);
                if ( value != null) {
                  if(value instanceof Boolean)
                    booleanValue = (Boolean)value;
                  else if(value instanceof Number)
                    booleanValue = Boolean.valueOf(((Number)value).intValue() == 1);
                }
                // 0 : false, 1 : true  [default : 0]
                pstmt.setInt(i, (booleanValue.booleanValue())?1:0);
              } else {   
               
/*                if(value instanceof java.util.Date && DAOFactory.getInstance().getDBMSProductName().equals("`")){
                  pstmt.setTimestamp(i, new Timestamp(((java.util.Date)value).getTime()));
                }
*/               
                pstmt.setObject(i, value);
              }
             
            }catch(java.sql.SQLException sqlException){
              String additionalInfo = "";
              if(failToFindInMethods && value == null)
                additionalInfo = "Make sure that the property [" + propertyName + "] is declared as a setter/getter.";
                               
              throw new Exception("GenericDAO ["+ daoClass.getName() +"] failed to bind value [" + value + "] to field [" + propertyName + "]. " + additionalInfo, sqlException);
            }
          }
        }
      }
    }
   
    return realSql.toString();
    }
   
  public Object invoke(Object proxy, Method m, Object[] argsthrows Throwable{
    String methodName = m.getName();
   
    if(m.getName().equals("getImplementationObject")){
      return getImplementationObject();
    }
   
    //if getter
    if(m.getName().startsWith("get")){
      String propertyName = methodName.substring(3).toUpperCase();
      propertyName = replaceReservedKeyword(propertyName);

      if(propertyName.length()==0 && args.length==1){//from untyped DAO's getter
        return get((String)args[0]);
      }else{//from typed DAO's getter
        Object returnValue;
           
        if(rowSet!=null) {
          if ( Boolean.class.isAssignableFrom(m.getReturnType()) ) {
            returnValue = Boolean.valueOf( (rowSet.getInt(propertyName)==1)?true:false );
          } else {
            if (m.getName().equals("getInt") || 
                m.getName().equals("getLong") ||
                m.getName().equals("getBoolean") ||
                m.getName().equals("getDate") ||
                m.getName().equals("getString")) {
              try{
                return m.invoke(this, args);   
              }catch(Exception e){
                throw e.getCause();
              }
            }
            returnValue = rowSet.getObject(propertyName);
          }
        } else {
          if (args!=null && args.length==1 && args[0] instanceof String &&
              (m.getName().equals("getInt") || 
              m.getName().equals("getLong") ||
              m.getName().equals("getBoolean") ||
              m.getName().equals("getDate") ||
              m.getName().equals("getString"))
            )
          {
            propertyName = ((String) args[0]).toUpperCase();
          }
         
          returnValue = cache.get(propertyName);
        }
       
        // try to convert an integer value to proper mapping values for types
        if(returnValue instanceof Number){
          Number returnValueInNumber = (Number)returnValue;
          if(m.getReturnType() == Long.class || m.getReturnType() == long.class ){
            return Long.valueOf(returnValueInNumber.longValue());
          }
          if(m.getReturnType() == Integer.class || m.getReturnType() == int.class ){
            return Integer.valueOf(returnValueInNumber.intValue());
          }
          if(m.getReturnType() == Boolean.class || m.getReturnType() == boolean.class ){
            return Boolean.valueOf(returnValueInNumber.intValue() == 1);
          }
        }
       
        // try to null values into proper default primitive types' values
        if(returnValue == null){
          if(m.getReturnType() == boolean.class){
            return Boolean.valueOf(false);
          }         
          if(m.getReturnType() == int.class){
            return Integer.valueOf(0);
          }         
          if(m.getReturnType() == long.class){
            return Long.valueOf(0);
          }         
        }
       
        //  try to parse the string value into integer type.
        if(returnValue instanceof String){
          if(m.getReturnType() == int.class || Integer.class.isAssignableFrom(m.getReturnType())){
            try{
              return new Integer((String)returnValue);
            }catch(Exception e){
            }
          } 
         
          if(m.getReturnType() == long.class || Long.class.isAssignableFrom(m.getReturnType())){
            try{
              return new Long((String)returnValue);
            }catch(Exception e){
            }
          }
        }
       
        //primitive type mappings
        if(returnValue instanceof Boolean && m.getReturnType() == boolean.class){
          return returnValue;
        }
       
        if(returnValue instanceof Number && (m.getReturnType() == int.class || m.getReturnType() == long.class)){
          return returnValue;
        }
        //end
         
        if(returnValue!=null && !m.getReturnType().isAssignableFrom(returnValue.getClass())){
          throw new Exception("DAO's field type of '"+propertyName+"' is mismatch with the actual table's field.");
        }
       
        return returnValue;
      }
    }else
    //if setter
    if(m.getName().startsWith("set")){
      isDirty = true;
     
      String propertyName = methodName.substring(3);
     
      propertyName = replaceReservedKeyword(propertyName);
     
      if(modifiedFieldMap==null) modifiedFieldMap = new HashMap();
      modifiedFieldMap.put(propertyName.toUpperCase(), propertyName);
     
      if(rowSet!=null){
        cache.clear();
        ResultSetMetaData rsMetaData = rowSet.getMetaData();
        for(int i=1; i<=rsMetaData.getColumnCount(); i++){
          String propName = rsMetaData.getColumnName(i);
          cache.put(propName.toUpperCase(), rowSet.getObject(i));
        }
       
        rowSet = null;
      }
     
      if(propertyName.length()==0 && args.length==2){
        propertyName = args[0].toString().toUpperCase();
        cache.put(propertyName, args[1]);
      }else{//TODO: type check for typed DAO        
        cache.put(propertyName.toUpperCase(), args[0]);
      }
     
//      else
//        pstmt.setObject(order, args[0]);
     
      if(modifiedFieldMap==null) modifiedFieldMap = new HashMap();
      modifiedFieldMap.put(propertyName.toUpperCase(), propertyName);
     

      return null;

    }else{
      try{
        return m.invoke(this, args);
       
      }catch(Exception e){
        throw e.getCause();
      }
    }
  }
 
 
  @SuppressWarnings("deprecation")
  public static String replaceReservedKeyword(String propertyName) {
    try {
      if(DAOFactory.getInstance().getDBMSProductName().equals("Cubrid")) {
        if (
            "alias".equalsIgnoreCase(propertyName) ||
            "value".equalsIgnoreCase(propertyName) ||
            "day".equalsIgnoreCase(propertyName)
        ) {
          propertyName = propertyName + "_";
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
   
    return propertyName;
  }
 
  public static IDAO createDAOImpl(String jndiName, String sqlStmt, Class daoClass) throws Exception{   
    return (IDAO)Proxy.newProxyInstance(
      daoClass.getClassLoader(),
      new Class[]{daoClass},
      new GenericDAO(jndiName, sqlStmt, daoClass)
    );   
  }
 
  public AbstractGenericDAO getImplementationObject(){
    return this;
  }

//  /**
//   * @deprecated
//   */
//  public static IDAO createDAOImpl(Connection conn, String sqlStmt, Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      daoClass.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(conn, sqlStmt, daoClass)
//    );   
//  }
 
//  public static IDAO createDAOImpl(String jndiName, String selectSqlStmt, String insertSqlStmt, String updateSqlStmt, Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      daoClass.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(jndiName, selectSqlStmt, insertSqlStmt, updateSqlStmt, daoClass)
//    );   
//  }
//
//  public static IDAO createDAOImpl(ConnectionFactory conn, String selectSqlStmt, String insertSqlStmt, String updateSqlStmt, Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      daoClass.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(conn, selectSqlStmt, insertSqlStmt, updateSqlStmt, daoClass)
//    );   
//  }

//  public static IDAO createDAOImpl(ConnectionFactory conn, String sqlStmt, Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      daoClass.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(conn, sqlStmt, daoClass)
//    );   
//  }
//
//  public static IDAO createDAOImpl(ConnectionFactory conn, String sqlStmt) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      IDAO.class.getClassLoader(),
//      new Class[]{IDAO.class},
//      new GenericDAO(conn, sqlStmt, IDAO.class)
//    );
//  }
//
//  public static IDAO createDAOImpl(String sqlStmt, Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      IDAO.class.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(new ConnectionFactory(), sqlStmt, daoClass)
//    );
//  }
//
//  public static IDAO createDAOImpl() throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      IDAO.class.getClassLoader(),
//      new Class[]{IDAO.class},
//      new GenericDAO(IDAO.class)
//    );
//  }
//
//  public static IDAO createDAOImpl(Class daoClass) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      IDAO.class.getClassLoader(),
//      new Class[]{daoClass},
//      new GenericDAO(daoClass)
//    );
//  }
//
//  public static IDAO createDAOImpl(String sqlStmt) throws Exception{   
//    return (IDAO)Proxy.newProxyInstance(
//      IDAO.class.getClassLoader(),
//      new Class[]{IDAO.class},
//      new GenericDAO(new ConnectionFactory(), sqlStmt, IDAO.class)
//    );
//  }

  public Object get(String propertyName) throws Exception {
    propertyName = propertyName.toUpperCase();
   
    if(rowSet!=null)
      return rowSet.getObject(propertyName);
    else
      return cache.get(propertyName);
  }

  public Object set(String propertyName, Object value) throws Exception {
    isDirty = true;
   
    if(modifiedFieldMap==null) modifiedFieldMap = new HashMap();
    modifiedFieldMap.put(propertyName.toUpperCase(), propertyName);
   
    if(rowSet!=null){
      cache.clear();
      ResultSetMetaData rsMetaData = rowSet.getMetaData();
      for(int i=1; i<=rsMetaData.getColumnCount(); i++){
        String propName = rsMetaData.getColumnName(i);
        cache.put(propName.toUpperCase(), rowSet.getObject(i));
      }
     
      rowSet = null;
    }
   
    return cache.put(propertyName.toUpperCase(), value);
  }
 

  public String getStatement() {
    return sqlStmt.toUpperCase(); //
  }
 
  public void setStatement(String sql) {
//    System.out.println("set SqlStmt : " + sql);
    this.sqlStmt = sql;
  }

  public RowSet getRowSet(){
    return rowSet;
  }
 


  public String toString(){
    StringBuffer sb = new StringBuffer();
      Iterator i = propertyTypes.keySet().iterator();
      while (i.hasNext()) {
        String propertyName = (String) i.next();
       
        Object value = null;
        try{
          value = get(propertyName);
        }catch(Exception e){
        }
       
        if (sb.length() > 0) sb.append(", ");
        sb.append(propertyName).append("=").append(value);
    };
   
    return sb.toString();
  }
 
}

/*
* $Log: AbstractGenericDAO.java,v $
* Revision 1.33  2010/04/08 01:27:21  allbegray
* *** empty log message ***
*
* Revision 1.32  2010/04/06 08:58:35  allbegray
* *** empty log message ***
*
* Revision 1.29  2010/01/25 13:30:13  pongsor
* patch for problem on reused DAO, which has its values in cache, doesn't support the unnamed and method name-typed call
*
* Revision 1.28  2009/06/16 09:02:25  erim79
* *** empty log message ***
*
* Revision 1.27  2009/04/15 09:17:04  kmooje
* *** empty log message ***
*
* Revision 1.26  2009/01/05 09:08:01  curonide
* *** empty log message ***
*
* Revision 1.25  2008/10/02 15:59:39  pongsor
* *** empty log message ***
*
* Revision 1.24  2008/03/24 02:14:43  pongsor
* WS-AT Support
*
* Revision 1.23  2008/03/19 13:18:11  pongsor
* *** empty log message ***
*
* Revision 1.22  2007/12/05 02:31:36  curonide
* *** empty log message ***
*
* Revision 1.5  2007/12/04 07:34:44  bpm
* *** empty log message ***
*
* Revision 1.3  2007/12/04 05:25:44  bpm
* *** empty log message ***
*
* Revision 1.21  2007/09/14 10:23:11  pongsor
* *** empty log message ***
*
* Revision 1.20  2007/01/16 22:31:35  pongsor
* Popup Subprocess Drilling down
*
* Revision 1.18  2007/01/12 06:39:09  pongsor
* 1. Connection Leakage Detector
* 2. Transaction Demarcation Support for External connection
* 4. DRoolsActivity has been enhanced
*
* Revision 1.17  2006/12/18 08:07:36  pongsor
* *** empty log message ***
*
* Revision 1.16  2006/12/06 06:00:10  pongsor
* *** empty log message ***
*
* Revision 1.15  2006/12/05 02:21:23  pongsor
* *** empty log message ***
*
* Revision 1.14  2006/12/04 13:46:19  pongsor
* *** empty log message ***
*
* Revision 1.13  2006/11/30 11:40:36  pongsor
* *** empty log message ***
*
* Revision 1.12  2006/11/28 04:23:36  iseenote
* *** empty log message ***
*
* Revision 1.11  2006/11/23 05:06:17  pongsor
* *** empty log message ***
*
* Revision 1.10  2006/11/21 07:05:08  pongsor
* *** empty log message ***
*
* Revision 1.9  2006/10/16 04:49:29  pongsor
* 2.0.2_02
*
* Revision 1.8  2006/09/14 01:16:48  pongsor
* uE 2.0_03
*
* Revision 1.7  2006/09/02 06:28:40  pongsor
* *** empty log message ***
*
* Revision 1.6  2006/08/10 05:21:53  pongsor
* ue20 final
*
* Revision 1.5  2006/07/17 09:03:15  pongsor
* - Multi-lingual support
* - Compensation Handler Event is added to ScopeActivity
*
* Revision 1.4  2006/07/17 03:20:22  pongsor
* *** empty log message ***
*
* Revision 1.2  2006/07/07 01:53:22  pongsor
* 1. Database Synchronized Process Variable
* 2. Customizable Instance List Feature is added
* 3. 'Key' field name has been renamed as 'KeyName' in the ProcessVariable table since the 'key' is a reserved word in MySQL.
*
* Revision 1.1  2006/06/17 07:51:26  pongsor
* uEngine 2.0
*
* Revision 1.25  2006/04/06 02:35:42  phz
* 1. back ó�� ���
*
* 2. insert �� rowSet; Ŭ���� ���� �ʵ��� ��d
*
* Revision 1.24  2006/03/31 08:31:53  phz
* Ȯ�� �� ����ϰ�=.
*
* Revision 1.23  2006/03/31 00:46:17  uengine
* [Definition Synchronizer] Addition of a tool for synchronizing definition data between the development system and the production system. Note that a few associated changes for implementing the tool are applied to GenericDAO framework.
*
* Revision 1.22  2006/03/18 08:24:37  cidea429
* log4j ��� ��d
*
* Revision 1.21  2006/03/12 09:15:24  ghbpark
* *** empty log message ***
*
* Revision 1.20  2006/03/11 05:57:22  ghbpark
* *** empty log message ***
*
* Revision 1.19  2006/02/28 03:25:18  ghbpark
* *** empty log message ***
*
* Revision 1.18  2006/01/27 08:21:54  ghbpark
* *** empty log message ***
*
* Revision 1.17  2006/01/24 10:19:36  uengine
* [���߷Ѱ�] ����
* [�� ���� ij��]
* [��ũ������] ���� ó��
*
* Revision 1.16  2006/01/06 18:48:00  ghbpark
* *** empty log message ***
*
* Revision 1.15  2005/12/07 06:57:02  uengine
* *** empty log message ***
*
* Revision 1.14  2005/12/06 05:19:21  uengine
* *** empty log message ***
*
* Revision 1.13  2005/11/16 23:55:10  southshine
* *** empty log message ***
*
* Revision 1.12  2005/11/04 11:05:26  phz
* phz
*
* Revision 1.11  2005/10/21 07:15:21  ghbpark
* *** empty log message ***
*
* Revision 1.10  2005/10/21 06:11:40  ghbpark
* *** empty log message ***
*
* Revision 1.9  2005/10/21 05:01:43  ghbpark
* *** empty log message ***
*
* Revision 1.8  2005/10/19 14:25:01  ghbpark
* *** empty log message ***
*
* Revision 1.7  2005/10/05 10:58:42  alcolins
* *** empty log message ***
*
* Revision 1.6  2005/10/05 08:29:43  ghbpark
* .
*
* Revision 1.5  2005/10/05 08:00:16  ghbpark
* .
*
* Revision 1.4  2005/09/28 02:42:42  khw
* *** empty log message ***
*
* Revision 1.3  2005/09/27 13:09:48  uengine
* ������ ��Ű�� �ݿ�
*
* Revision 1.2  2005/09/07 07:04:17  ghbpark
* .
*
* Revision 1.1  2005/09/06 07:08:15  ghbpark
* EagleBPM 2.0 start
*
* Revision 1.5  2005/05/09 01:37:01  ghbpark
* *** empty log message ***
*
* Revision 1.4  2005/04/11 10:48:50  ghbpark
* *** empty log message ***
*
* Revision 1.3  2005/04/11 10:45:17  uengine
* *** empty log message ***
*
* Revision 1.12.2.1  2005/03/28 02:14:10  uengine
* *** empty log message ***
*
* Revision 1.12  2005/03/08 10:57:00  uengine
* *** empty log message ***
*
* Revision 1.11  2005/02/28 05:04:15  uengine
* *** empty log message ***
*
* Revision 1.10  2005/02/24 05:32:33  uengine
* *** empty log message ***
*
* Revision 1.9  2005/02/23 01:27:09  uengine
* *** empty log message ***
*
* Revision 1.8  2005/02/17 05:22:54  uengine
* *** empty log message ***
*
* Revision 1.7  2005/02/16 07:43:43  ghbpark
* *** empty log message ***
*
* Revision 1.6  2005/02/11 08:00:13  uengine
* *** empty log message ***
*
* Revision 1.5  2005/02/02 06:12:04  uengine
* *** empty log message ***
*
* Revision 1.4  2005/01/20 02:51:15  uengine
* �wμ��� �ν��Ͻ��� shot; hashtable(serializable)�ϰ� ��; �� �ֵ��� �����Ͽ� ��: ���� �wμ��� ��� �����; v���Ͽ� �����ִ� viewer��� ����ս��� ���� �� ��=..
*
* - 1ȸ ��� ���ؼ� shotcopy�� ���Ͽ� ����ս� ��=
* - viewer�� shot; ���� �����ϰ� �Ͽ� ����ս��� ��=
* - ProcessManagerRemote.getProcessInstance(String instanceId)�� ���� remote�� ��; �� ��=
*
* Revision 1.3  2004/12/31 00:57:55  uengine
* *** empty log message ***
*
* Revision 1.2  2004/12/28 03:01:41  uengine
* *** empty log message ***
*
* Revision 1.4  2004/12/01 11:39:27  pongsor
* *** empty log message ***
*
* Revision 1.3  2004/11/12 04:41:21  pongsor
* *** empty log message ***
*
* Revision 1.2  2004/11/05 09:54:31  pongsor
* *** empty log message ***
*
* Revision 1.1  2004/11/03 23:38:55  pongsor
* *** empty log message ***
*
* Revision 1.7  2003/12/01 08:38:25  ghbpark
* first() �޼ҵ� ���� �߰�
*
* Revision 1.6  2003/11/27 06:54:24  ghbpark
* previous() �޼ҵ� �߰�
*
* Revision 1.5  2003/11/06 11:08:40  ghbpark
* Ŀ���� 'ġ�� ó=8�� �̵���Ű�� �޼ҵ� �߰�
*
* Revision 1.4  2003/10/10 10:55:52  winman
* *** empty log message ***
*
* Revision 1.3  2003/10/01 09:08:36  ghbpark
* size() �޼ҵ� �߰�
* -> RowSet�� ���ڵ� �� ����
*
* Revision 1.2  2003/09/30 15:30:37  ghbpark
* *** empty log message ***
*
* Revision 1.1  2003/09/29 11:51:01  ghbpark
* ���� DAO �� ���� ��f �߰�
*
*/
TOP

Related Classes of org.uengine.util.dao.AbstractGenericDAO

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.