com.wavemaker.runtime.data.util.QueryHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.wavemaker.runtime.data.util.QueryHandler.java

Source

/*
 *  Copyright (C) 2012-2013 CloudJee, Inc. All rights reserved.
 *
 *  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 com.wavemaker.runtime.data.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.beans.PropertyDescriptor;
import java.beans.Introspector;
import java.beans.IntrospectionException;

import com.wavemaker.runtime.security.SecurityService;
import com.wavemaker.runtime.security.WMUserDetails;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.mapping.PersistentClass;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.wavemaker.common.util.StringUtils;
import com.wavemaker.common.WMRuntimeException;
import com.wavemaker.runtime.RuntimeAccess;
import com.wavemaker.runtime.WMAppContext;
import org.springframework.security.core.context.SecurityContextHolder;

/**
 * This class wraps Hibernate APIs to incorporate the tenant ID in the DB queries.
 * 
 * @author Seung Lee
 */
public class QueryHandler implements InvocationHandler {

    private Object target;

    private boolean tenantAdded;

    private final Configuration cfg;

    private final Log log = LogFactory.getLog(QueryHandler.class);

    public QueryHandler(Configuration cfg) {
        this.cfg = cfg;
    }

    public QueryHandler(Object target, Configuration cfg) {
        this.target = target;
        this.cfg = cfg;
    }

    @Override
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        String methodName = m.getName();

        if (methodName == null || methodName.length() == 0) {
            return null;
        }

        if (!methodName.equals("save") && !methodName.equals("update") && !methodName.equals("delete")
                && !methodName.equals("getNamedQuery") && !methodName.equals("get")
                && !methodName.equals("createQuery") && !methodName.equals("createSQLQuery")) {
            return m.invoke(this.target, args);
        }

        String setterName;

        WMAppContext wmApp = WMAppContext.getInstance();
        String tFldName = wmApp.getTenantFieldName();
        int tid = SecurityService.getTenantId();
        boolean tidExists = true;

        if (tid == -1) {
            tid = wmApp.getDefaultTenantID();
        }

