Provide check in RHS for existence of a field inside pojo in drools - drools

I am new to drools.
I want to check in RHS that if a field is present in POJO or not.
{
"category": [
{
"nlp": [
{
"mainCategory": "Politics"
}
],
"crawler": [
{
"isNLP": true,
"mainCategory": "Politics"
}
]
}
]
}
This is list of the pojo that are generated
EsRootDoc.java
Crawler.java
Nlp.java
EsRootDoc is the main class which have methods and fields.`when
$RHSmap1:EsRootDoc()
and
$map1:EsRootDoc($categorylist1:category)
$category2:Category($nlplist2:nlp) from $categorylist1
$nlp2:Nlp(mainCategory=="politics") from $nlplist2
then
$RHSmap1.setEvent("fight");
end`
This is giving me following error
[Error: unable to resolve method using strict-mode: com.orkash.EnrichmentService.EnrichmentController.tempJsonToClass.EsRootDoc.setEvent(java.lang.String)]
[Near : {... $RHSmap1.setEvent("fight"); ....}]
I need to provide a check in RHS :- that if EsRootDoc has a field event or not

There is nothing in Drools (as far as I know) that allows you to do what you are looking for. The RHS of a rule is - almost- pure Java. The basic rule then is: if it can't be done in Java, it can't be done in the RHS of a rule in Drools.
The good news is that what you are trying to do can be achieved in Java using reflection. My recommendation would be for you to create a helper class that uses reflection to set the value of an attribute in an object if that attribute exists. Your rules then would look like this:
rule 'Some Rule'
when
$RHSmap1:EsRootDoc()
$map1:EsRootDoc($categorylist1:category)
$category2:Category($nlplist2:nlp) from $categorylist1
$nlp2:Nlp(mainCategory=="politics") from $nlplist2
then
Helper.setAttribute($RHSmap1, "event", "fight");
end
Hope it helps,

Related

Drools - how do I compare a string value present in a Java Object which is present inside a List

I am new to Drools and am having a tough time writing rules
Here is my data structure :
public class Premium{
private List<InsuranceType> insuranceTypes;
}
public class InsuranceType {
private String name;
}
So a Premium object will contain a List of Insurance types and I need to check if any of the insurance types has a name of "TPD"
Have tried the following :
rule "rule#3"
when
$fact:Premium($insuranceTypes : InsuranceType(name == 'TPD'))
then
System.out.println("Error");
end
However app server fails to start with the following error:
2021-11-30 12:16:37.004 ERROR 23500 --- [ main]
o.d.c.k.builder.impl.AbstractKieModule : Unable to build KieBaseModel:defaultKieBase
Unable to Analyse Expression InsuranceType(name == "TPD"):
[Error: unable to resolve method using strict-mode: com.xyz.Premium.name()]
[Near : {... InsuranceType(name == "TPD") ....}]
^
[Line: 29, Column: 5] : [Rule name='rule#3']
Unable to analyze expression 'InsuranceType(name == "TPD")' : [Rule name='rule#3']
Field Reader does not exist for declaration '$insuranceTypes' in '$insuranceTypes :
InsuranceType(name == "TPD")' in the rule 'rule#3' : [Rule name='rule#3']
I'm going to assume there's a public getName method on the InsuranceType class, and a public getInsuranceTypes method on the Premium class. If either of those isn't true, you need to add either getters or make those properties public.
Your rule was pretty close. However the problem you have is that insuranceTypes is a list but you were treating it as an object.
You have several options here, depending on your needs. However I'd go with the simplest, which is this:
rule "Example"
when
Premium( $insuranceTypes: insuranceTypes )
exists( InsuranceType( name == "TPD" ) from $insuranceTypes )
then
System.out.println("Error");
end
In the first line, I get the insurance types and assign them to the variable $insuranceTypes. This variable is now the list of types.
Then in the second line, I assert that there exists at least one InsuranceType in the list that has the name "TPD".
Note that Drools also has a memberOf operator, and a contains operator, which come in useful when working with lists and other iterable collections. These are inverses of each other, eg. you'd do Example( foo memberOf $someList ) or Example( myList contains $something ).

Watson Assistant Extract multiple pattern entities

I have an entity defined as
#code
- #code:type_1 = pattern 'Y(\d{3})'
- #code:type_2 = pattern 'order number(\d{3})'
- #code:type_3 = pattern 'CZ(\d{3})'
I am trying to capture the following context values like so
{
"context": {
"type_3s": "<? #code.filter(\"c\", \"c['value'] == 'type_3'\").joinToArray('%e.groups[1]%') ?>"
}
}
So that for input
Please delete codes CZ123, CZ456, and CZ789, my final context looks like this:
$type_3s =[123,456,789]
Currently getting the error
SpEL evaluation error: Expression [ entities['code'].filter("c", "c['value'] == 'type_3'").joinToArray('%e.groups[1]%') ] at position 63: EL1004E: Method call: Method joinToArray(String) cannot be found on ArrayList type
In the above example, code.values evaluates to:
#code.values =["type_3", "type_3", "type_3"]
Any help in achieving the desired context would be greatly appreciated, thank you so much!
My recommendation would be to take a look at the Watson Assistant entity syntax. .value returns the identified entity which would be type_3. You would need to use .literal to access what was really entered.
In the tutorial on building a database-driven Slackbot a similar method is used to access what was entered for a location entity. The code is on GitHub.

Scala - testing function that return json as string

