package com.linkedin.restli.client.config;
import java.util.HashSet;
import java.util.Set;
import com.linkedin.parseq.function.Function1;
class ConfigValueCoercers {
public static final Function1<Object, Long> LONG = val -> {
if (val instanceof Long)
{
return (Long)val;
}
else if (val instanceof Integer)
{
return (long)(Integer)val;
}
else if (val instanceof Short)
{
return (long)(Short)val;
}
else if (val instanceof String)
{
try
{
String trimmed = ((String)val).trim();
return isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed);
}
catch (NumberFormatException e)
{
throw new Exception("Caught error parsing String to Long, String value: " + val, e);
}
}
throw failCoercion(val, Long.class);
};
public static Function1<Object, Integer> INTEGER = val -> {
if (val instanceof Integer)
{
return (Integer) val;
}
else if (val instanceof Short)
{
return (int)(Short)val;
}
if (val instanceof String)
{
try
{
String trimmed = ((String)val).trim();
return isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed);
}
catch (NumberFormatException e)
{
throw new Exception("Caught error parsing String to Integer, String value: " + val, e);
}
}
throw failCoercion(val, Integer.class);
};
private static final Set<String> TRUE_VALUES = new HashSet<>(4);
private static final Set<String> FALSE_VALUES = new HashSet<>(4);
static {
TRUE_VALUES.add("true");
FALSE_VALUES.add("false");
TRUE_VALUES.add("on");
FALSE_VALUES.add("off");
TRUE_VALUES.add("yes");
FALSE_VALUES.add("no");
TRUE_VALUES.add("1");
FALSE_VALUES.add("0");
}
public static Function1<Object, Boolean> BOOLEAN = val -> {
if (val instanceof Boolean)
{
return (Boolean) val;
}
if (val instanceof String)
{
String value = ((String)val).trim();
if (value.length() == 0)
{
return null;
}
else if (TRUE_VALUES.contains(value))
{
return Boolean.TRUE;
}
else if (FALSE_VALUES.contains(value))
{
return Boolean.FALSE;
}
}
throw failCoercion(val, Boolean.class);
};
/**
* Determine whether the given value String indicates a hex number, i.e. needs to be
* passed into <code>Integer.decode</code> instead of <code>Integer.valueOf</code> (etc).
*/
private static boolean isHexNumber(String value) {
int index = (value.startsWith("-") ? 1 : 0);
return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index));
}
/**
* Generates a consistent exception that can be used if coercion fails.
*/
private static Exception failCoercion(final Object object, final Class<?> targetType)
{
return new Exception("Could not convert object to " + targetType.getSimpleName() + ". Object is instance of: "
+ object.getClass().getName() + ", value: " + object.toString());
}
}