XQuery: Using xs:time($arg) vs cast as xs:time - spring-boot

In one of my projects I'm using
XQuery 3.0
Saxon HE 9.8 (transitive because of Camel)
Spring Boot 2.1.0
Apache Camel 2.22.0
I consume a XML message in which the following element occurs:
<mytimeelement></mytimeelement>
As you can see it is empty so I thought that the following XQuery-Expression would return an empty sequence:
$transaction/*:flags/*:mytimeelement
Unfortunately this seems not to be the case because calling the XQuery-Expression from above in an xs:time($arg) like:
xs:time($transaction/*:flags/*:mytimeelement)
does not return an empty sequence as I would have expected but instead returns an exception:
Invalid time "" (too short)
The thing is: I want to use the xs:time($arg) as validation that if a value is in the element it has to have the correct format, but if it's empty it doesn't matter. So I did this not only with xs:time but also with xs:date and xs:decimal.
My question now is: Why is the expression not returning an empty sequence but an empty string? Or should I better use a cast as xs:time instead?

Related

SpelParseException: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'

I am trying to condtionally create a component using #ConditionalOnExpression("not ${service.synchronous} && not ${service.disabled}").
I based this on Spring Boot SpEL ConditionalOnExpression check multiple properties, which provides a multi-property conditional as follows: #ConditionalOnExpression("${properties.first.property.enable:true} && ${properties.second.property.startServer:false}")
However, I keep getting:
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
Those properties are always set in my .properties file so I did not provide a default value with the colon notation. What am I doing wrong?
You will need to provide the default values for your properties like in the example you followed, so update the expression to be:
#ConditionalOnExpression("not ${service.synchronous:false} && not ${service.disabled:true}")
In most such cases the properties your app is reading are not what you expect them to be.
Set a breakpoint on all constructors of SpelParseException. In the debugger you will see the expression that is parsed, that will give show you exactly which properties you are really using.
Maybe you have to go search a little in the stack until you find the right location where you can see the expression.
My mistake was that I had not imported the test properties file in a Spring test.
After I added #TestPropertySource("classpath:/application.properties") to the test class, the properties from the properties file were used.

ConstraintViolationException - extract field name which caused exception

I'm using hibernate-validator with a JAX-RS service to validate query parameters using #NotNull:
#GET
public Response doSomething(#NotNull #QueryParam("myParam") String myParam) {...}
This works as expected and throws a ConstraintViolationException if myParam is null. I'd like to extract the param name which is associated to the violation (e.g. myParam), and return that in the response message to the client but there does not appear to be an obvious way of extracting this from the exception. Can someone provide some insight?
As of BeanValidation 1.1 there is a ParameterNameProvider contract which makes parameter name extraction configurable. As mentioned in the other answer, with Java 8 you can get the parameter names in the byte code provided you compile with the -parameters flag. Use the ReflectionParameterNameProvider in this case. However, even with Java 7 you can get parameter names, for example by using the ParanamerParameterNameProvider. This parameter name provider is based on Paranamer and there are several ways to set it up.
This only works if you're using Java 8, as prior to Java 8 the actual parameter name was lost at compile time. Its now retained, assuming you compile and run at Java 8. See also http://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html_single/#_java_8_support

Stripes Framework expression validation on property

I am trying to add expression validation on my property on actionbean but I am unable to make it work. I have even tried with integers like this >0 but still the same exception is thrown. Below is the code
#Validate(required=true, minvalue=1, expression="${this > maxBudget}")
int minBudget;
int maxBudget;
I am getting the below exception:
net.sourceforge.stripes.exception.StripesRuntimeException: Could not parse the EL expression being used to validate
field minBudget. This is not a transient error. Please double check the following expression for errors: ${this > maxBudget}
caused by
javax.el.ELException: The identifier [this] is not a valid Java identifier as required by section 1.19 of the EL specification (Identifier ::= Java language identifier).
This check can be disabled by setting the system property org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
I have tried few variation, but every time it throws this exception.
Can some one please point out the mistake I am doing here
thanks
If you want to make sure minBudget is larger than maxBudget (isn't that the other way around?) you could just do:
#Validate(required=true, minvalue=1, expression="${minBudget > maxBudget}")
For greater flexibility you could consider implementing a custom validation method:
#ValidationMethod(on={"show"})
public void checkBudgetRange(ValidationErrors errors) {
if (minBudget < maxBudget)
errors.addGlobalError( new SimpleError("This is not good..."));
// all sorts of other checks to your liking
}
The on array argument holds the name(s) of the event handler(s) for which you want to perform this validation method. So in the example here that would be public Resolution show().
There's an excellent explanation at the Stripes Framework site at https://stripesframework.atlassian.net/wiki/display/STRIPES/Validation+Reference
UPDATE:
If you want to make use of the this keyword in validation expressions you may need to add a VM argument to your server (tested this on Tomcat 8):
-Dorg.apache.el.parser.SKIP_IDENTIFIER_CHECK=true
Otherwise the abovementioned error may be thrown.
The default value of org.apache.el.parser.SKIP_IDENTIFIER_CHECK was changed from true to false as of version 7 in Tomcat.
https://tomcat.apache.org/tomcat-6.0-doc/config/systemprops.html
https://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html

Apache Camel: How to properly nest a function?

In Camel's Simple documentation they say :
From Camel 2.9 onwards you can nest functions, such as shown below:
<setHeader headerName="myHeader">
<simple>${properties:${header.someKey}}</simple>
</setHeader>
Here is what I am trying to do:
<simple>${property.${property.prefix}variableName}</simple>
I am trying to access the exchange property whose name is:
exchange.getProperty("prefix", String.class) + "variableName"
But I'm getting this exception:
Caused by: org.apache.camel.language.simple.types.SimpleIllegalSyntaxException: ${ cannot accept or at location 22
${property.${property.prefix}variableName}
What am I doing wrong here?
I'm using Camel version 2.13.0.
I confirm the following code works fine with Camel 2.13.0:
from("...")
.setProperty("prefix", constant("pre-"))
.setProperty("pre-variable", constant("value"))
.setHeader("myHeader", simple("${property.${property.prefix}variable}"))
You may have special character in the prefix property that prevents proper resolution.

Spring Data MongoDB - $eq within $project support

I'm currently writing an aggregation query for MongoDB in my Spring project in which I'm using $project operator. Within this operator I would like to compare two fields in order to return the result as projected "matches" key value. Here's the mongoDB shell equivalent (which works):
{$project:
{matches:
{$eq: ["$lastDate", "$meta.date"]}
}
}
I've read Spring Data MongoDB documentation and found some useful info about ProjectionOperator's 'andExpression' method which uses SpEL. The result Java code of my investigation was:
new ProjectionOperation().andExpression("lastDate == meta.date").as("matches")
Unfortunately I'm receiving exception:
java.lang.IllegalArgumentException: Unsupported Element:
org.springframework.data.mongodb.core.spel.OperatorNode#70c1152a Type: class org.springframework.data.mongodb.core.spel.OperatorNode You probably have a syntax error in your SpEL expression!
As far as I've checked, Spring Data MongoDB handles all Arithmetic operators correctly but cannot handle the comparison ones. Therefore I want to ask is there any other way to create such query with Spring Data MongoDB? Or maybe I don't know something crucial about SpEL?
I resolved this issue by passing JSON aggregate command (created with DBObjects in order to preserve flexibility of the query) to MongoDB, i.e.:
MongoOperations#executeCommand(DBObject command)

Resources