Package com.ibatis.sqlmap.engine.builder

Source Code of com.ibatis.sqlmap.engine.builder.XmlSqlStatementParser

package com.ibatis.sqlmap.engine.builder;

import com.ibatis.sqlmap.client.SqlMapException;
import com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.parsing.XNode;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class XmlSqlStatementParser {

  private XmlSqlMapParser mapParser;
  private Ibatis2Configuration configuration;

  public XmlSqlStatementParser(XmlSqlMapParser mapParser) {
    this.mapParser = mapParser;
    this.configuration = mapParser.getConfigParser().getConfiguration();
  }

  public void parseGeneralStatement(XNode context) {
    // get attributes
    String id = context.getStringAttribute("id");
    String parameterMapName = context.getStringAttribute("parameterMap");
    String parameterClassName = context.getStringAttribute("parameterClass");
    String resultMapName = context.getStringAttribute("resultMap");
    String resultClassName = context.getStringAttribute("resultClass");
    String cacheModelName = context.getStringAttribute("cacheModel");
    String resultSetType = context.getStringAttribute("resultSetType");
    String fetchSize = context.getStringAttribute("fetchSize");
    String timeout = context.getStringAttribute("timeout");
    // 2.x -- String allowRemapping = context.getStringAttribute("remapResults");

    if (context.getStringAttribute("xmlResultName") != null) {
      throw new UnsupportedOperationException("xmlResultName is not supported by iBATIS 3");
    }

    if (mapParser.getConfigParser().isUseStatementNamespaces()) {
      id = mapParser.applyNamespace(id);
    }

    String[] additionalResultMapNames = null;
    if (resultMapName != null) {
      additionalResultMapNames = getAllButFirstToken(resultMapName);
      resultMapName = getFirstToken(resultMapName);
      resultMapName = mapParser.applyNamespace(resultMapName);
      for (int i = 0; i < additionalResultMapNames.length; i++) {
        additionalResultMapNames[i] = mapParser.applyNamespace(additionalResultMapNames[i]);
      }
    }

    String[] additionalResultClassNames = null;
    if (resultClassName != null) {
      additionalResultClassNames = getAllButFirstToken(resultClassName);
      resultClassName = getFirstToken(resultClassName);
    }
    Class[] additionalResultClasses = null;
    if (additionalResultClassNames != null) {
      additionalResultClasses = new Class[additionalResultClassNames.length];
      for (int i = 0; i < additionalResultClassNames.length; i++) {
        additionalResultClasses[i] = resolveClass(additionalResultClassNames[i]);
      }
    }

    Integer timeoutInt = timeout == null ? null : new Integer(timeout);
    Integer fetchSizeInt = fetchSize == null ? null : new Integer(fetchSize);

    // 2.x -- boolean allowRemappingBool = "true".equals(allowRemapping);

    SqlSource sqlSource = new SqlSourceFactory(mapParser).newSqlSourceIntance(mapParser, context);

    String nodeName = context.getNode().getNodeName();
    SqlCommandType sqlCommandType;
    try {
      sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase());
    } catch (Exception e) {
      sqlCommandType = SqlCommandType.UNKNOWN;
    }


    MappedStatement.Builder builder = new MappedStatement.Builder(configuration, id, sqlSource,sqlCommandType);

    builder.useCache(true);
    if (!"select".equals(context.getNode().getNodeName())) {
      builder.flushCacheRequired(true);
    }

    if (parameterMapName != null) {
      parameterMapName = mapParser.applyNamespace(parameterMapName);
      builder.parameterMap(configuration.getParameterMap(parameterMapName));
    } else if (parameterClassName != null) {
      Class parameterClass = resolveClass(parameterClassName);
      List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
      if (sqlSource instanceof SimpleSqlSource) {
        parameterMappings = sqlSource.getBoundSql(null).getParameterMappings();
      }
      ParameterMap.Builder parameterMapBuilder = new ParameterMap.Builder(configuration, id + "-ParameterMap", parameterClass, parameterMappings);
      builder.parameterMap(parameterMapBuilder.build());
    }

    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
    if (resultMapName != null) {
      resultMaps.add(configuration.getResultMap(resultMapName));
      if (additionalResultMapNames != null) {
        for (String additionalResultMapName : additionalResultMapNames) {
          resultMaps.add(configuration.getResultMap(additionalResultMapName));
        }
      }
    } else if (resultClassName != null) {
      Class resultClass = resolveClass(resultClassName);
      ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration, id + "-ResultMap", resultClass, new ArrayList<ResultMapping>());
      resultMaps.add(resultMapBuilder.build());
      if (additionalResultClasses != null) {
        for (Class additionalResultClass : additionalResultClasses) {
          resultMapBuilder = new ResultMap.Builder(configuration, id + "-ResultMap", additionalResultClass, new ArrayList<ResultMapping>());
          resultMaps.add(resultMapBuilder.build());
        }
      }
    }
    builder.resultMaps(resultMaps);

    builder.fetchSize(fetchSizeInt);

    builder.timeout(timeoutInt);

    if (cacheModelName != null) {
      cacheModelName = mapParser.applyNamespace(cacheModelName);
      Cache cache = configuration.getCache(cacheModelName);
      builder.cache(cache);
    }

    if (resultSetType != null) {
      builder.resultSetType(ResultSetType.valueOf(resultSetType));
    }

    // allowRemappingBool -- silently ignored

    findAndParseSelectKey(id, context);

    configuration.addMappedStatement(builder.build());
  }

  private Class resolveClass(String resultClassName) {
    try {
      if (resultClassName != null) {
        return configuration.getTypeAliasRegistry().resolveAlias(resultClassName);
      } else {
        return null;
      }
    } catch (Exception e) {
      throw new SqlMapException("Error.  Could not initialize class.  Cause: " + e, e);
    }
  }

  private void findAndParseSelectKey(String parentId, XNode context) {
    try {
      boolean runStatementFirst = false;
      NodeList children = context.getNode().getChildNodes();
      for (int i = 0; i < children.getLength(); i++) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.CDATA_SECTION_NODE
            || child.getNodeType() == Node.TEXT_NODE) {
          String data = ((CharacterData) child).getData();
          if (data.trim().length() > 0) {
            runStatementFirst = true;
          }
        } else if (child.getNodeType() == Node.ELEMENT_NODE
            && "selectKey".equals(child.getNodeName())) {
          buildSelectKeyStatement(parentId, context.newXNode(child), runStatementFirst);

          break;
        }
      }
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Error loading result class.  Cause: " + e, e);
    }
  }

  public String getFirstToken(String s) {
    return new StringTokenizer(s, ", ", false).nextToken();
  }

  public String[] getAllButFirstToken(String s) {
    List strings = new ArrayList();
    StringTokenizer parser = new StringTokenizer(s, ", ", false);
    parser.nextToken();
    while (parser.hasMoreTokens()) {
      strings.add(parser.nextToken());
    }
    return (String[]) strings.toArray(new String[strings.size()]);
  }

  private void buildSelectKeyStatement(String parentId, XNode context, boolean runStatementFirstParam) throws ClassNotFoundException {
    final String keyPropName = context.getStringAttribute("keyProperty");
    String resultClassName = context.getStringAttribute("resultClass");
    final SimpleSqlSource source = new SimpleSqlSource(mapParser, context);

    final boolean runStatementFirst = "post".equalsIgnoreCase(context.getStringAttribute("type", runStatementFirstParam ? "post" : "pre"));
    final String keyStatementId = SqlMapSessionImpl.selectKeyIdFor(parentId);
    TypeHandler typeHandler = configuration.getTypeHandlerRegistry().getUnknownTypeHandler();
    if (resultClassName != null) {
      final Class resultClass = configuration.getTypeAliasRegistry().resolveAlias(resultClassName);
      typeHandler = configuration.getTypeHandlerRegistry().getTypeHandler(resultClass);
    }

    ResultMapping.Builder mappingBuilder = new ResultMapping.Builder(configuration, keyPropName, keyPropName, typeHandler);
    ArrayList<ResultMapping> resultMappingArrayList = new ArrayList<ResultMapping>();
    resultMappingArrayList.add(mappingBuilder.build());

    ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration, keyStatementId + "ResultMap", HashMap.class, resultMappingArrayList);
    ArrayList<ResultMap> resultMapList = new ArrayList<ResultMap>();
    resultMapList.add(resultMapBuilder.build());

    MappedStatement.Builder builder = new MappedStatement.Builder(configuration, keyStatementId, source, SqlCommandType.SELECT);
    builder.resultMaps(resultMapList);

    configuration.setPostSelectKey(keyStatementId, runStatementFirst);
    configuration.addMappedStatement(builder.build());
  }

}
TOP

Related Classes of com.ibatis.sqlmap.engine.builder.XmlSqlStatementParser

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.