V1_0.java [src/java/d/soils/wwe03_rusle2soilinput] 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 d.soils.wwe03_rusle2soilinput;

import csip.Config;
import csip.ModelDataService;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import csip.api.server.ServiceException;
import d.util.SoilXMLWriter;
import java.io.File;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.ws.rs.Path;
import soils.Component;
import soils.Horizon;
import soils.MapUnit;
import soils.db.DBResources;
import static soils.db.DBResources.SDM;
import soils.db.SOILS_DATA;
import soils.db.SOILS_DB_Factory;
import soils.utils.EvalResult;

/**
 *
 * Brad
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 * sidereus od
 *
 */
@Name("WWE-03:  RUSLE2 Soil Input XML (rusle2soilinput)")
@Description("Gets data from the NRCS Soil Data Mart and generates a soil component XML input file for the RUSLE2 model")
@Path("d/rusle2soilinput/1.0")
@Resource(from = DBResources.class)
public class V1_0 extends ModelDataService {

  static final String KEY_COKEY = "cokey";

  @Override
  protected Map<String, Object> getConfigInfo() {
    return new LinkedHashMap<String, Object>() {
      {
        put("soils.gis.database.source", resources().getResolved("soils.gis.database.source"));
        put(SDM, resources().getResolved(SDM));
        put("fpp.version", "wwe-03 1.0");
      }
    };
  }

  @Override
  protected void doProcess() throws Exception {

    String cokey = parameter().getString(KEY_COKEY);

    // Validation.checkCokey(cokey);  Does NOT actually validate a cokey, merely makes sure it is an interger...see actual validation function below
    Component comp = new Component();
    comp.cokey(cokey);
    MapUnit mUnit = getSoilMapUnit(comp);

    if (mUnit.isExcluded()) {
      throw new ServiceException("MapUnit: " + mUnit.muname() + " has been excluded. Reason: " + comp.getExcludedReason());
    }

    if (comp.isExcluded()) {
      throw new ServiceException("Component: " + comp.compname() + " has been excluded. Reason: " + comp.getExcludedReason());
    }

    Horizon water_horizon = getSoilHorizonWater(comp);
    SoilXMLWriter soilXMLWriter = new SoilXMLWriter();

    File soilFile = soilXMLWriter.writeXMLfile(mUnit, comp, water_horizon, workspace().getDir().getAbsolutePath());
    results().put(soilFile);
  }

  private MapUnit getSoilMapUnit(Component comp) throws ServiceException, SQLException, Exception {
    MapUnit mapUnit = new MapUnit(comp);

    try (SOILS_DATA soilsDb = SOILS_DB_Factory.createEngine(getClass(), LOG, Config.getString("soils.gis.database.source"))) {
      if (soilsDb.validateComponent(Integer.parseInt(comp.cokey()))) {
        soilsDb.findHorizonsForCokey(mapUnit, comp);
      } else {
        throw new ServiceException("Invalid cokey provided to this service.  Cokey, " + comp.cokey() + ", was not found in SDM.");
      }
    }

    comp.slopelenusle_r(verifyValue(comp.slopelenusle_l(), comp.slopelenusle_r(), comp.slopelenusle_h()));
    comp.slope_r(verifyValue(comp.slope_l(), comp.slope_r(), comp.slope_h()));
    return mapUnit;
  }

  private Horizon getSoilHorizonWater(Component comp) {
    Horizon selectedHorizon = null;

    for (Horizon horizon : comp.horizons().values()) {
      if (horizon.selected() && horizon.hasSelectedReason("WATER")) {
        selectedHorizon = horizon;
        break;
      }
    }

    if (selectedHorizon != null) {
      selectedHorizon.cec7_r(verifyValue(selectedHorizon.cec7_l(), selectedHorizon.cec7_r(), selectedHorizon.cec7_h()));
      selectedHorizon.wthirdbar_r(verifyValue(selectedHorizon.wthirdbar_l(), selectedHorizon.wthirdbar_r(), selectedHorizon.wthirdbar_h()));
      selectedHorizon.wfifteenbar_r(verifyValue(selectedHorizon.wfifteenbar_l(), selectedHorizon.wfifteenbar_r(), selectedHorizon.wfifteenbar_h()));
      selectedHorizon.dbthirdbar_r(verifyValue(selectedHorizon.dbthirdbar_l(), selectedHorizon.dbthirdbar_r(), selectedHorizon.dbthirdbar_h()));
      selectedHorizon.ph1to1h2o_r(verifyValue(selectedHorizon.ph1to1h2o_l(), selectedHorizon.ph1to1h2o_r(), selectedHorizon.ph1to1h2o_h()));
      selectedHorizon.om_r(verifyValue(selectedHorizon.om_l(), selectedHorizon.om_r(), selectedHorizon.om_h()));
    }
    return selectedHorizon;
  }

  private double verifyValue(double low_c, double regular_c, double high_c) {

    if (EvalResult.testDefaultDouble(low_c)) {
      low_c = 0; // this is an assumption about null values
    }
    if (EvalResult.testDefaultDouble(high_c)) {
      high_c = 0; // this is an assumption about null values
    }
    double value;
    if (EvalResult.testDefaultDouble(regular_c)) {
      value = low_c + high_c / 2;
    } else {
      value = regular_c;
    }
    return value;
  }
}