Package org.teiid.translator.salesforce.execution.visitors

Source Code of org.teiid.translator.salesforce.execution.visitors.CriteriaVisitor

/*
* 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.translator.salesforce.execution.visitors;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.teiid.language.AndOr;
import org.teiid.language.ColumnReference;
import org.teiid.language.Comparison;
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.In;
import org.teiid.language.Like;
import org.teiid.language.Literal;
import org.teiid.language.NamedTable;
import org.teiid.language.Not;
import org.teiid.language.Comparison.Operator;
import org.teiid.language.visitor.HierarchyVisitor;
import org.teiid.metadata.Column;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.metadata.Table;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.salesforce.SalesForcePlugin;
import org.teiid.translator.salesforce.Util;


/**
* Parses Criteria in support of all of the ExecutionImpl classes.
*/
public abstract class CriteriaVisitor extends HierarchyVisitor implements ICriteriaVisitor {

    private static final String RESTRICTEDMULTISELECTPICKLIST = "restrictedmultiselectpicklist"; //$NON-NLS-1$
  private static final String MULTIPICKLIST = "multipicklist"; //$NON-NLS-1$
  protected static final String SELECT = "SELECT"; //$NON-NLS-1$
    protected static final String FROM = "FROM"; //$NON-NLS-1$
    protected static final String WHERE = "WHERE"; //$NON-NLS-1$
    protected static final String ORDER_BY = "ORDER BY"; //$NON-NLS-1$
    protected static final String LIMIT = "LIMIT"; //$NON-NLS-1$
    protected static final String SPACE = " "; //$NON-NLS-1$
    protected static final String EXCLUDES = "EXCLUDES"; //$NON-NLS-1$
    protected static final String INCLUDES = "includes"; //$NON-NLS-1$
    protected static final String COMMA = ","; //$NON-NLS-1$
    protected static final String SEMI = ";"; //$NON-NLS-1$
    protected static final String APOS = "'"; //$NON-NLS-1$
    protected static final String OPEN = "("; //$NON-NLS-1$
    protected static final String CLOSE = ")"; //$NON-NLS-1$

    protected RuntimeMetadata metadata;
    private HashMap<Comparison.Operator, String> comparisonOperators;
    protected List<String> criteriaList = new ArrayList<String>();
    protected boolean hasCriteria;
    protected Map<String, Column> columnElementsByName = new HashMap<String, Column>();
    protected List<TranslatorException> exceptions = new ArrayList<TranslatorException>();
    protected Table table;
    boolean onlyIDCriteria;
    protected Boolean queryAll = Boolean.FALSE;
 
    // support for invoking a retrieve when possible.
    protected In idInCriteria = null;
 

    public CriteriaVisitor( RuntimeMetadata metadata ) {
        this.metadata = metadata;
        comparisonOperators = new HashMap<Comparison.Operator, String>();
        comparisonOperators.put(Operator.EQ, "="); //$NON-NLS-1$
        comparisonOperators.put(Operator.GE, ">="); //$NON-NLS-1$
        comparisonOperators.put(Operator.GT, ">"); //$NON-NLS-1$
        comparisonOperators.put(Operator.LE, "<="); //$NON-NLS-1$
        comparisonOperators.put(Operator.LT, "<"); //$NON-NLS-1$
        comparisonOperators.put(Operator.NE, "!="); //$NON-NLS-1$
    }

    @Override
    public void visit( Comparison criteria ) {
        super.visit(criteria);
        try {
            addCompareCriteria(criteriaList, criteria);
            boolean isAcceptableID = (Operator.EQ == criteria.getOperator() && isIdColumn(criteria.getLeftExpression()));
            setHasCriteria(true, isAcceptableID);
            if (isAcceptableID) {
              this.idInCriteria = new In(criteria.getLeftExpression(), Arrays.asList(criteria.getRightExpression()), false);
            }
        } catch (TranslatorException e) {
            exceptions.add(e);
        }
    }

