/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * 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; * version 2.1 of the License. * * 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. * */ package org.geotools.arcsde.data.view; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.expression.CaseExpression; import net.sf.jsqlparser.expression.DateValue; import net.sf.jsqlparser.expression.DoubleValue; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.expression.InverseExpression; import net.sf.jsqlparser.expression.JdbcParameter; import net.sf.jsqlparser.expression.LongValue; import net.sf.jsqlparser.expression.NullValue; import net.sf.jsqlparser.expression.Parenthesis; import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.TimeValue; import net.sf.jsqlparser.expression.TimestampValue; import net.sf.jsqlparser.expression.WhenClause; import net.sf.jsqlparser.expression.operators.arithmetic.Addition; import net.sf.jsqlparser.expression.operators.arithmetic.Division; import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication; import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.Between; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.GreaterThan; import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals; import net.sf.jsqlparser.expression.operators.relational.InExpression; import net.sf.jsqlparser.expression.operators.relational.IsNullExpression; import net.sf.jsqlparser.expression.operators.relational.ItemsList; import net.sf.jsqlparser.expression.operators.relational.LikeExpression; import net.sf.jsqlparser.expression.operators.relational.MinorThan; import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals; import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.SubSelect; import org.geotools.arcsde.session.ISession; /** * Qualifies the column references (aliased or not) the ArcSDE "table.user." prefix as required by * the ArcSDE java api to not get confused when using joined tables. * * @author Gabriel Roldan, Axios Engineering * @version $Id$ * @source $URL: * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java * /org/geotools/arcsde/data/view/ExpressionQualifier.java $ * @since 2.3.x */ class ExpressionQualifier implements ExpressionVisitor { private Expression _qualifiedExpression; private ISession session; private Map<String, Object> tableAliases; /** * Creates a new ExpressionQualifier object. * * @param session */ private ExpressionQualifier(ISession session, Map<String, Object> tableAliases) { this.session = session; this.tableAliases = tableAliases; } public static Expression qualify(ISession session, Map<String, Object> tableAliases, Expression exp) { if (exp == null) { return null; } ExpressionQualifier qualifier = new ExpressionQualifier(session, tableAliases); exp.accept(qualifier); return qualifier._qualifiedExpression; } public void visit(NullValue nullValue) { _qualifiedExpression = nullValue; } public void visit(Function function) { Function qfunction = new Function(); qfunction.setAllColumns(function.isAllColumns()); qfunction.setEscaped(function.isEscaped()); qfunction.setName(function.getName()); ExpressionList parameters = function.getParameters(); ExpressionList qualifiedParams; qualifiedParams = (ExpressionList) ItemsListQualifier.qualify(session, tableAliases, parameters); qfunction.setParameters(qualifiedParams); this._qualifiedExpression = qfunction; } public void visit(InverseExpression inverseExpression) { InverseExpression qInv = new InverseExpression(); Expression exp = inverseExpression.getExpression(); Expression qExp = ExpressionQualifier.qualify(session, tableAliases, exp); qInv.setExpression(qExp); this._qualifiedExpression = qInv; } public void visit(JdbcParameter jdbcParameter) { this._qualifiedExpression = jdbcParameter; } public void visit(DoubleValue doubleValue) { this._qualifiedExpression = doubleValue; } public void visit(LongValue longValue) { this._qualifiedExpression = longValue; } public void visit(DateValue dateValue) { this._qualifiedExpression = dateValue; } public void visit(TimeValue timeValue) { this._qualifiedExpression = timeValue; } public void visit(TimestampValue timestampValue) { this._qualifiedExpression = timestampValue; } public void visit(Parenthesis parenthesis) { Expression pExp = parenthesis.getExpression(); Expression qualifiedExpression; qualifiedExpression = qualify(session, tableAliases, pExp); Parenthesis qualified = new Parenthesis(); qualified.setExpression(qualifiedExpression); this._qualifiedExpression = qualified; } public void visit(StringValue stringValue) { this._qualifiedExpression = stringValue; } private void visitBinaryExpression(BinaryExpression exp) { Expression left = ExpressionQualifier.qualify(session, tableAliases, exp.getLeftExpression()); Expression right = ExpressionQualifier.qualify(session, tableAliases, exp.getRightExpression()); BinaryExpression qualified; if (exp instanceof Addition) qualified = new Addition(); else if (exp instanceof Division) qualified = new Division(); else if (exp instanceof Multiplication) qualified = new Multiplication(); else if (exp instanceof Subtraction) qualified = new Subtraction(); else if (exp instanceof EqualsTo) qualified = new EqualsTo(); else if (exp instanceof GreaterThan) qualified = new GreaterThan(); else if (exp instanceof GreaterThanEquals) qualified = new GreaterThanEquals(); else if (exp instanceof LikeExpression) qualified = new LikeExpression(); else if (exp instanceof MinorThan) qualified = new MinorThan(); else if (exp instanceof MinorThanEquals) qualified = new MinorThanEquals(); else if (exp instanceof NotEqualsTo) qualified = new NotEqualsTo(); else throw new IllegalArgumentException("Unkown binary expression: " + exp); qualified.setLeftExpression(left); qualified.setRightExpression(right); this._qualifiedExpression = qualified; } public void visit(Addition addition) { visitBinaryExpression(addition); } public void visit(Division division) { visitBinaryExpression(division); } public void visit(Multiplication multiplication) { visitBinaryExpression(multiplication); } public void visit(Subtraction subtraction) { visitBinaryExpression(subtraction); } public void visit(AndExpression andExpression) { Expression left = qualify(session, tableAliases, andExpression.getLeftExpression()); Expression rigth = qualify(session, tableAliases, andExpression.getRightExpression()); AndExpression and = new AndExpression(left, rigth); this._qualifiedExpression = and; } public void visit(OrExpression orExpression) { Expression left = qualify(session, tableAliases, orExpression.getLeftExpression()); Expression rigth = qualify(session, tableAliases, orExpression.getRightExpression()); OrExpression or = new OrExpression(left, rigth); this._qualifiedExpression = or; } public void visit(Between between) { Between qualified = new Between(); Expression start = qualify(session, tableAliases, between.getBetweenExpressionStart()); Expression end = qualify(session, tableAliases, between.getBetweenExpressionEnd()); Expression left = qualify(session, tableAliases, between.getLeftExpression()); qualified.setBetweenExpressionStart(start); qualified.setBetweenExpressionEnd(end); qualified.setLeftExpression(left); this._qualifiedExpression = qualified; } public void visit(EqualsTo equalsTo) { visitBinaryExpression(equalsTo); } public void visit(GreaterThan greaterThan) { visitBinaryExpression(greaterThan); } public void visit(GreaterThanEquals greaterThanEquals) { visitBinaryExpression(greaterThanEquals); } public void visit(InExpression inExpression) { Expression left = qualify(session, tableAliases, inExpression.getLeftExpression()); ItemsList itemsList = ItemsListQualifier.qualify(session, tableAliases, inExpression.getItemsList()); InExpression qualified = new InExpression(); qualified.setLeftExpression(left); qualified.setItemsList(itemsList); this._qualifiedExpression = qualified; } public void visit(IsNullExpression isNullExpression) { IsNullExpression qualified = new IsNullExpression(); Expression left = qualify(session, tableAliases, isNullExpression.getLeftExpression()); qualified.setLeftExpression(left); qualified.setNot(isNullExpression.isNot()); this._qualifiedExpression = qualified; } public void visit(LikeExpression likeExpression) { visitBinaryExpression(likeExpression); } public void visit(MinorThan minorThan) { visitBinaryExpression(minorThan); } public void visit(MinorThanEquals minorThanEquals) { visitBinaryExpression(minorThanEquals); } public void visit(NotEqualsTo notEqualsTo) { visitBinaryExpression(notEqualsTo); } public void visit(Column tableColumn) { Column qualified = ColumnQualifier.qualify(session, tableAliases, tableColumn); this._qualifiedExpression = qualified; } public void visit(SubSelect subSelect) { SubSelect qualified = SubSelectQualifier.qualify(session, subSelect); this._qualifiedExpression = qualified; } @SuppressWarnings("unchecked") public void visit(CaseExpression caseExpression) { Expression switchExpr = qualify(session, tableAliases, caseExpression.getSwitchExpression()); Expression elseExpr = qualify(session, tableAliases, caseExpression.getElseExpression()); List<WhenClause> whenClauses = null; if (caseExpression.getWhenClauses() != null) { whenClauses = new ArrayList<WhenClause>(); for (Iterator<WhenClause> it = caseExpression.getWhenClauses().iterator(); it.hasNext();) { WhenClause whenClause = it.next(); WhenClause qWhen = (WhenClause) qualify(session, tableAliases, whenClause); whenClauses.add(qWhen); } } CaseExpression qualifiedWhen = new CaseExpression(); qualifiedWhen.setElseExpression(elseExpr); qualifiedWhen.setSwitchExpression(switchExpr); qualifiedWhen.setWhenClauses(whenClauses); this._qualifiedExpression = qualifiedWhen; } public void visit(WhenClause whenClause) { Expression whenExpr = qualify(session, tableAliases, whenClause.getWhenExpression()); Expression thenExpr = qualify(session, tableAliases, whenClause.getThenExpression()); WhenClause q = new WhenClause(); q.setWhenExpression(whenExpr); q.setThenExpression(thenExpr); this._qualifiedExpression = q; } }