name:
src/main/java/io/protobase/f7/formulas/AbstractFormula.java
-rw-r--r--
3571
1package io.protobase.f7.formulas;
2
3import io.protobase.f7.errors.F7Exception;
4import io.protobase.f7.errors.NAException;
5import io.protobase.f7.models.GridColumnRowKey;
6
7import java.util.function.BiFunction;
8import java.util.function.Function;
9
10/**
11 * Abstract formula that has some defaults to ensure the safe execution of formulas.
12 */
13public abstract class AbstractFormula implements Formula {
14 private static final Function<Object, Object> DEFAULT_LOOKUP = (value) -> value;
15 private static final BiFunction<GridColumnRowKey, Object, Object> DEFAULT_COLLATERAL_LOOKUP = (origin, value) -> value;
16
17 protected Function<Object, Object> lookup;
18 protected BiFunction<GridColumnRowKey, Object, Object> collateralLookup;
19
20 public AbstractFormula() {
21 lookup = DEFAULT_LOOKUP;
22 collateralLookup = DEFAULT_COLLATERAL_LOOKUP;
23 }
24
25 public AbstractFormula(Function<Object, Object> lookup, BiFunction<GridColumnRowKey, Object, Object> collateralLookup) {
26 this.lookup = lookup;
27 this.collateralLookup = collateralLookup;
28 }
29
30 /**
31 * Ensure that argument lengths are equal. If not, throw {@link NAException}.
32 *
33 * @param actualLength - actual length of arguments.
34 * @param expectedLength - expected length of arguments.
35 * @param caller - name of formula calling this.
36 */
37 public static void checkLength(int actualLength, int expectedLength, FormulaName caller) {
38 if (actualLength != expectedLength) {
39 throw new NAException(String.format("Wrong number of arguments to %s. Expected %d arguments, but got %d arguments",
40 caller, expectedLength, actualLength));
41 }
42 }
43
44 /**
45 * Ensure that arguments are at least a certain length. If not, throw {@link NAException}.
46 *
47 * @param actualLength - actual length of arguments.
48 * @param minExpectedLength - minimum expected length of arguments.
49 * @param caller - name of formula calling this.
50 */
51 public static void checkAtLeastLength(int actualLength, int minExpectedLength, FormulaName caller) {
52 if (actualLength < minExpectedLength) {
53 throw new NAException(String.format("Wrong number of arguments to %s. Expected at least %d arguments, but got %d arguments",
54 caller, minExpectedLength, actualLength));
55 }
56 }
57
58 /**
59 * Ensure that arguments are between a minimum and maximum length. If not, throw {@link NAException}.
60 *
61 * @param actualLength - actual length of arguments.
62 * @param min - minimum expected length of arguments, inclusively
63 * @param max - maximum expected length of arguments, inclusively
64 * @param caller - name of formula being called.
65 */
66 public static void checkLengthBetween(int actualLength, int min, int max, FormulaName caller) {
67 if (actualLength < min || actualLength > max) {
68 throw new NAException(String.format("Wrong number of arguments to %s. Expected between %d and %d arguments, but got %d arguments",
69 caller, min, max, actualLength));
70 }
71 }
72
73 /**
74 * By default, when we execute a formula, we want to catch the errors and return them as the resulting value.
75 *
76 * @param origin - origin cell that is running this formula.
77 * @param values - to use when calling the formula.
78 * @return the result of the formula implemented by the sub-class, or the error thrown by the formula implemented by
79 * the sub-class.
80 */
81 public Object apply(GridColumnRowKey origin, Object... values) {
82 try {
83 return this.internal(origin, values);
84 } catch (F7Exception error) {
85 return error;
86 }
87 }
88}