WeppSoil.java [src/java/m/wepp] Revision:   Date:
package m.wepp;

import csip.api.client.ModelDataServiceCall;
import csip.api.server.ServiceException;
import csip.SessionLogger;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import org.json.JSONException;

/**
 * A function library for communicating with the public Soil Data Mart and
 * retrieving SSURGO soils information.
 * <p>
 * The primary function of this class is the method
 * {@link #getSoilCSIP(int, String, String)} which constructs a Soil object
 * containing information derived from data in the SSURGO database.
 *
 * @author Eric.Theller
 *
 */
public class WeppSoil {

  String serviceURL;
  SessionLogger LOG;
  String csipSoilFilename;


  WeppSoil(SessionLogger log, String serviceURL) {
    this.LOG = log;
    this.serviceURL = serviceURL;
    this.csipSoilFilename = null;
  }


  /**
   * Get a WEPP soil given a COKEY into the SSURGO database. Relies on the CSIP
   * service to build the soil file.
   *
   * @param cokey SSURGO soil to get
   * @param workDir directory where to save soil file
   * @param soilFileName where to save soil data to
   * @return true if success, false otherwise
   * @throws JSONException JSON format of data
   * @throws org.codehaus.jettison.json.JSONException JSON exception
   * @throws Exception general
   */
  public boolean getSoilCSIP(int cokey, String workDir, String soilFileName) throws Exception {
    ModelDataServiceCall r = new ModelDataServiceCall()
        .put("cokey", cokey)
        .put("stream_file", true)
        .withDefaultLogger()
        .url(serviceURL)
        .call();

    if (r.serviceFinished()) {
      String name = r.getNames().get(0);
      String soilFileData = r.getString(name);
      csipSoilFilename = name + ".sol";
      File ietSoilName = new File(workDir, csipSoilFilename);
      File solFile = new File(workDir,soilFileName);

      FileUtils.writeStringToFile(ietSoilName, soilFileData, "UTF-8");
      FileUtils.writeStringToFile(solFile, soilFileData, "UTF-8");
    } else {
      return false;
    }
    return true;
  }


//  public boolean getSoilCSIP(JSONObject metaData, int cokey, String workDir, String soilFileName) throws Exception {
//
//    ModelDataServiceCall r = new ModelDataServiceCall()
//        .put("cokey", cokey)
//        .put("stream_file", true)
//        .withDefaultLogger()
//        .url(serviceURL)
//        .call();
//
//    if (r.serviceFinished()) {
//      try {
//        String name = r.getName(0);
//        String soilFileData = r.getString(name);
//        csipSoilFilename = name + ".sol";
//        File ietSoilName = new File(workDir, csipSoilFilename);
//        File solFile = new File(workDir, soilFileName);
//
//        try {
//          FileUtils.writeStringToFile(ietSoilName, soilFileData, "UTF-8");
//          FileUtils.writeStringToFile(solFile, soilFileData, "UTF-8");
//          return true;
//        } catch (IOException ex) {
//          throw new ServiceException("Cannot create the sol files locally with the returned data from WEPPSoilInput: " + ex.getMessage(), ex);
//        }
//      } catch (ServiceException E) {
//        return false;
//      }
//    } else {
//      if (r.getError().contains("excluded")) {
//        throw new ServiceException("The soil cokey provided does not meet the WEPP component filtering requirements provided by NRCS.");
//      }
//      return false;
//    }
//  }


  /**
   * This attempts to find the soil COKEY using the area and name. It is called
   * if the original COKEY becomes invalid this can be the result of a SSURGO
   * update/refresh. After the new COKEY is found it calls the CSIP function
   * with the correct COKEY.
   *
   * @param cokey original COKEY
   * @param workDir directory where to store soil file
   * @param soilFileName soil file name to create
   * @param soilName name of the soil
   * @param county county of soil
   * @param state state of soil
   * @param contextUrl the context url
   * @return true if soil file created
   * @throws JSONException if any
   * @throws org.codehaus.jettison.json.JSONException if any
   * @throws Exception if any
   */
  public boolean retryGetSoilCSIP(int cokey, String workDir, String soilFileName,
      String soilName, String county, String state, String contextUrl) throws Exception {

    ModelDataServiceCall r = new ModelDataServiceCall()
        .put("query", "getsoilcokey")
        .put("soilName", soilName)
        .put("county", county)
        .put("state", state)
        .withDefaultLogger()
        .url(contextUrl + "/m/weppdata/1.0")
        .call();

    if (r.serviceFinished()) {
      if (r.getCount() == 1) {
        JSONArray rescokey = r.getJSONArray(r.getNames().get(0));
        try {
          String newcokeystr = rescokey.getJSONObject(0).getString("cokey");
          int newcokey = Integer.parseInt(newcokeystr);
          return getSoilCSIP(newcokey, workDir, soilFileName);
        } catch (Exception e) {
          throw new ServiceException("Soil name could not be found, try choosing a different soil.");
        }
      } else {
        throw new ServiceException("Soil: " + soilName + " could not match unique COKEY.");
      }
    } else {
      throw new ServiceException("Soil: " + soilName + " could not be found.");
    }
  }


  /**
   * Get soil name in the response.
   *
   * @return filename
   */
  public String getSoilName() {
    return csipSoilFilename;
  }
}