Unable to parse full javascript if statement from within Java using javascript - java

So I posted this question
Putting a simple expression language into java
and got a great answer about using ScriptEngine to allow the user to write javascript which I did and it seemed to work
But whilst an expression like
(artist.length>0 ? artist + '-' :'') + (album.length>0 ? album + '-' :'')
works using a full if statement does not
if(artist.length>0) {artist + ':-'} + (album.length>0 ? album + '-' :'')
You might ask why Im doing this, well I was hoping I could use an if:else if:else statement and this was a step towards that

That simply isn't valid javascript. The
<cond> ? <iftrue> : <iffalse>
is the 'expression' form of if-else, and returns the value which can be used.
if {
} else {
}
is the 'statement' version, and is used to execute code, and does NOT return a value.

Related

Mule Expression Language AND OPERATOR

I want to use the Mule Expression Language to send two input parameters to an API (ex: CodePostal and LibelleVoie).
I do that :
[payload[1].getAdresseNonNormalisee().getObjetAttributs().getCodePostal()] && #[payload[1].getAdresseNonNormalisee().getObjetAttributs().getLibelleVoie()]]
But it does not work, it returns me a String
have you an idea please ?
You have to write everything in one MEL expression:
#[payload[1].getAdresseNonNormalisee().getObjetAttributs().getCodePostal() &&
payload[1].getAdresseNonNormalisee().getObjetAttributs().getLibelleVoie()]]
You used two expressions with some String in between: " && "

Using trim() to remove spaces,but still didn't get expected output

Ok,i am developing spring MVC based web application, application shows data is list, and i also facilitate filter options to enhanced search functionality, I also remove extra space by using trim(), but what happening now, when user input data in text field and enter the corresponding result will be displayed into the list, but if space added after input, the result will be "NOT FOUND" even i handle the space in javascript too
Java Code which fetches data from database
if (searchParamDTO.getRegNO().trim() != null && !searchParamDTO.getRegNO().trim().equals("") && !searchParamDTO.getRegNO().trim().equals("null")) {
query += " AND UR.REG_UNIQUE_ID = :REG_UNIQUE_ID ";
param.addValue("REG_UNIQUE_ID", searchParamDTO.getRegNO());
}
JavaScript Code: fetches the value in behalf of id
function setSearchParameters() {
regNo = $('#regNo').val().trim();}
i also attached two screenshot with spaces and without spaces
Without space
With space
I would suggest to trim on server side as well.
It is always better to validate on server side as we can use same serve code for different UI applications And request could be with wrong or tampered data.
String regNo = searchParamDTO.getRegNO().trim();
if (regNo != null && !"".equals(regNo) && !"null".equals(regNo)) {
query += " AND UR.REG_UNIQUE_ID = :REG_UNIQUE_ID ";
param.addValue("REG_UNIQUE_ID", regNo);
}

Best way to use/practice of using parentheses in java

While working on Sonar static code analyzer I found some confusing (may be only to me) statement by Sonar on using parentheses.
Below are the few code snippets where Sonar says remove useless parentheses:
line>1 String auth = "Basic "+ com.somepackge.someMethod(((String) (parent.proxyUsername+ ":" + parent.proxyPassword)));
line>2 return rawtime.length() > 3 ? (rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()) : rawtime;
though I have replaced above lines with below one to keep Sonar calm :) :
Line>3 String auth = "Basic "+ com.somepackge.someMethod((String) (parent.proxyUsername+ ":" + parent.proxyPassword));
Line>4 return rawtime.length() > 3 ? rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase() : rawtime;
So the reason for discussing this question is:
Actually using braces/parentheses are way to reduce the confusion so why to remove those parentheses.
What is best way to use parentheses while writing any complex statement in java.
See the line>1 and Line>4 here I think
(String) (parent.proxyUsername+ ":" + parent.proxyPassword)
this part of code should have the braces to avoid confusions but what Sonar expect is something like:
(String) parent.proxyUsername+ ":" + parent.proxyPassword
Any suggestion would be a great help. I got some links regarding this question but those were not much helpful.
First snippet
String auth = "Basic "+ someMethod(((String) (parent.proxyUsername+ ":" + parent.proxyPassword)));
You could rewrite it as:
String auth = "Basic "+ someMethod(parent.proxyUsername+ ":" + parent.proxyPassword);
because the string concatenation operator already does a string conversion. Unless you want a ClassCastException thrown when proxyUsername or proxyPassword are not Strings?
Second snippet
return rawtime.length() > 3 ? (rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()) : rawtime;
The parenthesis is indeed unnecessary but the statement is quite unreadable. If you want to keep using the ternary operator I would suggest splitting the statement across lines:
return rawtime.length() > 3
? rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()
: rawtime;
or you could revert the condition:
return rawtime.length() <= 3 ? rawtime :
rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase();
Line 1 has redundant parentheses, but Line 2's parentheses add clarity to the ternary statement.
Whether or not the extra parenthesis in 2 are useful is up for debate - but there's no reason not to remove the redundant ones in 1.
Generally it's best to use extra parenthesis to convey your intent about what the code should do, or to remove ambiguity in the order that things occur.
There is a semantic difference between these two versions:
(String) (parent.proxyUsername+ ":" + parent.proxyPassword)
(String) parent.proxyUsername+ ":" + parent.proxyPassword
In the first, the second set of () already evaluates to a String, implicitly calling parent.proxyUsername.toString() to convert proxyUsername to a String. So the cast is redundant and should be removed IMHO. The second version casts parent.proxyUsername to String, and will throw an exception is it hasn’t got runtime type String (only if it is declared a String is the cast redundant).
I agree that line 2 and 4 are complicated to read no matter if they have the redundant braces or not. Rewrite if you want clarity. That said, redundant braces are sometimes good for clarity IMHO, I do use them occasionally.
the best way is to put your class that you're casting to in a parentheses then the whole part to be converted in another parentheses, then include this whole code in a container parentheses, your code should look like this e.g ((String)(x+y)).
I hope that was helpful, thanks.