im trying to learn how to write good tests in general. I happen to write a function in Scala and I want to make sure the model that is returned from the function matches with the model that I define in the test case. here is an example json that is returned from the function
[
{
"id":1,
"uuid":"11111-1111111-11111111-11111111-11111",
"name":"test",
"type":"doc",
"contact":"abc#example.com",
"expires":213293842,
"user":1,
"ad":[
"test.com"
],
"details":{
"creation_time":1123212324,
"agent":2,
"apps":{
"type1":{
"mode":"standard"
},
"type2":{
"mode":"non-standard"
}
}
}
}
]
can I please get some help on how to test my model to make sure I account for model changes during testing
btw, I found this git https://github.com/stephennancekivell/scalatest-json but I cant figure out how to implement it

Unity3D & YamlDotNet Deserializing Data into Monobehaviour-derived classes

I'm trying to serialize data into / from my classes, derived from MonoBehaviour, which cannot be created from client code (e.g., with the new keyword), but rather must be created by a Unity3D-specific method, GameObject.AddComponent<T>(). How can I use the YamlDotNet framework to populate my classes with values without having to create an adapter for each one? Is there some sort of built-in adapter that I can configure, such that YamlDotNet doesn't instantiate the class it's trying to serialize to?
A typical file might contain a mapping of items, e.g.,
%YAML 1.1
%TAG !invt! _PathwaysEngine.Inventory.
%TAG !intf! _PathwaysEngine.Adventure.
---
Backpack_01: !invt!Item+yml
mass: 2
desc:
nouns: /^bag|(back)?pack|sack|container$/
description: |
Your backpack is only slightly worn, and...
rand_descriptions:
- "It's flaps twirl in the breeze."
- "You stare at it. You feel enriched."
MagLite_LR05: !invt!Lamp+yml
cost: 56
mass: 2
time: 5760
desc:
nouns: /^light|flashlight|maglite|lr_05$/
description: |
On the side of this flashlight is a label...
(Type "light" to turn it on and off.)
...
Where the tags are the fully specified class names of my Items, e.g., PathwaysEngine.Inventory.Lamp+yml, PathwaysEngine is the namespace I use for my game engine code, Inventory deals with items & whatnot, and Lamp+yml is how the compiler denotes a nested class, yml inside Lamp. Lamp+yml might look like this:
public partial class Lamp : Item, IWearable {
public new class yml : Item.yml {
public float time {get;set;}
public void Deserialize(Lamp o) {
base.Deserialize((Item) o);
o.time = time;
}
}
}
I call Deserialize() on all objects that derive from Thing from Awake(), i.e., once the MonoBehaviour classes exist in the game. Elsewhere, I've already created a pretty complicated Dictionary filled with objects of type Someclass+yml, and then Deserialize takes an instance of the real, runtime class Someclass and populates it with values. There's got to be a cleaner way to do this, right?
How can I:
Tell the Deserializer what my classes are?
See the second edit for a good solution for the above issue
Get the data without it attempting to create my MonoBehaviour-derived classes?
Edit: I've since worked at the problem, and have found out a good way of dealing with custom data (in my particular case of trying to parse regexes out of my data, and having them not be considered strings & therefore, un-castable to regex) is to use a IYamlTypeConverter for that particular string. Using YamlDotNet with Unity3D MonoBehaviours, however, is still an issue.
Another Edit: The above examples use a pretty ugly way of determining types. In my case, the best thing to do was to register the tags first with the deserializer, e.g.,
var pre = "tag:yaml.org,2002:";
var tags = new Dictionary<string,Type> {
{ "regex", typeof(Regex) },
{ "date", typeof(DateTime) },
{ "item", typeof(Item) }};
foreach (var tag in tags)
deserializer.RegisterTagMapping(
pre+tag.Key, tag.Value);
Then, I use the !!tag notation in the *.yml file, e.g.,
%YAML 1.1
---
Special Item: !!item
nouns: /thing|item|object/
someBoolean: true
Start Date: !!date 2015-12-17
some regex: !!regex /matches\s+whatever/
...
You can pass a custom implementation of IObjectFactory to the constructor of the Deserializer class. Every time the deserializer needs to create an instance of an object, it will use the IObjectFactory to create it.
Notice that your factory will be responsible for creating instances of every type that is deserialized. The easiest way to implement it is to create a decorator around DefaultObjectFactory, such as:
class UnityObjectFactory : IObjectFactory
{
private readonly DefaultObjectFactory DefaultFactory =
new DefaultObjectFactory();
public object Create(Type type)
{
// You can use specific types manually
if (type == typeof(MyCustomType))
{
return GameObject.AddComponent<MyCustomType>();
}
// Or use a marker interface
else if (typeof(IMyMarkerInterface).IsAssignableFrom(type))
{
return typeof(GameObject)
.GetMethod("AddComponent")
.MakeGenericMethod(type)
.Invoke();
}
// Delegate unknown types to the default factory
else
{
return DefaultFactory(type);
}
}
}

jqGrid adding a class to column by function

There's similar question here, but using cellatrr for whole column is quite overloaded. I know there's classes attribute, but it can be only set by static text. I would like to use a function instead like:
$("#jqgrid").jqGrid({
...
colModel:
[
{
name:'a',
index:'a',
classes: function() {
return (a < b ? "ui-state-error" : "ui-state-highlight");
}
]
});
Any ideas? Of course without modding jqGrid core :)
'title'=>'Name',
'name'=>'name',
'classes'=>'your class'
may be you can useful. check below link
http://guriddo.net/documentation/php/_2v70w5p2k.htm