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

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

/**
 * WQM-15: Sediment and Nutrient Practice Scores
 *
 * @author SrinivasReddy kontham
 * @author Shaun Case
 * @author Rumpal Sidhu
 *
 * @version 1.0
 */
@Name("WQM-15: Sediment and Nutrient Practice Scores (SedNutPractScores)")
@Description("This service computes scores for conservation practices applied "
        + "to mitigate nitrogen leaching, sediment runoff, nitrogen runoff, "
        + "and phosphorus runoff loss potential.")
@Path("m/nut_pract_scores/1.0")
@Resource(from = DBResources.class)

public class V1_0 extends ModelDataService {

    private int aoaId;
    private ArrayList<Practice> practiceList = new ArrayList<>();
    private PracticeScore practiceScores = new PracticeScore();

    @Override
    protected void preProcess() throws ServiceException, JSONException {
        aoaId = parameter().getInt("AoAId", 0);
        JSONArray groups = parameter().getJSONArray("practice_list");
        for (int i = 0; i < groups.length(); i++) {
            Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
            int id = JSONUtils.getIntParam(group, "plan_practice_id", 0);
            String discrimType = JSONUtils.getStringParam(group, "plan_practice_discrim_type", null);
            int discrimValue = JSONUtils.getIntParam(group, "plan_practice_discrim_value", 0);

            if (discrimType != null && discrimType.isEmpty()) {
                discrimType = null;
            }
            practiceList.add(new Practice(id, discrimType, discrimValue));
        }
    }

    @Override
    protected void doProcess() throws ServiceException, SQLException {
        try (Connection conn = resources().getJDBC(WQM_ID);) {
            for (Practice input : practiceList) {
                practiceScores.compute(conn, input);
            }
        }
    }

    @Override
    protected void postProcess() throws JSONException {
        results().put("AoAId", aoaId, "Area of Analysis Identifier");
        results().put("nleach_pract_score", practiceScores.nleach_pract_score, " Nitrogen Leaching Practice Mitigation Score");
        results().put("nsurf_pract_score", practiceScores.nsurf_pract_score, "Sediment Runoff Practice Mitigation Score");
        results().put("ssurf_pract_score", practiceScores.ssurf_pract_score, "Nitrogen Runoff Practice Mitigation Score");
        results().put("psurf_pract_score", practiceScores.psurf_pract_score, "Phosphorus Runoff Practice Mitigation Score");
        results().put("nleach_avoid_pract_score", practiceScores.nleach_avoid_pract_score, "Nitrogen Leaching Practice Score (Avoid)");
        results().put("nleach_control_pract_score", practiceScores.nleach_control_pract_score, "Nitrogen Leaching Practice Score (Control)");
        results().put("nleach_trap_pract_score", practiceScores.nleach_trap_pract_score, "Nitrogen Leaching Practice Score (Trap)");
        results().put("ssurf_avoid_pract_score", practiceScores.ssurf_avoid_pract_score, "Sediment Runoff Practice Score (Avoid)");
        results().put("ssurf_control_pract_score", practiceScores.ssurf_control_pract_score, "Sediment Runoff Practice Score (Control)");
        results().put("ssurf_trap_pract_score", practiceScores.ssurf_trap_pract_score, "Sediment Runoff Practice Score (Trap)");
        results().put("nsurf_avoid_pract_score", practiceScores.nsurf_avoid_pract_score, "Nitrogen Runoff Practice Score (Avoid)");
        results().put("nsurf_control_pract_score", practiceScores.nsurf_control_pract_score, "Nitrogen Runoff Practice Score (Control)");
        results().put("nsurf_trap_pract_score", practiceScores.nsurf_trap_pract_score, "Nitrogen Runoff Practice Score (Trap)");
        results().put("psurf_avoid_pract_score", practiceScores.psurf_avoid_pract_score, "Phosphorus Runoff Practice Score (Avoid)");
        results().put("psurf_control_pract_score", practiceScores.psurf_control_pract_score, "Phosphorus Runoff Practice Score (Control)");
        results().put("psurf_trap_pract_score", practiceScores.psurf_trap_pract_score, "Phosphorus Runoff Practice Score (Trap)");
    }

