Can switch use String.contains? - groovy

I'm trying to make this work, and it seems not to be accepted. Is there any fix, or workaround to it?
switch(email){
case (email.contains('acceptall')):
log.info email
break
default:
log.info "Doesn't work!"
}
I'm using groovy for a script in SoapUI

Use a regex, roughly:
switch (email) {
case ~/.*acceptall.*/:
log.info(email)
break;
default:
log.info("Doesn't work!")
}
http://groovy.codehaus.org/Logical+Branching#LogicalBranching-switchstatement
Switch supports the following kinds of comparisons
Class case values matches if the switchValue is an instanceof the
class
Regular expression case value matches if the string of the
switch
Value matches the regex Collection case value matches if the
switch
Value is contained in the collection. This also includes ranges
too (since they are Lists)
if none of the above are used then the case
value matches if the case value equals the switch value

you almost got it right, just need to turn it into a closure e.g.
switch (email) {
case { it.contains('acceptall') }:
log.info(email)
break;
default:
log.info("Doesn't work!")
}

Related

JSF - ignore case in URLs (OCPSoft)

Is there a way to define rewrite rules in OCPSoft rewrite independent of case instead of defining multiple rules, since any character could be lower or upper case?
cb.addRule(Join.path('/Test').to("/test.xhtml"));
cb.addRule(Join.path('/test').to("/test.xhtml"));
Something like:
boolean ignoreCase = true;
cb.addRule(Join.path('/Test', ignoreCase).to("/test.xhtml"));
Background:
Logging our 404 errors i encounter a lot of requests just with lower case URLs.
Yes! Absolutely.
The simplest way to do this is probably use a parameter with a regex .matches() constraint:
cb.addRule(
Join.path('/{path}').to("/test.xhtml"))
.where("path")
.matches("(?i)test"); // <-- your path regex pattern goes here
You could also use the Resource or Filesystem condition with a custom transform to make this a more global rule:
public class Lowercase implements Transposition<String>
{
#Override
public String transpose(Rewrite event, EvaluationContext context, String value)
{
return value.toLowerCase();
}
}
Then...
.addRule(Join.path("/{path}").to("/{path}.xhtml"))
.when(Resource.exists("{path}.xhtml"))
.where("path")
.matches("[a-zA-Z]+")
.transposedBy(new Lowercase())
This of course assumes that your xhtml files all use a lowercase naming scheme.
You could create your own custom .when() conditions to locate the most likely matches, then substitute the 'found / correct' value of {path} in the transposition, if you wanted to go even farther.

Using a range in a groovy case statement

I'm writing a Jenkins pipeline, and I'd like to use a groovy switch statement to match on a range on int values so I don't have to write a case for each number in the range. Not used to groovy, so apologies if this is a simple question. For example (not working):
switch (diskuse) {
case 1-5: //this doesn't work
println('disk use is under 50')
break
case [5-9]: //this also doesn't work
println('disk use is OVER 50!')
break
default: //the switch always hits this case
println('no disk use info available')
}
The correct range literal looks like 1..5 in Groovy.
Your switch op shall look like so:
switch (diskuse) {
case 1..5: //inclusive range
println('disk use is under 50')
break
case 5..<9: //exclusive range, 9 is exluded
println('disk use is OVER 50!')
break
default:
println('no disk use info available')
}

Switching on String Value Yields Unexpected Results in Groovy

