Package com.ibatis.sqlmap.engine.binding

Source Code of com.ibatis.sqlmap.engine.binding.MapperCommand

package com.ibatis.sqlmap.engine.binding;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapException;
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
import com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement;
import com.ibatis.sqlmap.engine.mapping.statement.StatementType;

import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class MapperCommand {

  private SqlMapClient client;
  private SqlMapExecutorDelegate delegate;

  private boolean hasSuppliedValueObject;

  private Method method;
  private int argCount;

  private boolean returnsList;
  private boolean hasListBounds;
  private boolean hasPageSize;

  private boolean returnsMap;
  private boolean hasMapValueKey;

  private StatementType type;
  private String statementName;
  private Class parameterClass;
  private Class resultClass;

  public MapperCommand(Method method, SqlMapClient client) {

    this.client = client;
    this.method = method;

    setupFields();
    determineStatementType();
    determineSelectMethod();
    validateStatement();
    validateResult();
    validateParameter();
  }

  private void setupFields() {
    this.statementName = method.getName();
    this.delegate = ((ExtendedSqlMapClient) client).getDelegate();
    GeneralStatement statement = (GeneralStatement) delegate.getMappedStatement(statementName);

    this.parameterClass = statement.getParameterClass();
    this.resultClass = statement.getResultMap() == null ? null : statement.getResultMap().getResultClass();
    this.type = statement.getStatementType();

    this.argCount = method.getParameterTypes().length;

  }

  private void determineStatementType() {
    // If proc or unkown, determine which type of statement we should execute using method names
    if (StatementType.PROCEDURE == type || StatementType.UNKNOWN == type) {
      if (statementName.startsWith("insert")) {
        type = StatementType.INSERT;
      } else if (statementName.startsWith("create")) {
        type = StatementType.INSERT;
      } else if (statementName.startsWith("update")) {
        type = StatementType.UPDATE;
      } else if (statementName.startsWith("save")) {
        type = StatementType.UPDATE;
      } else if (statementName.startsWith("delete")) {
        type = StatementType.DELETE;
      } else if (statementName.startsWith("remove")) {
        type = StatementType.DELETE;
      } else if (statementName.startsWith("select")) {
        type = StatementType.SELECT;
      } else if (statementName.startsWith("query")) {
        type = StatementType.SELECT;
      } else if (statementName.startsWith("get")) {
        type = StatementType.SELECT;
      } else if (statementName.startsWith("fetch")) {
        type = StatementType.SELECT;
      }
    }
  }

  private void determineSelectMethod() {
    if (StatementType.SELECT == type) {
      if (List.class.isAssignableFrom(method.getReturnType())) {
        // queryForList
        returnsList = true;
        if (argCount == 2) {
          hasPageSize = true;
        } else if (argCount == 3) {
          hasListBounds = true;
        }
      } else if (Map.class.isAssignableFrom(method.getReturnType())
          && argCount > 1
          && String.class.isAssignableFrom(method.getParameterTypes()[1])) {
        // queryForMap
        if (argCount == 2) {
          returnsMap = true;
          hasMapValueKey = false;
        } else if (argCount == 3) {
          returnsMap = true;
          hasMapValueKey = true;
        }
      } else {
        // queryForObject
        if (argCount == 2) {
          hasSuppliedValueObject = true;
        }
      }
    }
  }

  private void validateStatement() {
    try {
      delegate.getMappedStatement(statementName);
    } catch (Exception e) {
      throw new SqlMapException("Invalid bound statement (not found): " + statementName);
    }

    if (StatementType.UNKNOWN == type || StatementType.PROCEDURE == type) {
      throw new SqlMapException("Unkown statement type for statement: " + statementName);
    }
  }

  private void validateResult() {
    if (!returnsList && !returnsMap) {
//      if (method.getReturnType() == null || method.getReturnType() == Class.class) {
//        // Make sure both aren't null
//        if (resultClass != null) {
//          throw new SqlMapException("Invalid bound result for statement (mismatched null/void): " + statementName);
//        }
//      } else if (resultClass == null) {
//        // Make sure both aren't null
//        if (method.getReturnType() != null || method.getReturnType() == Class.class) {
//          System.out.println (method.getReturnType().getClass());
//          throw new SqlMapException("Invalid bound result for statement (mismatched null/void): " + statementName);
//        }
//      } else {
//        // Make sure types are compatible
//        if (!method.getReturnType().isAssignableFrom(resultClass)) {
//          throw new SqlMapException("Invalid bound result for statement (incompatible types): " + statementName);
//        }
//      }
    }
  }

  private void validateParameter() {
    if (argCount > 0) {
      // Make sure types are compatible
      Class paramType = method.getParameterTypes()[0];
      if (parameterClass != null) {
//        if (!parameterClass.isAssignableFrom(paramType.getClass())) {
//          throw new SqlMapException("Invalid bound parameter for statement (incompatible types): " + statementName);
//        }
      }
    }
    if (argCount > 1 && type != StatementType.SELECT) {
      // Only select statements can have multiple parameters
      throw new SqlMapException("Too many parameters for statement (must be 1 or 0): " + statementName);
    }
  }

  public Object execute(Object[] args) throws SQLException {
    Object result = null;
    if (StatementType.INSERT == type) {
      Object param = getParam(args);
      result = client.insert(statementName, param);
    } else if (StatementType.UPDATE == type) {
      Object param = getParam(args);
      result = new Integer(client.update(statementName, param));
    } else if (StatementType.DELETE == type) {
      Object param = getParam(args);
      result = new Integer(client.delete(statementName, param));
    } else if (StatementType.SELECT == type) {
      if (returnsList) {
        result = executeForList(args);
      } else if (returnsMap) {
        result = executeForMap(args);
      } else {
        result = executeForObject(args);
      }
    } else {
      throw new SqlMapException("Unkown execution method for: " + statementName);
    }

    return result;
  }

  private Object executeForObject(Object[] args) throws SQLException {
    Object result;
    if (hasSuppliedValueObject) {
      Object param = getParam(args);
      Object valueObject = args[1];
      result = client.queryForObject(statementName, param, valueObject);
    } else {
      Object param = getParam(args);
      result = client.queryForObject(statementName, param);
    }
    return result;
  }

  private Object executeForMap(Object[] args) throws SQLException {
    Object result;
    if (hasMapValueKey) {
      Object param = getParam(args);
      String keyProp = (String) args[1];
      String valueProp = (String) args[2];
      result = client.queryForMap(statementName, param, keyProp, valueProp);
    } else {
      Object param = getParam(args);
      String keyProp = (String) args[1];
      result = client.queryForMap(statementName, param, keyProp);
    }
    return result;
  }

  private Object executeForList(Object[] args) throws SQLException {
    Object result;
    if (hasListBounds) {
      Object param = getParam(args);
      int skip = ((Integer) args[1]).intValue();
      int max = ((Integer) args[2]).intValue();
      result = client.queryForList(statementName, param, skip, max);
    } else if (hasPageSize) {
      Object param = getParam(args);
      int pageSize = ((Integer) args[1]).intValue();
      result = client.queryForPaginatedList(statementName, param, pageSize);
    } else {
      Object param = getParam(args);
      result = client.queryForList(statementName, param);
    }
    return result;
  }

  private Object getParam(Object[] args) {
    if (args == null) {
      return null;
    }
    return args.length > 0 ? args[0] : null;

  }

}
TOP

Related Classes of com.ibatis.sqlmap.engine.binding.MapperCommand

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.