V1_0.java [src/java/m/rhem/rhem02_getclimatestations] Revision: f24c10865f5de1e85137754a1c7c9486d173735c  Date: Mon Oct 03 18:07:50 MDT 2016
/*
 * 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.rhem.rhem02_getclimatestations;

import csip.ModelDataService;
import csip.ServiceException;
import csip.annotations.Polling;
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.logging.Level;
import javax.ws.rs.Path;
import oms3.annotations.Description;
import oms3.annotations.Name;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import rhem.utils.DBResources;

/**
 * @version 1.0
 * @author Rumpal Sidhu
 */
@Name("RHEM-02:Get Climate Stations")
@Description("Returns a list of climate stations associated with the state "
        + "selected by the user. Information associated with each climate "
        + "station will be station name, latitude, longitude, number of "
        + "years of observed data, elevation (feet) and 300 year average "
        + "and monthly precipitation amounts (millimeters).")
@Path("m/rhem/getclimatestations/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)

public class V1_0 extends ModelDataService {

    private String stateId;
    private ClimateStationStates climateStationStates;

    @Override
    public void preProcess() throws ServiceException {
        try {
            this.stateId = getStringParam("stateid");
        } catch (ServiceException ex) {
            LOG.log(Level.SEVERE, "RHEM-02: Error in processing the request JSON.", ex);
            throw new ServiceException("Error in processing the request JSON.", ex);
        }
    }

    @Override
    public void doProcess() throws ServiceException {
        try (Connection connection = getResourceJDBC(DBResources.MSSQL_RHEM);
                Statement statement = connection.createStatement();) {

            String query = "SELECT state_name, latitude, longitude, zoom "
                    + "FROM rhem.d_rhem_climate_station_states "
                    + "WHERE state_id = '" + this.stateId + "';";
            ResultSet resultSet = statement.executeQuery(query);
            while (resultSet.next()) {
                climateStationStates = new ClimateStationStates(stateId,
                        resultSet.getString("state_name"),
                        resultSet.getDouble("latitude"),
                        resultSet.getDouble("longitude"),
                        resultSet.getInt("zoom"));
            }

            ArrayList<ClimateStation> climateStationsList = new ArrayList();
            query = "SELECT s.state, s.station, s.station_id, s.latitude, "
                    + "s.longitude, s.years, s.elevation, "
                    + "est.avg_yearly_precip_mm, est.jan_precip_mm, "
                    + "est.feb_precip_mm, est.mar_precip_mm, est.apr_precip_mm, "
                    + "est.may_precip_mm, est.jun_precip_mm, est.jul_precip_mm, "
                    + "est.aug_precip_mm, est.sep_precip_mm, est.oct_precip_mm, "
                    + "est.nov_precip_mm, est.dec_precip_mm "
                    + "FROM rhem.d_rhem_climate_stations s "
                    + "JOIN rhem.d_rhem_climate_stations_avg_300yr_est_rain est "
                    + "ON (s.station_id = est.station_id) "
                    + "WHERE s.state = 'CO';";
            resultSet = statement.executeQuery(query);
            while (resultSet.next()) {
                double[] monthlyPrecip = new double[12];
                monthlyPrecip[0] = resultSet.getDouble("jan_precip_mm");
                monthlyPrecip[1] = resultSet.getDouble("feb_precip_mm");
                monthlyPrecip[2] = resultSet.getDouble("mar_precip_mm");
                monthlyPrecip[3] = resultSet.getDouble("apr_precip_mm");
                monthlyPrecip[4] = resultSet.getDouble("may_precip_mm");
                monthlyPrecip[5] = resultSet.getDouble("jun_precip_mm");
                monthlyPrecip[6] = resultSet.getDouble("jul_precip_mm");
                monthlyPrecip[7] = resultSet.getDouble("aug_precip_mm");
                monthlyPrecip[8] = resultSet.getDouble("sep_precip_mm");
                monthlyPrecip[9] = resultSet.getDouble("oct_precip_mm");
                monthlyPrecip[10] = resultSet.getDouble("nov_precip_mm");
                monthlyPrecip[11] = resultSet.getDouble("dec_precip_mm");

                climateStationsList.add(new ClimateStation(
                        resultSet.getString("station_id"),
                        resultSet.getString("station"),
                        resultSet.getDouble("latitude"),
                        resultSet.getDouble("longitude"),
                        resultSet.getInt("years"),
                        resultSet.getInt("elevation"),
                        resultSet.getDouble("avg_yearly_precip_mm"),
                        monthlyPrecip));
            }
            climateStationStates.addClimateStationsList(climateStationsList);
        } catch (ServiceException | SQLException se) {
            LOG.log(Level.SEVERE, "RHEM-02: SQLException.", se);
            throw new ServiceException("SQL problem.", se);
        }
    }

    @Override
    public void postProcess() throws Exception {
        String[] listOfMonths = {"January", "February", "March", "April", "May",
            "June", "July", "August", "September", "October", "November", "December"};
        try {
            putResult("stateid", climateStationStates.getStateId(), "State abbreviation of climate station location");
            putResult("state_name", climateStationStates.getStateName(), "State name");
            putResult("latitude", climateStationStates.getStateLatitude(), "Central latitude of the state");
            putResult("longitude", climateStationStates.getStateLongitude(), "Central longitude of the state");
            putResult("zoom", climateStationStates.getZoom(), "Zoom level utilized to display state map on UI");

            JSONArray climateStationArray = new JSONArray();
            for (ClimateStation climateStation : climateStationStates.getClimateStationsList()) {
                JSONArray innerArray = new JSONArray();
                innerArray.put(JSONUtils.data("station_id", climateStation.getStationId(), "Climate station identification number"));
                innerArray.put(JSONUtils.data("station_name", climateStation.getStationName(), "Climate station name"));
                innerArray.put(JSONUtils.data("lat", climateStation.getStationLatitude(), "Climate station latitude"));
                innerArray.put(JSONUtils.data("long", climateStation.getStationLongitude(), "Climate station longitude"));
                innerArray.put(JSONUtils.data("year_recorded", climateStation.getYearRecorded(), "Number of years of recorded observations for climate station"));
                innerArray.put(JSONUtils.data("elevation_ft", climateStation.getElevation(), "Climate station elevation"));
                innerArray.put(JSONUtils.data("avg_yearly_precip_mm", climateStation.getAvgYearlyPrecip(), "300 year average annual precipitation (mm)"));
                for (int i = 0; i < 12; i++) {
                    innerArray.put(JSONUtils.data(listOfMonths[i].substring(0, 3).toLowerCase() + "_precip_mm",
                            climateStation.getMonthlyPrecip()[i], listOfMonths[i] + " estimated monthly average precipitation (mm)"));
                }
                climateStationArray.put(JSONUtils.dataDesc("mapunit", innerArray, "Mapuint"));
            }
            putResult("climate_station_list", climateStationArray, "Climate Station List");
        } catch (JSONException ex) {
            LOG.log(Level.SEVERE, "RHEM-02: Error in processing the reponse JSON.", ex);
            throw new ServiceException("Error in processing the reponse JSON.", ex);
        }
    }

    static class ClimateStationStates {

        protected String stateId;
        protected String stateName;
        protected double latitude;
        protected double longitude;
        protected int zoom;
        protected ArrayList<ClimateStation> climateStationsList;

        public ClimateStationStates(String stateId, String stateName, double latitude,
                double longitude, int zoom) {
            this.stateId = stateId;
            this.stateName = stateName;
            this.latitude = latitude;
            this.longitude = longitude;
            this.zoom = zoom;
        }

        public String getStateId() {
            return this.stateId;
        }

        public String getStateName() {
            return this.stateName;
        }

        public double getStateLatitude() {
            return this.latitude;
        }

        public double getStateLongitude() {
            return this.longitude;
        }

        public int getZoom() {
            return this.zoom;
        }

        public ArrayList<ClimateStation> getClimateStationsList() {
            return this.climateStationsList;
        }

        public void addClimateStationsList(ArrayList<ClimateStation> list) {
            this.climateStationsList = list;
        }

    }

    static class ClimateStation {

        protected String stationId;
        protected String stationName;
        protected double latitude;
        protected double longitude;
        protected int yearRecorded;
        protected int elevation_ft;
        protected double avgYearlyPrecip_mm;
        protected double[] monthlyPrecip_mm;

        public ClimateStation(String stationId, String stationName, double latitude,
                double longitude, int yearRecorded, int elevation,
                double avg_yearly_precip_mm, double[] monthlyPrecip_mm) {

            this.stationId = stationId;
            this.stationName = stationName;
            this.latitude = latitude;
            this.longitude = longitude;
            this.yearRecorded = yearRecorded;
            this.elevation_ft = elevation;
            this.avgYearlyPrecip_mm = avg_yearly_precip_mm;
            this.monthlyPrecip_mm = monthlyPrecip_mm;
        }

        public String getStationId() {
            return this.stationId;
        }

        public String getStationName() {
            return this.stationName;
        }

        public double getStationLatitude() {
            return this.latitude;
        }

        public double getStationLongitude() {
            return this.longitude;
        }

        public int getYearRecorded() {
            return this.yearRecorded;
        }

        public int getElevation() {
            return this.elevation_ft;
        }

        public double getAvgYearlyPrecip() {
            return this.avgYearlyPrecip_mm;
        }

        public double[] getMonthlyPrecip() {
            return this.monthlyPrecip_mm;
        }

    }
}