I am working in a groovy/grails set up and am having some trouble trying to execute a switch statement on a String value.
Basically, I am looping through the attribute names in a webservice response to see if they match pre-defined mappings that are configured on a per user basis. If they have established a mapping on that field, I pull the value out of the response and use it elsewhere.
The code looks something like this:
switch(attributeName)
{
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case user.getFirstNameMapping():
model.user.userInfo.firstName = attributeValue
break
case user.getLastNameMapping():
model.user.userInfo.lastName = attributeValue
break
case user.getAuthenticationKeyMapping():
model.authenticationValue = attributeValue
break
case user.getEmailMapping():
model.email = attributeValue.toLowerCase()
break
}
The value being switched on (attributeName) is of type String, and the getter methods for the user instance also return type String.
Based on my research and understanding of the Groovy language, switching on an Object such as a String should end up using String.equals() to make the comparison. The result, however, is that it is matching on the user.getFirstNameMapping() case every time, and repeatedly overwriting the value in the model; therefore, the last value that comes back in the response is what ends up saved, and none of the other values are saved.
What's interesting is that if I use an if/else structure and do something like this:
if(attributeName.equals(user.getFirstNameMapping())
{
...
}
It works fine every time. I've verified through logging that it's not something silly like extra whitespace or a capitalization issue. I've also tried changing things around to run the switch by default and explicitly compare the attributeName in the case like this:
switch(true)
{
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case {user.getFirstNameMapping().equals(attributeName)}:
model.user.userInfo.firstName = attributeValue
break
case {user.getLastNameMapping().equals(attributeName)}:
model.user.userInfo.lastName = attributeValue
break
case {user.getAuthenticationKeyMapping().equals(attributeName)}:
model.authenticationValue = attributeValue
break
case {user.getEmailMapping().equals(attributeName)}:
model.email = attributeValue.toLowerCase()
break
}
And it still fails to meet my expectations in the exact same way. So, I'm wondering why this is the behavior when the switch statement should simply be using .equals() to compare the strings, and when I explicitly compare them in an if/else using .equals(), it works as expected.
The issue is in your switch case.
Have a look here :-
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case user.getFirstNameMapping():
model.user.userInfo.firstName = attributeValue
break
As you can see your these two cases will run every time because the switch condition is :-
switch(attributeName)
So the first one will get match and will run until it encounters break; which is at after case 2 i.e. case user.getFirstNameMapping(): so i would suggest you to print the value of {attributeName} before the swtich starts.
Hope that will help you.
Thanks
I don't know exactly what's your issue, but the case statement works just fine, even with methods. See my example
String something = "Foo"
class User {
String firstName
String lastName
}
User u = new User(firstName: 'Something', lastName:'Foo')
switch(something) {
case u.getFirstName():
println "firstName: ${u.firstName}"
break;
case u.getLastName():
println "lastName: ${u.lastName}"
break;
default:
println "nothing..."
}
This code will print lastName as expected.
​

Groovy - How can I compare part of a list to a string

I have a list which contains two types of text. One type is used for authorization while other type is used for all other purposes.
The type used for authorization always uses the same text + some code after it.
I would like to compare content of these two types of text and separate them based on content.
My idea is to look for pattern in authorization type and if it matches the pattern then this would be marked as authorization, otherwise it would be marked as "other".
I researched about comparison of patterns in Groovy, but all variations I tried did not work for me. Here is the part which should do the comparison, I am obviously doing something wrong but I don't know what.
jdbcOperations.queryForList(sql).collect { row ->
if(assert (row['MSG'] ==~ /token/)){
mark as authorization
}
else{
mark as other
}
}
Sorry for the vague code, I can not share more than this.
I think you just missing the match for the rest of the text, since you are looking only for the first part to match.
assert ("abc" ==~ /abc/) == true
assert ("abcdefg" ==~ /abc/) == false
assert ("abcdefg" ==~ /abc(.*)/) == true // <--- This can also be made more complicated

Custom MongoDB search query

In my database I have documents which all contain the property foo. For each value of foo I have a function that either returns true or false. How can I query for all the documents for which the value of foo makes the function return true?
If you need to check if your string field's value is one of several, you need the $in modifier.
db.collection.find( { field : { $in : array } } );
It works fast and uses index (if possible).
If your field is an array and you pass a string, use this syntax.
db.collection.find({array_field : string_value});
It will check every element in the array and, if any of them matches your string, it will return the document.
You could use $where.
Example:
db.myCollection.find( { $where: "this.a > 3" });
db.myCollection.find( "this.a > 3" );
db.myCollection.find( { $where: function() { return this.a > 3;}});
Note, this is run in Javascript. This means two things.
You can put arbitrary Javacript into $where expression (the function form).
It'll be significantly slower than regular queries.
It really depends on what the function is and how you are using it. Is the function constant for any given record? Is it even a function you can evaluate on the database server? ...
In the extreme, if you need to check this value often, you might, for example, create a field that exists only when f(foo) is true and then create a sparse index on that field.
$where may well be the solution you are looking for, but depending on the access patterns there may be a better solution.

Resources