Check if PsiElement is a string - java

When adding 'intentions' to PhpStorm (or other JetBrains IDE's), how can I detect whether a PsiElement is a string? I've based my code off the only intention example I could find. I can't seem to find proper documentation. This is as far as I got:
#NonNls public class SomeIntention extends PsiElementBaseIntentionAction implements IntentionAction {
public boolean isAvailable(#NotNull Project project, Editor editor, #Nullable PsiElement element) {
if (element == null || !(element instanceof /* String? */) {
return false;
}
}
}
instanceof String obviously doesn't work, but even using PsiViewer I can't figure out how to test whether it's a string.

I would recommend looking into intellij-community source code, logging, debugging and using PsiViewer plugin, you would then find that PsiJavaToken of certain type contains a String.

The following worked to check if our current node is a string (either double quoted or single quoted):
ASTNode ast_node = element.getNode();
if(ast_node == null) {
return false;
}
IElementType element_type = ast_node.getElementType();
if(element_type != PhpTokenTypes.STRING_LITERAL
&& element_type != PhpTokenTypes.STRING_LITERAL_SINGLE_QUOTE) {
return false;
}
return true;
In my case, I only wanted 'raw strings', not strings with variables or concatenation. If any variables or concatenation signs exist in a string, PSI sees those as separate siblings. So I could find raw strings by ruling out strings with siblings:
// Disregards strings with variables, concatenation, etc.
if (element.getPrevSibling() != null || element.getNextSibling() != null) {
return false;
}
return true;

Related

Convert nested loops into a Stream

I want to replace nested for loops in the following code with streams:
private boolean check(St st) {
List<Co> prereqs = getCoPrereqs();
for (Co prereq : prereqs) {
List<En> stEns = st.getEns();
boolean flag = false;
for (En en : stEns) {
if (en.getCo().equals(prereq) && en.getGr() != null) {
if (en.hasPassedCo()) {
flag = true;
}
}
if (!flag)
return false;
}
}
return true;
}
The two loops and the variable flag is causing confusion. I am not sure if this can be converted to streams totally.
I have simplified your code somewhat by doing the following:
removing the boolean flag. It isn't necessary.
get the List<En> just one time outside of the Prereq loop. You can reiterate the original as often as necessary.
The major difference is to check for a false return from en.hasPassedCo() and return false immediately. Once the iterations are complete, then return true.
private boolean check(St st) {
List<Co> prereqs = getCoPrereqs();
List<En> stEns = st.getEns();
for (Co prereq : prereqs) {
for (En en : stEns) {
if (en.getCo().equals(prereq) && en.getGr() != null) {
if (!en.hasPassedCo()) {
return false;
}
}
}
}
return true;
}
I'm not certain that streams would improve this (at least not knowing more about the relationships of the fields to each other). Also, it doesn't make sense how Co relates to en.getCo. Seems to me that something like prereqs.contains(en.getCo()) would be more appropriate.
Probably, you can use nested streams with allMatch.
I'm saying "probably" because I can't be sure that the code you've proved does what expected, types name are not self-explanatory at all (names in the code matter a lot) and you have not accompanied the code with any explanations.
If I understood your code correctly, you need to validate every Co object returned by getCoPrereqs() and that entails checking each Co object against En object from a List<En> which should be extracted from the method parameter.
That's how it might look like:
private boolean check(St st){
return getCoPrereqs().stream()
.allMatch((Co prereq) -> st.getEns().stream()
.allMatch((En en) -> en.getCo().equals(prereq)
&& en.getGr() != null
&& en.hasPassedCo()
));
}
For readability reasons (to make it more easier to compare stream with loops), I've used explicitly typed lambda expressions (the common practice is to omit types for brevity and let the type inference do the job).

Cant identify blank string value [duplicate]

How can I check whether a string is not null and not empty?
public void doStuff(String str)
{
if (str != null && str != "**here I want to check the 'str' is empty or not**")
{
/* handle empty string */
}
/* ... */
}
What about isEmpty() ?
if(str != null && !str.isEmpty())
Be sure to use the parts of && in this order, because java will not proceed to evaluate the second part if the first part of && fails, thus ensuring you will not get a null pointer exception from str.isEmpty() if str is null.
Beware, it's only available since Java SE 1.6. You have to check str.length() == 0 on previous versions.
To ignore whitespace as well:
if(str != null && !str.trim().isEmpty())
(since Java 11 str.trim().isEmpty() can be reduced to str.isBlank() which will also test for other Unicode white spaces)
Wrapped in a handy function:
public static boolean empty( final String s ) {
// Null-safe, short-circuit evaluation.
return s == null || s.trim().isEmpty();
}
Becomes:
if( !empty( str ) )
Use org.apache.commons.lang.StringUtils
I like to use Apache commons-lang for these kinds of things, and especially the StringUtils utility class:
import org.apache.commons.lang.StringUtils;
if (StringUtils.isNotBlank(str)) {
...
}
if (StringUtils.isBlank(str)) {
...
}
Just adding Android in here:
import android.text.TextUtils;
if (!TextUtils.isEmpty(str)) {
...
}
To add to #BJorn and #SeanPatrickFloyd The Guava way to do this is:
Strings.nullToEmpty(str).isEmpty();
// or
Strings.isNullOrEmpty(str);
Commons Lang is more readable at times but I have been slowly relying more on Guava plus sometimes Commons Lang is confusing when it comes to isBlank() (as in what is whitespace or not).
Guava's version of Commons Lang isBlank would be:
Strings.nullToEmpty(str).trim().isEmpty()
I will say code that doesn't allow "" (empty) AND null is suspicious and potentially buggy in that it probably doesn't handle all cases where is not allowing null makes sense (although for SQL I can understand as SQL/HQL is weird about '').
str != null && str.length() != 0
alternatively
str != null && !str.equals("")
or
str != null && !"".equals(str)
Note: The second check (first and second alternatives) assumes str is not null. It's ok only because the first check is doing that (and Java doesn't does the second check if the first is false)!
IMPORTANT: DON'T use == for string equality. == checks the pointer is equal, not the value. Two strings can be in different memory addresses (two instances) but have the same value!
Almost every library I know defines a utility class called StringUtils, StringUtil or StringHelper, and they usually include the method you are looking for.
My personal favorite is Apache Commons / Lang, where in the StringUtils class, you get both the
StringUtils.isEmpty(String) and the
StringUtils.isBlank(String) method
(The first checks whether a string is null or empty, the second checks whether it is null, empty or whitespace only)
There are similar utility classes in Spring, Wicket and lots of other libs. If you don't use external libraries, you might want to introduce a StringUtils class in your own project.
Update: many years have passed, and these days I'd recommend using Guava's Strings.isNullOrEmpty(string) method.
This works for me:
import com.google.common.base.Strings;
if (!Strings.isNullOrEmpty(myString)) {
return myString;
}
Returns true if the given string is null or is the empty string.
Consider normalizing your string references with nullToEmpty. If you
do, you can use String.isEmpty() instead of this method, and you won't
need special null-safe forms of methods like String.toUpperCase
either. Or, if you'd like to normalize "in the other direction,"
converting empty strings to null, you can use emptyToNull.
There is a new method in java-11: String#isBlank
Returns true if the string is empty or contains only white space codepoints, otherwise false.
jshell> "".isBlank()
$7 ==> true
jshell> " ".isBlank()
$8 ==> true
jshell> " ! ".isBlank()
$9 ==> false
This could be combined with Optional to check if string is null or empty
boolean isNullOrEmpty = Optional.ofNullable(str).map(String::isBlank).orElse(true);
String#isBlank
How about:
if(str!= null && str.length() != 0 )
Returns true or false based on input
Predicate<String> p = (s)-> ( s != null && !s.isEmpty());
p.test(string);
Use Apache StringUtils' isNotBlank method like
StringUtils.isNotBlank(str)
It will return true only if the str is not null and is not empty.
For completeness: If you are already using the Spring framework, the StringUtils provide the method
org.springframework.util.StringUtils.hasLength(String str)
Returns:
true if the String is not null and has length
as well as the method
org.springframework.util.StringUtils.hasText(String str)
Returns:
true if the String is not null, its length is greater than 0, and it does not contain whitespace only
You can use the functional style of checking:
Optional.ofNullable(str)
.filter(s -> !(s.trim().isEmpty()))
.ifPresent(result -> {
// your query setup goes here
});
You should use org.apache.commons.lang3.StringUtils.isNotBlank() or org.apache.commons.lang3.StringUtils.isNotEmpty. The decision between these two is based on what you actually want to check for.
The isNotBlank() checks that the input parameter is:
not Null,
not the empty string ("")
not a sequence of whitespace characters (" ")
The isNotEmpty() checks only that the input parameter is
not null
not the Empty String ("")
If you don't want to include the whole library; just include the code you want from it. You'll have to maintain it yourself; but it's a pretty straight forward function. Here it is copied from commons.apache.org
/**
* <p>Checks if a String is whitespace, empty ("") or null.</p>
*
* <pre>
* StringUtils.isBlank(null) = true
* StringUtils.isBlank("") = true
* StringUtils.isBlank(" ") = true
* StringUtils.isBlank("bob") = false
* StringUtils.isBlank(" bob ") = false
* </pre>
*
* #param str the String to check, may be null
* #return <code>true</code> if the String is null, empty or whitespace
* #since 2.0
*/
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
test equals with an empty string and null in the same conditional:
if(!"".equals(str) && str != null) {
// do stuff.
}
Does not throws NullPointerException if str is null, since Object.equals() returns false if arg is null.
the other construct str.equals("") would throw the dreaded NullPointerException. Some might consider bad form using a String literal as the object upon wich equals() is called but it does the job.
Also check this answer: https://stackoverflow.com/a/531825/1532705
Simple solution :
private boolean stringNotEmptyOrNull(String st) {
return st != null && !st.isEmpty();
}
As seanizer said above, Apache StringUtils is fantastic for this, if you were to include guava you should do the following;
public List<Employee> findEmployees(String str, int dep) {
Preconditions.checkState(StringUtils.isNotBlank(str), "Invalid input, input is blank or null");
/** code here **/
}
May I also recommend that you refer to the columns in your result set by name rather than by index, this will make your code much easier to maintain.
You can use StringUtils.isEmpty(), It will result true if the string is either null or empty.
String str1 = "";
String str2 = null;
if(StringUtils.isEmpty(str)){
System.out.println("str1 is null or empty");
}
if(StringUtils.isEmpty(str2)){
System.out.println("str2 is null or empty");
}
will result in
str1 is null or empty
str2 is null or empty
I've made my own utility function to check several strings at once, rather than having an if statement full of if(str != null && !str.isEmpty && str2 != null && !str2.isEmpty). This is the function:
public class StringUtils{
public static boolean areSet(String... strings)
{
for(String s : strings)
if(s == null || s.isEmpty)
return false;
return true;
}
}
so I can simply write:
if(!StringUtils.areSet(firstName,lastName,address)
{
//do something
}
In case you are using Java 8 and want to have a more Functional Programming approach, you can define a Function that manages the control and then you can reuse it and apply() whenever is needed.
Coming to practice, you can define the Function as
Function<String, Boolean> isNotEmpty = s -> s != null && !"".equals(s)
Then, you can use it by simply calling the apply() method as:
String emptyString = "";
isNotEmpty.apply(emptyString); // this will return false
String notEmptyString = "StackOverflow";
isNotEmpty.apply(notEmptyString); // this will return true
If you prefer, you can define a Function that checks if the String is empty and then negate it with !.
In this case, the Function will look like as :
Function<String, Boolean> isEmpty = s -> s == null || "".equals(s)
Then, you can use it by simply calling the apply() method as:
String emptyString = "";
!isEmpty.apply(emptyString); // this will return false
String notEmptyString = "StackOverflow";
!isEmpty.apply(notEmptyString); // this will return true
If you are using Spring Boot then below code will do the Job
StringUtils.hasLength(str)
With Java 8 Optional you can do:
public Boolean isStringCorrect(String str) {
return Optional.ofNullable(str)
.map(String::trim)
.map(string -> !str.isEmpty())
.orElse(false);
}
In this expression, you will handle Strings that consist of spaces as well.
To check if a string is not empty you can check if it is null but this doesn't account for a string with whitespace. You could use str.trim() to trim all the whitespace and then chain .isEmpty() to ensure that the result is not empty.
if(str != null && !str.trim().isEmpty()) { /* do your stuffs here */ }
I would advise Guava or Apache Commons according to your actual need. Check the different behaviors in my example code:
import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
/**
* Created by hu0983 on 2016.01.13..
*/
public class StringNotEmptyTesting {
public static void main(String[] args){
String a = " ";
String b = "";
String c=null;
System.out.println("Apache:");
if(!StringUtils.isNotBlank(a)){
System.out.println(" a is blank");
}
if(!StringUtils.isNotBlank(b)){
System.out.println(" b is blank");
}
if(!StringUtils.isNotBlank(c)){
System.out.println(" c is blank");
}
System.out.println("Google:");
if(Strings.isNullOrEmpty(Strings.emptyToNull(a))){
System.out.println(" a is NullOrEmpty");
}
if(Strings.isNullOrEmpty(b)){
System.out.println(" b is NullOrEmpty");
}
if(Strings.isNullOrEmpty(c)){
System.out.println(" c is NullOrEmpty");
}
}
}
Result:
Apache:
a is blank
b is blank
c is blank
Google:
b is NullOrEmpty
c is NullOrEmpty
Simply, to ignore white space as well:
if (str == null || str.trim().length() == 0) {
// str is empty
} else {
// str is not empty
}
Consider the below example, I have added 4 test cases in main method. three test cases will pass when you follow above commented snipts.
public class EmptyNullBlankWithNull {
public static boolean nullEmptyBlankWithNull(String passedStr) {
if (passedStr != null && !passedStr.trim().isEmpty() && !passedStr.trim().equals("null")) {
// TODO when string is null , Empty, Blank
return true;
}else{
// TODO when string is null , Empty, Blank
return false;
}
}
public static void main(String[] args) {
String stringNull = null; // test case 1
String stringEmpty = ""; // test case 2
String stringWhiteSpace = " "; // test case 3
String stringWhiteSpaceWithNull = " null"; // test case 4
System.out.println("TestCase result:------ "+nullEmptyBlankWithNull(stringWhiteSpaceWithNull));
}
}
BUT test case 4 will return true(it has white space before null) which is wrong:
String stringWhiteSpaceWithNull = " null"; // test case 4
We have to add below conditions to make it work propper:
!passedStr.trim().equals("null")
If you use Spring framework then you can use method:
org.springframework.util.StringUtils.isEmpty(#Nullable Object str);
This method accepts any Object as an argument, comparing it to null and the empty String. As a consequence, this method will never return true for a non-null non-String object.
To check on if all the string attributes in an object is empty(Instead of using !=null on all the field names following java reflection api approach
private String name1;
private String name2;
private String name3;
public boolean isEmpty() {
for (Field field : this.getClass().getDeclaredFields()) {
try {
field.setAccessible(true);
if (field.get(this) != null) {
return false;
}
} catch (Exception e) {
System.out.println("Exception occurred in processing");
}
}
return true;
}
This method would return true if all the String field values are blank,It would return false if any one values is present in the String attributes
I've encountered a situation where I must check that "null" (as a string) must be regarded as empty. Also white space and an actual null must return true.
I've finally settled on the following function...
public boolean isEmpty(String testString) {
return ((null==testString) || "".equals((""+testString).trim()) || "null".equals((""+testString).toLowerCase()));
}

SonarQube - boolean logic correctness -

I have a problem with the logic expression on my method matches1().
Problem
SonarQube is telling me there is an error:
(expectedGlobalRule == null && actual != null)
SonarQube:
Change this condition so that it does not always evaluate to
"true".
Conditions should not unconditionally evaluate to "TRUE" or to "FALSE"
I'm essentially doing this logic to avoid a NPE on my "Block to be executed".
My code
matches1()
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if((expected == null && actual != null) || (expected != null && actual == null)) {
return false;
} else {
//Block to be executed
}
}
I inverted the logic in to see what SonarQube would tell me and he doesn't complain about it.
matches2()
private boolean matches2(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(expected != null && actual != null) {
//Block to be executed
} else {
return false;
}
}
Question
Do the problem is in my boolean logic or it's SonarQube that lost
his mind?
If the problem is within sonarQube, how could I resolve it?
The problem is in your logic. Let's take it piece by piece:
if(actual == null && expected == null) {
return true;
At this point if both vars are null then we're no longer in the method. So if we get any further, then at least one of them is non-null.
The viable options at this point are:
actual = null, expected = non-null
actual = non-null, expected = null
actual = non-null, expected = non-null
Now, let's look at the next bit of code:
} else if((expected == null && actual != null)
We already know that both variables can't be null, so as soon as we know expected == null, there's no need to test whether actual != null. That has already been proven by the fact that we got this far. So actual != null is always true, which is why an issue is raised.
Edit
This means that your code could be boiled down to:
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(actual == null || expected == null) {
return false;
}
//Block to be executed
}
Note that the else isn't needed & dropping it makes the code easier to read.
Even when the code is correct; seriously, it makes my eyes hurt. Thing is: it is hard to read. Such kind of nested conditions is something that one should not be writing in the first place.
If you can't avoid it; at least refactor it into something like
private boolean areActualAnedExpectedBothNull(args ...) {
return actual == null && expectedGlobalRule == null;
}
And please note; you can dramatically simply your code:
if (areActualAnedExpectedBothNull(actual, expected)) {
return true;
}
if (actual == null) {
return false;
}
if (expected == null) {
return false;
}
do your thing ...
and use such methods in your other code. And of course, you do a lot of unit testing; probably with coverage measurements; just to make sure that your tests really test all possible paths through this maze.
But as said; you better step back and think if there are ways to avoid writing such code in the first place.
The typical answer to booleans, and if/else chains in OO programming is polymorphism. So instead of asking something about its state; you turn to interfaces/abstract classes; and have different implementations of those. And then you have a factory giving you that implementation you need; and then you just call methods on that; without further need for if/else/whatever.
If you don't know what I am talking about - watch these videos; especially the second one!
The problem is with SonarQube.
See this article for more info on ignoring that issue: https://www.bsi-software.com/en/scout-blog/article/ignore-issues-on-multiple-criteria-in-sonarqube.html
You can just set it up to ignore that error within that file.
The gist of it is
Open the Settings (SonarQube General Settings or project Settings) and
select the Exclusions category. Switch to the Issues Exclusions and
scroll down to “Ignore Issues on Multiple Criteria”. Set squid:S00112
as Rule Key Pattern and **/*Activator.java as File Path Pattern.
You will need to change the rule key pattern to the pattern associated with the rule that is being violated for your code and the file pattern as the path of your .java file.

Check if a html input field is empty in java

I'm creating a web application by using java ee. I have a doubt. To check correctly if a text field is NOT empty is right to do this check?
if(home_number != null || !(home_number.equals("")))
{
}
There are also .isEmpty() functin and lenght() > 0 to check if a string is NOT EMPTY. Which is the best way?
In order to handle all the corner cases (what if string is null, what if it is only composed of spaces etc...) you'll probably be better off using a library that covers that properly for you like Apache commons lang and its StringUtils class: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
And therefore have a more readable code :
if(StringUtils.isNotEmpty(home_number)) { ...
isEmpty is more preferable as the documentation said
Returns true if, and only if, length() is 0.
so if the length is 0 then it will return directly as true.
vs. !(home_number.equals("")
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
You need to trim your string first before checking if its empty
}
The cleanest pattern, in my opinion is:
if (a != null && !a.isEmpty()) {
// ...
}
And instead of repeating that hundreds of times, write a small static utility method to wrap this behavior, or use Google Guava's Strings.isNullOrEmpty()
You can check if input-field is not empty using .isEmpty(), but what if the text-field is filled with spaces ???
So, I'll recommend you to use .trim() before checking for empty String :
if(str != null && !(str.trim().isEmpty())){
// do whatever you want
}

How do I check for nulls and empty string for a needle in a haystack?

Situation: I am coming across a lot of checks in my code. And I would like to know of a way in which I can reduce them.
if(needle!=null && haystack!=null)
{
if(needle.length()==0)
return true;
else
{
if(haystack.length()==0)
return false;
else
{
// Do 2 for loops to check character by character comparison in a substring
}
}
}
else
return false;
Perhaps a different code style would increase the readability of your code and reduce the amount of nested if statements for all of your checks.:
if (needle == null || haystack == null || haystack.isEmpty())
return false;
if (needle.isEmpty())
return true;
// compare strings here and return result.
You could consolidate that logic into a single method on a singleton 'StringFunctions' class and update the usages to use the common method as you encounter them.
You can create a wrapper class for the strings, then add a function like isValid() to them that checks if the length == 0. Use a Null Object that always returns false on isValid() to eliminate the null checks.
If you can create classes that you tell what to do, rather than passing strings that have to be null checked throughout your code, you will get more resuseable results:
class Haystack {
private static final Haystack NULL_HAYSTACK = new Haystack("");
private final String value;
public Haystack(String value) {
this.value = value;
}
public boolean containsNeedle(String needle) {
return needle != null && value.contains(needle);
}
}

Categories