Package com.ibatis.sqlmap.engine.mapping.sql.dynamic

Source Code of com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql

package com.ibatis.sqlmap.engine.mapping.sql.dynamic;

import com.ibatis.sqlmap.engine.builder.InlineParameterMapParser;
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
import com.ibatis.sqlmap.engine.mapping.sql.SqlChild;
import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.*;
import com.ibatis.sqlmap.engine.mapping.sql.simple.SimpleDynamicSql;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.type.TypeHandlerRegistry;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DynamicSql implements Sql, DynamicParent {

  private List children = new ArrayList();

  private ThreadLocal<SqlTagContext> sqlTagContext = new ThreadLocal<SqlTagContext>();

  private Configuration configuration;
  private TypeHandlerRegistry typeHandlerRegistry;
  private List<ParameterMapping> parameterMappings;

  public DynamicSql(Configuration configuration) {
    this.parameterMappings = new ArrayList<ParameterMapping>();
    this.configuration = configuration;
    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
  }

  public String getSql(Object parameterObject) {
    if (sqlTagContext.get() == null) {
      sqlTagContext.set(process(parameterObject));
    }
    return sqlTagContext.get().getDynamicSql();
  }

  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
    if (sqlTagContext.get() == null) {
      sqlTagContext.set(process(parameterObject));
    }
    return sqlTagContext.get().getParameterMappings();
  }

  private SqlTagContext process(Object parameterObject) {
    SqlTagContext ctx = new SqlTagContext();
    List localChildren = children;
    processBodyChildren(ctx, parameterObject, localChildren.iterator());

    String dynSql = ctx.getBodyText();

    // Processes $substitutions$ after DynamicSql
    if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) {
      dynSql = new SimpleDynamicSql(dynSql, ctx.getParameterMappings(), typeHandlerRegistry).getSql(parameterObject);
    }

    ctx.setDynamicSql(dynSql);
    for (ParameterMapping mapping : parameterMappings) {
      ctx.addParameterMapping(mapping);
    }
    return ctx;
  }

  private void processBodyChildren(SqlTagContext ctx, Object parameterObject, Iterator localChildren) {
    PrintWriter out = ctx.getWriter();
    processBodyChildren(ctx, parameterObject, localChildren, out);
  }

  private void processBodyChildren(SqlTagContext ctx, Object parameterObject, Iterator localChildren, PrintWriter out) {
    while (localChildren.hasNext()) {
      SqlChild child = (SqlChild) localChildren.next();
      if (child instanceof SqlText) {
        SqlText sqlText = (SqlText) child;
        String sqlStatement = sqlText.getText();
        if (sqlText.isWhiteSpace()) {
          out.print(sqlStatement);
        } else if (!sqlText.isPostParseRequired()) {

          // BODY OUT
          out.print(sqlStatement);

          List<ParameterMapping> mappings = sqlText.getParameterMappings();
          if (mappings != null) {
            for (int i = 0, n = mappings.size(); i < n; i++) {
              ctx.addParameterMapping(mappings.get(i));
            }
          }
        } else {

          IterateContext itCtx = ctx.peekIterateContext();

          if (null != itCtx && itCtx.isAllowNext()) {
            itCtx.next();
            itCtx.setAllowNext(false);
            if (!itCtx.hasNext()) {
              itCtx.setFinal(true);
            }
          }

          if (itCtx != null) {
            StringBuffer sqlStatementBuffer = new StringBuffer(sqlStatement);
            iteratePropertyReplace(sqlStatementBuffer, itCtx);
            sqlStatement = sqlStatementBuffer.toString();
          }

          sqlText = new InlineParameterMapParser(configuration).parseInlineParameterMap(sqlStatement);

          List<ParameterMapping> mappings = sqlText.getParameterMappings();
          out.print(sqlText.getText());
          if (mappings != null) {
            for (int i = 0, n = mappings.size(); i < n; i++) {
              ctx.addParameterMapping(mappings.get(i));
            }
          }
        }
      } else if (child instanceof SqlTag) {
        SqlTag tag = (SqlTag) child;
        SqlTagHandler handler = tag.getHandler();
        int response;
        do {
          StringWriter sw = new StringWriter();
          PrintWriter pw = new PrintWriter(sw);

          response = handler.doStartFragment(ctx, tag, parameterObject);
          if (response != SqlTagHandler.SKIP_BODY) {

            processBodyChildren(ctx, parameterObject, tag.getChildren(), pw);
            pw.flush();
            pw.close();
            StringBuffer body = sw.getBuffer();
            response = handler.doEndFragment(ctx, tag, parameterObject, body);
            handler.doPrepend(ctx, tag, parameterObject, body);

            if (response != SqlTagHandler.SKIP_BODY) {
              if (body.length() > 0) {
                out.print(body.toString());
              }
            }

          }
        } while (response == SqlTagHandler.REPEAT_BODY);

        ctx.popRemoveFirstPrependMarker(tag);

        if (ctx.peekIterateContext() != null && ctx.peekIterateContext().getTag() == tag) {
          ctx.setAttribute(ctx.peekIterateContext().getTag(), null);
          ctx.popIterateContext();
        }

      }
    }
  }

  protected void iteratePropertyReplace(StringBuffer bodyContent, IterateContext iterate) {
    if (iterate != null) {
      String[] mappings = new String[]{"#", "$"};
      for (String mapping : mappings) {
        int startIndex = 0;
        int endIndex = -1;
        while (startIndex > -1 && startIndex < bodyContent.length()) {
          startIndex = bodyContent.indexOf(mapping, endIndex + 1);
          endIndex = bodyContent.indexOf(mapping, startIndex + 1);
          if (startIndex > -1 && endIndex > -1) {
            String replacement = iterate.addIndexToTagProperty(bodyContent.substring(startIndex + 1, endIndex));
            bodyContent.replace(startIndex + 1, endIndex, replacement);
          }
        }
      }
    }
  }

  protected static void replace(StringBuffer buffer, String find, String replace) {
    int pos = buffer.toString().indexOf(find);
    int len = find.length();
    while (pos > -1) {
      buffer.replace(pos, pos + len, replace);
      pos = buffer.toString().indexOf(find);
    }
  }

  public void addChild(SqlChild child) {
    children.add(child);
  }

}
TOP

Related Classes of com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql

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.