I've found myself writing a method like this:
boolean isEmpty(MyStruct myStruct) {
return (myStruct.getStringA() == null || myStruct.getStringA().isEmpty())
&& (myStruct.getListB() == null || myStruct.getListB().isEmpty());
}
And then imagine this struct with lots of other properties and other nested lists, and you can imagine that this method gets very big and is tightly coupled to the data model.
Does Apache Commons, or Spring, or some other FOSS utility have the ability to recursively reflectively walk an object graph and determine that it's basically devoid of any useful data, other than the holders for Lists, Arrays, Maps, and such? So that I can just write:
boolean isEmpty(MyStruct myStruct) {
return MagicUtility.isObjectEmpty(myStruct);
}
allNull() is a static method of the ObjectUtils class that is used to check if all the values in the array point to a null reference. The method returns false if any value in the array of values is not null . The method returns true if all the values in the passed array are null or the array is null or empty.
hasOwnProperty(key): A function is created where the object is looped over and checked if it contains the 'key' property using the object. hasOwnProperty() method. This function would return true if it could find no keys in the loop, which means that the object is empty.
isEmpty. Checks if an Object is empty or null. The following types are supported: CharSequence : Considered empty if its length is zero.
Thanks to Vladimir for pointing me in the right direction (I gave you an upvote!) although my solution uses PropertyUtils
rather than BeanUtils
I did have to implement it but it wasn't hard. Here's the solution. I only did it for Strings and Lists since that's all I happen to have at the moment. Could be extended for Maps and Arrays.
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
public class ObjectUtils {
/**
* Tests an object for logical emptiness. An object is considered logically empty if its public gettable property
* values are all either null, empty Strings or Strings with just whitespace, or lists that are either empty or
* contain only other logically empty objects. Currently does not handle Maps or Arrays, just Lists.
*
* @param object
* the Object to test
* @return whether object is logically empty
*
* @author Kevin Pauli
*/
@SuppressWarnings("unchecked")
public static boolean isObjectEmpty(Object object) {
// null
if (object == null) {
return true;
}
// String
else if (object instanceof String) {
return StringUtils.isEmpty(StringUtils.trim((String) object));
}
// List
else if (object instanceof List) {
boolean allEntriesStillEmpty = true;
final Iterator<Object> iter = ((List) object).iterator();
while (allEntriesStillEmpty && iter.hasNext()) {
final Object listEntry = iter.next();
allEntriesStillEmpty = isObjectEmpty(listEntry);
}
return allEntriesStillEmpty;
}
// arbitrary Object
else {
try {
boolean allPropertiesStillEmpty = true;
final Map<String, Object> properties = PropertyUtils.describe(object);
final Iterator<Entry<String, Object>> iter = properties.entrySet().iterator();
while (allPropertiesStillEmpty && iter.hasNext()) {
final Entry<String, Object> entry = iter.next();
final String key = entry.getKey();
final Object value = entry.getValue();
// ignore the getClass() property
if ("class".equals(key))
continue;
allPropertiesStillEmpty = isObjectEmpty(value);
}
return allPropertiesStillEmpty;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}
you can combine Appache Common StringUtils.isEmpty()
method with BeanUtils.getProperties()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With