开发者

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'
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