    @Override
    public void visit( Like criteria ) {
        try {
            if (isIdColumn(criteria.getLeftExpression())) {
                TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.Id")); //$NON-NLS-1$
                exceptions.add(e);
            }
            if (isMultiSelectColumn(criteria.getLeftExpression())) {
                TranslatorException e = new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.LIKE.not.supported.on.multiselect")); //$NON-NLS-1$
                exceptions.add(e);
            }
        } catch (TranslatorException e) {
            exceptions.add(e);
        }
        boolean negated = criteria.isNegated();
        criteria.setNegated(false);
        criteriaList.add(criteria.toString());
        if (negated) {
          addNot();
          criteria.setNegated(true);
        }
        // don't check if it's ID, Id LIKE '123%' still requires a query
        setHasCriteria(true, false);
    }
   
    @Override
    public void visit(AndOr obj) {
      List<String> savedCriteria = new LinkedList<String>();
      savedCriteria.add(OPEN);
    super.visitNode(obj.getLeftCondition());
    savedCriteria.addAll(this.criteriaList);
    this.criteriaList.clear();
    savedCriteria.add(CLOSE);
    savedCriteria.add(SPACE);
    savedCriteria.add(obj.getOperator().toString());
    savedCriteria.add(SPACE);
    savedCriteria.add(OPEN);
    super.visitNode(obj.getRightCondition());
    savedCriteria.addAll(this.criteriaList);
    this.criteriaList.clear();
    this.criteriaList = savedCriteria;
    this.criteriaList.add(CLOSE);
    }
   
    @Override
    public void visit(Not obj) {
      super.visit(obj);
      addNot();
    }

  private void addNot() {
    if (!criteriaList.isEmpty()) {
        criteriaList.add(0, "NOT ("); //$NON-NLS-1$
        criteriaList.add(CLOSE);
      }
  }

    @Override
    public void visit( In criteria ) {
        try {
            Expression lExpr = criteria.getLeftExpression();
            if (lExpr instanceof ColumnReference) {
              ColumnReference cr = (ColumnReference)lExpr;
                Column column = cr.getMetadataObject();
                if (column != null && (MULTIPICKLIST.equalsIgnoreCase(column.getNativeType()) || RESTRICTEDMULTISELECTPICKLIST.equalsIgnoreCase(column.getNativeType()))) {
                    appendMultiselectIn(column, criteria);
                } else {
                    appendCriteria(criteria);
                }
            } else {
              appendCriteria(criteria);
            }
            setHasCriteria(true, isIdColumn(criteria.getLeftExpression()));
        } catch (TranslatorException e) {
            exceptions.add(e);
        }
    }

    public void parseFunction( Function func ) {
        String functionName = func.getName();
        try {
            if (functionName.equalsIgnoreCase("includes")) { //$NON-NLS-1$
                generateMultiSelect(func, INCLUDES);
            } else if (functionName.equalsIgnoreCase("excludes")) { //$NON-NLS-1$
                generateMultiSelect(func, EXCLUDES);
            }
        } catch (TranslatorException e) {
            exceptions.add(e);
        }
    }

    private void generateMultiSelect( Function func,
                                      String funcName ) throws TranslatorException {
        List<Expression> expressions = func.getParameters();
        validateFunction(expressions);
        Expression columnExpression = expressions.get(0);
        Column column = ((ColumnReference)columnExpression).getMetadataObject();
        StringBuffer criterion = new StringBuffer();
        criterion.append(column.getNameInSource()).append(SPACE).append(funcName);
        addFunctionParams((Literal)expressions.get(1), criterion);
        criteriaList.add(criterion.toString());
    }

    private void appendMultiselectIn( Column column,
                                      In criteria ) throws TranslatorException {
        StringBuffer result = new StringBuffer();
        result.append(column.getNameInSource()).append(SPACE);
        if (criteria.isNegated()) {
            result.append(EXCLUDES).append(SPACE);
        } else {
            result.append(INCLUDES).append(SPACE);
        }
        result.append('(');
        List<Expression> rightExpressions = criteria.getRightExpressions();
        Iterator<Expression> iter = rightExpressions.iterator();
        boolean first = true;
        while (iter.hasNext()) {
            Expression rightExpression = iter.next();
            if (first) {
                result.append(rightExpression.toString());
                first = false;
            } else {
                result.append(COMMA).append(rightExpression.toString());
            }

        }
        result.append(')');
        criteriaList.add(result.toString());
    }

