Drools rule to check a collection with compound value restriction - collections

I want to check if a collection contains not three elements. In java I would do
!(collection.contains("s1") && collection.contains("s2") && collection.contains("s3"))
How can I do this with drools? I searched for two hours and tried anything but can't find a solution for this "simple" problem. I found the "Compound Value Restriction" which is what I exactly need, but it does not work for collections and the "contains" operator.
I would appreciate your answers.
Nathanael

This does what the Java code does:
Collection( this not contains "s1" ||
this not contains "s2" ||
this not contains "s3")

I think, You can take rule dialect "java".
Following sample can help you.
global java.util.ArrayList responseList
rule "checkCollectionRule"
dialect "java"
salience -1
when
eval(ifContains(responseList, val1, val2.....))
then
responseList.add(new Boolean("true"));
end
function Boolean ifContains(List responseList, String val1, String val2,....) {
return (responseList.contains("s1") && responseList.contains("s2") && responseList.contains("s3"));
}
Hope this help.
Thanks.

Related

Using the replace function in firestore security rules

I'm struggling with Firestore security rules. I want to check on a value that needs the replace function, i.e. an e-mail address. I can find some documentation in the general security docs, but that does not seem to work with Firestore.
For example this works:
allow write: if resource.data.members.data[(request.auth.token.email)] in ["admin"];
but this doesn't (and I changed the key in the members object accordingly):
allow write: if resource.data.members.data[(request.auth.token.email.replace('.' , ',')] in ["admin"];
Another option would be to have a way to use dots in the address of a query, so they don't have to be replaced like this:
var emailSanitized = email.replace('.' , '.');
db.collection('someCollection').where('members.' + emailSanitized, '==', 'admin')
Any ideas here?
A little late, but you can simulate the replace function on a string with this one :
function replace(string, replace, by) {
return string.split(replace).join(by);
}
So you need to define this function in your firestore.rules file and then you can call replace(request.auth.token.email, '.' , ',') to get the same result as request.auth.token.email.replace('.' , ',') in javascript.
There are two reasons why you might have been having issues.
The replace function was added to Security Rules after you asked your question.
The replace function uses regular expressions for the first argument and so matching on '.' will match literally everything.
Consider instead using: request.auth.token.email.replace('\\.' , ',')
var emailSanitized = email.replace('.' , '.');
db.collection('someCollection').where('members.' + emailSanitized, '==', 'admin')

Asp.net mvc razor view string.format does not seems to work

I am using string.format to format my model value inside razor view but it does not gives desired result
#string.Format("{0:00}", Model.Range == null ? "" : Model.Range.ToString())
It should result as 05
if i am using below it gives me result but not from model
#string.Format("{0:00}", 5)
Someone have any idea or same experience ?
If Model.Range is a number type then you need to write:
#string.Format("{0:00}", Model.Range == null ? "" : Model.Range)
because with the Model.Range.ToString() you have converted your Range to string so the number formatting cannot be applied because it is not a number anymore.
By the way string.Format handles null arguments so it is enough to write:
#string.Format("{0:00}", Model.Range)
If Model.Range is not a number but with Model.Range.ToString() you get a number in a string representation then you need to first convert it to a number (like using int.Parse or its other variants) then you can pass the number to string.Format which can now apply the correct formatting.

Silverstripe: DataList Filter equivalent of 'Value > x OR Value = y'

I understand that I can specify multiple values for my filter in a way such as:
xxx::get()->filter('FirstName', array('Sam', 'Sig'));
Which gives me the equivalent of:
... WHERE FirstName = 'Sam' OR FirstName = 'Sig'
However, there doesn't appear to be anyway of combining OR's with the modifiers ('LastVisited:GreaterThan' => '2011-01-01')
I need to be able to filter like so:
WHERE ExpiryDate > 29-11-2012 OR ExpiryDate IS NULL
Is what I am trying to achieve possible? I have read the docs but have not found the answer to my issue.
Thanks
You could always use the where() function if nothing else will do what you need.
xxx::get()->where("\"ExpiryDate\" > 29-11-2012 OR \"ExpiryDate\" IS NULL");
http://doc.silverstripe.org/framework/en/topics/datamodel#where-clauses

how to separate two array?

I'm creating a music to show notes on Treble and Bass but came to think the staffArray and staffArray2 is true for a given situation.
Such as staffArray and staffArray2 has a value of "1","1","1","1" and "2",2",2",2",2",2"...
When one of the function will identify if the i=0 is 1 then draw note:
if(staffArray[i] == "1" && typeArray[i]=="half" && stemArray[i]=="down") {
drawHalfDown(child,"-","-"); //child is the sprite name
}
Now will draw a note on a staff 2, the above staffArray is still valid and cause the note on staff 2 to be error, how do I rectify these array?
I'm not sure I understand all of what you are trying to do, but your error is probably caused by a typo in your if-clause: The single & is a bitwise, not a logical boolean operator and evaluates to a very different result. If you're interested, you can find out about bitwise AND here.
Your code should be:
if(staffArray[i] == "1" && typeArray[i]=="half" && stemArray[i]=="down") {
drawHalfDown(child,"-","-");
}

How can I tell if E4X expression has a match or not?

I am trying to access an XMLList item and convert it to am XML object.
I am using this expression:
masonicXML.item.(#style_number == styleNum)
For example if there is a match everything works fine but if there is not a match then I get an error when I try cast it as XML saying that it has to be well formed. So I need to make sure that the expression gets a match before I cast it as XML. I tried setting it to an XMLList variable and checking if it as a text() propertie like this:
var defaultItem:XMLList = DataModel.instance.masonicXML.item.(#style_number == styleNum);
if(defaultItem.text())
{
DataModel.instance.selectedItem = XML(defaultItem);
}
But it still give me an error if theres no match. It works fine if there is a match.
THANKS!
In my experience, the simplest way to check for results is to grab the 0th element of the list and see if it's null.
Here is your code sample with a few tweaks. Notice that I've changed the type of defaultItem from XMLList to XML, and I'm assigning it to the 0th element of the list.
var defaultItem:XML =
DataModel.instance.masonicXML.item.(#style_number == styleNum)[0];
if( defaultItem != null )
{
DataModel.instance.selectedItem = defaultItem;
}
OK I got it to work with this:
if(String(defaultItem.#style_number).length)
Matt's null check is a good solution. (Unless there is the possibility of having null items within an XMLList.. probably not, but I haven't verified this.)
You can also check for the length of the XMLList without casting it to a String:
if (defaultItem.#style_number.length() > 0)
The difference to String and Array is that with an XMLList, length() is a method instead of a property.

Resources