Creating a dynamic query with MongoDB, Java and Jongo

I'm using a combination of Java, the Play Framework using Java and not Scala, MongoDB and Jongo as my go between for a basic web CRUD app. I keep receiving a JSON parse exception even though my string doesn't contain any illegal characters. It's actually failing on closing curly bracket at the end of the statement. Below is my error and code. The query string is just a string builder, searching if an object is empty or has a value, if it has a value it's appended to a string.
Jongo method:
public static Iterable<OneDomain> findWithQueryString(String queryString){
return domains().find("{#}", queryString).as(OneDomain.class);
}
Controller Methods:
String builder example:
if(queryStringBuilder.toString().equalsIgnoreCase("")){
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}else{
queryStringBuilder.append(" , ");
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}
String queryString = queryStringBuilder.toString();
Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);
Gives me this error:
Caused by: com.mongodb.util.JSONParseException:
{"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
^
with the error on the "}" ending it.
In addition to that, if I try to escape the characters by putting in a \" so it becomes \"date\" it will parse and error out like so:
Caused by: com.mongodb.util.JSONParseException:
{"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}
Can I actually do this or because it's Java being inserted into it, the quotes will be around the whole string and thus it's trying to read it as a single JSON field vs it being the whole query?
First, make sure not to make your self vulnerable to injection attacks. Read up on injection attacks in general, and more specifically on MongoDB, eg OWASP page on Testing for NoSQL injection.
While you can indeed pass a generated query string into the find method I would not advise it. I did the same and had big problem when we generated a query containing the jongo substitution parameter #, ie
// This will throw an exception:
// java.lang.IllegalArgumentException: Not enough parameters passed to query: {"value":"#"}
...find("{" + "\"value\":\"#\"" + "}")
My solution is to pass a DBObject:
import com.mongodb.BasicDBObject
...find("#", new BasicDBObject().append("value", "#"))
It can also be built with the QueryBuilder:
import com.mongodb.QueryBuilder
...find("#", QueryBuilder.start("value").is("#").get())
It would be nice though to have query builder support directly in the Jongo API: https://github.com/bguerout/jongo/issues/173
Found the answer. Need to drop the substitution and instead my method looks like
domains().find("{"+queryString+"}").as(OneDomain.class);

How to assert a JSON node has child nodes with certain values assigned to them?

I have a JSON String like the following:
json = "{\"Things\": \n" +
" {\"Thing\": {\n" +
" \"ID\":\"123\",\n" +
" \"name\":\"Yet Another Thing\",\n" +
" \"price\":\"$12.99\",\n" }\n" +
" }\n" +
"}";
Is there a way I can assert that the ID of Thing is 123 AND that it's name is "Yet Another Thing" in the same statement/assert?
At the moment, I seem to fail using filters:
JsonPath.read(json, "$.Things.Thing[?(#.ID == '123')].name")
I get the following exception:
java.lang.IllegalArgumentException: Invalid container object
Is that maybe because thereis no array notation [] in the JSON string above? Should there be?
On a related note, is there a good introduction to using Hamcrest (with JSON assert)? I know the official tutorial, but I always seem to get it wrong...
UPDATE: The rational for this was: what if I get several Thing elements back, about whose order I have no guarantee (so I can't match Thing[1] (unless I looped through them all))? How do I make sure one element has both, the right ID and the right name? If I check for the children separately, don't I run the risk that one Thing has the right name and another the right ID, but none has both? (Would that be possible with that JSON format, or would I have to an array in that case anyway, like "Thing": [ { ... }, { ... } ], ... ?
P.S.: I tried to use the JsonPath above as follows in the end: assertEquals("Yet Another Thing", JsonPath.read(json, "$.Things.Thing[?(#.ID == '123')].name"));
So that's where the exception might have come from, too. Also, I initially asked this question on the JsonPath mailing list, but didn't get any replies so far, so was hoping I might get help here quicker... :)
The tutorial gives the solution to your problem, it seems:
JsonAssert.with(json).assertThat("$.Things.Thing.ID", Matchers.equalTo("123"))
.assertThat("$.Things.Thing.name", Matchers.equalTo("Yet Another Thing"));

Categories