I’m using MongoDB with Groovy + Grails on top. While the MongoDB Java API is sinfully verbose, Groovy helps in this regard by being able to write HashMaps like so:
def map = [foo: "bar", one: "two"]
In MongoDB, objects are added to the database as BasicDBObjects, which extend HashMap, so I can write something like this in Groovy:
things.save([ foo: "bar" ] as BasicDBObject)
While I don’t know where the BasicDBOBject cast is coming from (is it built-in because BasicDBObject already inherits from HashMap?), it would be splendid if I didn’t have to add the explicit cast every time I want to persist an object.
Does Groovy/Java have a way of making superclass-subclass casts implicit, or at least defining custom implicit casts as to avoid using the as operator everywhere?
Well, if you are on Groovy, why not some metaprogramming? 🙂
The idea is simple: we add a new method on
thingsobject, which is a save() method that receives a Map and redirect the call to thethings.save(BasicDBObject)casting accordingly.If you want, you can add this method directly to the thing’s class:
I wrote the following script trying to simulate what you described, i hope i got it right:
Also note that it doesn’t need square brackets neither parens. The colon gives away the map thing
For the
asmethod, which is an operator that can be overloaded through the.asType(Class), i believe it works because it tries to instantiate a newBasicDBObjectpassing the map as a parameter in the constructor. It can be found around line 316 in the following link:https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java