EvalResult.java [src/soils/utils] Revision: default  Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package soils.utils;

import csip.api.server.ServiceException;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngine;
import java.io.IOException;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import static soils.utils.EvalResult.writeDouble;

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

  private static final double DEFAULT_EMPTY_DOUBLE = Double.NaN;
  private static final float DEFAULT_EMPTY_FLOAT = Float.NaN;
  private static final String DEFAULT_EMPTY_STRING = "";
  private static final int DEFAULT_EMPTY_INTEGER = Integer.MAX_VALUE;
  private static final Boolean DEFAULT_EMPTY_BOOLEAN = Boolean.FALSE;
  private static final GISObject DEFAULT_EMPTY_GEOMETRY = null;
  private static final LocalDate DEFAULT_EMPTY_DATE = LocalDate.MIN;

  private static final String DEFAULT_EMPTY_STRING_WRITE_VALUE = "NULL";
  private static final String DEFAULT_EMPTY_DOUBLE_WRITE_VALUE = "NULL";
  private static final String DEFAULT_EMPTY_INTEGER_WRITE_VALUE = "NULL";
  private static final String DEFAULT_EMPTY_DATE_WRITE_VALUE = "NULL";

  public static final String DEFAULT_DATE_TYPE = LocalDate.class.getSimpleName();

  private static boolean USE_TYPE_CHECKING = false;
  private static final String DEFAULT_VALUE_STRING = csip.ModelDataService.KEY_VALUE;
  private static final String DEFAULT_TYPE_VALUE_STRING = "type";

  public static double getDefaultDouble() {
    return DEFAULT_EMPTY_DOUBLE;
  }

  public static int getDefaultInteger() {
    return DEFAULT_EMPTY_INTEGER;
  }

  public static float getDefaultFloat() {
    return DEFAULT_EMPTY_FLOAT;
  }

  public static String getDefaultString() {
    return DEFAULT_EMPTY_STRING;
  }

  public static Boolean getDefaultBoolean() {
    return DEFAULT_EMPTY_BOOLEAN;
  }

  public static LocalDate getDefaultDate() {
    return DEFAULT_EMPTY_DATE;
  }

  public static double getDouble(ResultSet result, String name) throws SQLException {
    double ret_val = DEFAULT_EMPTY_DOUBLE;
    String temp = result.getString(name);
    if (!result.wasNull() && (null != temp) && (!temp.isEmpty())) {
      try {
        ret_val = Double.parseDouble(temp);
      } catch (NumberFormatException ex) {
        ret_val = DEFAULT_EMPTY_DOUBLE;
      }
    }

    return ret_val;
  }

  public static int getInteger(ResultSet result, String name) throws SQLException {
    int ret_val = DEFAULT_EMPTY_INTEGER;
    String temp = result.getString(name);
    if (!result.wasNull() && (null != temp) && (!temp.isEmpty())) {
      try {
        ret_val = Integer.parseInt(temp);
      } catch (NumberFormatException ex) {
        ret_val = DEFAULT_EMPTY_INTEGER;
      }
    }
    return ret_val;
  }

  public static float getFloat(ResultSet result, String name) throws SQLException {
    float ret_val = DEFAULT_EMPTY_FLOAT;
    String temp = result.getString(name);
    if (!result.wasNull() && (null != temp) && (!temp.isEmpty())) {
      try {
        ret_val = Float.parseFloat(temp);
      } catch (NumberFormatException ex) {
        ret_val = DEFAULT_EMPTY_FLOAT;
      }
    }
    return ret_val;
  }

  public static Boolean getBoolean(ResultSet result, String name) throws SQLException {
    String value = result.getString(name);

    Boolean ret_val = ((null != value) ? ((value.equalsIgnoreCase("1") || value.equalsIgnoreCase("yes")) ? Boolean.TRUE : ((value.equalsIgnoreCase("0") || value.equalsIgnoreCase("no")) ? Boolean.FALSE : Boolean.parseBoolean(value))) : Boolean.FALSE);

    //Boolean ret_val = result.getBoolean(name);
    if (result.wasNull()) {
      ret_val = DEFAULT_EMPTY_BOOLEAN;
    }
    return ret_val;
  }

  public static LocalDate getDate(ResultSet result, String name) throws SQLException {
    LocalDate ret_val;
    Date temp = result.getDate(name);
    if (result.wasNull()) {
      ret_val = DEFAULT_EMPTY_DATE;
    } else {
      ret_val = temp.toLocalDate();
    }

    return ret_val;
  }

  public static String getString(ResultSet result, String name) throws SQLException {
    String ret_val = result.getString(name);
    if (result.wasNull()) {
      ret_val = DEFAULT_EMPTY_STRING;
    }
    return ret_val;
  }

  public static String getStringValue(JSONObject inputJSON) throws ServiceException {
    String ret_val = DEFAULT_EMPTY_STRING;

    if (null != DEFAULT_VALUE_STRING) {
      if (null != inputJSON) {
        ret_val = inputJSON.optString(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_STRING);
      } else {
        throw new ServiceException("No input JSON provided for " + DEFAULT_VALUE_STRING + " in SOILS_DATA.EvalResult.getString()");
      }
    } else {
      throw new ServiceException("No input parameter value name provided in SOILS_DATA.EvalResult.getString()");
    }

    return ret_val;
  }

  public static double getDoubleValue(JSONObject inputJSON) throws ServiceException {
    double ret_val = DEFAULT_EMPTY_DOUBLE;

    if (null != DEFAULT_VALUE_STRING) {
      if (null != inputJSON) {
        ret_val = inputJSON.optDouble(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_DOUBLE);
      } else {
        throw new ServiceException("No input JSON provided for " + DEFAULT_VALUE_STRING + " in SOILS_DATA.EvalResult.getDouble()");
      }
    } else {
      throw new ServiceException("No input parameter value name provided in SOILS_DATA.EvalResult.getDouble()");
    }

    return ret_val;
  }

  public static int getIntegerValue(JSONObject inputJSON) throws ServiceException {
    int ret_val = DEFAULT_EMPTY_INTEGER;

    if (null != DEFAULT_VALUE_STRING) {
      if (null != inputJSON) {
        ret_val = inputJSON.optInt(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_INTEGER);
      } else {
        throw new ServiceException("No input JSON provided for " + DEFAULT_VALUE_STRING + " in SOILS_DATA.EvalResult.getInteger()");
      }
    } else {
      throw new ServiceException("No input parameter value name provided in SOILS_DATA.EvalResult.getInteger()");
    }

    return ret_val;
  }

  public static Boolean getBooleanValue(JSONObject inputJSON) throws ServiceException {
    Boolean ret_val = DEFAULT_EMPTY_BOOLEAN;

    if (null != DEFAULT_VALUE_STRING) {
      if (null != inputJSON) {
        ret_val = inputJSON.optBoolean(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_BOOLEAN);
      } else {
        throw new ServiceException("No input JSON provided for " + DEFAULT_VALUE_STRING + " in SOILS_DATA.EvalResult.getBoolean()");
      }
    } else {
      throw new ServiceException("No input parameter value name provided in SOILS_DATA.EvalResult.getBoolean()");
    }

    return ret_val;
  }

  public static LocalDate getDateValue(JSONObject inputJSON) throws ServiceException {
    LocalDate ret_val = DEFAULT_EMPTY_DATE;
    String temp;

    if (inputJSON != null) {
      if (USE_TYPE_CHECKING) {
        String val_type = inputJSON.optString(DEFAULT_TYPE_VALUE_STRING);
        if (null != val_type) {
          if (val_type.equalsIgnoreCase(DEFAULT_DATE_TYPE)) {
            temp = inputJSON.optString(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_DATE_WRITE_VALUE);
          } else {
            throw new ServiceException("EvalResult.getDateValue():  Invalid type specified for " + inputJSON.optString(csip.ModelDataService.KEY_NAME, "[no variable name]") + ".  Expecting type " + DEFAULT_DATE_TYPE + " but found " + val_type);
          }
        } else {
          throw new ServiceException("EvalResult.getDateValue():  Type-Checking specified, but no 'type' name/value pair exists in this JSON object: " + inputJSON.toString());
        }
      } else {
        //No type checking enabled                  
        temp = inputJSON.optString(DEFAULT_VALUE_STRING, DEFAULT_EMPTY_DATE_WRITE_VALUE);
      }

      if (!temp.equals(DEFAULT_EMPTY_DATE_WRITE_VALUE)) {
        ret_val = LocalDate.parse(temp);
      }

    } else {
      throw new ServiceException("No input JSON provided for " + DEFAULT_VALUE_STRING + " in EvalResult.getDateValue()");
    }

    return ret_val;
  }

  /**
   * This function assumes that the result set contains a geometry specified as
   * WKT. To insure this, please use ".STAsText()" in all MS-SQL calls for a
   * geometry column's data.
   *
   * @param result
   * @param name
   * @param engine This parameter must contain a valid a valid GISEngine, or
   * null
   * @throws SQLException This exception is thrown on error reading the
   * resultset or on error interpreting the data contained in the resultset for
   * the geometry column.
   */
  public static GISObject getGeometry(ResultSet result, String name, GISEngine engine) throws SQLException {
    String wkt = result.getString(name);
    GISObject ret_val = null;

    if (result.wasNull()) {
      ret_val = DEFAULT_EMPTY_GEOMETRY;
    } else {
      try {
        ret_val = GISObjectFactory.createGISObject(wkt, engine);
      } catch (GISObjectException ex) {
        throw new SQLException("Invalid WKT geometry passed to GISObject conversion: " + ex.getMessage(), ex);
      }
    }

    return ret_val;
  }

  public static GISObject getGeometryValue(JSONObject inputJSON, GISEngine engine) throws ServiceException {
    GISObject ret_val = DEFAULT_EMPTY_GEOMETRY;

    try {
      ret_val = GISObjectFactory.createGISObject(inputJSON, engine);
    } catch (JSONException ex) {
      throw new ServiceException("Invalid geoJSON geometry specified: " + ex.getMessage(), ex);
    } catch (IOException ex) {
      throw new ServiceException("Cannot read the input geoJSON: " + ex.getMessage(), ex);
    } catch (GISObjectException ex) {
      throw new ServiceException("Cannot create a new geometry from the input geoJSON: " + ex.getMessage(), ex);
    }

    return ret_val;
  }

  public static String writeDouble(double value) {
    String ret_val = DEFAULT_EMPTY_DOUBLE_WRITE_VALUE;

    if (!testDefaultDouble(value)) {
      ret_val = Double.toString(value);
    }

    return ret_val;
  }

  public static String writeDouble(double value, String format) {
    String ret_val = DEFAULT_EMPTY_DOUBLE_WRITE_VALUE;

    if (null == format) {
      return writeDouble(value);
    } else {
      if (!testDefaultDouble(value)) {
        ret_val = String.format(format, value);
      }
    }

    return ret_val;
  }

  public static String writeDate(LocalDate value, String format) {
    String ret_val = DEFAULT_EMPTY_DATE_WRITE_VALUE;

    if (!testDefaultDate(value)) {
      if (format != null) {
        ret_val = value.format(DateTimeFormatter.ofPattern(format));
      } else {
        ret_val = value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
      }
    }

    return ret_val;
  }

  public static String writeInteger(int value) {
    String ret_val = DEFAULT_EMPTY_INTEGER_WRITE_VALUE;

    if (!testDefaultInteger(value)) {
      ret_val = Integer.toString(value);
    }

    return ret_val;
  }

  public static String writeBoolean(Boolean value) {
    String ret_val = Boolean.toString(value);
    return ret_val;
  }

  public static String writeString(String value) {
    String ret_val = DEFAULT_EMPTY_STRING_WRITE_VALUE;

    if ((null != value) && (!value.equals(DEFAULT_EMPTY_STRING))) {
      ret_val = value;
    }

    return ret_val;
  }

  public static boolean testDefaultDouble(double testVal) {
    boolean ret_val;

    if (Double.isNaN(DEFAULT_EMPTY_DOUBLE)) {
      ret_val = Double.isNaN(testVal);
    } else {
      ret_val = (DEFAULT_EMPTY_DOUBLE == testVal);
    }

    return ret_val;
  }

  public static boolean testDefaultFloat(float testVal) {
    boolean ret_val;

    if (Float.isNaN(DEFAULT_EMPTY_FLOAT)) {
      ret_val = Float.isNaN(testVal);
    } else {
      ret_val = (DEFAULT_EMPTY_FLOAT == testVal);
    }

    return ret_val;
  }

  public static boolean testDefaultInteger(int testVal) {
    return (DEFAULT_EMPTY_INTEGER == testVal);
  }

  public static boolean testDefaultEmptyString(String testVal) {
    if (null == testVal) {
      if (null == DEFAULT_EMPTY_STRING) {
        return true;
      }
      return false;
    }

    return (testVal.equals(DEFAULT_EMPTY_STRING));
  }

  public static boolean testDefaultDate(LocalDate value) {
    return (value.equals(DEFAULT_EMPTY_DATE));
  }

  public static String cleanStringForSQL(String value) {
    String ret_val = value;

    ret_val = ret_val.replaceAll("'", "''");
    ret_val = ret_val.replaceAll("_", "__");
    ret_val = ret_val.replaceAll(";", ";;");

    return ret_val;
  }
}