The following String:
x=92 and y=29
Produces a valid output: x=92 AND y=29 and it works fine with CCJSqlParserUtil.parseCondExpression but shouldn't it throw an exception for the following?
x=92 lasd y=29
But the output is just: x=92
Furthermore which Expression I should use to implement my own visitor? i.e,
CCJSqlParser c= new CCJSqlParser(new StringReader(str));
Expression e = c.Expression(); // or SimpleExpression, etc..
So that when 'lasd' (anything other than not,or,and) is encountered I can throw an exception and not silently ignore the rest of the expression?
Recently a patch of JSqlParser (1.2-SNAPSHOT) was published to provide the needed behaviour:
CCJSqlParserUtil.parseExpression(String expression, boolean allowPartialParse)
and
CCJSqlParserUtil.parseCondExpression(String expression, boolean allowPartialParse)
Setting allowPartialParse to false will result in the mentioned Exception.
For on the fly interpreted stuff the already existing behaviour is still needed, e.g. to provide expressions from within an text. (Syntax coloring, Context help, ...)
Related
I have a SpEL expression that I am trying to use for an FtpMessageHandler (specifically for outputHandler.setRemoteDirectoryExpressionString("headers['" + ftpOutPath + "']");).
Through debugging I have found that this SpEL expression is not getting compiled. When compilation time comes, SpelCompilerMode is set to OFF. So as a result the expression is not being compiled and just returning null (and my FTP client is trying to just write to the root directory instead of the one I am specifying).
Looking at the Spring SpEL documentation (https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/core.html#expressions) , it says that in order to enable SpEL compilation you need to set the property spring.expression.compiler.mode. I have done this to no effect - I have set spring.expression.compiler.mode to immediate in my application.properties file, yet SpelCompilerMode is still OFF.
Why is this happening? How can I fix this?
I know someone will ask for a code sample but honestly I have no idea what I can provide as this is all stuff internal to Spring. But here are some samples of related code:
The FtpMessageHandler:
#Value("${my.ftp.outPath}")
private String ftpOutPath;
#Bean
#ServiceActivator(inputChannel = "myChannel")
public MessageHandler getOutputHandle(){
FtpMessageHandler outputHandler = new FtpMessageHandler(mySessionFactory());
outputHandler.setRemoteDirectoryExpressionString("headers['" + ftpOutPath + "']");
return outputHandler;
}
application.yaml
spring:
expression:
compiler:
mode: immediate
my:
ftp:
outPath: myPath
I still am not sure why the expression was not compiling / intrepreting properly, however changing the code to use LiteralExpression worked instead of using the String.
outputHandler.setRemoteDirectoryExpression(new LiteralExpression(ftpOutPath));
I'm using a .bnf parser to detect specific expressions and I'm using JFlex to detect the different sections of these expressions. My issue is, some of these expressions may contain nested expressions and I dont know how to handle that.
I've tried to include the .bnf parser in my JFlex by using %include, then referencing the expression in the relative macro using PARAMETERS = ("'"[:jletter:] [:jletterdigit:]*"'") | expression. This fails as JFlex reports the .bnf to be malformed.
Snippet of JFlex:
%{
public Lexer() {
this((java.io.Reader)null);
}
%}
%public
%class Lexer
%implements FlexLexer
%function advance
%type IElementType
%include filename.bnf
%unicode
PARAMETERS= ("'"[:jletter:] [:jletterdigit:]*"'") | <a new expression element>
%%
<YYINITIAL> {PARAMETERS} {return BAD_CHARACTER;} some random return
Snippet of .bnf parser:
{
//list of classes used.
}
expression ::= (<expression definition>)
Any input would be greatly appreciated. Thanks.
I've found the solution to my issue. In further depth, the problem was in both my grammar file and my flex file. To solve the issue, I recursively called the expression in the grammar file like so:
expression = (start value expression? end)
With the JFlex, I declared numerous states until I found a way to chain together and endless amount of expressions. Looks a little like this:
%state = WAITING_EXPRESSION
<WAITING_NEXT> "<something which indicates start of nested expression>" { yybegin(WAITING_EXPRESSION); return EXPRESSION_START; }
Is there any way to assert in a method that input String has certain length?
I tried assert stringName[4]; but seems like it doesn't work
If you just want to use the Java's assert keyword and not any library like JUnit, then you can probably use:
String myStr = "hello";
assert myStr.length() == 5 : "String length is incorrect";
From the official docs:
The assertion statement has two forms. The first, simpler form is:
assert Expression1;
where Expression1 is a boolean expression. When
the system runs the assertion, it evaluates Expression1 and if it is
false throws an AssertionError with no detail message.
The second form of the assertion statement is:
assert Expression1 : Expression2 ;
where:
Expression1 is a boolean expression. Expression2 is an expression that
has a value. (It cannot be an invocation of a method that is declared
void.)
You can use the following if you're using a testing library like JUnit:
String myStr = "hello";
assertEquals(5, myStr.length());
Update:
As correctly pointed out in the comments by AxelH, after compilation, you run the first solution as java -ea AssertionTest. The -ea flag enables assertions.
Instead of using assert, I'd recommend using Exception to check the state of the variables as a simple demo:
String[] arr = new String[3];
if (arr.length != 4) {
throw new IllegalStateException("Array length is not expected");
}
This will directly give the hint by exceptions and you don't need to bother with assert in jvm options.
Exception in thread "main" java.lang.IllegalStateException: Array length is not expected
at basic.AssertListLength.main(AssertListLength.java:7)
If you are using hamcrest, then you can do:
assertThat("text", hasLength(4))
See http://hamcrest.org/JavaHamcrest/javadoc/2.2/ > CharSequenceLength
Good thing about this is that it will have a proper error message, among others including the string itself.
Use AssertJ hasSize():
assertThat(stringName).hasSize(4)
I've got the following Scenario:
XQUERY:
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare variable $udgHeader external;
let $msg-name := upper-case($udgHeader/msg-name/text())
let $recipient := upper-case($udgHeader/recipient/text())
return
<recipients>
<recipient>
<dest>
{
if (($msg-name = "ARS_ISTP") and ($recipient = "ISTP")) then
'IstpArs'
else if (($msg-name = "ARS_ESM") and ($recipient = "ESM")) then
'EsmArs'
else
error(xs:QName('fase'), concat("Unknown msg-name/recipient combination ['", $msg-name,"'/'", $recipient, "']! Please check fase recipient list."))
}
</dest>
</recipient>
</recipients>
My incoming XML will throw the error.
This Error I want to compare to a File (expected Result) with Java (negative Test).
expected Result content:
Unknown msg-name/recipient combination ['ARS_XYZ'/'ARS']! Please check fase recipient list.
My problem is, that I get this error:
org.apache.xmlbeans.XmlRuntimeException: weblogic.xml.query.exceptions.XQueryUserException: line 29, column 5: fase: Unknown msg-name/recipient combination ['ARS_XYZ'/'ESM']! Please check fase recipient list.
How can I handle this error to match my expected Result?
The details of what happens when you call error() are a little dependent on your processor API, but in a Java environment I would expect your invocation of the query processor to exit with an exception rather than with a normal result. If you want a normal result, then return some element (or other object) that you recognize as an error result, rather than calling error().
In 3.0/3.1 you can achieve this by calling error() when the error occurs, and then catching it using try/catch at the top level of the query.
I'm writing a parser for a DSL that uses the syntax (nodeHead: nodeBody). The problem is that nodeBody may contain parens, at some cases.
The between operator of JParsec should have been a good solution, yet the following code fails:
public void testSample() {
Parser<Pair<String,String>> sut = Parsers.tuple(Scanners.IDENTIFIER.followedBy(Scanners.among(":")),
Scanners.ANY_CHAR.many().source()
).between(Scanners.among("("), Scanners.among(")"));
sut.parse("(hello:world)");
}
It does not fail when I change ANY_CHAR to IDENTIFIER, so I assume the issue here is that the second parser in the tuple is too greedy. Alternatively, can I make JParsec apply the between parsers before it applies the body?
Any ideas are very much appriciated.
At the time I was asking, seems like there was no way to do that. However, a github fork-and-pull later, there is: reluctantBetween().
Big thanks to #abailly on the fast response.
If the syntax rule is that the last character will always be ")", you could probably do:
static <T> Parser<T> reluctantBetween(
Parser<?> begin, Parser<T> parser, Parser<?> end) {
Parser<?> terminator = end.followedBy(eof());
return between(begin, terminator.not().next(parser).many(), terminator);
}