V2_0.java [src/java/m/wqm/wqm05_nutrientslp] Revision:   Date:
package m.wqm.wqm05_nutrientslp;

import csip.ModelDataService;
import static csip.ModelDataService.KEY_DESC;
import static csip.ModelDataService.KEY_NAME;
import static csip.ModelDataService.KEY_VALUE;
import csip.api.server.PayloadResults;
import csip.api.server.ServiceException;
import csip.utils.JSONUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import soils.SoilsData;
import soils.db.tables.TableComponent;
import soils.db.tables.TableComponentCalculations;
import soils.db.tables.TableMapUnit;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
@Name("WQM-05: Nutrient Soil Leaching Potential (NutrientSLP)")
@Description("This service computes nutrient soil leaching potential for soil "
    + "components in an area of analysis, and then computes nutrient soil "
    + "leaching potential representing the area of analysis (AoA). The service "
    + "primarily will consume data from the WQM-02 WQMSoilAttributes service "
    + "to compute nutrient soil leaching potentials used later by the WQM-13 "
    + "service to compute threshold treatment level scores.")
@Path("m/nutrient_slp/2.0")
public class V2_0 extends ModelDataService {

  private V2_0.AoA aoa;

  @Override
  protected void preProcess() throws ServiceException {
    V2_0.AoA.setRequiredInputs(new ArrayList<>(Arrays.asList(AoA.AOA_ID, AoA.MAP_UNIT_LIST)),
        new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, SoilsData.MAPUNIT_COMPONENT_LIST_NAME)),
        new ArrayList<>(Arrays.asList(TableComponent.COKEY, TableComponent.TAXORDER_NAME, TableComponent.SLOPE_R_NAME,
            TableComponent.HYDGRP_NAME,
            TableComponentCalculations.COMP_AREA_NAME, TableComponentCalculations.COARSE_FRAG_NAME,
            TableComponentCalculations.KFFACT_NAME, TableComponentCalculations.WTBL_TOP_MIN_NAME)),
        null);
  }

  @Override
  protected void doProcess() throws ServiceException, JSONException {
    aoa = new V2_0.AoA(JSONUtils.preprocess(getParam()));
    aoa.computeComponentNSLP();
    aoa.computeAoANSLP();
  }

  @Override
  protected void postProcess() throws Exception {
    JSONArray tArray = aoa.toJSON();

    for (int i = 0; i < tArray.length(); i++) {
      JSONObject outObject = tArray.getJSONObject(i);
      if (outObject.optString(KEY_NAME, "").equalsIgnoreCase(soils.AoA.MAP_UNIT_LIST)) {
        JSONArray outArray2 = outObject.getJSONArray(KEY_VALUE);
        results().put(soils.AoA.MAP_UNIT_LIST, outArray2);
      } else {
        writeResults(results(), outObject);
      }
    }
  }

  protected void writeResults(PayloadResults results, JSONObject outObject) throws Exception {
    results.put(outObject.getString(KEY_NAME), outObject.getString(KEY_VALUE), outObject.getString(KEY_DESC));
  }

////////////////////////////////    
//    
//  Inner Classes
//    
//////////////////////////////// 
  /**
   *
   */
  public class AoA extends soils.AoA {

    /**
     *
     * @param params
     * @throws ServiceException
     * @throws JSONException
     */
    public AoA(Map<String, JSONObject> params) throws ServiceException, JSONException {
      super(params);
    }

    /**
     *
     * @throws JSONException
     */
    public JSONArray toJSON() throws JSONException {
      JSONArray outArray = new JSONArray();

      tableAoA.setOutputColumns(new ArrayList<>(Arrays.asList(AoA.AOA_ID, AoA.NSLP)));
            try {
      setMapUnitOutputColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY)),
          new ArrayList<>(Arrays.asList(TableComponent.COKEY, TableComponentCalculations.NSLP_NAME)));
            } catch (ServiceException ex) {
                throw new JSONException("Cannot format JSON Results: " + ex.getMessage());
            }

      toJSON(true, outArray);

//            //Using put result here because need access to "res" in ModelDataServices.  [Perhaps results() should be protected and not private?]
//            //  Because the TableColumn class handles all the specifics of how to format information, and if units, descriptions, etc., were required
//            //  for the output JSON, it is all contained and abstracted to avoid confusion for programmers writing simple services.  Thus,
//            //  direct access to the ModelDataServices.res member would be hugely benefitial here...
//            for (int i = 0; i < outArray.length(); i++) {
//                results().put(outArray.getJSONObject(i));
//            }
      return outArray;
    }
  }
}