net.paoding.rose.jade.statement.interpreter.Jexl3Interpreter Maven / Gradle / Ivy
/*
* Copyright 2009-2012 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License i 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 net.paoding.rose.jade.statement.interpreter;
import net.paoding.rose.jade.annotation.condition.SQLCondition;
import net.paoding.rose.jade.cache.JadeCache;
import net.paoding.rose.jade.statement.StatementRuntime;
import net.paoding.rose.jade.statement.jexl.Jexl3Analysis;
import net.paoding.rose.jade.statement.jexl.Jexl3Execute;
import net.paoding.rose.jade.statement.jexl.analysis.Analysis;
import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.BadSqlGrammarException;
import java.sql.SQLSyntaxErrorException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* commons-jexl3 解析器
* @author fusheng.zhang
*/
public class Jexl3Interpreter implements Interpreter {
private final JadeCache> jadeCache;
public Jexl3Interpreter(JadeCache> jadeCache) {
this.jadeCache = jadeCache;
}
@Override
public void interpret(StatementRuntime runtime) {
String sqlExpression = runtime.getSQL();
try {
Map parameters = runtime.getParameters();
Map constants = runtime.getMetaData().getDAOMetaData().getConstants();
//
List analyses = jadeCache.get(sqlExpression)
.orElseGet(() -> new Jexl3Analysis(sqlExpression).compile());
Jexl3Execute jexl3Execute = new Jexl3Execute(parameters, constants);
analyses.forEach(analysis -> analysis.execute(jexl3Execute));
StringBuilder sql = new StringBuilder(jexl3Execute.getResult());
//
runtime.setArgs(jexl3Execute.getArgs().toArray());
runtime.setSQL(sql.toString());
// 转换 and or like 等 表达式
SQLCondition[] sqlConditions = runtime.getSQLCondition();
if (Objects.isNull(sqlConditions) || sqlConditions.length <= 0) return;
AtomicBoolean appendWhere = new AtomicBoolean(true);
Arrays.stream(sqlConditions).forEach(sqlCondition -> {
String condition = sqlCondition.condition();
boolean conditionNotBlank = StringUtils.isNotBlank(condition);
ArrayList valueList = new ArrayList<>(Arrays.asList(sqlCondition.values()));
valueList.add(sqlCondition.value());
valueList.stream().filter(StringUtils::isNotBlank).forEach(expression -> {
//
List sqlAndAnalysis = jadeCache.get(expression)
.orElseGet(() -> new Jexl3Analysis(expression).compile());
Jexl3Execute sqlAndExecute = new Jexl3Execute(parameters, constants);
sqlAndAnalysis.forEach(analysis -> analysis.execute(sqlAndExecute));
String sqlConditionStr = sqlAndExecute.getResult();
if (StringUtils.isNotBlank(sqlConditionStr)) {
if (appendWhere.get() && conditionNotBlank && sqlCondition.appendWhere()) {
sql.append(" where ").append(sqlConditionStr);
appendWhere.set(false);
} else {
sql.append(" ").append(condition).append(" ").append(sqlConditionStr);
}
runtime.setArgs(sqlAndExecute.getArgs().toArray());
}
});
});
runtime.setSQL(sql.toString());
} catch (Exception e) {
String daoInfo = runtime.getMetaData().toString();
throw new BadSqlGrammarException(daoInfo, sqlExpression,
new SQLSyntaxErrorException(daoInfo + " @SQL('" + sqlExpression + "')", e));
}
}
}