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

import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Resource;
import csip.utils.JSONUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
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;

/**
 *
 * @Srinivas @author Rumpal Sidhu
 * @update Sandeep
 * @author Shaun Case
 */
@Name("WQM-04: Pesticide Attributes and Loss Potentials (WQMPestLossPot)")
@Description("The service consumes a request payload of one or more pesticide "
        + "application operations from a farm crop rotation for an area of "
        + "analysis, get attributes from the WQM pesticide table for each "
        + "instance of pesticide active ingredient applied. The pesticide "
        + "active ingredient attributes will be used later in WQM to compute "
        + "hazard ratings. The service computes loss potentials for pesticide "
        + "leaching, solution runoff, and adsorbed runoff also to be used later "
        + "for computing soil/pesticide interaction ratings.")
@Path("m/pestlosspot/1.0")
@Resource(from = DBResources.class)

public class V1_0 extends ModelDataService {

    //  Static defines.  Keeps the programmer from making spelling mistakes in code that breaks the algorithm.
    private static final String WPLP_SPOTTREATMENT = "Spot Treatment";
    private static final String WPLP_LOW = "LOW";
    private static final String WPLP_VERYLOW = "VERY LOW";
    private static final String WPLP_ULTRALOW = "ULTRA LOW";
    private static final String WPLP_INTERMEDIATE = "INTERMEDIATE";
    private static final String WPLP_HIGH = "HIGH";
    private static final String WPLP_FOLIARAPPLICATION = "Foliar Application";
    private static final String WPLP_BANDED = "Banded";
    private static final String WPLP_SOILINCORPORATED = "Soil Incorporated";

    //JSONArray getArray
    private HashMap<String, m.wqm.wqm04_pestlosspot.V1_0.Input> components; // store the set of all input soilcomponents as objects
    private ArrayList<m.wqm.wqm04_pestlosspot.V1_0.Result1> result1;  // store the result as objects
    private StringBuilder pest_ids;

    @Override
    // reading the inputs from the json file into input object and placing it in the arraylist
    protected void preProcess() throws Exception {
        int j = 0;
        pest_ids = new StringBuilder();
        components = new HashMap<>();
        try {
            JSONArray groups = parameter().getJSONArray("pestcomponents");
            for (int i = 0; i < groups.length(); i++) {
                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
                int AoAId = JSONUtils.getIntParam(group, "AoAId", 0);
                int operation_id = JSONUtils.getIntParam(group, "operation_id", 0);
                String op_pest_id = JSONUtils.getStringParam(group, "op_pest_id", "err");
                String app_rate = JSONUtils.getStringParam(group, "app_rate", "err");
                String app_area = JSONUtils.getStringParam(group, "app_area", "err");
                String app_method = JSONUtils.getStringParam(group, "app_method", "err");
                components.put(op_pest_id, new m.wqm.wqm04_pestlosspot.V1_0.Input(AoAId,
                        operation_id, op_pest_id, app_rate, app_area, app_method));
                if (j > 0) {
                    pest_ids.append(", ");
                } else {
                    j++;
                }
                pest_ids.append("'");
                pest_ids.append(op_pest_id);
                pest_ids.append("'");
            }
        } catch (JSONException ex) {
            LOG.log(Level.SEVERE, "Error in processing the request JSON for WQM-4!", ex);
            throw new ServiceException("Error in processing the request JSON.", ex);
        }
    }

