Check.java [src/csip] Revision: Date:
/*
* $Id: 2.7+14 Check.java 773d4dd2e419 2022-10-27 od $
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API and application suite.
*
* 2012-2022, Olaf David and others, 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 csip;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
/**
* Check for data correctness.
*
* @author od
*/
public class Check {
static final double conus_top = 49.3457868; // north lat
static final double conus_left = -124.7844079; // west long
static final double conus_right = -66.9513812; // east long
static final double conus_bottom = 24.7433195; // south lat
// generic Object, can be Number, String or date
List<Function<Object, String>> checks = new ArrayList<>();
public Number forNumber(Number n) throws IllegalArgumentException {
return forNumber(n, "");
}
public Number forNumber(Number n, String prefix) throws IllegalArgumentException {
return (Number) forObject(n, prefix);
}
public LocalDate forLocalDate(LocalDate n) throws IllegalArgumentException {
return forLocalDate(n, "");
}
public LocalDate forLocalDate(LocalDate n, String prefix) throws IllegalArgumentException {
return (LocalDate) forObject(n, prefix);
}
public String forString(String n) throws IllegalArgumentException {
return forString(n, "");
}
public String forString(String n, String prefix) throws IllegalArgumentException {
return (String) forObject(n, prefix);
}
Object forObject(Object n, String prefix) throws IllegalArgumentException {
if (n == null)
throw new NullPointerException(prefix + " for argument.");
for (Function<Object, String> check : checks) {
String err = check.apply(n);
if (err != null)
throw new IllegalArgumentException(prefix + err);
}
return n;
}
public Check eq(double val) {
checks.add(n -> {
if (Double.compare(toDouble(n), val) == 0)
return null;
return n + " not equal to " + val;
});
return this;
}
public Check lt(double val) {
checks.add(n -> {
if (toDouble(n) < val)
return null;
return n + " not lower than " + val;
});
return this;
}
public Check gt(double val) {
checks.add(n -> {
if (toDouble(n) > val)
return null;
return n + " not greater than " + val;
});
return this;
}
public Check positive() {
checks.add(n -> {
if (!(toDouble(n) > 0.0))
return " not positive: " + n;
return null;
});
return this;
}
public Check negative() {
checks.add(n -> {
if (!(toDouble(n) < 0.0))
return " not negative: " + n;
return null;
});
return this;
}
public Check notNaN() {
checks.add(n -> {
if (Double.isNaN(toDouble(n)))
return " is NaN";
return null;
});
return this;
}
public Check isConusLat() {
checks.add(n -> {
double d = toDouble(n);
if (d < conus_top && d > conus_bottom)
return null;
return "Not a CONUS lat: " + d;
});
return this;
}
public Check isConusLon() {
checks.add(n -> {
double d = toDouble(n);
if (d > conus_left && d < conus_right)
return null;
return "Not a CONUS lat: " + d;
});
return this;
}
public Check isLatitude() {
checks.add(n -> {
double d = toDouble(n);
if (d > -90d && d < 90d)
return null;
return "Not a latitude: " + d;
});
return this;
}
public Check isLongitude() {
checks.add(n -> {
double d = toDouble(n);
if (d > -180d && d < 180d)
return null;
return "Not a longitude: " + d;
});
return this;
}
public Check isCMZ() {
checks.add(n -> {
String cmz = n.toString().trim();
if (cmz.indexOf(' ') > 0) {
if (cmz.equals("72 AK") || cmz.equals("73 HI")
|| cmz.equals("74 PB") || cmz.equals("75 PR"))
return null;
}
try {
float val = Float.parseFloat(cmz);
if (val == 4.1f || val == 15.1f || val == 37.1f || val == 38.1f)
return null;
if (val >= 1 && val <= 71 && (val == (int) val))
return null;
return "Invalid CMZ: " + cmz;
} catch (NumberFormatException E) {
return "Invalid CMZ: " + cmz;
}
});
return this;
}
public Check isEcoclassId() {
checks.add(n -> {
String ecId = n.toString();
if (ecId.length() == 11 && (ecId.charAt(0) == 'R' || ecId.charAt(0) == 'F'))
return null;
return "Invalid Ecoclass ID: " + ecId;
});
return this;
}
public Check isISODateString() {
checks.add(n -> {
String date = n.toString();
try {
LocalDate.parse(date, DateTimeFormatter.ISO_DATE);
return null;
} catch (DateTimeParseException E) {
try {
LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE);
return null;
} catch (DateTimeParseException E1) {
return "Invalid Date: " + date;
}
}
});
return this;
}
public Check inRange(double min, double max) {
checks.add(n -> {
double d = toDouble(n);
if (d < min || d > max)
return d + " not in range " + min + "..." + max;
return null;
});
return this;
}
public Check inRange(int min, int max) {
checks.add(n -> {
int d = toInt(n);
if (d < min || d > max)
return d + " not in range " + min + "..." + max;
return null;
});
return this;
}
public Check inBetween(LocalDate start, LocalDate end) {
checks.add(n -> {
LocalDate d = (LocalDate) n;
if (!(d.isAfter(start) && d.isBefore(end)))
return d + " not in date range " + start + "..." + end;
return null;
});
return this;
}
public Check inSet(int... vals) {
checks.add(i -> {
int ii = toInt(i);
for (int val : vals) {
if (val == ii)
return null;
}
return i + " not in: " + Arrays.toString(vals);
});
return this;
}
public Check inSet(Object... vals) {
checks.add(s -> {
for (Object val : vals) {
if (val.equals(s))
return null;
}
return s + " not found in: " + Arrays.toString(vals);
});
return this;
}
public Check inSetIngnoreCase(String... vals) {
checks.add(s -> {
for (String val : vals) {
if (val.equalsIgnoreCase(s.toString()))
return null;
}
return s + " not found in: " + Arrays.toString(vals);
});
return this;
}
public Check notInSet(Object... vals) {
checks.add(s -> {
for (Object val : vals) {
if (val.equals(s))
return s + " in: " + Arrays.toString(vals);
}
return null;
});
return this;
}
private double toDouble(Object o) {
if (o instanceof Number)
return ((Number) o).doubleValue();
if (o instanceof String) {
return Double.parseDouble((String) o);
}
throw new IllegalArgumentException(o + " cannot be converted into double.");
}
private int toInt(Object o) {
if (o instanceof Number)
return ((Number) o).intValue();
if (o instanceof String) {
return Integer.parseInt((String) o);
}
throw new IllegalArgumentException(o + " cannot be converted into int.");
}
}