How do i write Decoding function Using Conditional operator in java - java

We are trying to map data using Talend DI tool. In that, we have to capture transformation which is related to Conditional operator.(Because of limitation of tool it won't allow if-then-else syntax instead it does support conditional operator.
Sample Data :
I am trying to write this expression into talend tmap component . How to write this expression into tmap component expression builder using ternary operator. Additional, i have to check for null values.
case when [TCode]='(00) PRE-PAID' then '00'when[TCode]='(01) C.O.D.' then '01'when[TCode]='(02) EOM' then '02'when[TCode]='10' then '(10) NET 10 DAYS'when[TCode]='15' then '(15) NET 15 DAYS'when[TCode]='21' then '(21) 2 % 30 NET 31'when[TCode]='23' then '(23) 2% NET 30 DAYS'when[TCode]='3' then '(3) CHECK'when[TCode]='30' then '(30) NET 30 DAYS' else [TCode]end as TCode
Tried this conditional operator :
"(00) PRE-PAID".equals(row.tCode) ?"00" :
"(01) C.O.D".equals(row.tCode) ?"01" :
"(02) EOM".equals(row.tCode) ? "02" :
"Unknown"
Getting error when tried above conditional operator :
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
XML_API_tXMLMap_1 cannot be resolved to a type
XML_API_tXMLMap_1 cannot be resolved to a type
Syntax error on token ""(00) PRE-PAID"", delete this token
Thanks in advance !

Analysis
According to the link in your comment, you try to execute the following:
row1.tcode==null?null:row1.tcode.length()==0?null:row1.tcode.toUpperCase()
"(00) PRE-PAID".equals(row.tCode) ?"00" :
"(01) C.O.D".equals(row.tCode) ?"01" :
"(02) EOM".equals(row.tCode) ? "02" :
"Unknown"
and you are getting the following error:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
XML_API_tXMLMap_1 cannot be resolved to a type
XML_API_tXMLMap_1 cannot be resolved to a type
Syntax error on token ""(00) PRE-PAID"", delete this token
NOTE: Java is a case sensitive language. So either tcode or tCode is correct, not both.
Explanation
You provided two separate rows of code and Java doesn't know how to interpret this.
Your first line of code is (usually ended with a ;):
row1.tcode==null?null:row1.tcode.length()==0?null:row1.tcode.toUpperCase()
and the second line (albeit it has more lines in itself it is seen as "one line") of code is:
"(00) PRE-PAID".equals(row.tCode) ?"00" :
"(01) C.O.D".equals(row.tCode) ?"01" :
"(02) EOM".equals(row.tCode) ? "02" :
"Unknown"
We need to put those two instructions together.
Solution
(row1.tCode != null && !row1.tCode.equals("")) ? (
"(00) PRE-PAID".equals(row.tCode.toUpperCase()) ? "00" :
"(01) C.O.D".equals(row.tCode.toUpperCase()) ? "01" :
"(02) EOM".equals(row.tCode.toUpperCase()) ? "02" :
"Unknown") : "Unknown"
Alternatively, to shorten the first row, you could set a Default value for tCode if that makes any sense. The default value could be "" and you don't have to check for null anymore. Again, this depends on your use case.

Related

Drools Rules : Can a static method be called in the when section of a drool file

I am trying to write a drools rule that would check if a student has an average of more than 5 at a discipline and i get this error whenever i try to run a static method in the when clause. Moreover, i couldn't find in the drools documentation if it's possible to call a static method in the when section.
This is the rule :
rule "student with at least two grades and average less than 5" salience 8
when
$student : Student(grades.size() >= 2)
$list : ArrayList() from eval(computeAverageGrade($student))
$value : Double() from $list
Boolean(booleanValue() == true) from $value < 5.0
then
System.out.println(2);
student.setValid(false)
end
This is the method's header:
public static List<Double> computeAverageGrade(Student student)
and this is the error i am getting :
Caused by: org.mvel2.PropertyAccessException: [Error: null pointer or function not found: eval]
[Near : {... eval(computeAverageGrade($stud ....}]
^
[Line: 1, Column: 1]
The error explains what's wrong: that's not how you use eval.
Unlike other languages like Javascript, eval doesn't execute arbitary code and return a value: it executes arbitrary code and evaluates a boolean.
You should have declared $list like this:
$list: ArrayList() from computeAverageGrade($student)
$value : Double(this < 5.0) from $list
An example for how you'd use eval, would be to evaluate some sort of truthiness from arbitrary code ... for example like this:
eval( $someValue < someExampleFunctionCall() )
Of course you should always avoid the use of eval because Drools is very good at simplifying conditions for efficient processing, and eval forces it to evaluate your code as-written, thus losing all efficiencies/performance improvements the engine could otherwise give you.
Almost any place you can use eval can be rewritten in a better way -- the example above can, for instance, be rewritten as Double(this > $someValue) from someExampleFunctionCall().
Solved it by replacing ArrayList with Object() and removing eval from the static method call.
found it here : https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html#drl-rules-WHEN-con_drl-rules

ANTLR not recognizing special characters tokens

I am writing the grammar rules for complex logic operations and I am stuck with the tokens. My lexer grammar goes like this:
VAR : 'A'..'Z';
WS : [ \t\r]+ -> skip;
NL : '\n';
TRUE : '1';
FALSE : '0';
AND : '∧';
NAND : '⊼';
OR : '∨';
XOR : '⊻';
NOR : '⊽';
IMPLIES : '⇒';
BICOND : '⇔';
NEGATE : '¬';
EQUIV : '≡';
EQ : '=';
LPAR : '(';
RPAR : ')';
As you can see I am using special symbols for every operation (that should be recognized). The problem is that when I test the parser and I try to visit the tree it gives me the next error:
line 1:1 token recognition error at: '⊼'
It gives me the same error using every operator.
I can tell that the problem is related to encoding because if I replace the symbols for more common ones it visits the tree and gives me the correct result of the operation.
I am using ANTLR in Java.
Thanks in advance!
I just found out the solution. As I thought it was an encoding problem, I just had to set the tool-option encoding in the grammar file as UTF-8.
Thank you anyways!

Jess in Protege: multi-slot setting issue

Based on the example rule AssertingHasSiblingMulti1 for multi-slot setting given in AddingRuleWithJessTab I have created the following Jess rule for setting multi-slot values on my property foundPollutionSources:
(defrule findPHPolluters
(declare (salience 553))
(object
(is-a http..#PollutionSources)
(OBJECT ?sitepoll)
(http..potentialPollutant
$? ?b&:(eq (instance-name ?b)(instance-name http..#pH)) $?)
(http..#pollutionSourceName ?psName)
(http..#pollutionType ?psType)
)
(object
(is-a http..#MeasurementSite)
(OBJECT ?loc)
(http..#hasSourcesOfPollution $?sitepoll_list)
)
(object
(is-a http..#ModeratePHMeasurement)
(OBJECT ?mob)
(http..#observationResultLocation ?loc)
(http..#foundPollutionSources $?existing_poll_list)
)
=>
(if (not (member$ ?sitepoll $?sitepoll_list)) then
(printout t "pH pollution source: " ?psName " (Location: " ?psType ")" crlf)
(slot-set ?mob http..#foundPollutionSources (create$ $?existing_poll_list ?sitepoll))
)
)
But, when I run this rule the following exception appears:
Jess reported an error in routine ValueVector.set while executing
rule LHS (MTELN) while executing rule LHS (TECT). Message: Bad
index 117 in call to set() on this vector:...
There is a deviation from the usual Jess usage pattern of a variable bound to (part of) a multislot value. Observe:
(object
...
(http..#foundPollutionSources $?existing_poll_list))
The prefixed '$' causes all values in the foundPollutionSources slot to be bound to ?existing_poll_list. The usual usage (cf. the Jess manual and the linked example) would be, for instance:
(printout t "pollution sources " ?existing_poll_list crlf))
But your RHS code has
(create$ $?existing_poll_list ...)
Note the spurious '$' - I'd omit it and try again.
I don't know what protege and/or Jess might make of this, and I don't have the time to research it in the latter.

How to change operators dynamically in rule file

I want to evaluate facts dynamically using drool engine. Rule conditions attributes & their conditional operators are stored in database and load in to WM when engine start.
So I want to use that operator in rule file as below.
$dynCx : DynCustomer()
$attrib : Attribute() from $dynCx.attributes
$offer : Offer($ofCode : offer_code, $domainName : domainName )
$rdef : OfferRuleDef($entity : entity,
$code : code,
$value : value,
$atrName : attributeName,
$atrVal : attributeVal,
$op : operation,
$entity == $domainName,
$code == "OFFER_CODE",
$value == $ofCode,
$atrName == $attrib.name,
$atrVal $op $attrib.value
)
but I'm getting below error
Caused by: java.lang.RuntimeException: [59,14]: [ERR 102] Line 59:14 mismatched input '$op' in rule "Evaluate Generic Offer Eligibility"
[0,0]: Parser returned a null Package
How we can achieve this?
Operators can't be resolved at runtime, so you can't write that kind of rule. Based on the version you are using and the number of operators you envision, you have a few options.
1) Write a rule for each operator:
OfferRuleDef( ..., operator == "==", attributeVal == $attrib.value )
to avoid excessive code repetition, consider that rules can "extend" each other.
2) In recent versions, create a static helper function and pass the three values:
OfferRuleDef( ..., MyHelper.applyOperator($attrValue, $op, $attrib.value) )

Drools Expert output object in Scala

I'm a novice in both Scala and Drools Expert, and need some help getting information out of a Drools session. I've successfully set up some Scala classes that get manipulated by Drools rules. Now I want to create an object to store a set of output facts for processing outside of Drools. Here's what I've got.
I've got a simple object that stores a numeric result (generated in the RHS of a rule), along with a comment string:
class TestResults {
val results = new MutableList[(Float, String)]()
def add(cost: Float, comment: String) {
results += Tuple2(cost, comment)
}
}
In the DRL file, I have the following:
import my.domain.app.TestResults
global TestResults results
rule "always"
dialect "mvel"
when
//
then
System.out.println("75 (fixed)")
results.add(75, "fixed")
end
When I run the code that includes this, I get the following error:
org.drools.runtime.rule.ConsequenceException: rule: always
at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
...
Caused by: [Error: null pointer or function not found: add]
[Near : {... results.add(75, "fixed"); ....}]
^
[Line: 2, Column: 9]
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:997)
This looks to me like there's something goofy with my definition of the TestResults object in Scala, such that the Java that Drools compiles down to can't quite see it. Type mismatch, perhaps? I can't figure it out. Any suggestions? Thank you!
You need to initialize your results global variable before executing your session. You can initialize it using:
knowledgeSession.setGlobal("results", new TestResults()))
Try
import my.domain.app.TestResults
global TestResults results
rule "always"
dialect "mvel"
when
//
then
System.out.println("75 (fixed)")
results().add(75.0f, "fixed")
end
My guess is that the types don't line up and the error message is poor. (75 is an Int, wants a Float)
That's right.. and try to add a condition to your rule, so it make more sense (the when part).
The condition evaluation is the most important feature of rule engines, writing rules without conditions doesn't make too much senses.
Cheers

Categories