CalculationContext Class

A data structure containing a HashMap of named ComputeField objects, a HashMap of named TableArray objects, and a FormulaFieldsDescriptor object.

Introduction

The ACE4J library is completely independent from a spreadsheet context. It has its own calculation context represented by a data structure that contains a HashMap of named ComputeField objects, a HashMap of named TableArray objects, a FormulaFieldsDescriptor object, and a user defined functions (UDF) class name key to the UDFLocator registry. This data structure is uniquely identified by the application name appName.

A CalculationContext object is used as a parameter in the majority of the ACE4J API methods including the primary methods of formula evaluation, evaluateDependentFormulas() and evaluateAllFormulas(). The last two methods internally invoke the compileAllFormulas() method to compile all formulas and create the FormulaFieldsDescriptor component of the CalculationContext parameter.

Consider the following spreadsheet from the XLOOKUP Example published on our website:

Illustration of Excel cell via Computefield. Example of a range of cells B1:C4 that forms a produce table.

The below code creates a CalculationContext object to evaluate a formula in this example. The following name mapping is used to make the code content more meaningful for readers:

B2 −> car

C2 −> model_formula

C5:C12 −> car_make

D5:D12 −> model

Using this mapping method the code creates two ComuteField and two TableArray objects. Then it creates the CalculationContext object based on these objects:

Object[][] lookupTable = {{"Country",       "Car Make",       "Model"},
                      {"France",        "PEUGEOT",         "1007"},
                      {"Germany",       "BMW",               "X3"},
                      {"Italy",         "ALFA ROMEO",    "GIULIA"},
                      {"Japan",         "TOYOTA",         "CAMRY"},
                      {"South Korea",   "KIA",           "SELTOS"},
                      {"Sweden",        "VOLVO",            "V90"},
                      {"UK",            "LAND ROVER",  "DEFENDER"},
                      {"United States", "FORD",          "RANGER"}};

// Car Make column without its title
TableArray carMake = new TableArray(lookupTable, 1, 1, lookupTable.length - 1, 1);
// Model column without its title
TableArray model = new TableArray(lookupTable, 1, lookupTable[0].length - 1,
    lookupTable.length - 1, lookupTable[0].length - 1);
InputField car = new InputField(ComputeFieldType.ALPHANUMERIC);
String myFormulaText = "XLOOKUP(car, \"Car_Make\", \"Model\")";
FormulaField myFormulaField = new FormulaField(ComputeFieldType.ALPHANUMERIC, myFormulaText);
CalculationContext calculationContext = new CalculationContext("MyApp");

// TableArrays
calculationContext.put("Car_Make", carMake);
calculationContext.put("Model", model);

// ComputeFields
calculationContext.put("car", car);
calculationContext.put("model_formula", myFormulaField);