    private void validateFunction( List<Expression> expressions ) throws TranslatorException {
        if (expressions.size() != 2) {
            throw new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.invalid.arg.count")); //$NON-NLS-1$
        }
        if (!(expressions.get(0) instanceof ColumnReference)) {
            throw new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.function.not.column.arg")); //$NON-NLS-1$
        }
        if (!(expressions.get(1) instanceof Literal)) {
            throw new TranslatorException(SalesForcePlugin.Util.getString("CriteriaVisitor.function.not.literal.arg")); //$NON-NLS-1$
        }
    }

    private void addFunctionParams( Literal param,
                                    StringBuffer criterion ) {
        criterion.append(OPEN);
        boolean first = true;
        String fullParam = param.toString();
        String[] params = fullParam.split(","); //$NON-NLS-1$
        for (int i = 0; i < params.length; i++) {
            String token = params[i];
            if (first) {
                criterion.append(SPACE).append(Util.addSingleQuotes(token));
                first = false;
            } else {
                criterion.append(COMMA).append(SPACE).append(Util.addSingleQuotes(token));
            }
        }
        criterion.append(CLOSE);
    }

    protected void addCompareCriteria( List criteriaList,
                                       Comparison compCriteria ) throws TranslatorException {
        Expression lExpr = compCriteria.getLeftExpression();
        if (lExpr instanceof Function) {
            parseFunction((Function)lExpr);
        } else {
            ColumnReference left = (ColumnReference)lExpr;
            Column column = left.getMetadataObject();
            String columnName = column.getNameInSource();
            StringBuffer queryString = new StringBuffer();
            queryString.append(column.getParent().getNameInSource());
            queryString.append('.');
            queryString.append(columnName).append(SPACE);
            queryString.append(comparisonOperators.get(compCriteria.getOperator()));
            queryString.append(' ');
            Expression rExp = compCriteria.getRightExpression();
            if(rExp instanceof Literal) {
              Literal literal = (Literal)rExp;
              if (column.getJavaType().equals(Boolean.class)) {
                queryString.append(((Boolean)literal.getValue()).toString());
              } else if (column.getJavaType().equals(java.sql.Timestamp.class)) {
                Timestamp datetime = (java.sql.Timestamp)literal.getValue();
                String value = Util.getSalesforceDateTimeFormat().format(datetime);
                String zoneValue = Util.getTimeZoneOffsetFormat().format(datetime);
                queryString.append(value).append(zoneValue.subSequence(0, 3)).append(':').append(zoneValue.subSequence(3, 5));
              } else if (column.getJavaType().equals(java.sql.Time.class)) {
                String value = Util.getSalesforceDateTimeFormat().format((java.sql.Time)literal.getValue());
                queryString.append(value);
              } else if (column.getJavaType().equals(java.sql.Date.class)) {
                String value = Util.getSalesforceDateFormat().format((java.sql.Date)literal.getValue());
                queryString.append(value);
              } else {
                queryString.append(compCriteria.getRightExpression().toString());
              }
            } else if(rExp instanceof ColumnReference) {
              ColumnReference right = (ColumnReference)lExpr;
                column = left.getMetadataObject();
                columnName = column.getNameInSource();
                queryString.append(columnName);
            }

            criteriaList.add(queryString.toString());

            if (columnName.equals("IsDeleted")) { //$NON-NLS-1$
                Literal isDeletedLiteral = (Literal)compCriteria.getRightExpression();
                Boolean isDeleted = (Boolean)isDeletedLiteral.getValue();
                if (isDeleted) {
                    this.queryAll = isDeleted;
                }
            }
        }
    }

