I'm creating an decision table using Drools and having trouble with the greater than character ('>').
I saw on the drools documentation that you could use '>' and '<' but I seem to get something wrong.
The column is (I don't have enough reputation yet to post images):
|CONDITION|
| | (empty cell)
|duration >|
|Duration|
|50|
|200|
The thing is that the architecture doesn't allow me to get the full object. I can only have some fields from the RemoteObject.
So the thing I can do is:
Integer duration = getRemoteObjectDuration();
kSession.insert(duration);
kSession.fireAllRules();
Which results in:
[6,2]: [ERR 102] Line 6:2 mismatched input '>' in rule "RuleTable_11"
[14,2]: [ERR 102] Line 14:2 mismatched input '>' in rule "RuleTable_12"
[0,0]: Parser returned a null Package
I could create a dummy object containing my field, but there must be something better to do.
Does anyone have an idea about this?
To match an Integer you can use a rule like
rule findInt
when
Integer( $iv: intValue > 42 )
then
System.out.println( "got an Integer > 42: " + $iv );
end
and, consequently, a spreadsheet column according to
CONDITION
Integer
intValue >
- ... -
42
This is, of course, doomed to fail when you have several Integer objects floating around in working memory, not being able to identify what is what.
For your predicament I'd create a shadow object for holding all fields of the remote object rather than wrap the fields individually.
Thanks to laune's comment, I finally made it work, but I had to create a custom object only containing the field I needed and I wrote the name of this new class below CONDITION.
Related
I have some working code:
#if( !$lead.First_5_Lines_in_Basket__c.isEmpty() )
#set( $First_5_Lines_in_Basket__c = $lead.First_5_Lines_in_Basket__c )
#foreach( $fivelines in $First_5_Lines_in_Basket__c.split("\n", -1) )
${fivelines.replaceAll("Part","<br><br>Part")}
#end
#end
Which outputs puts the following:
Part - 7984219, P2220 Oscilloscope Probe, Passive, 300 V Qty. - 11
Is it possible to split the First_5_Lines_in_Basket__c field to 3 separate field, such as
Field 1 = Part - 7984219
Field 2 = P2220 Oscilloscope Probe, Passive, 300 V
Field 3 = Qty. - 11***
This will allow me to place field anywhere within an HTML table.
Thanks,
You actually already have most of your answer in your codeāin this case, because you're using $fivelines.replaceall, there's no reason you couldn't use this with a little regex to split your string into individual lines, then add those each to an array that you'd output as a table. The real difficulty comes with $fivelines itself, as it's not marked up in a way that makes it straightforward to split out your field values. If you can alter that somehow (whether that's adding a separator character, structuring the data in some way, etc.) that will go farther and make whatever solution you come up with less fragile.
I am trying to use a full id of a block in the getmaterial part of the code below. this does not work any way that i try.
I cannot find any documentation supporting this issue of handling an id which contains a 'colon :' .
Snip: (Example the 5758:6 below does not work and the string name neither.)
emerald.setIngredient('L', Material.getMaterial("5758:6"));
Material.getMaterial(406) //this is expecting an integer so i cannot give it two numbers
Material.getMaterial(406:1) //this fails as is expecting int
Assuming that emerald is a ShapedRecipe object (since you're using the setIngredient(char, Material) method), then you can also use the setIngredient(char, MaterialData) method instead. You could construct the MaterialData object you want using the (deprecated...) MaterialData(int, byte) constructor. Your new code would look like:
emerald.setIngredient('L', new MaterialData(5758, 6));
The colon in the "full id of a block" is just separating the "id" and "data" values. I think this will do what you're looking for, but if not, let me know so I can clarify.
I don't think you're supposed to be dealing with that number colon thing. Instead, if you want to get to, say, the BRICK material, use Material.BRICK or Material.valueOf("BRICK"). If you want to find the name of a Material m, use m.name() which returns a String.
I have structure as below
Parameter -> Condition -> Rule
Let say i need to create a Business rule, Customer Age > 18
I have two parameters, Customer Age (P1) and 18(P2), where P1 is Field Parameter (Ognl) and P2 is constant Parameter with value 18.
So my Condition now is , Customer Age > 18 and so as my Rule.
Problem Statement : Avoid user from creating duplicate parameter/condition and rules.
Solution : Constant Parameters, Field Parameters etc i can check in DB and compare if already present.
Now condition for me,
Customer Age > 18 and 18 < Customer Age is same in business terms.
The above cases can be more complex.
(a + b) * (c + d) is same as (b + a) * (d + c)
I need to validate the above expressions.
First Approach - Load all expression from DB (Can be 10000's) and compare using Stack/Tree Structure, which will really kill my objective.
Second Approach - I was thinking of building power full, let say hashcode generator or we can say one int value against every expression (considering operators/brackets also). this value should be generated in such a way that it validates above expression.
Means a + b and b + a should generate same int value, and a - b and b - a should generate different.
Maybe a simplified version of your first approach: What about filtering only the relevant expressions by looking for similar content as you are about to insert into the database?
If you know that you are about to insert Customer Age you can find all expressions containing this parameter and build the stack/tree based on this reduced set of expressions.
I think that you cannot avoid writing a parser of expressions, building an AST of the expressions and code rewrite rules to detect expressions equivalence.
It may not be as time consuming as you think.
For the parsing and AST building part, you can start from exp4j:
http://www.objecthunter.net/exp4j/
For the rewrite rules, you can have a look at: Strategies for simplifying math expressions
For a 100% safe solution you should analyze the expressions with a computer algebra system to see whether there are mathemiatically equal. But that's not so easy.
A pragmatic approach that can be to test whether two expressions are similar:
Check whether they have the same variables
Compare their outputs for a number of different inputs, see if the outputs are equal
You can store the variable list and outputs for a predefined set of inputs as a "hash" for the expression. This hash does not give a guarentee that two expresions are equal, but you could present expressions with the same hash to the user asking if this new rule is equal to one of these similar ones.
System.out.println("neon.mems.cmu.edu/people/".split("/").length); // output is 2
I was doing some url processing. To my surprise I just got the result above. I thought the number of elements could be the number of splitters plus one.
I didn't realize the last empty string(or just null) is cut off from the splitted array until now. I wonder if this is the case with every programming language.
No that's not the case for every programming language and there is no universal specification so there is no reason it should be.
Go
a := strings.Split("neon.mems.cmu.edu/people/", "/")
fmt.Println(len(a)) // prints 3
Javascript
Type this in the console of your browser :
"neon.mems.cmu.edu/people/".split('/')
The result is
["neon.mems.cmu.edu", "people", ""]
What you should do when a match is empty isn't something obvious or inherent to the split concept. A proof of that is that old Internet Explorer versions did remove those empty matches.
why it is discarded empty string?
String#split(regx) internally call String#split(regx,0) which execute Pattern.compile(regex).split(this, limit); actually - code snippet
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
where empty string has been discarded from resultSize if limit is 0.
How to get desired result?
String#split(regx,limit) use get desired result.
System.out.println("neon.mems.cmu.edu/people/".split("/",3).length);
Result :
3
And about language specification I am agree with #dystroy
I have a string;
String allIn = "(50 > 100) AND (85< 100)";
Now I need to evaluate if the conditions inside are TRUE or FALSE, how can I do it?
In real the string will be a value from a field in my DB, where I will substitute different values and they will form a string as shown above.
Take a look at the eval project
To me this looks like a "Compiler Design" question where you:
Parse the string into it's individual components using space, < > AND OR != as delimeters
Push on to the stack when you encounter a value
Pop from the stack when you encounter an operator and get next part of expression
But personally - I would go down the Eval route (as stated already) if at all possible - even if it means that you have to change the current syntax of the string or parse and convert the syntax:
https://eval.dev.java.net/