Extracting expression variables

Hey folks,

I know, that the answer to this question might be absolutly trivial, but I am stuck somehow:

Is there a way to parse an expression-text, so I get access to the included variables without extracting them manually?

For example: “(garage.carsGreen+garage.carsYellow)*130>maxCarsFactor” should return the three used variables “garage.carsGreen”, “garage.carsYellow” and “maxCarsFactor” for further usage…

This means, I do not want to get the boolean-result of the expression, but the names of the variables. Is this possible somehow? Peraps by using any method in scala, I could not find yet?

Thanks a lot!

Georg

1 Like

@gwolffgang Did you configured this expression in BPMN file? Can you provide your BPMN it would be easier to provide solution.

@aravindhrs Thanks for your quick answer.
Sure thing. I build you an example dmn (without any sense, but explaining the problem):

<Help needed: How to paste code in the forums?!>

< ?xml version=“1.0” encoding=“UTF-8”?>
< definitions xmlns=“http://www.omg.org/spec/DMN/20151101/dmn.xsd” xmlns:biodi=“http://bpmn.io/schema/dmn/biodi/1.0” xmlns:camunda=“http://camunda.org/schema/1.0/dmn” id=“Definitions_0d0ibd1” name=“DRD” namespace=“http://camunda.org/schema/1.0/dmn” exporter=“Camunda Modeler” exporterVersion=“3.3.5”>
< decision id=“Decision_1yxwdsz” name=“Decision 1”>
< extensionElements>
< biodi:bounds x=“323” y=“81” width=“180” height=“80” />
< biodi:edge source=“InputData_03lk8dv”>
< biodi:waypoints x=“271” y=“236” />
< biodi:waypoints x=“371” y=“161” />
< /biodi:edge>
< biodi:edge source=“InputData_1j8nnwc”>
< biodi:waypoints x=“512” y=“251” />
< biodi:waypoints x=“447” y=“161” />
< /biodi:edge>
< /extensionElements>
< informationRequirement>
< requiredInput href="#InputData_03lk8dv" />
< /informationRequirement>
< informationRequirement>
< requiredInput href="#InputData_1j8nnwc" />
< /informationRequirement>
< decisionTable id=“decisionTable_1”>
< input id=“input_1” label=“Truth” camunda:inputVariable=“truth”>
< inputExpression id=“inputExpression_1” typeRef=“boolean”>
< text>(owner.age+animal.age)/2>3
< /inputExpression>
< /input>
< output id=“output_1” label=“Result” name=“result” typeRef=“string” />
< rule id=“DecisionRule_1egcfwl”>
< inputEntry id=“UnaryTests_18ddo7y”>
< text>true
< /inputEntry>
< outputEntry id=“LiteralExpression_0i2p1bi”>
< text>“yes, indeed”
< /outputEntry>
< /rule>
< rule id=“DecisionRule_0fevsvv”>
< inputEntry id=“UnaryTests_0vnyj5a”>
< text>false
< /inputEntry>
< outputEntry id=“LiteralExpression_09f9jo7”>
< text>“not really”
< /outputEntry>
< /rule>
< /decisionTable>
< /decision>
< inputData id=“InputData_03lk8dv” name=“owner.age”>
< extensionElements>
< biodi:bounds x=“177” y=“236” width=“125” height=“45” />
< /extensionElements>
< /inputData>
< inputData id=“InputData_1j8nnwc” name=“animal.age”>
< extensionElements>
< biodi:bounds x=“465” y=“251” width=“125” height=“45” />
< /extensionElements>
< /inputData>
< /definitions>

So what I understood is that you are trying to extract fields from the dmn expression. Why do you want to extract the fields?

@aravindhrs
If the variables are called fields, then yes, I would like to extract them.
If you need to know: I am trying to write a program, that is able to read expressions and write the javacode of a method, that is able to do the same, as the expression. So I need the input for the method and this should equal the variables/fields used in the expression.

@gwolffgang you can read dmn file and parse it like below. you can either use DecisionService Java api or rest api to get the dmn file.

Using repositoryService you can directly get the DmnModelInstance.

public DmnModelInstance getDmnModelInstance() {
  String decisionDefinitionId = repositoryService.createDecisionDefinitionQuery()
    .decisionDefinitionKey(DECISION_KEY).singleResult().getId();
  DmnModelInstance modelInstance = repositoryService
    .getDmnModelInstance(decisionDefinitionId);
  return modelInstance; 
}

Below code is to read the input expressions from decision definition:

public List<String> getInputExpression(String dmnSource){   	
    
    InputStream inputStream = new ByteArrayInputStream(dmnSource.getBytes(Charset.forName("UTF-8")));

    DmnModelInstance dmnModelInstance = Dmn.readModelFromStream(inputStream);
        
    DecisionTable decisionTable = dmnModelInstance.getModelElementById("Decision_1yxwdsz");
             
	List<String> expressions = new ArrayList<>();
    Collection<Input> inputs = decisionTable.getInputs();
    inputs.stream().forEach(input->{
        //add your logic to getInputExpression
        InputExpression inputExpression = input.getInputExpression();
        expressions.add(inputExpression.getText().getTextContent()); //check this returns expected o/p	
    });

    return expressions;
}

@aravindhrs
Thank you for your code, but extracting the expressions is not the problem. I have access to them already. The complicated part starts now by analysing the extracted expressions. I would like to have a List of Strings with all the variables, that are used by each expression without having to extract them by myself. There should be a way, how your dmnEngine knows, which input to use to solve the expression. Shouldn’t it?

Thanks again!
Georg

@gwolffgang you can refer the source code here.

https://github.com/camunda/camunda-bpm-platform/blob/master/engine-dmn/engine/src/main/java/org/camunda/bpm/dmn/engine/impl/evaluation/DecisionTableEvaluationHandler.java

@aravindhrs
I solved my problem the hard way by extracting them by myself. But thank you for all your support anyway!

Greetings
Georg