The following JSON object shows the structure and content of the CalculationContext object created in this example:

  • JSON CalculationContext {6}
    • computeFields {2}
      • car {1}
        • InputField {7}
          • computeFieldType : ALPHANUMERIC
          • value : null
          • errorCode : 0
          • error : false
          • displayValue :
          • rangeName : null
          • rangePosition : null
      • model_formula {1}
        • FormulaField {11}
          • computeFieldType : ALPHANUMERIC
          • formulaText : XLOOKUP(car, \"car_make\", \"model\")
          • value : null
          • errorCode : 0
          • operandInErrorName : null
          • formulaIterator : null
          • formulaFieldOverridden : false
          • error : false
          • displayValue :
          • rangeName : null
          • rangePosition : null
    • tableArrays {2}
      • car_make {1}
        • table {8}
          • 0 [1]
            • 0 : PEUGEOT
          • 1 [1]
            • 0 : BMW
          • 2 [1]
            • 0 : ALFA ROMEO
          • 3 [1]
            • 0 : TOYOTA
          • 4 [1]
            • 0 : KIA
          • 5 [1]
            • 0 : VOLVO
          • 6 [1]
            • 0 : LAND ROVER
          • 7 [1]
            • 0 : FORD
      • model {1}
        • table {8}
          • 0 [1]
            • 0 : 1007
          • 1 [1]
            • 0 : X3
          • 2 [1]
            • 0 : GIULIA
          • 3 [1]
            • 0 : CAMRY
          • 4 [1]
            • 0 : SELTOS
          • 5 [1]
            • 0 : V90
          • 6 [1]
            • 0 : DEFENDER
          • 7 [1]
            • 0 : RANGER
    • formulaFieldsDescriptor {7}
      • formulaFieldsDependencies [0]
        • (empty array)
      • formulaFieldsEvaluationOrder [0]
        • (empty array)
      • missingComputeFields [0]
        • (empty array)
      • computeFieldsInError [0]
        • (empty array)
      • error : false
      • missingComputeFieldsIndicator : false
      • computeFieldsInErrorIndicator : false
    • udfClassName : null
    • appName : MyApp
    • recompileFormulas : false

If we add the following two lines of code:

car.setValue("VOLVO");
HybridFormulaEvaluator.evaluateAllFormulas(calculationContext);

the formula in our example will be evaluated such that the value of the formulaField model_formula will become "V90."

This is reflected in the following JSON object:

  • JSON CalculationContext {6}
    • computeFields {2}
      • car {1}
        • InputField {7}
          • computeFieldType : ALPHANUMERIC
          • value : VOLVO
          • errorCode : 0
          • error : false
          • displayValue : VOLVO
          • rangeName : null
          • rangePosition : null
      • model_formula {1}
        • FormulaField {11}
          • computeFieldType : ALPHANUMERIC
          • formulaText : XLOOKUP(car, \"car_make\", \"model\")
          • value : V90
          • errorCode : 0
          • operandInErrorName : null
          • formulaFieldOverridden : false
          • formulaIterator : null
          • error : false
          • displayValue : V90
          • rangeName : null
          • rangePosition : null
    • tableArrays {2}
      • car_make {1}
        • table {8}
          • 0 [1]
            • 0 : PEUGEOT
          • 1 [1]
            • 0 : BMW
          • 2 [1]
            • 0 : ALFA ROMEO
          • 3 [1]
            • 0 : TOYOTA
          • 4 [1]
            • 0 : KIA
          • 5 [1]
            • 0 : VOLVO
          • 6 [1]
            • 0 : LAND ROVER
          • 7 [1]
            • 0 : FORD
      • model {1}
        • table {8}
          • 0 [1]
            • 0 : 1007
          • 1 [1]
            • 0 : X3
          • 2 [1]
            • 0 : GIULIA
          • 3 [1]
            • 0 : CAMRY
          • 4 [1]
            • 0 : SELTOS
          • 5 [1]
            • 0 : V90
          • 6 [1]
            • 0 : DEFENDER
          • 7 [1]
            • 0 : >RANGER
    • formulaFieldsDescriptor {7}
      • formulaFieldsDependencies [2]
        • car [1]
          • 0 : model_formula
        • model_formula [0]
          • (empty array)
      • formulaFieldsEvaluationOrder [1]
        • 0 : model_formula
      • missingComputeFields [0]
        • (empty array)
      • computeFieldsInError [0]
        • (empty array)
      • error : false
      • missingComputeFieldsIndicator : false
      • computeFieldsInErrorIndicator : false
    • udfClassName : null
    • appName : MyApp
    • recompileFormulas : false

Overview

The CalculationContext class has one constructor:

CalculationContex(String appName);

It throws the IllegalArgumentException if the application name appName is null or empty.

This class offers the following methods:

ComputeField get(String computeFieldName)

put(String computeFieldName, ComputeField computeField)

put(String tableArrayName, TableArray tableArray)

Map<String, ComputeField> getComputeFields()

setComputeFields(Map<String, ComputeField> computeFields)

Map<String, TableArray> getTableArrays()

setTableArrays(Map<String, TableArray> tableArrays)

FormulaFieldsDescriptor getFormulaFieldsDescriptor()

setFormulaFieldsDescriptor(FormulaFieldsDescriptor ffd)

String getUDFClassName()

setUDFClassName(String UDFClassName)

String getAppName()

The ACE4J library provides the JsonConverter class that can be used as a utility to convert a CalculationContext object into a JSON string, and vice versa. This class uses the Jackson library and is described in the Adaptive Calculation Engine Javadoc, distributed via our free download.