WWESoilParams.java [src/java/services] Revision: 140e9385ed92c087ca093c5841797b906be8d707  Date: Fri Dec 06 08:44:44 MST 2019
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2019, 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 services;

import static csip.ModelDataService.KEY_METAINFO;
import static csip.ModelDataService.KEY_PARAMETER;
import csip.ServiceException;
import csip.utils.JSONUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import utils.ServiceCall;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
public class WWESoilParams extends ServiceCall {

    protected JSONObject _callingMetaInfo;
    protected JSONObject _location;
    private SortedMap<Double, SoilResult> componentOrderList = new TreeMap<>(Collections.reverseOrder());

    public WWESoilParams(JSONObject metaInfo, JSONObject shape, String URI) {
        super(URI);
        _callingMetaInfo = metaInfo;
        errorPrefix = "WWESoilParams_ServiceCall";
        _location = shape;
    }

    @Override
    protected void createRequest() throws ServiceException {
        JSONArray dataArray;

        requestMetainfoObject = new JSONObject();
        request = new JSONObject();

        dataArray = new JSONArray();
        try {
            requestMetainfoObject.put("MultipartRequest", "Bundled Service Request From csip-crp MetaModeling Assessment Service");
            requestMetainfoObject.put("CRPAssessment_Metainfo", _callingMetaInfo);
            request.put(KEY_METAINFO, requestMetainfoObject);

            if (null != _location) {
                _location.put("name", "aoa_geometry");
                dataArray.put(_location);

                request.put(KEY_PARAMETER, dataArray);
            } else {
                throwServiceCallException("Cannot convert centroid buffer to JSON.");
            }
        } catch (JSONException ex) {
            throwServiceCallException("Cannot create the JSON request for WWESoilParams call.", ex);
        }
    }

    @Override
    protected void parseResults() throws ServiceException {
        //   Error checking has already been done on these results.
        // If we get to this function, no further error
        // checking is necessary, except to look at the "results" array in the output, if desired.
        if (null == callResultSection) {
            throwServiceCallException("Cannot find results in the call to " + this.URI + " .");
        }

        try {
            //  Get the region results and store them.
            Map<String, JSONObject> resultMap = JSONUtils.getResults(results);

            if (resultMap.containsKey("Map Units")) {
                JSONArray mapUnitList = JSONUtils.getJSONArrayParam(resultMap, "Map Units");

                for (int i = 0; i < mapUnitList.length(); i++) {
                    JSONArray mapUnitData = mapUnitList.getJSONArray(i);
                    Map<String, JSONObject> mapUnitObject = JSONUtils.preprocess(mapUnitData);
                    if (mapUnitObject.containsKey("Components")) {
                        JSONArray componentList = JSONUtils.getJSONArrayParam(mapUnitObject, "Components");

                        for (int j = 0; j < componentList.length(); j++) {
                            JSONArray componentData = componentList.getJSONArray(j);
                            Map<String, JSONObject> componentObject = JSONUtils.preprocess(componentData);

                            if (componentObject.containsKey("area")) {

                                double area = JSONUtils.getDoubleParam(componentObject, "area", Double.NaN);
                                if (Double.isNaN(area)) {
                                    throwServiceCallException("Returned component list does not contain the required result value for 'area' for a component.");
                                }

                                if (componentObject.containsKey("cokey")) {
                                    String cokey = JSONUtils.getStringParam(componentObject, "cokey", "");
                                    if (cokey.isEmpty()) {
                                        throwServiceCallException("Returned component list does not contain the required result value for 'area' for a component.");
                                    }

                                    if (componentObject.containsKey("length_r")) {
                                        double length = JSONUtils.getDoubleParam(componentObject, "length_r", Double.NaN);
                                        if (Double.isNaN(length)) {
                                            throwServiceCallException("Returned component list does not contain the required result value for 'length_r' for a component.");
                                        }

                                        if (componentObject.containsKey("slope_r")) {
                                            double slope_r = JSONUtils.getDoubleParam(componentObject, "slope_r", Double.NaN);
                                            if (Double.isNaN(slope_r)) {
                                                throwServiceCallException("Returned component list does not contain the required result value for 'slope_r' for a component.");
                                            }
                                            SoilResult soilResult = new SoilResult();
                                            soilResult.cokey = cokey;
                                            soilResult.length = length;
                                            soilResult.area = area;
                                            soilResult.slope_r = slope_r;
                                            soilResult.area_pct = JSONUtils.getDoubleParam(componentObject, "area_pct", Double.NaN);
                                            soilResult.soilName = JSONUtils.getStringParam(componentObject, "compname", "NONE");
                                            soilResult.soilLongName = JSONUtils.getStringParam(componentObject, "comp_long_name", "NONE");

                                            componentOrderList.put(area, soilResult);
                                        }
                                    } else {
                                        throwServiceCallException("Returned component list does not contain the required result 'length_r' for a component.");
                                    }
                                } else {
                                    throwServiceCallException("Returned component list does not contain the required result 'cokey' for a component.");
                                }

                            } else {
                                throwServiceCallException("Returned component list does not contain the required result 'area' for a component.");
                            }
                        }
                    }
                }
            } else {
                throwServiceCallException("No list of map units was returned by the WWESoilParams service.");
            }

        } catch (JSONException ex) {
            throwServiceCallException("Could not build the results map: " + ex.getMessage(), ex);
        }
    }

    public ArrayList<SoilResult> getTopThree() throws ServiceException {
        ArrayList<SoilResult> ret_val = new ArrayList<>();

        if (!componentOrderList.isEmpty()) {
            int count = 0;

            Set s = componentOrderList.entrySet();
            Iterator i = s.iterator();

            while (i.hasNext() && (count < 3)) {
                Map.Entry entry = (Map.Entry) i.next();
                SoilResult soilResult = (SoilResult) entry.getValue();

                ret_val.add(soilResult);
                count++;
            }

        } else {
            throw new ServiceException("There were no returned components for the AoA provided to the WWESoilParam Service.");
        }

        return ret_val;
    }

    public class SoilResult{
        public double area;
        public String cokey;
        public double length;
        public double slope_r;
        public double windErosion;
        public double waterErosion;
        public double area_pct;
        public String soilName;
        public String soilLongName;       
    }
}