    static class Practice {

        int plan_practice_id;
        String plan_practice_discrim_type;
        int plan_practice_discrim_value;

        public Practice(int plan_practice_id, String plan_practice_discrim_type, int plan_practice_discrim_value) {
            this.plan_practice_id = plan_practice_id;
            this.plan_practice_discrim_type = plan_practice_discrim_type;
            this.plan_practice_discrim_value = plan_practice_discrim_value;
        }
    }

    static class PracticeScore {

        int nleach_pract_score, nleach_avoid_pract_score, nleach_control_pract_score, nleach_trap_pract_score;
        int nsurf_pract_score, nsurf_avoid_pract_score, nsurf_control_pract_score, nsurf_trap_pract_score;
        int psurf_pract_score, psurf_avoid_pract_score, psurf_control_pract_score, psurf_trap_pract_score;
        int ssurf_pract_score, ssurf_avoid_pract_score, ssurf_control_pract_score, ssurf_trap_pract_score;

        public void compute(Connection conn, Practice input) throws SQLException {
            //Compute practice mitigation scores for Nitrogen in Ground Water and total scores
            nleach_avoid_pract_score += computePractScore(conn, input, "Nitrogen in Ground Water", "Avoid");
            nleach_control_pract_score += computePractScore(conn, input, "Nitrogen in Ground Water", "Control");
            nleach_trap_pract_score += computePractScore(conn, input, "Nitrogen in Ground Water", "Trap");
            nleach_pract_score = nleach_avoid_pract_score + nleach_control_pract_score + nleach_trap_pract_score;

            //Compute practice mitigation scores for Nitrogen in Surface Water and total scores
            nsurf_avoid_pract_score += computePractScore(conn, input, "Nitrogen in Surface Water", "Avoid");
            nsurf_control_pract_score += computePractScore(conn, input, "Nitrogen in Surface Water", "Control");
            nsurf_trap_pract_score += computePractScore(conn, input, "Nitrogen in Surface Water", "Trap");
            nsurf_pract_score = nsurf_avoid_pract_score + nsurf_control_pract_score + nsurf_trap_pract_score;

            //Compute practice mitigation scores for Sediment in Surface Water and total scores
            ssurf_avoid_pract_score += computePractScore(conn, input, "Sediment in Surface Water", "Avoid");
            ssurf_control_pract_score += computePractScore(conn, input, "Sediment in Surface Water", "Control");
            ssurf_trap_pract_score += computePractScore(conn, input, "Sediment in Surface Water", "Trap");
            ssurf_pract_score = ssurf_avoid_pract_score + ssurf_control_pract_score + ssurf_trap_pract_score;

            //Compute practice mitigation scores for Phosphorus in Surface Water and total scores
            psurf_avoid_pract_score += computePractScore(conn, input, "Phosphorus in Surface Water", "Avoid");
            psurf_control_pract_score += computePractScore(conn, input, "Phosphorus in Surface Water", "Control");
            psurf_trap_pract_score += computePractScore(conn, input, "Phosphorus in Surface Water", "Trap");
            psurf_pract_score = psurf_avoid_pract_score + psurf_control_pract_score + psurf_trap_pract_score;
        }

        public int computePractScore(Connection conn, Practice input, String concern, String mofeOfAction) throws SQLException {
            int practScore = 0;
            try (Statement statement = conn.createStatement();) {
                String query = DBQueries.WQM15Query01(input.plan_practice_id, concern, mofeOfAction, input.plan_practice_discrim_type, input.plan_practice_discrim_value);
                try (ResultSet resultSet = statement.executeQuery(query);) {
                    while (resultSet.next()) {
                        practScore += resultSet.getInt("nut_pract_score");
                    }
                }
            }
            return practScore;
        }
    }
}