2016-07-15 17 views
1

我對groovy比較陌生,並且在gradle構建的上下文中使用它。所以,如果有一個簡單的開箱即用的解決方案,請不要苛刻。從groovy中的鍵創建嵌套的地圖

基本上我試圖完成相反的Return Nested Key in Groovy。也就是說,我從System.properties地圖讀取了一些鑰匙,例如user.home和相應的值,如C:\User\dpr。現在,我想創建一個地圖,反映了這個結構,使用它在一個groovy.text.SimpleTemplateEngine爲綁定:

[user : [home : 'C:\Users\dpr']] 

鍵可以定義一個任意深層次結構。例如java.vm.specification.vendor=Oracle Corporation應該變成:

[java : [vm : [spec : [vendor : 'Oracle Corporation']]]] 

此外,還有與父母如user.name=dpruser.country=US相同的屬性:

[ 
    user: [ 
    name: 'dpr', 
    country: 'US' 
    ] 
] 

編輯:雖然ConfigSlurper是非常好的,它是有點在創建嵌套地圖時過於防守,因爲它會停止嵌套在某個鍵的最小深度。

我現在結束了使用此

def bindings = [:] 
System.properties.sort().each { 
    def map = bindings 
    def split = it.key.split("\\.") 
    for (int i = 0; i < split.length; i++) { 
    def part = split[i]; 

    // There is already a property value with the same parent 
    if (!(map instanceof Map)) { 
     println "Skipping property ${it.key}" 
     break; 
    } 

    if (!map.containsKey(part)) { 
     map[part] = [:] 
    } 

    if (i == split.length - 1) { 
     map[part] = it.value 
    } else { 
     map = map[part] 
    } 
    } 
    map = it.value 
} 

這種解決方案的性能file.encoding.pkgjava.vendor.urljava.vendor.url.bug被丟棄,這是不是很好,但東西我可以應付。

但是,上面的代碼不是很groovyish。

回答

3

你可以使用一個ConfigSlurper

def conf = new ConfigSlurper().parse(System.properties) 
println conf.java.specification.version 
+0

這似乎是工作部分只對某些屬性的正確結構是爲他人創造不是:'【JAVA:[runtime.name:Java(TM)SE運行時環境,runtime.version:1.8.0_92-b14,...' – dpr

+0

我認爲這可能與某個屬性路徑的最小深度有關。有'java.home',因此它直接在'java'鍵下創建所有'java。*'條目而不需要進一步嵌套。 – dpr

+1

是的,如果a.b有一個值,那麼它不能被實現爲一個映射,並且它不能有嵌套的值。在這種情況下,ConfigSlurper使用具有a的鍵創建嵌套值。內。例如,'java.vendor'是一個String,所以你必須用'java ['vendor.url']' –