I have the following code in a Groovy Server Page:
How can I check if the value of IntegerNameValueListName is a string in general and not compare it only to one specific string ?
IntegerNameValueListName has the following value:
The usual Java instanceof operator should work, but bear in mind that GString values are not instanceof String so this may give you false negatives. Depending on exactly what you're trying to achieve a simple != '' or even a Groovy-truth test="${IntegerNameValueListName}" may be enough.
Related
Hy guys, i'm working on a IDEA plugin and custom references. I have many references working, but i'm stuck with a difficult one.
I'd like to detect patterns in groovy such as this one :
result = run service: 'createAgreementItem', with: createAgreementItemInMap
In the above line, i'd like to get the createAgreementItem element to match.
run is defined in a groovy base script
package org.apache.ofbiz.service.engine
abstract class GroovyBaseScript extends Script {
//...
Map run(Map args) throws ExecutionServiceException {
return runService((String)args.get('service'), (Map)args.get('with', new HashMap()))
}
//...
The problem is, what i'm trying to get isn't technically a parameter, it's a value from a map with the key equals to service.
So this won't work :
GroovyPatterns.groovyLiteralExpression()
.methodCallParameter(0,
GroovyPatterns.psiMethod().withName("run")
.definedInClass("org.apache.ofbiz.service.engine.GroovyBaseScript"))
Do you have any ideas or any help ? Thanks in advance !
EDIT :
Actually, i'm looking for a doc or an example for any use of the org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns
library.
I don't get it, maybe i'm not familiar enough with groovy though i used it a bit.
Any help welcome on this.
The problem is, what i'm trying to get isn't technically a parameter,
it's a value from a map with the key equals to "service"
If all you want to do is retrieve the service value from the Map then instead of args.get('with', new HashMap()) you could do args.with.service. If you wanted null safety, you could do args?.with?.service.
val result: Boolean = aList.union(bList).any { it.something?.someOtherFlag == true }
I have two lists I need to join and check if any of the items has some flag set.
This has been giving me some bad results. During debugging:
the data before the line indicates result = true (true should be the right answer)
I get result = false by running the program
directly after the line, when I use the Evaluate expression tool, I get result = true
What is definitely NOT the problem is that there is NO change in the data in between.
Kotlin versions of my app/IDE plugin are different:
Kotlin Plugin: 203-1.5.0
App: 1.4.21
What I am looking for is an explanation: what can be the problem?
The union method returns a set that will keep only distinct elements, and it might discard different elements when running and when evaluating in debugger. I'm not sure how deterministic it's supposed to be, but the order could matter.
This could happen if equals() and/or hashCode() for your elements are defined without using something, or if equals()/hashCode() for something's class is defined without using someOtherFlag. How are these classes defined?
Note that for data classes, only the properties that are present in the primary constructor are taken into account for the generated equals and hashcode methods.
I have a boolean expression in string format, example:
name := "Fred"
type := "Person"
I want to evaluate this expression as true or false.
exp := "(name == Fred) && (type == Person)"
Eventually, I would like to be able to execute conditional statements such as:
if (exp) {
...
}
However, from research this is not something Go supports out of the box. I have seen suggestions on using AST to parse and evaluate. But, I am fairly new to go and especially AST, thus not sure how to go about that. Can someone please provide any guidance on how I may go about evaluating a string boolean expression? I have not come across any packages that support this entirely.
The following is true in theory. But since you're using Go if you can use Go syntax then you can use Go's parser and AST. I don't see any code that can evaluate a Go AST at runtime. But you could probably write one that supported the parts you wanted. Then you'd have a Go interpreter.
The following is what you need to do to support any random expression syntax:
You are going to want to lex and parse. Build an AST (Abstract Syntax Tree) in memory. Then evaluate it.
Your tree nodes might be (my Go syntax is way wrong for this):
Scope {Tree {
Assignment { Symbol: "name", Symbol: "_literal_1" }
Assignment { Symbol: "exp", Value: Tree: {
AndOperation { Tree{...}, Tree{...} }
}
}
Etc.
Then your program can traverse your AST directly or you can write it into bytecode form, but that's really only useful if you want it to be smaller and easy to cache for later.
To illustrate the following example I created a litte spock test (but it's about groovy itself, not spock):
void "some spock test"() {
given: String value = null
expect: someMethod(value) == 3
}
int someMethod(String s) {
return 3
}
int someMethod(Map s) {
return 5
}
There are two methods who's signatures only differ by the type of the given parameter. I thought that when I give it a null value that is explicitly typed as a string, the string-method will be called.
But that doesn't happen; the test fails, because the map-method is called! Why?
I guess groovy ignores the type and treats all nulls the same. There seems to be some kind of priority of types: When I use Object instead of Map as the parameter type of the wrong-method, its all the same, but when I for instance use Integer, the test succeeds.
But than again: If groovy really ignores the type of nulls, why can the following fix the original test:
expect: someMethod((String) value) == 3
If you read my answer to the question Tim already mentioned you will see that I talk there about runtime types. The static type plays normally no role in this. I also described there how the distance calculation is used and that for null the distance to Object is used to determine the best fitting method. What I did not mention is that you can force method selection by using a cast. Internally Groovy will use a wrapper for the object, that also transports the type. Then the transported type is used instead. But you surely understand, that this means a one additional object creation per method class, which is very inefficient. Thus it is not the standard. In the future Groovy maybe change to include that static type information, but this requires a change to the MOP as well. And that is difficult
I'm using stored numeric values in calculations and matching situations and javascript doubles are a big "NO-NO" when doing these kind of operations.
However I can't find a solution on how to use java BigDecimal in SSJS in Xpages.
Since one should construct a BigDecimal using a string I have tried different approaches i SSJS. Whatever test the result is the same, the call is ambiguous:
Ambiguity when calling new java.math.BigDecimal(long) and new
java.math.BigDecimal(int)
How do I use a BigDecimal in my SSJS when values are stored in documents as Numbers?
How do I use BigDecimal with a string argument when values are stored in documents as Numbers?
edit/amend:
After accepting Svens answer I got a bit further and to my second question.
The value retrieved from the document is 451368 but it will be stored in variable as 451367.99999999994
How do I recover from that when the user should match against original value?
Use Java-Objects instead:
var value = new java.lang.Integer(1);
new java.math.BigDecimal(value);