Groovy中的动态对象图导航

时间:2011-04-07 08:28:38

标签: groovy

人们! 我希望能够动态导航Groovy对象图,使用string:

中的路径
def person = new Person("john", new Address("main", new Zipcode("10001", "1234")))
def path = 'address.zip.basic'

我知道我可以使用地图表示法访问某个属性,但它只有一个级别:

def path = 'address'
assert person[path] == address

有没有办法评估更深的路径?

谢谢!

1 个答案:

答案 0 :(得分:1)

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