    @Override
    protected void doProcess() throws ServiceException {
        String ai_name;
        double ai_ph;
        double ai_sol;
        double ai_koc;
        double ai_hl;
        double ai_fishtox;
        String ai_fishtoxtype;
        double ai_humtox;
        String ai_humtoxtype;
        result1 = new ArrayList<>();

        try (Connection conn = resources().getJDBC(WQM_ID);
                Statement statement = conn.createStatement()) {
            /*String query = "SELECT PC_CODE, AI_NAME, PH, SOIL_HL_RV, KOC_RV, "
                    + "SOL_RV, HUMAN_TOX_PPB, HUMAN_TOX_TYPE, FISH_TOX_PPB, "
                    + "FISH_TOX_TYPE FROM wqm.wqm_pesticides "
                    + "WHERE PC_CODE IN (" + pest_ids.toString() + ");";*/

            try (ResultSet results = statement.executeQuery(DBQueries.WQM04Query(pest_ids.toString()))) {
                while (results.next()) {
                    ai_name = results.getString("AI_NAME");
                    ai_ph = results.getDouble("PH");
                    ai_hl = results.getDouble("SOIL_HL_RV");
                    ai_koc = results.getDouble("KOC_RV");
                    ai_sol = results.getDouble("SOL_RV");
                    ai_humtox = results.getDouble("HUMAN_TOX_PPB");
                    ai_humtoxtype = results.getString("HUMAN_TOX_TYPE");
                    ai_fishtox = results.getDouble("FISH_TOX_PPB");
                    ai_fishtoxtype = results.getString("FISH_TOX_TYPE");
                    m.wqm.wqm04_pestlosspot.V1_0.Input ip = this.components.remove(results.getString("PC_CODE"));

                    //     #Compute pesticide leaching potential for each operation pesticide
                    double log_val = (Math.log10(ai_hl)) * (4 - Math.log10(ai_koc));
                    String ai_plp;
                    if (log_val >= 2.8) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_plp = WPLP_LOW;
                        } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                            ai_plp = WPLP_INTERMEDIATE;
                        } else {
                            ai_plp = WPLP_HIGH;
                        }
                    } else if ((log_val < 0.0) || ((ai_sol < 1) && (ai_hl <= 1))) {
                        ai_plp = WPLP_VERYLOW;
                    } else if (log_val <= 1.8) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_plp = WPLP_VERYLOW;
                        } else {
                            ai_plp = WPLP_LOW;
                        }
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                        ai_plp = WPLP_VERYLOW;
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                        ai_plp = WPLP_LOW;
                    } else {
                        ai_plp = WPLP_INTERMEDIATE;
                    }

                    String ai_psrp;
                    //   #Compute pesticide solution runoff potential for each operation pesticide
                    if (((ai_sol >= 1) && (ai_hl > 35) && (ai_koc < 100_000)) || (((ai_sol >= 10) && (ai_sol < 100) && (ai_koc <= 700)))) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_psrp = WPLP_LOW;
                        } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                            ai_psrp = WPLP_INTERMEDIATE;
                        } else {
                            ai_psrp = WPLP_HIGH;
                        }
                    } else if ((ai_koc >= 100_000) || ((ai_koc >= 1_000) && (ai_hl <= 1)) || ((ai_sol < 0.5) && (ai_hl < 35))) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_psrp = WPLP_VERYLOW;
                        } else {
                            ai_psrp = WPLP_LOW;
                        }
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                        ai_psrp = WPLP_VERYLOW;
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                        ai_psrp = WPLP_LOW;
                    } else {
                        ai_psrp = WPLP_INTERMEDIATE;
                    }

                    //    #Compute pesticide adsorbed runoff potential for each operation pesticide
                    String ai_parp;
                    if (((ai_hl >= 40) && (ai_koc >= 1_000)) || ((ai_hl >= 40) && (ai_koc >= 500) && (ai_sol <= 0.5))) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_parp = WPLP_LOW;
                        } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                            ai_parp = WPLP_INTERMEDIATE;
                        } else {
                            ai_parp = WPLP_HIGH;
                        }
                    } else if ((ai_hl <= 1) || ((ai_hl <= 2) && (ai_koc <= 500)) || ((ai_hl <= 4) && (ai_koc <= 900) && (ai_sol >= 0.5)) || ((ai_hl <= 40) && (ai_koc <= 500) && (ai_sol >= 0.5)) || ((ai_hl <= 50) && (ai_koc <= 900) && (ai_sol >= 2))) {
                        if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                            ai_parp = WPLP_VERYLOW;
                        } else {
                            ai_parp = WPLP_LOW;
                        }
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_SPOTTREATMENT)) || (ip.app_rate.equalsIgnoreCase(WPLP_ULTRALOW))) {
                        ai_parp = WPLP_VERYLOW;
                    } else if ((ip.app_area.equalsIgnoreCase(WPLP_BANDED)) || (ip.app_method.equalsIgnoreCase(WPLP_FOLIARAPPLICATION)) || (ip.app_method.equalsIgnoreCase(WPLP_SOILINCORPORATED)) || (ip.app_rate.equalsIgnoreCase(WPLP_LOW))) {
                        ai_parp = WPLP_LOW;
                    } else {
                        ai_parp = WPLP_INTERMEDIATE;
                    }

                    result1.add(new m.wqm.wqm04_pestlosspot.V1_0.Result1(ip.AoAId,
                            ip.operation_id, ip.op_pest_id, ip.app_rate,
                            ai_name, ai_ph, ai_hl, ai_koc, ai_sol, ai_humtox,
                            ai_humtoxtype, ai_fishtox, ai_fishtoxtype, ai_plp,
                            ai_psrp, ai_parp, ip.app_area, ip.app_method));
                }
            }
        } catch (SQLException ex) {
            LOG.log(Level.SEVERE, "SQLException for WQM-4!", ex);
            throw new ServiceException("SQL problem.", ex);
        }

    }

    @Override
    //writing the results back to JSON
    protected void postProcess() throws Exception {
        try {
            JSONArray result1Arr = new JSONArray();
            for (m.wqm.wqm04_pestlosspot.V1_0.Result1 rs1 : result1) {
                JSONArray tmpArr = new JSONArray();
                tmpArr.put(JSONUtils.dataDesc("AoAId", rs1.AoAId, "Area of Analysis Identifier"));
                tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.operation_id, "Operation ID"));
                tmpArr.put(JSONUtils.dataDesc("op_pest_id", rs1.op_pest_id, "Pesticide Identifier (PC_CODE)"));
                tmpArr.put(JSONUtils.dataDesc("app_rate", rs1.app_rate, "Pesticide Application Rating"));
                tmpArr.put(JSONUtils.dataDesc("ai_name", rs1.ai_name, "Active Ingredient Name (AI_NAME)"));
                tmpArr.put(JSONUtils.dataDesc("ai_ph", rs1.ai_ph, "Active ingredient pH of associate properties (PH)"));
                tmpArr.put(JSONUtils.dataDesc("ai_hl", rs1.ai_hl, "Active ingredient field half life (HL)"));
                tmpArr.put(JSONUtils.dataDesc("ai_koc", rs1.ai_koc, "Active ingredient soil organic carbon sorption coefficient (KOC)"));
                tmpArr.put(JSONUtils.dataDesc("ai_sol", rs1.ai_sol, "Active ingredient solubility in water (SOL)"));
                tmpArr.put(JSONUtils.dataDesc("ai_humtox", rs1.ai_humtox, "Active ingredient human toxicity value – long term"));
                tmpArr.put(JSONUtils.dataDesc("ai_humtoxtype", rs1.ai_humtoxtype, "Active ingredient human toxicity type"));
                tmpArr.put(JSONUtils.dataDesc("ai_fistox", rs1.ai_fishtox, "Active ingredient maximum acceptable toxicant concentration-fish"));
                tmpArr.put(JSONUtils.dataDesc("ai_fishtoxtype", rs1.ai_fishtoxtype, "Active ingredient fish toxicity type"));
                tmpArr.put(JSONUtils.dataDesc("ai_plp", rs1.ai_plp, "Active ingredient pesticide leaching potential"));
                tmpArr.put(JSONUtils.dataDesc("ai_psrp", rs1.ai_psrp, "Active ingredient pesticide solution runoff potential"));
                tmpArr.put(JSONUtils.dataDesc("ai_parp", rs1.ai_parp, "Active ingredient pesticide adsorbed runoff potential"));
                tmpArr.put(JSONUtils.dataDesc("op_app_area", rs1.app_area, "Pesticide application operation area"));
                tmpArr.put(JSONUtils.dataDesc("op_app_method", rs1.app_method, "Pesticide application operation method"));
                result1Arr.put(JSONUtils.dataDesc("pesticide summary", tmpArr, "Pest"));
            }
            results().put("operation", result1Arr);
        } catch (JSONException ex) {
            LOG.log(Level.SEVERE, "Error in processing the response JSON for WQM-4!", ex);
            throw new ServiceException("Error in processing the response JSON.", ex);
        }
    }

    static class Input {

        int operation_id;
        int AoAId;
        String op_pest_id;
        String app_rate;
        String app_area;
        String app_method;

        public Input(int AoAId, int operation_id, String op_pest_id,
                String app_rate, String app_area, String app_method) {
            this.AoAId = AoAId;
            this.operation_id = operation_id;
            this.op_pest_id = op_pest_id;
            this.app_rate = app_rate;
            this.app_area = app_area;
            this.app_method = app_method;

        }
    }

    static class Result1 {

        int operation_id;
        int AoAId;
        String op_pest_id;
        String app_rate;
        String app_area;
        String app_method;
        String ai_name = "";
        Double ai_ph = 0.0;
        Double ai_sol = 0.0;
        Double ai_koc = 0.0;
        Double ai_hl = 0.0;
        Double ai_fishtox = 0.0;
        String ai_fishtoxtype = "";
        Double ai_humtox = 0.0;
        String ai_humtoxtype = "";
        String ai_plp;
        String ai_psrp;
        String ai_parp;

        public Result1(int AoAId, int operation_id, String op_pest_id,
                String app_rate, String ai_name, Double ai_ph,
                Double ai_hl, Double ai_koc, Double ai_sol, Double humtox,
                String humtoxtype, Double fishtox, String fishtoxtype,
                String ai_plp, String ai_psrp, String ai_parp,
                String op_app_area, String op_app_method) {

            this.AoAId = AoAId;
            this.operation_id = operation_id;
            this.op_pest_id = op_pest_id;
            this.app_rate = app_rate;
            this.ai_name = ai_name;
            this.ai_ph = ai_ph;
            this.ai_hl = ai_hl;
            this.ai_koc = ai_koc;
            this.ai_sol = ai_sol;
            this.ai_humtox = humtox;
            this.ai_humtoxtype = humtoxtype;
            this.ai_fishtox = fishtox;
            this.ai_fishtoxtype = fishtoxtype;
            this.ai_plp = ai_plp;
            this.ai_psrp = ai_psrp;
            this.ai_parp = ai_parp;
            this.app_area = op_app_area;
            this.app_method = op_app_method;
        }
    }
}