skip to Main Content

I have an object with fields a and b. For example, I need to add object.a+10 logic to JSON, and then pass this JSON to Java and perform an action on the object and its field a.

I want to write, for example, like this:

{
"object" : {
             "a": 1,
             "b": 10
           },
"operand1": "object.a",
"operand2": "10",
"operation": "+"
}

Or like this:

{
"object" : {
             "a": 1,
             "b": 10
           },
"action": "object.a + 10",
}

Is it possible? How can this be better implemented?

2

Answers


  1. You can use the first option and turn operation into a enum so that it can handle some operation.

    Don’t forget to add appropriate exception handling etc.

    public class Calculation {
        private Operand object;
        private String operand1;
        private String operand2;
        private OperationEnum operation;
        
        // . . .
    
        public int calculate(){
           int number1 = Integer.parseInt(operand1 );
           int number2 = Integer.parseInt(operand1 );
           return operation.apply(number1, number2);
        }
    
    }
    
    public enum OperationEnum{
        PLUS("+", (a, b) -> a + b),
        MINUS("-", (a, b) -> a - b),
        DIVIDE("/", (a, b) -> {
            if (b == 0) throw new ArithmeticException("Cannot divide by zero");
            return a / b;
        }),
        MULTIPLY("*", (a, b) -> a * b);
    
        private final String symbol;
        private final BiFunction<Integer, Integer, Integer> operation;
    
        Operation(String symbol, BiFunction<Integer, Integer, Integer> operation) {
            this.symbol = symbol;
            this.operation = operation;
        }
    
        public int apply(int a, int b) {
            return operation.apply(a, b);
        }
        // . . .
    }
    
    Login or Signup to reply.
  2. Seems that you want to support both supplying directly a value as an operand and a reference to a value. The example with the reference is basically a JSONPath (well, almost).

    JSONPath defines a string syntax for selecting and extracting JSON
    (RFC 8259) values from within a given JSON value.

    For simple use cases you could write your own simplified implementation, but for anything more complex you should use a library. I would suggest Jayway JsonPath, it is a java implementation of the JSONPath specification.

    Map<String, Object> data = //parse json, use a library!!!
    
    ToIntFunction<String> jsonPathOperandResolver = val -> JsonPath.parse(data).read("$." + val);
    ToIntFunction<String> directValueOperandResolver = Integer::parseInt;
    
    //analyze the value and pick the correct resolver
    //for operand1 it's json path
    int operand1 = jsonPathOperandResolver.applyAsInt(data.get("operand1").toString());
    //for operand2 it's direct value
    int operand2 = directValueOperandResolver.applyAsInt(data.get("operand2").toString());
    //apply the operation on 1st and 2nd operand
    

    The most important (missing part) in this example is that you write the logic to select the correct resolver based on the value. A simplified example, based on delegation may look like this:

    class DelegatingOperandResolver implements ToIntFunction<String> {
    
      @Override
      public int applyAsInt(String value) {
        try {
          return directValueOperandResolver.applyAsInt(value);
        } catch (NumberFormatException exc) {
          return jsonPathOperandResolver.applyAsInt(value);
        }
      }
    }
    

    I would also strongly suggest to rethink your json structure and pick something, which does not constrain you into using Map<String, Object>. Basically something, which would allow you to parse into custom object, something like this:

    public record CalculationData(String firstOperand, String secondOperand, String operation,
                                  Map<String, Object> objToReferValueIn) {
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search