Johan
Johan

Reputation: 40510

Can I do this with ExpandoMetaClasses in Groovy?

When upgrading from Groovy 1.8.4 to 1.8.5 the JsonSlurper returns a BigDecimal instead of a float or double for numbers in Json. For example consider the following JSON document:

{"person":{"name":"Guillaume","age":33.4,"pets":["dog","cat"]}} 

In Groovy 1.8.4 "age" would be represented as a float whereas in Groovy 1.8.5+ it's represented as a BigDecimal. I've created a Java framework that uses the Groovy JsonSlurper under the hood so in order to maintain backward-compatibility I'd like to convert JSON numbers (such as 33.4) to float or double transparently. Having looked at the groovy-json source code I see that JsonSluper uses a JsonToken which is the one that creates a BigDecimal out of 33.4 in its "getValue()" method. This method is called by the JsonSlurper instance.

So what (I think) I want to do is to override the getValue() method in the JsonToken class to have it return a float or double instead. This is what I've tried:

    def original = JsonToken.metaClass.getMetaMethod("getValue")
    JsonToken.metaClass.getValue = {->
        def result = original.invoke(delegate)

        // Convert big decimal to float or double
        if (result instanceof BigDecimal) {
            if (result > Float.MAX_VALUE) {
                result = result.doubleValue();
            } else {
                result = result.floatValue();
            }
        }
        result
    }

The problem is that even though the code stated above is executed before new JsonSluper().parseText(..) the overridden "getValue()" in JsonToken is not called (the original getValue() method is called instead). But if I copy all code from the JsonSlurper class into my own class, let's call it JsonSlurper2, and do new JsonSluper2().parseText(..) the overridden method of "getValue()" is called and everything works as expected. Why is this? What would I have to do to avoid copying JsonSlurper to my own class?

Upvotes: 0

Views: 196

Answers (1)

doelleri
doelleri

Reputation: 19682

JsonSlurper is a Java class and therefore you are unable to override its methods via metaClass. See this mailing list thread.

This question looks like it might have a way for you to do this.

Upvotes: 1

Related Questions