V1_0.java [src/java/m/wqm/wqm10_soilpestlosspot] Revision:   Date:
package m.wqm.wqm10_soilpestlosspot;

import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Polling;
import csip.annotations.Resource;
import csip.utils.JSONUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.logging.Level;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import wqm.utils.DBQueries;
import wqm.utils.DBResources;
import static wqm.utils.DBResources.WQM_ID;

/**
 *
 * @author RUMPAL SIDHU
 * @author Shaun Case
 */
@Name("WQM-10: Soil Pesticide Interaction Loss Potentials (SoilPestLossPot)")
@Description("This service computes soil pesticide interaction loss potentials "
        + "for leaching, solution runoff, and adsorbed runoff.")
@Path("m/soilpestlosspot/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
public class V1_0 extends ModelDataService {

    private AoA aoa;
    private String error_msg;

    //Response
    private ArrayList<Result> result;

    @Override
    protected void preProcess() throws Exception {
        error_msg = "";
        try {
            aoa = new AoA(parameter().getString("AoAId"), parameter().getString("aoa_pslp"), parameter().getString("aoa_ssrp"),
                    parameter().getString("aoa_sarp"), parameter().getString("aoa_rain_prob"), parameter().getJSONArray("operationlist"));
            error_msg = aoa.getErrorMsg();
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, "Error in processing the request JSON for WQM-10!", ex);
            throw new ServiceException("Error in processing the request JSON.", ex);

        }
    }

    @Override
    protected void doProcess() throws Exception {

        if (error_msg.isEmpty()) {
            if (aoa.calculate()) {
                result = aoa.getResults();
            } else {
                LOG.log(Level.SEVERE, "WQM-10: " + aoa.getErrorMsg());
                throw new ServiceException(aoa.getErrorMsg());
            }

        }

        if (result == null) {
            LOG.log(Level.SEVERE, "No return data found, cannot validate "
                    + "input or results for WQM-10!");
            throw new ServiceException("  No return data found, cannot validate "
                    + "input or results.  Please check your input parameters.");
        }

    }

    @Override
    //writing the results back to JSON
    protected void postProcess() throws Exception {
        JSONArray resultArr = new JSONArray();

        if (result != null) {
            String currentOperationId = "";
            Collections.sort(result);

            //Put out the AoA top line
            results().put("AoAId", result.get(0).getAoaId(), "Area of Analysis Identifier");
            JSONArray tmpArr = new JSONArray();
            JSONArray tmpArr2 = new JSONArray();
            for (Result rs1 : result) {
                if (!rs1.getOperationId().equals(currentOperationId)) {
                    if (!currentOperationId.isEmpty()) {
                        currentOperationId = rs1.getOperationId();
                        //resultArr.put(JSONUtils.dataDesc("operation summary", tmpArr2, "Summary of this operation"));
                        tmpArr.put(JSONUtils.dataDesc("pesticideList", tmpArr2, null));

                        tmpArr2 = new JSONArray();
                        tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.getOperationId(), "Pesticide Application Operation Identifier"));
                    } else {
                        tmpArr2 = new JSONArray();
                        currentOperationId = rs1.getOperationId();
                        tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.getOperationId(), "Pesticide Application Operation Identifier"));
                    }
                }

                JSONArray tmpArr3 = new JSONArray();
                tmpArr3.put(JSONUtils.dataDesc("op_pesticide_id", rs1.getOpPesticideId(), "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"));
                tmpArr3.put(JSONUtils.dataDesc("op_pest_ilp", rs1.getOpPestIlp(), "Operation Soil Pesticide Interaction Leaching Potential"));
                tmpArr3.put(JSONUtils.dataDesc("op_pest_isrp", rs1.getOpPestIsrp(), "Operation Soil Pesticide Interaction Solution Runoff Potential"));
                tmpArr3.put(JSONUtils.dataDesc("op_pest_iarp", rs1.getOpPestIarp(), "Operation Soil Pesticide Interaction Adsorbed Runoff Potential"));

                tmpArr2.put(tmpArr3);
            }

            tmpArr.put(JSONUtils.dataDesc("pesticideList", tmpArr2, "List of Pesticides"));
            resultArr.put(tmpArr);
            results().put("operationList", resultArr);
        }
    }

    class AoA {

        private final String AoAId;
        private final String aoa_pslp;
        private final String aoa_ssrp;
        private final String aoa_sarp;
        private final String aoa_rain_prob;
        private ArrayList<pesticideOperation> pesticideOperationList;
        private String error_msg;
        ArrayList<Result> results;

        AoA(String AoAId, String aoa_pslp, String aoa_ssrp, String aoa_sarp,
                String aoa_rain_prob, JSONArray operationList) throws ServiceException {
            error_msg = "";
            this.AoAId = AoAId;
            this.aoa_pslp = aoa_pslp;
            this.aoa_ssrp = aoa_ssrp;
            this.aoa_sarp = aoa_sarp;
            this.aoa_rain_prob = aoa_rain_prob;
            pesticideOperationList = new ArrayList<>();

            //  Create pesticide operation list here...
            try {
                for (int i = 0; i < operationList.length(); i++) {
                    Map<String, JSONObject> operation
                            = JSONUtils.preprocess(operationList.getJSONArray(i));

                    pesticideOperationList.add(new pesticideOperation(
                            JSONUtils.getStringParam(operation, "operation_id", "err"),
                            this, JSONUtils.getJSONArrayParam(operation, "pesticidelist")));
                }
            } catch (JSONException ex) {
                LOG.log(Level.SEVERE, "Error in processing the request JSON for WQM-10!", ex);
                throw new ServiceException("Error in processing the request JSON.", ex);
            }
        }

        //Get Methods
        public String getAoaId() {
            return AoAId;
        }

        public String getAoa_pslp() {
            return aoa_pslp;
        }

        public String getAoa_ssrp() {
            return aoa_ssrp;
        }

        public String getAoa_sarp() {
            return aoa_sarp;
        }

        public String getAoa_rain_prob() {
            return aoa_rain_prob;
        }

        public String getErrorMsg() {
            return error_msg;
        }

        public Boolean calculate() throws ServiceException {
            Boolean ret_val = true;

            for (pesticideOperation pesticides : pesticideOperationList) {
                if (!pesticides.calculate()) {
                    ret_val = false;
                    error_msg = pesticides.getError();
                    break;
                }
            }

            return ret_val;
        }

        public ArrayList<Result> getResults() {
            results = new ArrayList<>();

            for (pesticideOperation pOperation : pesticideOperationList) {
                results = pOperation.getResult(results);
            }

            return results;
        }
    }

    class pesticideOperation {

        private final String operation_id;
        private final AoA aoa;
        private ArrayList<pesticide> pesticideList;
        private String error_msg = "";

        pesticideOperation(String operation_id, AoA aoa, JSONArray pesticides) throws ServiceException {
            this.operation_id = operation_id;
            this.aoa = aoa;
            pesticideList = new ArrayList<>();

            try {

                for (int i = 0; i < pesticides.length(); i++) {
                    Map<String, JSONObject> pesticidesData = JSONUtils.preprocess(pesticides.getJSONArray(i));
                    pesticideList.add(new pesticide(JSONUtils.getStringParam(pesticidesData, "op_pesticide_id", "err"),
                            JSONUtils.getStringParam(pesticidesData, "ai_plp", "err"),
                            JSONUtils.getStringParam(pesticidesData, "ai_psrp", "err"),
                            JSONUtils.getStringParam(pesticidesData, "ai_parp", "err")));
                }
            } catch (JSONException ex) {
                LOG.log(Level.SEVERE, "Error in processing the request JSON for WQM-10!", ex);
                throw new ServiceException("Error in processing the request JSON.", ex);
            }
        }

        String getError() {
            return error_msg;
        }

        Boolean calculate() throws ServiceException {
            Boolean ret_val = true;

            for (pesticide pst : pesticideList) {
                String tResult = pst.getILP() + " " + pst.getISRP() + " " + pst.getIARP();
                if ((tResult.contains("ERROR")) || (tResult.contains("err"))) {
                    ret_val = false;
                    error_msg += "  For operation: " + operation_id + ", " + pst.getErrorMsg();
                    break;
                }
            }

            return ret_val;
        }

        ArrayList<Result> getResult(ArrayList<Result> results) {

            for (pesticideOperation.pesticide pesticide : pesticideList) {
                results.add(pesticide.getResult());
            }

            return results;
        }

        class pesticide {

            private final String op_pesticide_id;
            private final String ai_plp;
            private final String ai_psrp;
            private final String ai_parp;
            private String error_msg = "";
            private String op_pest_ilp = "ERROR";
            private String op_pest_isrp = "ERROR";
            private String op_pest_iarp = "ERROR";

            pesticide(String op_pesticide_id, String ai_plp, String ai_psrp, String ai_parp) {
                this.op_pesticide_id = ("err".equals(op_pesticide_id) ? (error_msg = "Pesticide Id invalid or missing") : op_pesticide_id);
                this.ai_plp = ("err".equals(ai_plp) ? (error_msg = "Active Ingredient Pesticide Leaching Potential invalid or missing") : ai_plp);
                this.ai_psrp = ("err".equals(ai_psrp) ? (error_msg = "Active Ingredient Pesticide Solution Runoff Potential invalid or missing") : ai_psrp);
                this.ai_parp = ("err".equals(ai_parp) ? (error_msg = "Active Ingredient Pesticide Adsorbed Runoff Potential invalid or missing") : ai_parp);
            }

            String getILP() throws ServiceException {
                if ("ERROR".equals(op_pest_ilp)) {
                    //Calculate it
                    //conservation_resources database; wqm schema
                    /*String query = "SELECT wqm_ilp FROM wqm.wqm_soil_pest_interaction_leaching "
                            + "WHERE wqm_plp='" + ai_plp + "' AND wqm_slp='" + aoa.getAoa_pslp() + "';";*/
                    try (Connection conn = resources().getJDBC(WQM_ID);
                            Statement statement = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
                        try (ResultSet resultSet = statement.executeQuery(DBQueries.WQM10Query01(ai_plp, aoa.getAoa_pslp()))) {
                            if (resultSet.first()) {
                                op_pest_ilp = resultSet.getString("wqm_ilp");
                            } else {
                                error_msg += "For pesticide: " + op_pesticide_id + ", Cannot find that ai_plp and aoa_pslp combination in the database.";
                            }

                            if ("LOW".equals(aoa.getAoa_rain_prob())) {
                                switch (op_pest_ilp) {
                                    case "HIGH":
                                        op_pest_ilp = "INTERMEDIATE";
                                        break;
                                    case "INTERMEDIATE":
                                        op_pest_ilp = "LOW";
                                        break;
                                    case "LOW":
                                        op_pest_ilp = "VERY LOW";
                                        break;
                                }
                            }
                        }
                    } catch (SQLException ex) {
                        LOG.log(Level.SEVERE, "SQL problem for WQM-10!", ex);
                        throw new ServiceException("SQL problem.", ex);
                    }
                }

                return op_pest_ilp;
            }

            String getISRP() throws ServiceException {
                if ("ERROR".equals(op_pest_isrp)) {
                    //Calculate it
                    //conservation_resources database; wqm schema
                    /*String query = "SELECT wqm_isrp FROM wqm.wqm_soil_pest_interaction_solution_runoff "
                            + "WHERE wqm_psrp='" + ai_psrp + "' AND wqm_ssrp ='" + aoa.getAoa_ssrp() + "';";*/

                    try (Connection conn = resources().getJDBC(WQM_ID);
                            Statement statement = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
                        try (ResultSet resultSet = statement.executeQuery(DBQueries.WQM10Query02(ai_psrp, aoa.getAoa_ssrp()))) {
                            op_pest_isrp = "err";
                            if (resultSet.first()) {
                                op_pest_isrp = resultSet.getString("wqm_isrp");
                            } else {
                                LOG.log(Level.SEVERE, "WQM-10: For pesticide: " + op_pesticide_id
                                        + ", Cannot find that ai_psrp and aoa_ssrp combination in the database.");
                                throw new ServiceException("For pesticide: " + op_pesticide_id
                                        + ", Cannot find that ai_psrp and aoa_ssrp combination in the database.");
                            }

                            if ("LOW".equals(aoa.getAoa_rain_prob())) {
                                switch (op_pest_isrp) {
                                    case "HIGH":
                                        op_pest_isrp = "INTERMEDIATE";
                                        break;
                                    case "INTERMEDIATE":
                                        op_pest_isrp = "LOW";
                                        break;

                                    /*case "LOW":
                                 op_pest_isrp = "LOW";
                                 break;\
                                     */
                                }
                            }
                        }
                    } catch (SQLException ex) {
                        LOG.log(Level.SEVERE, "SQL problem for WQM-10!", ex);
                        throw new ServiceException("SQL problem.", ex);
                    }

                }

                return op_pest_isrp;
            }

            String getIARP() throws ServiceException {
                if ("ERROR".equals(op_pest_iarp)) {
                    //Calculate it
                    //conservation_resources database; wqm schema
                    /*String query = "SELECT wqm_iarp FROM wqm.wqm_soil_pest_interaction_adsorbed_runoff "
                            + "WHERE wqm_parp='" + ai_parp + "' AND wqm_sarp='" + aoa.getAoa_sarp() + "';";*/
                    try (Connection conn = resources().getJDBC(WQM_ID);
                            Statement statement = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {

                        try (ResultSet resultSet = statement.executeQuery(DBQueries.WQM10Query03(ai_parp, aoa.getAoa_sarp()))) {
                            op_pest_iarp = "err";
                            if (resultSet.first()) {
                                op_pest_iarp = resultSet.getString("wqm_iarp");
                            } else {
                                error_msg += "For pesticide: " + op_pesticide_id + ", Cannot find that ai_parp and aoa_sarp combination in the database.";
                            }

                            if ("LOW".equals(aoa.getAoa_rain_prob())) {
                                switch (op_pest_iarp) {
                                    case "HIGH":
                                        op_pest_iarp = "INTERMEDIATE";
                                        break;
                                    case "INTERMEDIATE":
                                        op_pest_iarp = "LOW";
                                        break;

                                    /*case "LOW":
                                 op_pest_iarp = "VERY LOW";
                                 break;
                                     */
                                }
                            }
                        }
                    } catch (SQLException ex) {
                        LOG.log(Level.SEVERE, "SQL problem for WQM-10!", ex);
                        throw new ServiceException("SQL problem.", ex);
                    }
                }

                return op_pest_iarp;
            }

            String getErrorMsg() {
                return error_msg;
            }

            Result getResult() {
                Result result = new Result(aoa.getAoaId(), operation_id, op_pesticide_id, op_pest_ilp, op_pest_isrp, op_pest_iarp);
                return result;
            }
        }
    }

    class Result implements Comparable<Result> {

        private final String AoAId;
        private final String operation_id;
        private final String op_pesticide_id;
        private final String op_pest_ilp;
        private final String op_pest_isrp;
        private final String op_pest_iarp;

        Result(String AoAId, String operation_id, String op_pesticide_id, String op_pest_ilp, String op_pest_isrp, String op_pest_iarp) {
            this.AoAId = AoAId;
            this.operation_id = operation_id;
            this.op_pesticide_id = op_pesticide_id;
            this.op_pest_ilp = op_pest_ilp;
            this.op_pest_isrp = op_pest_isrp;
            this.op_pest_iarp = op_pest_iarp;
        }

        public String getAoaId() {
            return AoAId;
        }

        public String getOperationId() {
            return operation_id;
        }

        public String getOpPesticideId() {
            return op_pesticide_id;
        }

        public String getOpPestIlp() {
            return op_pest_ilp;
        }

        public String getOpPestIsrp() {
            return op_pest_isrp;
        }

        public String getOpPestIarp() {
            return op_pest_iarp;
        }

        @Override
        public int compareTo(Result rs) {
            return getOperationId().compareTo(rs.getOperationId());
        }
    }
}