/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.query.sql.navigator;
import java.util.Collection;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.*;
import org.teiid.query.sql.proc.*;
import org.teiid.query.sql.symbol.*;
/**
* @since 4.2
*/
public class PreOrPostOrderNavigator extends AbstractNavigator {
public static final boolean PRE_ORDER = true;
public static final boolean POST_ORDER = false;
private boolean order;
private boolean deep;
private boolean skipEvaluatable;
public PreOrPostOrderNavigator(LanguageVisitor visitor, boolean order, boolean deep) {
super(visitor);
this.order = order;
this.deep = deep;
}
protected void preVisitVisitor(LanguageObject obj) {
if(order == PRE_ORDER) {
visitVisitor(obj);
}
}
protected void postVisitVisitor(LanguageObject obj) {
if(order == POST_ORDER) {
visitVisitor(obj);
}
}
public void visit(AggregateSymbol obj) {
preVisitVisitor(obj);
Expression[] args = obj.getArgs();
if(args != null) {
for(int i=0; i<args.length; i++) {
visitNode(args[i]);
}
}
visitNode(obj.getOrderBy());
visitNode(obj.getCondition());
postVisitVisitor(obj);
}
public void visit(AliasSymbol obj) {
preVisitVisitor(obj);
visitNode(obj.getSymbol());
postVisitVisitor(obj);
}
public void visit(MultipleElementSymbol obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(AssignmentStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getVariable());
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(BatchedUpdateCommand obj) {
preVisitVisitor(obj);
visitNodes(obj.getUpdateCommands());
postVisitVisitor(obj);
}
public void visit(BetweenCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
visitNode(obj.getLowerExpression());
visitNode(obj.getUpperExpression());
postVisitVisitor(obj);
}
public void visit(Block obj) {
preVisitVisitor(obj);
visitNodes(obj.getStatements());
visitNodes(obj.getExceptionStatements());
postVisitVisitor(obj);
}
public void visit(BranchingStatement obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(CaseExpression obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
for(int i=0; i<obj.getWhenCount(); i++) {
visitNode(obj.getWhenExpression(i));
visitNode(obj.getThenExpression(i));
}
visitNode(obj.getElseExpression());
postVisitVisitor(obj);
}
public void visit(CommandStatement obj) {
preVisitVisitor(obj);
if (deep) {
visitNode(obj.getCommand());
}
postVisitVisitor(obj);
}
public void visit(CompareCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getLeftExpression());
visitNode(obj.getRightExpression());
postVisitVisitor(obj);
}
public void visit(CompoundCriteria obj) {
preVisitVisitor(obj);
visitNodes(obj.getCriteria());
postVisitVisitor(obj);
}
public void visit(Constant obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(CreateProcedureCommand obj) {
preVisitVisitor(obj);
visitNode(obj.getBlock());
postVisitVisitor(obj);
}
public void visit(DeclareStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getVariable());
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(Delete obj) {
preVisitVisitor(obj);
visitNode(obj.getGroup());
visitNode(obj.getCriteria());
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(DependentSetCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(ElementSymbol obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(ExistsCriteria obj) {
preVisitVisitor(obj);
if (deep && (!obj.shouldEvaluate() || !skipEvaluatable)) {
visitNode(obj.getCommand());
}
postVisitVisitor(obj);
}
public void visit(ExpressionSymbol obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(From obj) {
preVisitVisitor(obj);
visitNodes(obj.getClauses());
postVisitVisitor(obj);
}
public void visit(Function obj) {
preVisitVisitor(obj);
Expression[] args = obj.getArgs();
if(args != null) {
for(int i=0; i<args.length; i++) {
visitNode(args[i]);
}
}
postVisitVisitor(obj);
}
public void visit(GroupBy obj) {
preVisitVisitor(obj);
visitNodes(obj.getSymbols());
postVisitVisitor(obj);
}
public void visit(GroupSymbol obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(IfStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getCondition());
visitNode(obj.getIfBlock());
visitNode(obj.getElseBlock());
postVisitVisitor(obj);
}
public void visit(Insert obj) {
preVisitVisitor(obj);
visitNode(obj.getGroup());
visitNodes(obj.getVariables());
visitNodes(obj.getValues());
if(deep && obj.getQueryExpression()!=null) {
visitNode(obj.getQueryExpression());
}
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(Create obj) {
preVisitVisitor(obj);
visitNode(obj.getTable());
visitNodes(obj.getColumnSymbols());
visitNodes(obj.getPrimaryKey());
postVisitVisitor(obj);
}
public void visit(Drop obj) {
preVisitVisitor(obj);
visitNode(obj.getTable());
postVisitVisitor(obj);
}
public void visit(Into obj) {
preVisitVisitor(obj);
visitNode(obj.getGroup());
postVisitVisitor(obj);
}
public void visit(IsNullCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(JoinPredicate obj) {
preVisitVisitor(obj);
visitNode(obj.getLeftClause());
visitNode(obj.getJoinType());
visitNode(obj.getRightClause());
visitNodes(obj.getJoinCriteria());
postVisitVisitor(obj);
}
public void visit(JoinType obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(Limit obj) {
preVisitVisitor(obj);
visitNode(obj.getOffset());
visitNode(obj.getRowLimit());
postVisitVisitor(obj);
}
public void visit(LoopStatement obj) {
preVisitVisitor(obj);
if (deep) {
visitNode(obj.getCommand());
}
visitNode(obj.getBlock());
postVisitVisitor(obj);
}
public void visit(MatchCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getLeftExpression());
visitNode(obj.getRightExpression());
postVisitVisitor(obj);
}
public void visit(NotCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getCriteria());
postVisitVisitor(obj);
}
public void visit(Option obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(OrderBy obj) {
preVisitVisitor(obj);
visitNodes(obj.getOrderByItems());
postVisitVisitor(obj);
}
@Override
public void visit(OrderByItem obj) {
preVisitVisitor(obj);
visitNode(obj.getSymbol());
postVisitVisitor(obj);
}
public void visit(Query obj) {
preVisitVisitor(obj);
visitNodes(obj.getWith());
visitNode(obj.getSelect());
visitNode(obj.getInto());
visitNode(obj.getFrom());
visitNode(obj.getCriteria());
visitNode(obj.getGroupBy());
visitNode(obj.getHaving());
visitNode(obj.getOrderBy());
visitNode(obj.getLimit());
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(RaiseStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
public void visit(Reference obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
public void visit(ScalarSubquery obj) {
preVisitVisitor(obj);
if (deep && (!obj.shouldEvaluate() || !skipEvaluatable)) {
visitNode(obj.getCommand());
}
postVisitVisitor(obj);
}
public void visit(SearchedCaseExpression obj) {
preVisitVisitor(obj);
for(int i=0; i<obj.getWhenCount(); i++) {
visitNode(obj.getWhenCriteria(i));
visitNode(obj.getThenExpression(i));
}
visitNode(obj.getElseExpression());
postVisitVisitor(obj);
}
public void visit(Select obj) {
preVisitVisitor(obj);
visitNodes(obj.getSymbols());
postVisitVisitor(obj);
}
public void visit(SetCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
visitNodes(obj.getValues());
postVisitVisitor(obj);
}
public void visit(SetQuery obj) {
preVisitVisitor(obj);
visitNodes(obj.getWith());
visitNodes(obj.getQueryCommands());
visitNode(obj.getOrderBy());
visitNode(obj.getLimit());
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(StoredProcedure obj) {
preVisitVisitor(obj);
Collection<SPParameter> params = obj.getParameters();
if(params != null && !params.isEmpty()) {
for (SPParameter parameter : params) {
Expression expression = parameter.getExpression();
visitNode(expression);
}
}
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(SubqueryCompareCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getLeftExpression());
if (deep) {
visitNode(obj.getCommand());
}
visitNode(obj.getArrayExpression());
postVisitVisitor(obj);
}
public void visit(SubqueryFromClause obj) {
preVisitVisitor(obj);
if (deep) {
visitNode(obj.getCommand());
}
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
public void visit(SubquerySetCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
if (deep) {
visitNode(obj.getCommand());
}
postVisitVisitor(obj);
}
public void visit(UnaryFromClause obj) {
preVisitVisitor(obj);
visitNode(obj.getGroup());
postVisitVisitor(obj);
}
public void visit(Update obj) {
preVisitVisitor(obj);
visitNode(obj.getGroup());
visitNode(obj.getChangeList());
visitNode(obj.getCriteria());
visitNode(obj.getOption());
postVisitVisitor(obj);
}
public void visit(WhileStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getCondition());
visitNode(obj.getBlock());
postVisitVisitor(obj);
}
/**
* NOTE: we specifically don't need to visit the as columns or the using identifiers.
* These will be resolved by the dynamic command resolver instead.
*
* @see org.teiid.query.sql.LanguageVisitor#visit(org.teiid.query.sql.lang.DynamicCommand)
*/
public void visit(DynamicCommand obj) {
preVisitVisitor(obj);
visitNode(obj.getSql());
visitNode(obj.getIntoGroup());
if (obj.getUsing() != null) {
for (SetClause setClause : obj.getUsing().getClauses()) {
visitNode(setClause.getValue());
}
}
postVisitVisitor(obj);
}
public void visit(SetClauseList obj) {
preVisitVisitor(obj);
visitNodes(obj.getClauses());
postVisitVisitor(obj);
}
public void visit(SetClause obj) {
preVisitVisitor(obj);
visitNode(obj.getSymbol());
visitNode(obj.getValue());
postVisitVisitor(obj);
}
@Override
public void visit(TextLine obj) {
preVisitVisitor(obj);
visitNodes(obj.getExpressions());
postVisitVisitor(obj);
}
@Override
public void visit(XMLForest obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
visitNodes(obj.getArgs());
postVisitVisitor(obj);
}
@Override
public void visit(JSONObject obj) {
preVisitVisitor(obj);
visitNodes(obj.getArgs());
postVisitVisitor(obj);
}
@Override
public void visit(XMLAttributes obj) {
preVisitVisitor(obj);
visitNodes(obj.getArgs());
postVisitVisitor(obj);
}
@Override
public void visit(XMLElement obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
visitNode(obj.getAttributes());
visitNodes(obj.getContent());
postVisitVisitor(obj);
}
@Override
public void visit(XMLNamespaces obj) {
preVisitVisitor(obj);
postVisitVisitor(obj);
}
@Override
public void visit(TextTable obj) {
preVisitVisitor(obj);
visitNode(obj.getFile());
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
@Override
public void visit(XMLTable obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
visitNodes(obj.getPassing());
for (XMLTable.XMLColumn column : obj.getColumns()) {
visitNode(column.getDefaultExpression());
}
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
@Override
public void visit(ObjectTable obj) {
preVisitVisitor(obj);
visitNodes(obj.getPassing());
for (ObjectTable.ObjectColumn column : obj.getColumns()) {
visitNode(column.getDefaultExpression());
}
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
@Override
public void visit(XMLQuery obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
visitNodes(obj.getPassing());
postVisitVisitor(obj);
}
@Override
public void visit(XMLExists obj) {
preVisitVisitor(obj);
visitNode(obj.getXmlQuery().getNamespaces());
visitNodes(obj.getXmlQuery().getPassing());
postVisitVisitor(obj);
}
@Override
public void visit(XMLCast obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(DerivedColumn obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(XMLSerialize obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(QueryString obj) {
preVisitVisitor(obj);
visitNode(obj.getPath());
visitNodes(obj.getArgs());
postVisitVisitor(obj);
}
@Override
public void visit(XMLParse obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(ExpressionCriteria obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(WithQueryCommand obj) {
preVisitVisitor(obj);
visitNodes(obj.getColumns());
if (deep) {
visitNode(obj.getCommand());
}
postVisitVisitor(obj);
}
@Override
public void visit(TriggerAction obj) {
preVisitVisitor(obj);
visitNode(obj.getBlock());
postVisitVisitor(obj);
}
@Override
public void visit(ArrayTable obj) {
preVisitVisitor(obj);
visitNode(obj.getArrayValue());
visitNode(obj.getGroupSymbol());
postVisitVisitor(obj);
}
@Override
public void visit(AlterProcedure obj) {
preVisitVisitor(obj);
visitNode(obj.getTarget());
if (deep) {
visitNode(obj.getDefinition());
}
postVisitVisitor(obj);
}
@Override
public void visit(AlterTrigger obj) {
preVisitVisitor(obj);
visitNode(obj.getTarget());
if (deep) {
visitNode(obj.getDefinition());
}
postVisitVisitor(obj);
}
@Override
public void visit(AlterView obj) {
preVisitVisitor(obj);
visitNode(obj.getTarget());
if (deep) {
visitNode(obj.getDefinition());
}
postVisitVisitor(obj);
}
@Override
public void visit(WindowFunction obj) {
preVisitVisitor(obj);
visitNode(obj.getFunction());
visitNode(obj.getWindowSpecification());
postVisitVisitor(obj);
}
@Override
public void visit(WindowSpecification obj) {
preVisitVisitor(obj);
visitNodes(obj.getPartition());
visitNode(obj.getOrderBy());
postVisitVisitor(obj);
}
@Override
public void visit(Array array) {
preVisitVisitor(array);
visitNodes(array.getExpressions());
postVisitVisitor(array);
}
@Override
public void visit(ExceptionExpression exceptionExpression) {
preVisitVisitor(exceptionExpression);
visitNode(exceptionExpression.getMessage());
visitNode(exceptionExpression.getSqlState());
visitNode(exceptionExpression.getErrorCode());
visitNode(exceptionExpression.getParent());
postVisitVisitor(exceptionExpression);
}
@Override
public void visit(ReturnStatement obj) {
preVisitVisitor(obj);
visitNode(obj.getExpression());
postVisitVisitor(obj);
}
@Override
public void visit(IsDistinctCriteria obj) {
preVisitVisitor(obj);
//don't visit as that will fail the validation that scalar/row value groupsymbols can't be referenced
//visitNode(obj.getLeftRowValue());
//visitNode(obj.getRightRowValue());
postVisitVisitor(obj);
}
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
doVisit(object, visitor, order, false);
}
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order, boolean deep) {
PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, order, deep);
object.acceptVisitor(nav);
}
public void setSkipEvaluatable(boolean skipEvaluatable) {
this.skipEvaluatable = skipEvaluatable;
}
}