SearchFilter.java [src/java/m/wqm/wqm03_pesticideattributes] Revision:   Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package m.wqm.wqm03_pesticideattributes;

import csip.api.server.ServiceException;
import csip.utils.JSONUtils;
import java.util.Map;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
class SearchFilter {

    private static final String[] compareTypes = {"begins_with", "ends_with", "contains", "is_exactly"};
    private SearchFilter.columnName filterName;
    private String searchValue = "";
    private int compareTypeIdx = -1;  //Error condition value.  If still set to -1 after the below for-loop then there was an error.

    SearchFilter(JSONArray filterArray) throws ServiceException {
        try {
            Map<String, JSONObject> filterMap = JSONUtils.preprocess(filterArray);
            if (filterMap.containsKey("pp_filter_name")) {
                filterName = new SearchFilter.columnName(filterMap.get("pp_filter_name").getString("value"));
                if (filterMap.containsKey("pp_filter_value")) {
                    searchValue = filterMap.get("pp_filter_value").getString("value");
                    for (int i = 0; i < compareTypes.length; i++) {
                        if (filterMap.containsKey(compareTypes[i])) {
                            if (filterMap.get(compareTypes[i]).getBoolean("value")) {
                                if (-1 == compareTypeIdx) {
                                    compareTypeIdx = i;
                                } else {
                                    throw new ServiceException("Only one form of compare type is allowed per filter.");
                                }
                            }
                        }
                    }

                    if (-1 == compareTypeIdx) {
                        String availableCompares = "";
                        for (int i = 0; i < compareTypes.length; i++) {
                            availableCompares += ((i > 0) ? ", " : "") + compareTypes[i];
                        }
                        throw new ServiceException("Missing a compare method type parameter for this filter name, [" + filterName.getName() + "], request. Available compare types are: " + availableCompares);
                    } else {
                        if (filterName.isInteger() && (!compareTypes[compareTypeIdx].equals("is_exactly"))) {
                            throw new ServiceException("The filter name specified, [" + filterName.getName() + "], requires the use of the 'is_exactly' compare type.");
                        }
                    }
                } else {
                    throw new ServiceException("Missing 'pp_filter_value' parameter for this filter request.  Cannot proceed.");
                }
            } else {
                throw new ServiceException("Missing 'pp_filter_name' parameter for this filter request.  Cannot proceed.");
            }

        } catch (JSONException ex) {
            throw new ServiceException("JSONException", ex);
        }

        if (!filterName.isValid()) {
            throw new ServiceException("Filter name specified is not a valid column name.  Cannot proceed.");
        }
    }

    boolean isIntegerType() {
        return filterName.isInteger();
    }

    String getWhereCondition() {
        String ret_val = "";

        if (filterName.isValid() && !filterName.isInteger() && compareTypeIdx >= 0 && compareTypeIdx < compareTypes.length) {
            ret_val = searchValue;
        }

        return ret_val;
    }

    String getWhereClause() {
        String ret_val = "";

        if (filterName.isValid() && compareTypeIdx >= 0 && compareTypeIdx < compareTypes.length) {
            if (!filterName.isInteger()) {
                if (compareTypes[compareTypeIdx].equals("is_exactly")) {
                    ret_val = "( " + filterName.getFullName() + "=? )";
                } else {
                    ret_val = "( " + filterName.getFullName() + " LIKE ";
                    if (compareTypes[compareTypeIdx].equals("begins_with") && !filterName.isInteger()) {
                        ret_val += "CONCAT(?,'%')";
                    } else if (compareTypes[compareTypeIdx].equals("contains") && !filterName.isInteger()) {
                        ret_val += "CONCAT('%',?,'%')";
                    } else if (compareTypes[compareTypeIdx].equals("ends_with") && !filterName.isInteger()) {
                        ret_val += "CONCAT('%',?)";
                    }

                    ret_val += " ) ";

                }
            } else if (compareTypes[compareTypeIdx].equals("is_exactly")) {
                ret_val = "( " + filterName.getFullName() + "=" + Integer.parseInt(searchValue) + " )";
            }
        }

        return ret_val;
    }

    //  Since the column names used in the filter are constrained, this class will help
    // ensure that the contraints are adhered to.
    protected static class columnName {

        protected static final String names[] = {"reg_no", "prod_name", "type_desc", "pc_code", "ai_name", "epa_code", "company_code", "product_code", "product_row_id"};
        protected static final String fullNames[] = {"wqm.d_pesticides_products.reg_no", "wqm.d_pesticides_products.prod_name", "type_desc",
            "wqm.d_pesticides_formula.pc_code", "wqm.d_pesticides_ais.ai_name", "wqm.d_pesticides_products.epa_code",
            "wqm.d_pesticides_products.company_code", "wqm.d_pesticides_products.product_code", "wqm.d_pesticides_products.Id"};
        protected int nameIdx;
        protected static int NAMES_LEN = names.length;
        protected String Type = "string";

        columnName(String cName) {
            nameIdx = -1;
            for (int i = 0; i < NAMES_LEN; i++) {
                if (names[i].equals(cName)) {
                    nameIdx = i;
                    break;
                }
            }

            switch (nameIdx) {
                case 6:
                case 7:
                case 8:
                    Type = "integer";
            }

        }

        public boolean isInteger() {
            return Type.equals("integer");
        }

        public String getType() {
            return Type;
        }

        public String getFullName() {
            String ret_val = "";
            if ((nameIdx >= 0) && (nameIdx <= NAMES_LEN)) {
                ret_val = fullNames[nameIdx];
            }
            return ret_val;
        }

        public String getName() {
            String ret_val = "";
            if ((nameIdx >= 0) && (nameIdx <= NAMES_LEN)) {
                ret_val = names[nameIdx];
            }
            return ret_val;
        }

        public boolean isValid() {
            return ((nameIdx >= 0) && (nameIdx <= NAMES_LEN));
        }
    }
}