I need to retrieve sum of a String column so i wrote this :
<variable name="totalQt" class="java.lang.Integer" calculation="Sum">
<variableExpression>
<![CDATA[Integer.parseInt($F{QTARTBP}.replaceAll(" ", ""))]]>
</variableExpression>
</variable>
But i'm getting this error :
....
Caused by: java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:504)
at java.lang.Integer.parseInt(Integer.java:527)
at
articleBonPreparation_1385730226859_237481.evaluateEstimated(articleBonPreparation_1385730226859_237481:428)
at net.sf.jasperreports.engine.fill.JREvaluator.evaluateEstimated(JREvaluator.java:254)
So there are empty string , so how to use zero in that case , i wrote thiw but it's wrong
:
<variableExpression>
<![CDATA[$F{QTARTBP}.equals("") ? 0 : Integer.parseInt($F{QTARTBP}.replaceAll(" ", ""))]]>
</variableExpression>
Any idea will be appreciated
It would be useful to see what input data you are using, but despite that, it's clear that your code will fail if the value of $F{QTARTBP} is a single space (" "). You could try the following expression instead, which will include the single space in your empty string check and will return 0 instead:
$F{QTARTBP}.replaceAll(" ", "").equals("") ? 0 : Integer.parseInt($F{QTARTBP}.replaceAll(" ", ""))
You should be aware that this is will still fail if any of your input strings cannot be interpreted as an integer.
Jasper are not to calculate - you should generate String in your java-code. And calculate what you need in java too.
Upd. This answer is incorrect. I learned JR more deeper and understand it.
Related
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.
I'm parsing stock data and trying to put it into a SQL database. All of the info from the parse is retrieved as a string. I am using the Integer.parseInt() method to try and convert the strings to integers for some of the info. The issue I am having is with the Change data. When it is a positive change the number has a "+" sign in front of it and I am getting an error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "+0.14" //
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) //
at java.lang.Integer.parseInt(Integer.java:492) //
at java.lang.Integer.parseInt(Integer.java:527) //
at getStockData.main(getStockData.java:91)" (the //s are to signify end lines, having issues with formatting)
My Output is:
Ticker ID: MSFT: Change - [+0.14]
int Change = Integer.parseInt(di.getTextContent());
I don't really know how to get around this error at the moment, and haven't found anything similar to this after googling / searching stackoverflow.
The issue is 0.14 is not a valid int. Try using Double.parseDouble(String) to parse the double value. Like
double v = Double.parseDouble("+0.14");
System.out.println(v);
Output is
0.14
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);
I got a question about printf in a program, in the end i wrote:
System.out.print(area[i]+" ");
It prints:
2.000000000000001 12.0 28.274333882308138
Then I tried to use printf to replace it:
System.out.printf("%4.1f",area[i]+" ");
However, it has errors when it was executed:
f != java.lang.String
I know probably it is because 4.1 is wrong configuration for the value of 2.000000000000001, as there wont be 4 digits wide if I only retrieve 1 digit after the dot, but what does the error message mean?
Due to the concatenation operator +; area[i] + " " is a java.lang.String type. The error on execution is telling you this.
Error messages are your friends. Do learn to appreciate them.
The error may comme from the fact that in your expression :
System.out.printf("%4.1f",area[i]+" ");
You don't print a float, but a String (yes, area[i]+" " is a String).
Try with :
System.out.printf("%4.1f",area[i]);
It should go better, doesn't it ?
im trying to format this string into a fixed column style but cant get it to work, heres my code, whats up?
System.out.format("%32s%10n%32s%10n%32s%10n", "Voter: " + e.voteNo + "Candidate: " + vote + "Booth: " + boothId);
All variables are integers,
I want the output to be like
Voter: 1 Candidate: 0 Booth: 1
Thanks
Please stop trying to program by accident. Your code looks like the glued-together parts of 3 different approaches to solving the issue. Try to read the documentation on the topic (JavaDoc is your friend!) and apply what you learned instead.
String result = String.format("Voter: %-10d Candidate: %-10d Booth: %-10d", e.voteNo, vote, boothId);
System.out.println(result);
For more information on String.format check its JavaDoc.
Edit: apparently I didn't get the memo that there's actually a PrintStream.format, so you can actually write it like this:
System.out.format("Voter: %-10d Candidate: %-10d Booth: %-10d", e.voteNo, vote, boothId);