345 lines
8.3 KiB
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;
|
|
}
|
|
}
|