package org.fanhongtao.mybatis.frame; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.builder.xml.dynamic.ChooseSqlNode; import org.apache.ibatis.builder.xml.dynamic.ForEachSqlNode; import org.apache.ibatis.builder.xml.dynamic.IfSqlNode; import org.apache.ibatis.builder.xml.dynamic.MixedSqlNode; import org.apache.ibatis.builder.xml.dynamic.SetSqlNode; import org.apache.ibatis.builder.xml.dynamic.SqlNode; import org.apache.ibatis.builder.xml.dynamic.TextSqlNode; import org.apache.ibatis.builder.xml.dynamic.TrimSqlNode; import org.apache.ibatis.builder.xml.dynamic.WhereSqlNode; import org.apache.ibatis.session.Configuration; import org.fanhongtao.lang.ReflectUtil; /** * @author Fan Hongtao * @created 2010-8-31 */ public class SqlNodeUtils { public static SqlNode clone(SqlNode sqlNode) { SqlNode newSqlNode = null; if (sqlNode instanceof ChooseSqlNode) { newSqlNode = cloneChooseSqlNode((ChooseSqlNode) sqlNode); } else if (sqlNode instanceof ForEachSqlNode) { newSqlNode = cloneForEachSqlNode((ForEachSqlNode) sqlNode); } else if (sqlNode instanceof IfSqlNode) { newSqlNode = cloneIfSqlNode((IfSqlNode) sqlNode); } else if (sqlNode instanceof MixedSqlNode) { newSqlNode = cloneMixedSqlNode((MixedSqlNode) sqlNode); } else if (sqlNode instanceof TextSqlNode) { newSqlNode = cloneTextSqlNode((TextSqlNode) sqlNode); } else if (sqlNode instanceof SetSqlNode) { newSqlNode = cloneSetSqlNode((SetSqlNode) sqlNode); } else if (sqlNode instanceof WhereSqlNode) { newSqlNode = cloneWhereSqlNode((WhereSqlNode) sqlNode); } else if (sqlNode instanceof TrimSqlNode) { newSqlNode = cloneTrimSqlNode((TrimSqlNode) sqlNode); } else { throw new RuntimeException("Unsupported SqlNode: " + sqlNode.getClass()); } return newSqlNode; } private static ChooseSqlNode cloneChooseSqlNode(ChooseSqlNode sqlNode) { @SuppressWarnings("unchecked") List<IfSqlNode> ifSqlNodes = (List<IfSqlNode>) ReflectUtil.getField(sqlNode, "ifSqlNodes"); SqlNode defaultSqlNode = (SqlNode) ReflectUtil.getField(sqlNode, "defaultSqlNode"); List<IfSqlNode> newIfSqlNodes = new ArrayList<IfSqlNode>(); for (IfSqlNode ifSqlNode : ifSqlNodes) { newIfSqlNodes.add(cloneIfSqlNode(ifSqlNode)); } SqlNode newDefaultSqlNode = null; if (defaultSqlNode != null) { newDefaultSqlNode = clone(defaultSqlNode); } ChooseSqlNode chooseSqlNode = new ChooseSqlNode(newIfSqlNodes, newDefaultSqlNode); return chooseSqlNode; } private static ForEachSqlNode cloneForEachSqlNode(ForEachSqlNode sqlNode) { Configuration configuration = (Configuration) ReflectUtil.getField(sqlNode, "configuration"); SqlNode contents = (SqlNode) ReflectUtil.getField(sqlNode, "contents"); String collectionExpression = (String) ReflectUtil.getField(sqlNode, "collectionExpression"); String index = (String) ReflectUtil.getField(sqlNode, "index"); String item = (String) ReflectUtil.getField(sqlNode, "item"); String open = (String) ReflectUtil.getField(sqlNode, "open"); String close = (String) ReflectUtil.getField(sqlNode, "close"); String separator = (String) ReflectUtil.getField(sqlNode, "separator"); SqlNode newContents = clone(contents); ForEachSqlNode forEachSqlNode = new ForEachSqlNode(configuration, newContents, collectionExpression, index, item, open, close, separator); return forEachSqlNode; } private static IfSqlNode cloneIfSqlNode(IfSqlNode sqlNode) { SqlNode contents = (SqlNode) ReflectUtil.getField(sqlNode, "contents"); String test = (String) ReflectUtil.getField(sqlNode, "test"); SqlNode newContents = clone(contents); IfSqlNode ifSqlNode = new IfSqlNode(newContents, test); return ifSqlNode; } private static MixedSqlNode cloneMixedSqlNode(MixedSqlNode sqlNode) { @SuppressWarnings("unchecked") List<SqlNode> contents = (List<SqlNode>) ReflectUtil.getField(sqlNode, "contents"); List<SqlNode> newContents = new ArrayList<SqlNode>(); for (SqlNode content : contents) { newContents.add(clone(content)); } MixedSqlNode mixedSqlNode = new MixedSqlNode(newContents); return mixedSqlNode; } private static TextSqlNode cloneTextSqlNode(TextSqlNode sqlNode) { String text = (String) ReflectUtil.getField(sqlNode, "text"); TextSqlNode textSqlNode = new TextSqlNode(text); return textSqlNode; } private static SetSqlNode cloneSetSqlNode(SetSqlNode sqlNode) { Configuration configuration = (Configuration) ReflectUtil.getField(TrimSqlNode.class, sqlNode, "configuration"); SqlNode contents = (SqlNode) ReflectUtil.getField(TrimSqlNode.class, sqlNode, "contents"); SqlNode newContents = clone(contents); SetSqlNode setSqlNode = new SetSqlNode(configuration, newContents); return setSqlNode; } private static WhereSqlNode cloneWhereSqlNode(WhereSqlNode sqlNode) { Configuration configuration = (Configuration) ReflectUtil.getField(TrimSqlNode.class, sqlNode, "configuration"); SqlNode contents = (SqlNode) ReflectUtil.getField(TrimSqlNode.class, sqlNode, "contents"); SqlNode newContents = clone(contents); WhereSqlNode whereSqlNode = new WhereSqlNode(configuration, newContents); return whereSqlNode; } private static TrimSqlNode cloneTrimSqlNode(TrimSqlNode sqlNode) { Configuration configuration = (Configuration) ReflectUtil.getField(sqlNode, "configuration"); SqlNode contents = (SqlNode) ReflectUtil.getField(sqlNode, "contents"); String prefix = (String) ReflectUtil.getField(sqlNode, "prefix"); String prefixesToOverride = (String) ReflectUtil.getField(sqlNode, "prefixesToOverride"); String suffix = (String) ReflectUtil.getField(sqlNode, "suffix"); String suffixesToOverride = (String) ReflectUtil.getField(sqlNode, "suffixesToOverride"); SqlNode newContents = clone(contents); TrimSqlNode trimSqlNode = new TrimSqlNode(configuration, newContents, prefix, prefixesToOverride, suffix, suffixesToOverride); return trimSqlNode; } }