/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * 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 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 jef.database.jsqlparser.visitor; import java.util.ArrayDeque; import java.util.Deque; import java.util.Iterator; import jef.common.Pair; import jef.database.jsqlparser.expression.AllComparisonExpression; import jef.database.jsqlparser.expression.AnyComparisonExpression; import jef.database.jsqlparser.expression.BinaryExpression; import jef.database.jsqlparser.expression.CaseExpression; import jef.database.jsqlparser.expression.Column; import jef.database.jsqlparser.expression.DateValue; import jef.database.jsqlparser.expression.DoubleValue; import jef.database.jsqlparser.expression.Function; import jef.database.jsqlparser.expression.Interval; import jef.database.jsqlparser.expression.InverseExpression; import jef.database.jsqlparser.expression.JdbcParameter; import jef.database.jsqlparser.expression.JpqlParameter; import jef.database.jsqlparser.expression.LongValue; import jef.database.jsqlparser.expression.NullValue; import jef.database.jsqlparser.expression.Over; import jef.database.jsqlparser.expression.Parenthesis; import jef.database.jsqlparser.expression.StringValue; import jef.database.jsqlparser.expression.Table; import jef.database.jsqlparser.expression.TimeValue; import jef.database.jsqlparser.expression.TimestampValue; import jef.database.jsqlparser.expression.WhenClause; import jef.database.jsqlparser.expression.operators.arithmetic.Addition; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseAnd; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseOr; import jef.database.jsqlparser.expression.operators.arithmetic.BitwiseXor; import jef.database.jsqlparser.expression.operators.arithmetic.Concat; import jef.database.jsqlparser.expression.operators.arithmetic.Division; import jef.database.jsqlparser.expression.operators.arithmetic.Mod; import jef.database.jsqlparser.expression.operators.arithmetic.Multiplication; import jef.database.jsqlparser.expression.operators.arithmetic.Subtraction; import jef.database.jsqlparser.expression.operators.conditional.AndExpression; import jef.database.jsqlparser.expression.operators.conditional.OrExpression; import jef.database.jsqlparser.expression.operators.relational.Between; import jef.database.jsqlparser.expression.operators.relational.EqualsTo; import jef.database.jsqlparser.expression.operators.relational.ExistsExpression; import jef.database.jsqlparser.expression.operators.relational.ExpressionList; import jef.database.jsqlparser.expression.operators.relational.GreaterThan; import jef.database.jsqlparser.expression.operators.relational.GreaterThanEquals; import jef.database.jsqlparser.expression.operators.relational.InExpression; import jef.database.jsqlparser.expression.operators.relational.IsNullExpression; import jef.database.jsqlparser.expression.operators.relational.LikeExpression; import jef.database.jsqlparser.expression.operators.relational.MinorThan; import jef.database.jsqlparser.expression.operators.relational.MinorThanEquals; import jef.database.jsqlparser.expression.operators.relational.NotEqualsTo; import jef.database.jsqlparser.statement.create.CreateTable; import jef.database.jsqlparser.statement.delete.Delete; import jef.database.jsqlparser.statement.drop.Drop; import jef.database.jsqlparser.statement.insert.Insert; import jef.database.jsqlparser.statement.replace.Replace; import jef.database.jsqlparser.statement.select.AllColumns; import jef.database.jsqlparser.statement.select.AllTableColumns; import jef.database.jsqlparser.statement.select.Join; import jef.database.jsqlparser.statement.select.Limit; import jef.database.jsqlparser.statement.select.OrderBy; import jef.database.jsqlparser.statement.select.OrderByElement; import jef.database.jsqlparser.statement.select.PlainSelect; import jef.database.jsqlparser.statement.select.Select; import jef.database.jsqlparser.statement.select.SelectExpressionItem; import jef.database.jsqlparser.statement.select.StartWithExpression; import jef.database.jsqlparser.statement.select.SubJoin; import jef.database.jsqlparser.statement.select.SubSelect; import jef.database.jsqlparser.statement.select.Union; import jef.database.jsqlparser.statement.select.WithItem; import jef.database.jsqlparser.statement.truncate.Truncate; import jef.database.jsqlparser.statement.update.Update; /** * 通用的访问者,该访问者将遍历AST上的每一个元素。 * 并可以通过visitPath(一个先进后出的Deque)来访问到根节点的路径。 * * @author jiyi * */ public class VisitorAdapter implements SelectVisitor, ExpressionVisitor, StatementVisitor, SelectItemVisitor { protected final Deque<Object> visitPath = new ArrayDeque<Object>(); public void visit(PlainSelect plainSelect) { visitPath.push(plainSelect); for (SelectItem s : plainSelect.getSelectItems()) { s.accept(this); } if(plainSelect.getFromItem()!=null){ plainSelect.getFromItem().accept(this); } if (plainSelect.getJoins() != null) { for (Iterator<Join> joinsIt = plainSelect.getJoins().iterator(); joinsIt.hasNext();) { Join join = (Join) joinsIt.next(); join.accept(this); } } if (plainSelect.getWhere() != null) plainSelect.getWhere().accept(this); if (plainSelect.getStartWith() != null) plainSelect.getStartWith().accept(this); if (plainSelect.getHaving() != null) plainSelect.getHaving().accept(this); if (plainSelect.getOrderBy() != null) { plainSelect.getOrderBy().accept(this); } if(plainSelect.getLimit()!=null){ plainSelect.getLimit().accept(this); } visitPath.pop(); } public void visit(OrderBy orderBy) { visitPath.push(orderBy); for (OrderByElement o : orderBy.getOrderByElements()) { o.accept(this); } visitPath.pop(); } public void visit(Union union) { visitPath.push(union); for (Iterator<PlainSelect> iter = union.getPlainSelects().iterator(); iter.hasNext();) { PlainSelect plainSelect = iter.next(); visit(plainSelect); } visitPath.pop(); } public void visit(SubSelect subSelect) { visitPath.push(subSelect); subSelect.getSelectBody().accept(this); visitPath.pop(); } public void visit(Addition addition) { visitPath.push(addition); visitBinaryExpression(addition); visitPath.pop(); } public void visit(AndExpression andExpression) { visitPath.push(andExpression); visitBinaryExpression(andExpression); visitPath.pop(); } public void visit(Between between) { visitPath.push(between); between.getLeftExpression().accept(this); between.getBetweenExpressionStart().accept(this); between.getBetweenExpressionEnd().accept(this); visitPath.pop(); } public void visit(Division division) { visitPath.push(division); visitBinaryExpression(division); visitPath.pop(); } public void visit(Mod mod) { visitPath.push(mod); visitBinaryExpression(mod); visitPath.pop(); } public void visit(DoubleValue doubleValue) { } public void visit(EqualsTo equalsTo) { visitPath.push(equalsTo); visitBinaryExpression(equalsTo); visitPath.pop(); } public void visit(Function function) { visitPath.push(function); if (function.getParameters() != null) function.getParameters().accept(this); if (function.getOver() != null) { function.getOver().accept(this); } visitPath.pop(); } public void visit(GreaterThan greaterThan) { visitPath.push(greaterThan); visitBinaryExpression(greaterThan); visitPath.pop(); } public void visit(GreaterThanEquals greaterThanEquals) { visitPath.push(greaterThanEquals); visitBinaryExpression(greaterThanEquals); visitPath.pop(); } public void visit(InExpression inExpression) { visitPath.push(inExpression); inExpression.getLeftExpression().accept(this); inExpression.getItemsList().accept(this); visitPath.pop(); } public void visit(InverseExpression inverseExpression) { visitPath.push(inverseExpression); inverseExpression.getExpression().accept(this); visitPath.pop(); } public void visit(IsNullExpression isNullExpression) { visitPath.push(isNullExpression); isNullExpression.getLeftExpression().accept(this); visitPath.pop(); } public void visit(LikeExpression likeExpression) { visitPath.push(likeExpression); visitBinaryExpression(likeExpression); visitPath.pop(); } public void visit(ExistsExpression existsExpression) { visitPath.push(existsExpression); existsExpression.getRightExpression().accept(this); visitPath.pop(); } public void visit(LongValue longValue) { } public void visit(MinorThan minorThan) { visitPath.push(minorThan); visitBinaryExpression(minorThan); visitPath.pop(); } public void visit(MinorThanEquals minorThanEquals) { visitPath.push(minorThanEquals); visitBinaryExpression(minorThanEquals); visitPath.pop(); } public void visit(Multiplication multiplication) { visitPath.push(multiplication); visitBinaryExpression(multiplication); visitPath.pop(); } public void visit(NotEqualsTo notEqualsTo) { visitPath.push(notEqualsTo); visitBinaryExpression(notEqualsTo); visitPath.pop(); } public void visit(NullValue nullValue) { } public void visit(OrExpression orExpression) { visitPath.push(orExpression); visitBinaryExpression(orExpression); visitPath.pop(); } public void visit(Parenthesis parenthesis) { parenthesis.getExpression().accept(this); } public void visit(StringValue stringValue) { } public void visit(Subtraction subtraction) { visitPath.push(subtraction); visitBinaryExpression(subtraction); visitPath.pop(); } private void visitBinaryExpression(BinaryExpression binaryExpression) { binaryExpression.getLeftExpression().accept(this); binaryExpression.getRightExpression().accept(this); } public void visit(ExpressionList expressionList) { visitPath.push(expressionList); for (Iterator<Expression> iter = expressionList.getExpressions().iterator(); iter.hasNext();) { Expression expression = iter.next(); expression.accept(this); } visitPath.pop(); } public void visit(JdbcParameter jdbcParameter) { } public void visit(DateValue dateValue) { } public void visit(TimestampValue timestampValue) { } public void visit(TimeValue timeValue) { } public void visit(CaseExpression caseExpression) { visitPath.push(caseExpression); if (caseExpression.getSwitchExpression() != null) { caseExpression.getSwitchExpression().accept(this); } if (caseExpression.getWhenClauses() != null) { for (WhenClause when : caseExpression.getWhenClauses()) { when.accept(this); } } if (caseExpression.getElseExpression() != null) { caseExpression.getElseExpression().accept(this); } visitPath.pop(); } public void visit(WhenClause whenClause) { visitPath.push(whenClause); whenClause.getWhenExpression().accept(this); whenClause.getThenExpression().accept(this); visitPath.pop(); } public void visit(AllComparisonExpression allComparisonExpression) { visitPath.push(allComparisonExpression); allComparisonExpression.GetSubSelect().getSelectBody().accept(this); visitPath.pop(); } public void visit(AnyComparisonExpression anyComparisonExpression) { visitPath.push(anyComparisonExpression); anyComparisonExpression.GetSubSelect().accept((ExpressionVisitor) this); visitPath.pop(); } public void visit(SubJoin subjoin) { visitPath.push(subjoin); subjoin.getLeft().accept(this); subjoin.getJoin().accept(this); visitPath.pop(); } public void visit(Concat concat) { visitPath.push(concat); visitBinaryExpression(concat); visitPath.pop(); } public void visit(BitwiseAnd bitwiseAnd) { visitPath.push(bitwiseAnd); visitBinaryExpression(bitwiseAnd); visitPath.pop(); } public void visit(BitwiseOr bitwiseOr) { visitPath.push(bitwiseOr); visitBinaryExpression(bitwiseOr); visitPath.pop(); } public void visit(BitwiseXor bitwiseXor) { visitPath.push(bitwiseXor); visitBinaryExpression(bitwiseXor); visitPath.pop(); } public void visit(Column tableColumn) { } public void visit(Table tableName) { } public void visit(Select select) { visitPath.push(select); if(select.getWithItemsList()!=null){ for(WithItem with: select.getWithItemsList()){ with.accept(this); } } if (select.getSelectBody() != null) select.getSelectBody().accept(this); visitPath.pop(); } public void visit(Delete delete) { visitPath.push(delete); delete.getTable().accept(this); if (delete.getWhere() != null) { delete.getWhere().accept(this); } visitPath.pop(); } public void visit(Update update) { visitPath.push(update); update.getTable().accept(this); for (Pair<Column,Expression> pair : update.getSets()) { pair.first.accept(this); pair.second.accept(this); } if (update.getWhere() != null) { update.getWhere().accept(this); } visitPath.pop(); } public void visit(Insert insert) { visitPath.push(insert); if (insert.getColumns() != null) { for (Column c : insert.getColumns()) { visit(c); } } insert.getTable().accept(this); insert.getItemsList().accept(this); visitPath.pop(); } public void visit(Replace replace) { visitPath.push(replace); for (Column c : replace.getColumns()) { visit(c); } for (Expression ex : replace.getExpressions()) { ex.accept(this); } replace.getTable().accept(this); replace.getItemsList().accept(this); visitPath.pop(); } public void visit(Drop drop) { } public void visit(Truncate truncate) { visitPath.push(truncate); truncate.getTable().accept(this); visitPath.pop(); } public void visit(CreateTable createTable) { visitPath.push(createTable); createTable.getTable().accept(this); visitPath.pop(); } public void visit(AllColumns allColumns) { } public void visit(AllTableColumns allTableColumns) { } public void visit(SelectExpressionItem selectExpressionItem) { visitPath.push(selectExpressionItem); selectExpressionItem.getExpression().accept(this); visitPath.pop(); } public void visit(JpqlParameter parameter) { } public void visit(OrderByElement orderBy) { visitPath.push(orderBy); orderBy.getExpression().accept(this); visitPath.pop(); } public void visit(Interval interval) { visitPath.push(interval); if(interval.getValue()!=null){ interval.getValue().accept(this); } visitPath.pop(); } public void visit(StartWithExpression startWithExpression) { visitPath.push(startWithExpression); Expression start = startWithExpression.getStartExpression(); Expression connectBy = startWithExpression.getConnectExpression(); if (start != null) start.accept(this); if (connectBy != null) connectBy.accept(this); visitPath.pop(); } public void visit(Over over) { visitPath.push(over); if (over.getPartition() != null) { for (Expression exp : over.getPartition()) { exp.accept(this); } } if (over.getOrderBy() != null) { over.getOrderBy().accept(this); } visitPath.pop(); } public void visit(Join join) { visitPath.push(join); join.getRightItem().accept(this); if (join.getOnExpression() != null) { join.getOnExpression().accept(this); } if (join.getUsingColumns() != null) { for (Column c : join.getUsingColumns()) { c.accept(this); } } visitPath.pop(); } public void visit(WithItem with) { visitPath.push(with); if(with.getWithItemList()!=null){ for(SelectItem item:with.getWithItemList()){ item.accept(this); } } if(with.getSelectBody()!=null){ with.getSelectBody().accept(this); } visitPath.pop(); } @Override public void visit(Limit limit) { visitPath.push(limit); if(limit.getOffsetJdbcParameter()!=null){ limit.getOffsetJdbcParameter().accept(this); } if(limit.getRowCountJdbcParameter()!=null){ limit.getRowCountJdbcParameter().accept(this); } visitPath.pop(); } }