Dynamic object graph navigation in Groovy
folks! I want to be able to navigate Groovy object graph dynamically, having the path in string:
def person = new Person("john", new Address("main", new Zipcode("10001", "1234")))
def path = 'address.zip.basic'
I k开发者_JS百科now that I can access a property in map notation, but it's only one level deep:
def path = 'address'
assert person[path] == address
Is there any way to evaluate deeper path?
Thanks!
This can be achieved by overriding the getAt
operator and traversing the property graph. The following code uses Groovy Category
but inheritance or mixins could also be used.
class ZipCode {
String basic
String segment
ZipCode(basic, segment) {
this.basic = basic
this.segment = segment
}
}
class Address {
String name
ZipCode zip
Address(String name, ZipCode zip) {
this.name = name
this.zip = zip
}
}
class Person {
String name
Address address
Person(String name, Address address) {
this.name = name
this.address = address
}
}
@Category(Object)
class PropertyPath {
static String SEPARATOR = '.'
def getAt(String path) {
if (!path.contains(SEPARATOR)) {
return this."${path}"
}
def firstPropName = path[0..path.indexOf(SEPARATOR) - 1]
def remainingPath = path[path.indexOf(SEPARATOR) + 1 .. -1]
def firstProperty = this."${firstPropName}"
firstProperty[remainingPath]
}
}
def person = new Person('john', new Address('main', new ZipCode('10001', '1234')))
use(PropertyPath) {
assert person['name'] == 'john'
assert person['address.name'] == 'main'
assert person['address.zip.basic'] == '10001'
}
PropertyPath.SEPARATOR = '/'
use(PropertyPath) {
assert person['address/zip/basic'] == '10001'
}
精彩评论