OperationUtils.java
package com.github.mygreen.sqlmapper.metamodel.support;
import com.github.mygreen.sqlmapper.metamodel.expression.Expression;
import com.github.mygreen.sqlmapper.metamodel.operator.ArithmeticOp;
import com.github.mygreen.sqlmapper.metamodel.operator.BooleanOp;
import com.github.mygreen.sqlmapper.metamodel.operator.ComparisionOp;
import com.github.mygreen.sqlmapper.metamodel.operator.Operator;
import com.github.mygreen.sqlmapper.metamodel.operator.UnaryOp;
/**
* 演算操作に関するユーティリティ
*
*
* @author T.TSUCHIE
*
*/
public class OperationUtils {
/**
* 式の評価結果を括弧で囲むか判定する。
* @param parentOp 親ノードの演算子
* @param childOp 子ノードの演算子
* @return 括弧で囲むときは {@literal true} を返す。
*/
public static boolean isEnclosedParenthesis(Operator parentOp, Operator childOp) {
if(parentOp.getPriority() < childOp.getPriority()) {
// 親ノードの演算子の優先度が高い(値が小さい)とき
return true;
} else if(parentOp == BooleanOp.OR && childOp == BooleanOp.AND) {
// 親ノードがORで子ノードがANDのとき
// 実際は括弧で囲まなくてもよいが見やすさのために囲む
return true;
} else if(parentOp instanceof BooleanOp && childOp == ComparisionOp.BETWEEN) {
// 親ノードがOR/ANDで子ノードがBETWEENのとき
// 実際は括弧で囲まなくてもよいが見やすさのために囲む
return true;
} else if(parentOp == UnaryOp.NOT || parentOp == UnaryOp.EXISTS || parentOp == UnaryOp.NOT_EXISTS) {
// 親ノードが NOT /EXISTS / NOT_EXISTS 演算子のとき
return true;
} else if(parentOp.getClass().equals(childOp.getClass())) {
// 親ノードと子ノードが同じ演算子グループの場合、それぞれの優先度に従う
return parentOp.getPriority() < childOp.getPriority();
} else if(childOp instanceof ArithmeticOp) {
// 子ノードが算術演算子の場合、必ず囲む。
return true;
}
return false;
}
/**
* 式ノードをデバッグ情報形式の文字列に変換する。
* @param exp 式ノード
* @return デバッグ情報
*/
public static String toDebugString(final Expression<?> exp) {
DebugVisitor visitor = new DebugVisitor();
DebugVisitorContext context = new DebugVisitorContext();
exp.accept(visitor, context);
return context.getCriteria();
}
}