I have a situation where I will be given a String and I need to determine what Class<?>
best suits its value given the following constraints:
"true"
or "false"
, it's a Boolean
Integer
Double
YYYY-MM-DD hh:mm:ss.sss
, then its a Java Date
String
afterallMy best attempt is nasty and involves a lot of nested try/catch
blocks:
// Groovy pseudo-code
Class<?> determineValueType(String value) {
Class<?> clazz
if(value.equalsIgnoreCase('true') || value.equalsIgnoreCase('false')) {
clazz = Boolean
} else {
try {
Integer.parse(value)
clazz = Integer
} catch(Exception ex1) {
try {
Double.parse(value)
clazz = Double
} catch(Exception ex2) {
try {
Date.parse('YYYY-MM-DD hh:mm:ss.sss', value)
clazz = Date
} catch(Exception ex3) {
clazz = String
}
}
}
}
clazz
}
Are there any Groovier ways of accomplishing this, perhaps something endemic to some obscure Groovy reflection API?
There are two methods which can help you in Groovy's extended String class (actually on CharSequence
):
But for other cases, AFAIK, you are on your own to implement the parsing. You could try working with a map and some closures, to reduce some boilerplate:
Class parse(val) {
def convert = [
(Integer) : { it.toInteger() },
(Double) : { it.toDouble() },
(Date) : { Date.parse('YYYY-MM-DD hh:mm:ss.sss', it) },
(Boolean) : { Boolean.parseBoolean it },
(String) : { it }
]
convert.findResult { key, value ->
try {
if (value(val)) return key
} catch (e) {}
}
}
assert parse('9.1') == Double
assert parse('9') == Integer
assert parse('1985-10-26 01:22:00.000') == Date // great scott!
assert parse('chicken') == String
assert parse('True') == Boolean
Note that if (Double)
precedes (Integer)
the tests won't work, since 9
is both a double and a integer.