Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql Maven / Gradle / Ivy
/*
* Copyright 2004-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibatis.sqlmap.engine.mapping.sql.dynamic;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
import com.ibatis.sqlmap.engine.mapping.parameter.InlineParameterMapParser;
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;
import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
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 com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.ibatis.sqlmap.engine.scope.StatementScope;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* The Class DynamicSql.
*/
public class DynamicSql implements Sql, DynamicParent {
/** The Constant PARAM_PARSER. */
private static final InlineParameterMapParser PARAM_PARSER = new InlineParameterMapParser();
/** The children. */
private List children = new ArrayList();
/** The delegate. */
private SqlMapExecutorDelegate delegate;
/**
* Instantiates a new dynamic sql.
*
* @param delegate
* the delegate
*/
public DynamicSql(SqlMapExecutorDelegate delegate) {
this.delegate = delegate;
}
public String getSql(StatementScope statementScope, Object parameterObject) {
String sql = statementScope.getDynamicSql();
if (sql == null) {
process(statementScope, parameterObject);
sql = statementScope.getDynamicSql();
}
return sql;
}
public ParameterMap getParameterMap(StatementScope statementScope, Object parameterObject) {
ParameterMap map = statementScope.getDynamicParameterMap();
if (map == null) {
process(statementScope, parameterObject);
map = statementScope.getDynamicParameterMap();
}
return map;
}
public ResultMap getResultMap(StatementScope statementScope, Object parameterObject) {
return statementScope.getResultMap();
}
public void cleanup(StatementScope statementScope) {
statementScope.setDynamicSql(null);
statementScope.setDynamicParameterMap(null);
}
/**
* Process.
*
* @param statementScope
* the statement scope
* @param parameterObject
* the parameter object
*/
private void process(StatementScope statementScope, Object parameterObject) {
SqlTagContext ctx = new SqlTagContext();
List localChildren = children;
processBodyChildren(statementScope, ctx, parameterObject, localChildren.iterator());
ParameterMap map = new ParameterMap(delegate);
map.setId(statementScope.getStatement().getId() + "-InlineParameterMap");
map.setParameterClass(((MappedStatement) statementScope.getStatement()).getParameterClass());
map.setParameterMappingList(ctx.getParameterMappings());
String dynSql = ctx.getBodyText();
// Processes $substitutions$ after DynamicSql
if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) {
dynSql = new SimpleDynamicSql(delegate, dynSql).getSql(statementScope, parameterObject);
}
statementScope.setDynamicSql(dynSql);
statementScope.setDynamicParameterMap(map);
}
/**
* Process body children.
*
* @param statementScope
* the statement scope
* @param ctx
* the ctx
* @param parameterObject
* the parameter object
* @param localChildren
* the local children
*/
private void processBodyChildren(StatementScope statementScope, SqlTagContext ctx, Object parameterObject,
Iterator localChildren) {
PrintWriter out = ctx.getWriter();
processBodyChildren(statementScope, ctx, parameterObject, localChildren, out);
}
/**
* Process body children.
*
* @param statementScope
* the statement scope
* @param ctx
* the ctx
* @param parameterObject
* the parameter object
* @param localChildren
* the local children
* @param out
* the out
*/
private void processBodyChildren(StatementScope statementScope, 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);
ParameterMapping[] mappings = sqlText.getParameterMappings();
if (mappings != null) {
for (int i = 0, n = mappings.length; i < n; i++) {
ctx.addParameterMapping(mappings[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) {
StringBuilder sqlStatementBuffer = new StringBuilder(sqlStatement);
iteratePropertyReplace(sqlStatementBuffer, itCtx);
sqlStatement = sqlStatementBuffer.toString();
}
sqlText = PARAM_PARSER.parseInlineParameterMap(delegate.getTypeHandlerFactory(), sqlStatement);
ParameterMapping[] mappings = sqlText.getParameterMappings();
out.print(sqlText.getText());
if (mappings != null) {
for (int i = 0, n = mappings.length; i < n; i++) {
ctx.addParameterMapping(mappings[i]);
}
}
}
} else if (child instanceof SqlTag) {
SqlTag tag = (SqlTag) child;
SqlTagHandler handler = tag.getHandler();
int response = SqlTagHandler.INCLUDE_BODY;
do {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
response = handler.doStartFragment(ctx, tag, parameterObject);
if (response != SqlTagHandler.SKIP_BODY) {
processBodyChildren(statementScope, ctx, parameterObject, tag.getChildren(), pw);
pw.flush();
pw.close();
StringBuilder body = new StringBuilder(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();
}
}
}
}
/**
* Iterate property replace.
*
* @param bodyContent
* the body content
* @param iterate
* the iterate
*/
protected void iteratePropertyReplace(StringBuilder bodyContent, IterateContext iterate) {
if (iterate != null) {
String[] mappings = new String[] { "#", "$" };
for (int i = 0; i < mappings.length; i++) {
int startIndex = 0;
int endIndex = -1;
while (startIndex > -1 && startIndex < bodyContent.length()) {
startIndex = bodyContent.indexOf(mappings[i], endIndex + 1);
endIndex = bodyContent.indexOf(mappings[i], startIndex + 1);
if (startIndex > -1 && endIndex > -1) {
bodyContent.replace(startIndex + 1, endIndex,
iterate.addIndexToTagProperty(bodyContent.substring(startIndex + 1, endIndex)));
}
}
}
}
}
/**
* Replace.
*
* @param builder
* the builder
* @param find
* the find
* @param replace
* the replace
*/
protected static void replace(StringBuilder builder, String find, String replace) {
int pos = builder.toString().indexOf(find);
int len = find.length();
while (pos > -1) {
builder.replace(pos, pos + len, replace);
pos = builder.toString().indexOf(find);
}
}
public void addChild(SqlChild child) {
children.add(child);
}
}