strolch/utils/src/main/java/li/strolch/utils/ObjectHelper.java

345 lines
8.3 KiB
Java

package li.strolch.utils;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import li.strolch.utils.iso8601.ISO8601;
public class ObjectHelper {
public static boolean equals(Object left, Object right, boolean ignoreCase) {
if (left == null && right == null)
return true;
if (left == right)
return true;
if (left == null || right == null)
return false;
if (left instanceof Collection<?> leftCollection) {
if (right instanceof Collection<?> rightCollection) {
if (leftCollection.size() != rightCollection.size())
return false;
Iterator<?> leftIter = leftCollection.iterator();
Iterator<?> rightIter = rightCollection.iterator();
while (leftIter.hasNext()) {
Object l = leftIter.next();
Object r = rightIter.next();
// since we ignore case, we can toString()
if (ignoreCase) {
if (!l.toString().equalsIgnoreCase(r.toString()))
return false;
} else {
if (!l.equals(r))
return false;
}
}
return true;
}
if (right instanceof String[] rightArr) {
int i = 0;
for (Object l : leftCollection) {
Object r = rightArr[i];
// since we ignore case, we can toString()
if (ignoreCase) {
if (!l.toString().equalsIgnoreCase(r.toString()))
return false;
} else {
if (!l.equals(r))
return false;
}
i++;
}
return true;
}
// since right is neither a collection nor an array, we can't check for equals!
return false;
}
if (left instanceof String && right instanceof Enum<?>)
right = ((Enum<?>) right).name();
else if (right instanceof String && left instanceof Enum<?>)
left = ((Enum<?>) left).name();
if (left.getClass() != right.getClass())
return false;
// since we ignore case, we can toString()
if (ignoreCase)
return left.toString().equalsIgnoreCase(right.toString());
return left.equals(right);
}
public static int compare(Object left, Object right, boolean ignoreCase) {
if (left == right)
return 0;
if (left == null)
return -1;
if (right == null)
return 1;
if (ignoreCase && left instanceof String && right instanceof String)
return ((String) left).compareToIgnoreCase((String) right);
if (left instanceof Comparable) {
@SuppressWarnings("unchecked") Comparable<Object> comparable = (Comparable<Object>) left;
return comparable.compareTo(right);
}
int answer = left.getClass().getName().compareTo(right.getClass().getName());
return (answer == 0) ? left.hashCode() - right.hashCode() : answer;
}
public static boolean contains(Object left, Object right, boolean ignoreCase) {
return contains(left, right, ignoreCase, true);
}
public static boolean contains(Object left, Object right, boolean ignoreCase, boolean matchAll) {
if (left == null && right == null)
return true;
if (left == null)
return false;
if (right == null)
return false;
if (left instanceof Collection<?> leftCollection) {
if (right instanceof Collection<?> rightCollection) {
for (Object l : leftCollection) {
for (Object r : rightCollection) {
if (contains(l, r, ignoreCase, matchAll))
return true;
}
}
return false;
}
if (right instanceof String[] rightArr) {
for (Object l : leftCollection) {
for (Object r : rightArr) {
if (contains(l, r, ignoreCase, matchAll))
return true;
}
}
return false;
}
for (Object l : leftCollection) {
if (contains(l, right, ignoreCase, matchAll))
return true;
}
return false;
}
if (left instanceof String leftString) {
if (right instanceof String[] rightArr) {
if (ignoreCase) {
leftString = leftString.toLowerCase();
for (String s : rightArr) {
if (!matchAll && leftString.contains(s.toLowerCase()))
return true;
else if (matchAll && !leftString.contains(s.toLowerCase()))
return false;
}
} else {
for (String s : rightArr) {
if (!matchAll && leftString.contains(s))
return true;
else if (matchAll && !leftString.contains(s))
return false;
}
}
return matchAll;
}
if (right.getClass().isEnum())
right = ((Enum<?>) right).name();
if (right instanceof String rightString) {
if (ignoreCase)
return leftString.toLowerCase().contains(rightString.toLowerCase());
else
return leftString.contains(rightString);
}
}
// comparing non-strings we use equals, as contains fits as well
if (left.getClass() == right.getClass())
return left.equals(right);
// try to coerce the right side to the left side
if (right instanceof String rightString) {
Object rightO;
if (left instanceof Integer) {
rightO = Integer.valueOf(rightString);
} else if (left instanceof Float) {
rightO = Float.valueOf(rightString);
} else if (left instanceof Double) {
rightO = Double.valueOf(rightString);
} else if (left instanceof Boolean) {
rightO = Boolean.valueOf(rightString);
} else if (left instanceof Date) {
rightO = ISO8601.parseToDate(rightString);
} else {
throw new IllegalArgumentException(
"Unhandled type combination " + left.getClass() + " / " + right.getClass());
}
return rightO.equals(left);
}
throw new IllegalArgumentException("Unhandled type combination " + left.getClass() + " / " + right.getClass());
}
public static boolean isIn(Object left, Object right, boolean ignoreCase) {
if (left == null && right == null)
return true;
if (left == null)
return false;
if (right == null)
return false;
if (right instanceof Collection<?> collectionRight) {
if (left instanceof Collection<?> collectionLeft) {
for (Object l : collectionLeft) {
for (Object r : collectionRight) {
if (equals(r, l, ignoreCase))
return true;
}
}
return false;
} else if (left instanceof String[] leftArr) {
for (Object r : collectionRight) {
for (Object l : leftArr) {
if (equals(r, l, ignoreCase))
return true;
}
}
return false;
} else {
for (Object o : collectionRight) {
if (equals(o, left, ignoreCase))
return true;
}
return false;
}
}
if (right instanceof Object[] arrayRight) {
if (left instanceof Collection<?> collectionLeft) {
for (Object o : arrayRight) {
for (Object l : collectionLeft) {
if (equals(l, o, ignoreCase))
return true;
}
}
return false;
} else if (left instanceof String[] leftArr) {
for (Object o : arrayRight) {
for (Object l : leftArr) {
if (equals(l, o, ignoreCase))
return true;
}
}
return false;
} else {
for (Object o : arrayRight) {
if (equals(left, o, ignoreCase))
return true;
}
}
return false;
}
if (right instanceof String || right instanceof Number || right instanceof Boolean) {
return equals(left, right, ignoreCase);
}
throw new IllegalArgumentException("Unhandled type combination " + left.getClass() + " / " + right.getClass());
}
public static boolean startsWith(Object left, Object right, boolean ignoreCase) {
if (left == null && right == null)
return true;
if (left == null)
return false;
if (right == null)
return false;
if (left instanceof String str && right instanceof String subStr) {
if (ignoreCase)
return str.toLowerCase().startsWith(subStr.toLowerCase());
return str.startsWith(subStr);
}
throw new IllegalArgumentException("Unhandled type combination " + left.getClass() + " / " + right.getClass());
}
public static boolean endsWith(Object left, Object right, boolean ignoreCase) {
if (left == null && right == null)
return true;
if (left == null)
return false;
if (right == null)
return false;
if (left instanceof String str && right instanceof String subStr) {
if (ignoreCase)
return str.toLowerCase().endsWith(subStr.toLowerCase());
return str.endsWith(subStr);
}
throw new IllegalArgumentException("Unhandled type combination " + left.getClass() + " / " + right.getClass());
}
public static boolean isEmpty(Object object) {
if (object == null)
return true;
if (object instanceof String)
return ((String) object).isEmpty();
if (object instanceof Boolean)
return !((Boolean) object);
if (object instanceof Number)
return ((Number) object).doubleValue() == 0.0D;
return false;
}
}