        String qryStr;
        this.tenantAdded = false;
        if (methodName.equalsIgnoreCase("createQuery")) {
            qryStr = modifySQL(args[0], tFldName, tid);
            Query qry = (Query) m.invoke(this.target, qryStr);
            if (this.tenantAdded) {
                qry.setInteger("wmtidval", tid);
            }
            return qry;
        } else if (methodName.equalsIgnoreCase("createSQLQuery")) {
            qryStr = modifySQL(args[0], tFldName, tid);
            SQLQuery sqlqry = (SQLQuery) m.invoke(this.target, qryStr);
            if (this.tenantAdded) {
                sqlqry.setInteger("wmtidval", tid);
            }
            return sqlqry;
        } else if (methodName.equalsIgnoreCase("getNamedQuery")) {
            Map namedQueries = this.cfg.getNamedQueries();
            NamedQueryDefinition qd = (NamedQueryDefinition) namedQueries.get(args[0]);
            qryStr = qd.getQuery();
            Query qry = (Query) m.invoke(this.target, args);
            if (qryStr.contains("wmtidval")) {
                qry.setInteger("wmtidval", tid);
            }
            return qry;
        } else if (methodName.equalsIgnoreCase("get")) {
            Object o = m.invoke(this.target, args);
            Class<?> cls = o.getClass();
            Object no = cls.newInstance();
            cloneObject(o, no, cls);
            String t = tFldName.substring(0, 1).toUpperCase();
            String getterName = "get" + t + tFldName.substring(1);
            Method tidGetter = null;
            int val;
            try {
                tidGetter = cls.getMethod(getterName);
            } catch (NoSuchMethodException ne) {
                tidExists = false;
            }
            if (tidExists) {
                val = (Integer) tidGetter.invoke(o);
                if (tid != val) {
                    String err = "*** Security Viloation - Tenant ID mismatch ***";
                    err = err + "*** Tenant ID passed = " + val + ", Tenant ID of login user = " + tid + " ***";
                    throw new WMRuntimeException(err);
                }
            }
            cloneObject(no, o, cls);
            return o;
        } else if (methodName.equalsIgnoreCase("update")) {
            Object o = args[0];
            Class<?> cls = o.getClass();
            String t = tFldName.substring(0, 1).toUpperCase();
            String getterName = "get" + t + tFldName.substring(1);
            Method tidGetter = null;
            Object no;
            int val;
            try {
                tidGetter = cls.getMethod(getterName);
            } catch (NoSuchMethodException ne) {
                tidExists = false;
            }

            if (tidExists) {
                val = (Integer) tidGetter.invoke(o);
                if (tid != val) {
                    String err = "*** Security Viloation - Tenant ID mismatch ***";
                    err = err + "*** Tenant ID passed = " + val + ", Tenant ID of login user = " + tid + " ***";
                    throw new WMRuntimeException(err);
                } else {
                    no = cls.newInstance();
                    cloneObject(o, no, cls);
                    Class tcls = this.target.getClass();
                    Method rm = tcls.getMethod("refresh", Object.class);
                    rm.invoke(this.target, o);
                    val = (Integer) tidGetter.invoke(o);
                    if (tid != val) {
                        String err = "*** Security Viloation - Tenant ID mismatch ***";
                        err = err + "*** You can only update records that belong to you ***";
                        throw new WMRuntimeException(err);
                    }
                }
                cloneObject(no, o, cls);
            }
            return m.invoke(this.target, args);
        } else { // save, delete, contains
            Object o = args[0];
            Class<?> cls = o.getClass();
            String s = tFldName.substring(0, 1).toUpperCase();
            setterName = "set" + s + tFldName.substring(1);
            Method setter = null;
            try {
                setter = cls.getMethod(setterName, Integer.class);
            } catch (NoSuchMethodException ne) {
                tidExists = false;
            }
            if (tidExists) {
                setter.invoke(o, tid);
            }

            return m.invoke(this.target, args);
        }
    }

    private Object cloneObject(Object oldObj, Object newObj, Class cls) {
        PropertyDescriptor[] beanProps;
        try {
            beanProps = Introspector.getBeanInfo(cls).getPropertyDescriptors();
            for (PropertyDescriptor propertyDescriptor : beanProps) {
                if (propertyDescriptor.getName().equals("class")) {
                    continue;
                }
                Method getter = propertyDescriptor.getReadMethod();
                Method setter = propertyDescriptor.getWriteMethod();
                Object val = getter.invoke(oldObj);
                setter.invoke(newObj, val);
            }
        } catch (Exception ex) {
            throw new WMRuntimeException(ex);
        }

        return newObj;
    }

    public static List<String> parseSQL(String qryStr) {
        List<String> words = new ArrayList<String>();

        // First, break the query into word elements

        StringBuffer token = new StringBuffer();
        String twoLetters = null;
        boolean holdIt = false;

        for (int i = 0; i < qryStr.length(); i++) {
            String aLetter = qryStr.substring(i, i + 1);
            if (holdIt) {
                if (twoLetters.equals("<") && (aLetter.equals("=") || aLetter.equals(">"))
                        || twoLetters.equals(">") && aLetter.equals("=")
                        || twoLetters.equals("|") && aLetter.equals("|")
                        || twoLetters.equals("\r") && aLetter.equals("\n")) {
                    twoLetters = twoLetters + aLetter;
                    words.add(twoLetters);
                } else {
                    if (isDelimiter(aLetter)) {
                        words.add(twoLetters);
                        words.add(aLetter);
                    } else if (aLetter.equals(" ")) {
                        words.add(twoLetters);
                    }
                }
                holdIt = false;
            } else {
                if (aLetter.equals("<") || aLetter.equals(">") || aLetter.equals("|") || aLetter.equals("\r")) {
                    holdIt = true;
                    twoLetters = aLetter;
                    if (token.length() > 0) {
                        words.add(token.toString());
                        token.setLength(0);
                    }
                } else if (isDelimiter(aLetter)) {
                    if (token.length() > 0) {
                        words.add(token.toString());
                        token.setLength(0);
                    }
                    words.add(aLetter);
                } else if (aLetter.equals(" ")) {
                    if (token.length() > 0) {
                        words.add(token.toString());
                        token.setLength(0);
                    }
                } else {
                    token.append(aLetter);
                }
            }
        }

        if (token.length() > 0) {
            words.add(token.toString());
        }

        return words;
    }

    public String modifySQL(Object o, String fieldName, int tid) {
        // String qryStr = o.toString();
        List<String> words = parseSQL(o.toString());

        /*
         * ArrayList<String> words = new ArrayList<String>();
         * 
         * //First, break the query into word elements
         * 
         * StringBuffer token = new StringBuffer(); String twoLetters = null; boolean holdIt = false;
         * 
         * for (int i=0; i<qryStr.length(); i++) { String aLetter = qryStr.substring(i, i+1); if (holdIt) { if
         * ((twoLetters.equals("<") && (aLetter.equals("=") || aLetter.equals(">"))) || (twoLetters.equals(">") &&
         * aLetter.equals("=")) || (twoLetters.equals("|") && aLetter.equals("|")) || (twoLetters.equals("\r") &&
         * aLetter.equals("\n"))) { twoLetters = twoLetters + aLetter; words.add(twoLetters); } else { if
         * (isDelimiter(aLetter)) { words.add(twoLetters); words.add(aLetter); } else if (aLetter.equals(" ")) {
         * words.add(twoLetters); } } holdIt = false; } else { if (aLetter.equals("<") || aLetter.equals(">") ||
         * aLetter.equals("|") || aLetter.equals("\r")) { holdIt = true; twoLetters = aLetter; if (token.length() > 0) {
         * words.add(token.toString()); token.setLength(0); } } else if (isDelimiter(aLetter)) { if (token.length() > 0)
         * { words.add(token.toString()); token.setLength(0); } words.add(aLetter); } else if (aLetter.equals(" ")) { if
         * (token.length() > 0) { words.add(token.toString()); token.setLength(0); } } else { token.append(aLetter); } }
         * }
         * 
         * if (token.length() > 0) words.add(token.toString());
         */

        // Process the array of words

        int len = words.size();

        String word;
        int qid = -1;
        HashMap<Integer, SingleQuery> tm = new HashMap<Integer, SingleQuery>();

        String aliasName;
        int tidInsertPosition = 0;
        int openingInsertPosition = 0;

        boolean queryEndProcessed = false; // to catch a case that a single query is enclosed with multiple parenthesis
        boolean fieldInserted = false;
        boolean valueInserted = false;
        boolean addTIDValueForInsert = false;
        boolean inInsertFldList = false;
        boolean inInsertValueList = false;
        boolean firstStatement = true;

        StringBuffer sb = new StringBuffer();
        SingleQuery sq = null;

        for (int i = 0; i < len; i++) {
            word = words.get(i);
            if (byPassChar(word)) {
                sb.append(word);
                continue;
            } else if (word.equalsIgnoreCase("select")) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                if (qid > -1) {
                    tm.put(qid, sq);
                }
                qid++;
                sq = new SingleQuery("select", qid, true);
                queryEndProcessed = false;
                if (inInsertFldList) {
                    tidInsertPosition = sb.length() + 1;
                    inInsertFldList = false;
                    addTIDValueForInsert = true;
                }

            } else if (word.equalsIgnoreCase("from")) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                if (sq == null || !sq.inQuery) {
                    if (qid > -1) {
                        tm.put(qid, sq);
                    }
                    qid++;
                    sq = new SingleQuery("select", qid, true);
                }
                sq.inFrom = true;
                queryEndProcessed = false;
                sq.aliasNum = 0;

            } else if (word.equalsIgnoreCase("update") && firstStatement) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                qid++;
                sq = new SingleQuery("update", qid, true);
                queryEndProcessed = false;
                sq.inUpdate = true;
                sq.aliasNum = 0;

            } else if (word.equalsIgnoreCase("set")) {
                sb = sq.appendTableAlias(sb, words, i, fieldName);
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                sq.inSet = true;
                sq.inUpdate = false;

            } else if (word.equalsIgnoreCase("delete") && firstStatement) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                qid++;
                sq = new SingleQuery("delete", qid, true);
                queryEndProcessed = false;
                sq.inDelete = true;
                sq.aliasNum = 0;

            } else if (word.equalsIgnoreCase("insert") && words.get(i + 1).equalsIgnoreCase("into") && i == 0) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                qid++;
                sq = new SingleQuery("insert", qid, true);
                queryEndProcessed = false;

            } else if (word.equalsIgnoreCase("into") && words.get(i - 1).equalsIgnoreCase("insert")) {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                sq.inInsert = true;
                sq.aliasNum = 0;

            } else if (word.equalsIgnoreCase("where")) {
                sb = sq.appendTableAlias(sb, words, i, fieldName);
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                openingInsertPosition = sb.length() + 1;
                if (tidInsertPosition >= openingInsertPosition) {
                    tidInsertPosition++;
                }
                sq.inWhere = true;
                sq.inFrom = false;
                sq.inUpdate = false;
                sq.inSet = false;
                sq.inDelete = false;

            } else if ((word.equalsIgnoreCase("group") || word.equalsIgnoreCase("order")) // group by / order by
                    && words.get(i + 1).equalsIgnoreCase("by")) {
                if (!sq.tenantProcessed) {
                    if (sq.tableAliases.size() > 0) {
                        if (sq.inWhere) {
                            sb.insert(openingInsertPosition, "(");
                            if (tidInsertPosition >= openingInsertPosition) {
                                tidInsertPosition++;
                            }
                            sb.append(") and (");
                            sb.append(insertTenantID(sq, fieldName));
                            sb.append(")");
                        } else {
                            sb.append(" where ");
                            sb.append(insertTenantID(sq, fieldName));
                        }
                    }
                    sq.tenantProcessed = true;
                }
                sb = sq.appendTableAlias(sb, words, i, fieldName);
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                sq.inFrom = false;
                sq.inWhere = false;
                sq.inSet = false;

            } else if (word.equalsIgnoreCase("(")) {
                if (sq.inInsert && !inInsertFldList && !inInsertValueList) {
                    sq.inInsert = false;
                    inInsertFldList = true;
                }
                sq.openings = sq.openings + 1;
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);

            } else if (word.equalsIgnoreCase(")")) { // end of the current query statement
                if (sq.openings <= 0) {
                    if (!queryEndProcessed) {
                        sb = sq.appendTableAlias(sb, words, i, fieldName);
                        if (!sq.tenantProcessed) {
                            if (sq.tableAliases.size() > 0) {
                                if (sq.inWhere) {
                                    sb.insert(openingInsertPosition, "(");
                                    if (tidInsertPosition >= openingInsertPosition) {
                                        tidInsertPosition++;
                                    }
                                    sb.append(") and (");
                                    sb.append(insertTenantID(sq, fieldName));
                                    sb.append(")");
                                } else {
                                    sb.append(" where ");
                                    sb.append(insertTenantID(sq, fieldName));
                                }
                            }
                            sq.tenantProcessed = true;
                        }

                        sq.inFrom = false;
                        sq.inWhere = false;
                        sq.inUpdate = false;
                        sq.inSet = false;
                        sq.inDelete = false;
                        sq.inInsert = false;
                        sq.inQuery = false;

                        qid--;

                        sq = tm.get(qid); // get parent sql object
                        queryEndProcessed = true;
                    }
                } else {
                    sq.openings = sq.openings - 1;
                }
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);

            } else if (word.equalsIgnoreCase("values")) {
                if (inInsertFldList) {
                    inInsertFldList = false;
                    inInsertValueList = true;
                }
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
            } else if (word.equalsIgnoreCase("inner") || // misc key words that must turn off inForm flag
                    word.equalsIgnoreCase("left") || word.equalsIgnoreCase("right") || word.equalsIgnoreCase("full")
                    || word.equalsIgnoreCase("join") || word.equalsIgnoreCase("fetch")) {
                sb = sq.appendTableAlias(sb, words, i, fieldName);
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
                sq.inFrom = false;

            } else if (sq.queryType.equalsIgnoreCase("select") && sq.inFrom
                    || sq.queryType.equalsIgnoreCase("update") && sq.inUpdate
                    || sq.queryType.equalsIgnoreCase("delete") && sq.inDelete) { // populate table names array
                if (!word.equalsIgnoreCase("as") && !word.equalsIgnoreCase("\r\n") && !word.equalsIgnoreCase("\n")
                        && !word.equalsIgnoreCase(",")) {
                    if (sq.alias) {
                        sq.addAliasNames(words, i, fieldName, word);
                        sq.alias = false;
                        sq.qryIncludeAlias = true;
                    } else {
                        sq.alias = true;
                    }
                }

                if (word.equalsIgnoreCase(",")) {
                    sb = sq.appendTableAlias(sb, words, i, fieldName);
                }

                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
            } else if (inInsertFldList && !fieldInserted) { // add tid in the field list
                sb.append(fieldName);
                sb.append(", ");
                fieldInserted = true;
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
            } else if (inInsertValueList && !valueInserted) {
                sb.append(tid);
                sb.append(", ");
                valueInserted = true;
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
            } else {
                if (appendSpace(sb.toString(), word)) {
                    sb.append(" ");
                }
                sb.append(word);
            }
            firstStatement = false;
        }

        if (sq.inFrom && !sq.qryIncludeAlias) {
            aliasName = "table" + sq.aliasNum++;
            if (appendSpace(sb.toString(), aliasName)) {
                sb.append(" ");
            }
            sb.append(aliasName);
            sq.addAliasNames(words, len - 1, fieldName, aliasName);
        }

        if (!sq.tenantProcessed) {
            if (sq.tableAliases.size() > 0) {
                if (sq.inWhere) {
                    sb.insert(openingInsertPosition, "(");
                    if (tidInsertPosition >= openingInsertPosition) {
                        tidInsertPosition++;
                    }
                    sb.append(") and (");
                    sb.append(insertTenantID(sq, fieldName));
                    sb.append(")");
                } else {
                    sb.append(" where ");
                    sb.append(insertTenantID(sq, fieldName));
                }
            }
            sq.tenantProcessed = true;
        }

        if (addTIDValueForInsert) { // add tid value in the field list
            String tidfld = sq.tableAliases.get(0) + "." + fieldName + ", ";
            sb.insert(tidInsertPosition, tidfld);
        }

        return sb.toString();
    }

    private String insertTenantID(SingleQuery sq, String tField) {
        StringBuffer sb = new StringBuffer();
        int cnt = 0;
        for (String table : sq.tableAliases) {
            if (cnt > 0) {
                sb.append(" and ");
            }
            sb.append(table);
            sb.append(".");
            sb.append(tField);
            sb.append(" = :wmtidval");
            this.tenantAdded = true;
            cnt++;
        }

        return sb.toString();
    }

    public static boolean isDelimiter(String val) {
        // String[] list = {"+", "-", "*", "/", "=", "<=", ">=", "<>", "<", ">",
        // "!=", "||", "(", ")", "\r\n", "\n", ","};
        String[] list = { "+", "-", "*", "/", "=", "<", ">", "!=", "(", ")", "\n", ",", "\r" };

        for (String s : list) {
            if (s.equalsIgnoreCase(val)) {
                return true;
            }
        }

        return false;
    }

    private boolean byPassChar(String val) {
        String[] list = { "+", "-", "*", "/", "=", "<", ">", "!=", "\n", "\r" };

        for (String s : list) {
            if (s.equalsIgnoreCase(val)) {
                return true;
            }
        }

        return false;
    }

    private boolean appendSpace(String str, String word) {
        if (str.length() == 0 || str.endsWith("(") || str.endsWith(" ")) {
            return false;
        }
        if (word.startsWith(")") || word.startsWith(",") || word.startsWith(" ")) {
            return false;
        }
        return true;
    }

    private boolean tenantFieldExists(String className, String fldName) {

        try {
            Iterator classList = this.cfg.getClassMappings();
            while (classList.hasNext()) {
                Class cls = ((PersistentClass) classList.next()).getMappedClass();
                String clsName = StringUtils.getClassName(cls.getName());
                if (clsName.equals(StringUtils.getClassName(className))) {
                    String s = fldName.substring(0, 1).toUpperCase();
                    String setterName = "set" + s + fldName.substring(1);
                    cls.getMethod(setterName, Integer.class);
                    return true;
                }
            }
        } catch (NoSuchMethodException ne) {
            return false;
        }
        return false;
    }

    private int getFirstNoneDelimiterPosBackward(int pos, List<String> words) {
        for (int i = pos; i > -1; i--) {
            if (!isDelimiter(words.get(i))) {
                return i;
            }
        }

        return -1;
    }

    class SingleQuery {

        String queryType;

        int parentQueryId;

        int queryId;

        int openings = 0; // number of left parenthesis

        boolean inFrom = false;

        boolean inWhere = false;

        boolean inQuery = false;

        boolean inSet = false;

        boolean inUpdate = false;

        boolean inDelete = false;

        boolean inInsert = false;

        boolean tenantProcessed = false;

        boolean alias = false;

        int aliasNum = 0;

        boolean qryIncludeAlias = false;

        ArrayList<String> tableAliases = new ArrayList<String>();

        private SingleQuery(String qtype, int qid, boolean flag) {
            this.queryType = qtype;
            this.queryId = qid;
            this.inQuery = flag;
        }

        private void addAliasNames(List<String> words, int indx, String fieldName, String alias) {
            String tableClassName;
            int indx1 = getFirstNoneDelimiterPosBackward(indx, words);
            if (indx1 < 0) {
                return;
            }
            int indx2 = getFirstNoneDelimiterPosBackward(indx1 - 1, words);
            if (indx2 < 0) {
                return;
            }
            int indx3 = getFirstNoneDelimiterPosBackward(indx2 - 1, words);

            String val1 = words.get(indx1);
            String val2 = words.get(indx2);

            if (indx3 < 0) {
                if (!val2.equalsIgnoreCase("from")) {
                    tableClassName = val2;
                } else {
                    tableClassName = val1;
                }
            } else if (val2.equalsIgnoreCase("as")) {
                tableClassName = words.get(indx3);
            } else {
                if (!val2.equalsIgnoreCase("from")) {
                    tableClassName = val2;
                } else {
                    tableClassName = val1;
                }
            }

            if (tenantFieldExists(tableClassName, fieldName)) {
                this.tableAliases.add(alias);
            }
        }

        private StringBuffer appendTableAlias(StringBuffer sb, List<String> words, int indx, String fieldName) {
            if ((this.queryType.equalsIgnoreCase("select") && this.inFrom
                    || this.queryType.equalsIgnoreCase("insert") && this.inInsert
                    || this.queryType.equalsIgnoreCase("update") && this.inUpdate
                    || this.queryType.equalsIgnoreCase("delete") && this.inDelete) && !this.qryIncludeAlias) {
                String tableClassName;
                if (words.get(indx - 1).equalsIgnoreCase("as")) {
                    tableClassName = words.get(indx - 2);
                } else {
                    tableClassName = words.get(indx - 1);
                }

                if (tenantFieldExists(tableClassName, fieldName)) {
                    String aliasName = "table" + this.aliasNum++;
                    if (appendSpace(sb.toString(), aliasName)) {
                        sb.append(" ");
                    }
                    sb.append(aliasName);
                    this.tableAliases.add(aliasName);
                    this.alias = false;
                }
            }
            return sb;
        }
    }
}