    private void appendCriteria( In criteria ) throws TranslatorException {
        StringBuffer queryString = new StringBuffer();
        Expression leftExp = criteria.getLeftExpression();
        if(isIdColumn(leftExp)) {
          idInCriteria  = criteria;
        }
        queryString.append(getValue(leftExp));
        queryString.append(' ');
        if (criteria.isNegated()) {
            queryString.append("NOT "); //$NON-NLS-1$
        }
        queryString.append("IN"); //$NON-NLS-1$
        queryString.append('(');
        Column column = ((ColumnReference)criteria.getLeftExpression()).getMetadataObject();
        boolean timeColumn = isTimeColumn(column);
        boolean first = true;
        Iterator iter = criteria.getRightExpressions().iterator();
        while (iter.hasNext()) {
            if (!first) queryString.append(',');
            if (!timeColumn) queryString.append('\'');
            queryString.append(getValue((Expression)iter.next()));
            if (!timeColumn) queryString.append('\'');
            first = false;
        }
        queryString.append(')');
        criteriaList.add(queryString.toString());
    }

    private boolean isTimeColumn( Column column ) throws TranslatorException {
        boolean result = false;
        if (column.getJavaType().equals(java.sql.Timestamp.class) || column.getJavaType().equals(java.sql.Time.class)
            || column.getJavaType().equals(java.sql.Date.class)) {
            result = true;
        }
        return result;
    }

    protected String getValue( Expression expr ) throws TranslatorException {
        String result;
        if (expr instanceof ColumnReference) {
            ColumnReference element = (ColumnReference)expr;
            Column element2 = element.getMetadataObject();
            result = element2.getNameInSource();
        } else if (expr instanceof Literal) {
            Literal literal = (Literal)expr;
            result = literal.getValue().toString();
        } else {
            throw new RuntimeException("unknown type in SalesforceQueryExecution.getValue(): " + expr.toString()); //$NON-NLS-1$
        }
        return result;
    }

    protected void loadColumnMetadata( NamedTable group ) throws TranslatorException {
        table = group.getMetadataObject();
        String supportsQuery = table.getProperties().get("Supports Query"); //$NON-NLS-1$
        if (!Boolean.valueOf(supportsQuery)) {
            throw new TranslatorException(table.getNameInSource() + " " + SalesForcePlugin.Util.getString("CriteriaVisitor.query.not.supported")); //$NON-NLS-1$ //$NON-NLS-2$
        }
        List<Column> columnIds = table.getColumns();
        for (Column element : columnIds) {
            // influences queryAll behavior
            if (element.getNameInSource().equals("IsDeleted")) { //$NON-NLS-1$
                String isDeleted = element.getDefaultValue();
                if (Boolean.parseBoolean(isDeleted)) {
                    this.queryAll = true;
                }
            }
        }
    }

    protected boolean isIdColumn( Expression expression ) throws TranslatorException {
        boolean result = false;
        if (expression instanceof ColumnReference) {
            Column element = ((ColumnReference)expression).getMetadataObject();
            String nameInSource = element.getNameInSource();
            if (nameInSource.equalsIgnoreCase("id")) { //$NON-NLS-1$
                result = true;
            }
        }
        return result;
    }

    protected boolean isMultiSelectColumn( Expression expression ) throws TranslatorException {
        boolean result = false;
        if (expression instanceof ColumnReference) {
            Column element = ((ColumnReference)expression).getMetadataObject();
            String nativeType = element.getNativeType();
            if (MULTIPICKLIST.equalsIgnoreCase(nativeType) || RESTRICTEDMULTISELECTPICKLIST.equalsIgnoreCase(nativeType)) {
                result = true;
            }
        }
        return result;
    }

    public boolean hasCriteria() {
        return hasCriteria;
    }

    public void setHasCriteria( boolean hasCriteria,
                                boolean isIdCriteria ) {
        if (isIdCriteria) {
            if (hasCriteria()) {
                this.onlyIDCriteria = false;
            } else {
                this.onlyIDCriteria = true;
            }
        } else if (this.onlyIDCriteria) {
            this.onlyIDCriteria = false;
        }
        this.hasCriteria = hasCriteria;
    }

    public boolean hasOnlyIDCriteria() {
        return this.onlyIDCriteria;
    }

    public String getTableName() throws TranslatorException {
        return table.getNameInSource();
    }
   
    protected void addCriteriaString(StringBuffer result) {
      if(hasCriteria()) {
      result.append(WHERE).append(SPACE);
      for (String string : criteriaList) {
        result.append(string);
      }
      result.append(SPACE);
    }
  }
}
TOP

Related Classes of org.teiid.translator.salesforce.execution.visitors.CriteriaVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.