Bool.java
package org.klojang.convert;
import java.util.Set;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
/**
* Converts values from various non-boolean types to boolean values. Where
* applicable, {@code null} is accepted as an argument and evaluates to
* {@code false}. Values evaluating to {@code true} and values evaluating to
* {@code false} will both be tightly defined, rather than (for example) 1 counting
* as {@code true} and anything else as {@code false}. If an argument is neither a
* {@code true} value nor a {@code false} value, an {@link IllegalArgumentException}
* is thrown. The static method use the {@link #TRUE_STRINGS} and
* {@link #FALSE_STRINGS} sets to determine if a {@code String} is true-ish or falsy.
* You can also instantiate the {@code Bool} class with your own {@code true} strings
* and {@code false} strings.
*
* @author Ayco Holleman
*/
public class Bool {
/**
* The default set of strings that count as {@code true} values (ignoring case):
* "true", "1", "yes", "on", "enabled".
*/
public static final Set<String> TRUE_STRINGS = Set.of("true",
"1",
"yes",
"on",
"enabled");
/**
* The default set of strings that count as {@code false} values (ignoring case):
* "false", "0", "false", "off", "disabled".
*/
public static final Set<String> FALSE_STRINGS = Set.of("false",
"0",
"no",
"off",
"disabled");
/**
* Attempts to convert the specified object to a {@code Boolean}. This is done by
* delegating to one of the more specific {@code from} methods, according to the
* type of the argument. If the object's type is not covered by any of the other
* {@code from} methods an {@link IllegalArgumentException} is thrown.
*
* @param obj the object to convert
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(Object obj) {
return INSTANCE.test(obj);
}
/**
* Converts the specified {@code String} to a {@code Boolean} value. This method
* checks whether the argument is either one of {@link #TRUE_STRINGS} or one of
* {@link #FALSE_STRINGS} (ignoring case).
*
* @param s the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(String s) {
return INSTANCE.test(s);
}
/**
* Returns {@code true} if the specified string is {@code null} or one of the
* string that count as {@code true} or {@code false}.
*
* @param s the string to evaluate
* @return whether the specified string is one of the string that count as
* {@code true} or {@code false}
*/
public static boolean isConvertible(String s) {
return INSTANCE.isBoolean(s);
}
/**
* Converts the specified {@code Number} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(Number n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code int} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(int n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code character} to a {@code Boolean} value.
*
* @param c the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(char c) {
return INSTANCE.test(c);
}
/**
* Converts the specified {@code double} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(double n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code long} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(long n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code float} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(float n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code short} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(short n) {
return INSTANCE.test(n);
}
/**
* Converts the specified {@code Number} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public static Boolean from(byte n) {
return INSTANCE.test(n);
}
private static final Bool INSTANCE = new Bool();
private final Set<String> trueStrings;
private final Set<String> falseStrings;
private Bool() {
this(TRUE_STRINGS, FALSE_STRINGS);
}
/**
* Creates a new {@code Bool} instance that will use the provided {@code true}
* strings and {@code false} strings to evaluate {@code String} arguments.
*
* @param trueStrings the string values that must count as {@code true}
* @param falseStrings the string values that must count as {@code false}
*/
public Bool(Set<String> trueStrings, Set<String> falseStrings) {
this.trueStrings = trueStrings;
this.falseStrings = falseStrings;
}
/**
* Attempts to convert the specified object to a {@code Boolean}. This is done by
* delegating to one of the more specific {@code getBoolean} methods, according to
* the type of the argument. If the object's type is not covered by any of the
* other {@code getBoolean} methods, a {@link TypeConversionException} is thrown.
*
* @param obj the object to convert
* @return the corresponding {@code Boolean} value
*/
public Boolean test(Object obj) {
return obj == null
? FALSE
: obj.getClass() == Boolean.class
? (Boolean) obj
: obj.getClass() == String.class
? test((String) obj)
: obj instanceof Number
? test((Number) obj)
: obj.getClass() == Character.class
? test(((Character) obj).charValue())
: noCanDo(obj);
}
/**
* Converts the specified {@code String} to a {@code Boolean} value. Null values
* are allowed and will result in {@code Boolean.FALSE} being returns.
*
* @param s the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(String s) {
if (s == null || falseStrings.contains(s.toLowerCase())) {
return FALSE;
}
if (trueStrings.contains(s.toLowerCase())) {
return TRUE;
}
throw new TypeConversionException(s, Boolean.class);
}
/**
* Returns {@code true} if the specified string is {@code null} or one of the
* string that count as {@code true} or {@code false}.
*
* @param s the string to evaluate
* @return whether the specified string is {@code null} or one of the string that
* count as {@code true} or {@code false}
*/
public boolean isBoolean(String s) {
return s == null
|| falseStrings.contains(s.toLowerCase())
|| trueStrings.contains(s.toLowerCase());
}
/**
* Converts the specified {@code Number} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(Number n) {
if (n == null) {
return FALSE;
}
Integer i = NumberMethods.convert(n, Integer.class);
return i == 1 ? TRUE : i == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code int} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(int n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code double} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(double n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code long} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(long n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code float} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(float n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code short} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(short n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code byte} to a {@code Boolean} value.
*
* @param n the value to be converted
* @return the corresponding {@code Boolean} value
*/
public Boolean test(byte n) {
return n == 1 ? TRUE : n == 0 ? FALSE : noCanDo(n);
}
/**
* Converts the specified {@code char} to a {@code Boolean} value. Returns
* {@code true} if the argument equals '1'; {@code false} if the argument equals
* '0'; otherwise throws a {@link TypeConversionException}.
*
* @param c The argument
* @return the corresponding {@code Boolean} value
*/
public Boolean test(char c) {
return c == '1' ? TRUE : c == '0' ? FALSE : noCanDo(c);
}
private static Boolean noCanDo(Object obj) {
throw new TypeConversionException(obj, Boolean.class);
}
}