V1_0.java [src/java/m/svap/svap07c_svaprefstream] Revision: default  Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package m.svap.svap07c_svaprefstream;

import csip.Client;
import csip.Config;
import csip.ModelDataService;
import csip.ServiceException;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Polling;
import csip.annotations.Resource;
import static csip.annotations.ResourceType.OUTPUT;
import csip.utils.JSONUtils;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngine;
import static gisobjects.db.GISEngineFactory.createGISEngine;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Map;
import javax.ws.rs.Path;
import javax.ws.rs.core.UriBuilder;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import svap.utils.DBQueries;
import svap.utils.DBResources;
import static svap.utils.DBResources.CRDB;

/**
 * SVAP-07c: Get Reference Stream Record
 *
 * This service fetches the record for the specified reference stream to be used
 * as a guide for SVAP assessment.
 *
 * @author Rumpal Sidhu
 * @version 1.0
 */
@Name("SVAP-07c: Get Reference Stream Record")
@Description("This service fetches the record for the specified reference "
    + "stream to be used as a guide for SVAP assessment.")
@Path("m/svap/getsvaprefstream/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
@Resource(file = "*", type = OUTPUT)

public class V1_0 extends ModelDataService {

  private int refStreamId;
  private String refStreamName, includeExpired;
  private GISObject streamLocation;
  private String streamDescription, lastUpdate, expiredDate;
  private String usfsEcoregion, epaEcoregion, nrcsMlrasym, nrcsMlra, huc12Name;
  private double streamGradient;

  private ArrayList<Element> elementList = new ArrayList<>();
  private ArrayList<StreamPhoto> streamPhotoList = new ArrayList<>();


  @Override
  protected void preProcess() throws ServiceException {
    refStreamId = parameter().getInt("ref_stream_id");
    refStreamName = parameter().getString("ref_stream_name");
    includeExpired = parameter().getString("include_expired");
  }


  @Override
  protected void doProcess() throws ServiceException, SQLException, GISObjectException, JSONException, IOException, URISyntaxException, Exception {
    try (Connection connection = resources().getJDBC(CRDB);) {
      try (Statement statement = connection.createStatement();) {
        try (ResultSet resultSet = statement.executeQuery(DBQueries.SVAP7cQuery01(refStreamId))) {
          while (resultSet.next()) {
            refStreamName = resultSet.getString("name");
            streamDescription = resultSet.getString("description");
            lastUpdate = resultSet.getString("last_update");
            expiredDate = resultSet.getString("expired_date");
            String location = resultSet.getString("location");
            try (GISEngine gisEngine = createGISEngine(connection);) {
              streamLocation = GISObjectFactory.createGISObject(location, gisEngine);
            }
          }
        }

        try (ResultSet resultSet = statement.executeQuery(DBQueries.SVAP7cQuery02(refStreamId))) {
          while (resultSet.next()) {
            int id = resultSet.getInt("id");
            int score = resultSet.getInt("score");
            String comment = resultSet.getString("comment");
            elementList.add(new Element(id, score, comment));
          }
        }

        try (ResultSet resultSet = statement.executeQuery(DBQueries.SVAP7cQuery03(refStreamId))) {
          while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String description = resultSet.getString("description");
            byte[] fileBytes = resultSet.getBytes("photo_file");

            String photoFileName = name + "_" + id + ".jpg";
            OutputStream targetFile = new FileOutputStream(new File(workspace().getDir(), photoFileName));
            targetFile.write(fileBytes);
            targetFile.close();
            streamPhotoList.add(new StreamPhoto(id, name, description, photoFileName));
          }
        }
      }
    }
    getUsfsEcoregion();
    getEpaEcoregion();
    getNrcsMlra();
    getHuc12Name();
    getStreamGradient();
  }


  @Override
  protected void postProcess() throws ServiceException, JSONException {
    results().put("ref_stream_id", refStreamId, "Reference stream identifier");
    results().put("ref_stream_name", refStreamName, "Reference stream name");
    try {
      results().put("ref_stream_location", streamLocation.toJSON(), "Reference Stream Location");
    } catch (IOException ex) {
      throw new ServiceException(ex);
    }
    results().put("ref_stream_description", streamDescription, "Reference Stream Description");
    results().put("last_update", lastUpdate, "Reference Stram Last Update Date");
    results().put("expired_date", expiredDate, "Reference Stream Expiration Date");
    results().put("usfs_ecoregion", usfsEcoregion, "USFS Ecoregion");
    results().put("epa_ecoregion", epaEcoregion, "EPA Ecoregion");
    results().put("nrcs_mlrasym", nrcsMlrasym, "NRCS MLRA Symbol");
    results().put("nrcs_mlra", nrcsMlra, "NRCS Major Land Resource Area (MLRA)");
    results().put("huc12_name", huc12Name, "HUC 12 Name");
    results().put("ref_stream_gradient", streamGradient, "Reference Stream Gradient");

    JSONArray elementArray = new JSONArray();
    for (int i = 0; i < elementList.size(); i++) {
      JSONArray elementArr = new JSONArray();
      elementArr.put(JSONUtils.dataDesc("svap_element_id", elementList.get(i).id, "SVAP Element Identifier"));
      elementArr.put(JSONUtils.dataDesc("svap_score", elementList.get(i).score, "SVAP Element Score"));
      elementArr.put(JSONUtils.dataDesc("svap_score_comment", elementList.get(i).comment, "SVAP Element Score Comment"));
      elementArray.put(elementArr);
    }
    results().put("Element List", elementArray);

    JSONArray streamPhotoArray = new JSONArray();
    for (int i = 0; i < streamPhotoList.size(); i++) {
      JSONArray streamPhotoArr = new JSONArray();
      streamPhotoArr.put(JSONUtils.dataDesc("svap_photo_id", streamPhotoList.get(i).id, "Reference Stream Photo Identifier"));
      streamPhotoArr.put(JSONUtils.dataDesc("svap_photo_name", streamPhotoList.get(i).name, "Reference Stream Photo Name"));
      streamPhotoArr.put(JSONUtils.dataDesc("svap_photo_description", streamPhotoList.get(i).description, "Reference Stream Photo Description"));
//            streamPhotoArr.put(JSONUtils.dataDesc("svap_photo_file", getWorkspaceFile(streamPhotoList.get(i).photoFileName), "Reference Stream Photo File"));
      streamPhotoArray.put(streamPhotoArr);
    }
    results().put("Reference stream photos", streamPhotoArray);
  }


  private void getUsfsEcoregion() throws JSONException, Exception {
    Client client = new Client();
    String uri = UriBuilder.fromUri(request().getURL()).replacePath(request().getContext() + Config.getString("svap_1a")).toString();
    JSONObject resultJSON = client.doPOST(uri, requestJSON());

    JSONArray resultArray = resultJSON.getJSONArray("result");
    Map<String, JSONObject> topLevel = JSONUtils.preprocess(resultArray);
    usfsEcoregion = JSONUtils.getStringParam(topLevel, "usfs_ecoreg_subsect_name", "Error");
  }


  private void getEpaEcoregion() throws JSONException, Exception {
    Client client = new Client();
    String uri = UriBuilder.fromUri(request().getURL()).replacePath(request().getContext() + Config.getString("svap_1b")).toString();
    JSONObject resultJSON = client.doPOST(uri, requestJSON());

    JSONArray resultArray = resultJSON.getJSONArray("result");
    Map<String, JSONObject> topLevel = JSONUtils.preprocess(resultArray);
    epaEcoregion = JSONUtils.getStringParam(topLevel, "epa_ecoreg_l3_name", "Error");
  }


  private void getNrcsMlra() throws JSONException, Exception {
    Client client = new Client();
    String uri = UriBuilder.fromUri(request().getURL()).replacePath(request().getContext() + Config.getString("svap_1c")).toString();
    JSONObject resultJSON = client.doPOST(uri, requestJSON());

    JSONArray resultArray = resultJSON.getJSONArray("result");
    Map<String, JSONObject> topLevel = JSONUtils.preprocess(resultArray);
    nrcsMlra = JSONUtils.getStringParam(topLevel, "mlra_name", "Error");
    nrcsMlrasym = JSONUtils.getStringParam(topLevel, "mlra_sym", "Error");
  }


  private void getHuc12Name() throws JSONException, Exception {
    Client client = new Client();
    String uri = UriBuilder.fromUri(request().getURL()).replacePath(request().getContext() + Config.getString("svap_02")).toString();
    JSONObject resultJSON = client.doPOST(uri, requestJSON());

    JSONArray resultArray = resultJSON.getJSONArray("result");
    Map<String, JSONObject> topLevel = JSONUtils.preprocess(resultArray);
    huc12Name = JSONUtils.getStringParam(topLevel, "huc12_name", "Error");
  }


  private void getStreamGradient() throws JSONException, Exception {
    Client client = new Client();
    String uri = UriBuilder.fromUri(request().getURL()).replacePath(request().getContext() + Config.getString("svap_09")).toString();
    JSONObject resultJSON = client.doPOST(uri, requestJSON());

    JSONArray resultArray = resultJSON.getJSONArray("result");
    Map<String, JSONObject> topLevel = JSONUtils.preprocess(resultArray);
    streamGradient = JSONUtils.getDoubleParam(topLevel, "gradient", 0);
  }


  private JSONObject requestJSON() throws JSONException, IOException {
    JSONObject requestJSON = new JSONObject();

    JSONObject metainfo = new JSONObject();
    metainfo.put("OriginalRequest", request().getURL());
    metainfo.put("OriginalSUID", getSUID());
    requestJSON.put("metainfo", metainfo);

    JSONArray parameter = new JSONArray();
    parameter.put(new JSONObject().put("name", "assessment_id").put("value", 1));
    JSONObject location = new JSONObject();
    location.put("name", "assessment_location");
    location.put("type", "Point");
    location.put("coordinates", streamLocation.toJSON().getJSONArray("coordinates"));
    parameter.put(location);
    requestJSON.put("parameter", parameter);
    return requestJSON;
  }

  static class Element {

    int id, score;
    String comment;


    public Element(int id, int score, String comment) {
      this.id = id;
      this.score = score;
      this.comment = comment;
    }

  }

  static class StreamPhoto {

    int id;
    String name, description;
    File file;
    String photoFileName;


    public StreamPhoto(int id, String name, String description, String photoFileName) {
      this.id = id;
      this.name = name;
      this.description = description;
      this.photoFileName = photoFileName;
    }

  }
}