Reputation: 191
I have a JSON configuration file that I want to read with groovy this file has "defaults" in case one key would be missing because no specific configuration has been added.
json
{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}
What would be the most groovy way to search for the value and falling back to the outer most "default" key? here's how I implemented it but I'm not sure this would work:
if (presets[appTeam])
if (presets[appTeam][appName])
if (presets[appTeam][appName][compName])
this.preset = presets[appTeam][appName][compName]
else
this.preset = presets[appTeam][appName]['default']
else
this.preset = presets[appTeam]['default']
else
this.preset = presets['default']
Thank you in advance
Upvotes: 1
Views: 189
Reputation: 28564
another way
def value(presets, team, app, compt) {
def defkey = 'default'
return presets.get(team)?.get(app)?.get(compt) ?:
presets.get(team)?.get(app)?.get(defkey) ?:
presets.get(team)?.get(defkey) ?:
presets.get(defkey)
}
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'
Upvotes: 1
Reputation: 20699
A simple generic recursion would help:
def input = new groovy.json.JsonSlurper().parseText '''{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}'''
def findRecursive
findRecursive = { json, List keys, List defaults = [] ->
if( !json || ( json in String ) || !keys ) return json
if( json.default ) defaults << json.default
findRecursive json[ keys.remove( 0 ) ] ?: defaults.last(), keys, defaults
}
assert 'preset_team1App1Comp1' == findRecursive( input.presets, [ 'Team1', 'AppName1', 'Component1' ] )
assert 'preset_team2App1Comp1' == findRecursive( input.presets, [ 'Team2', 'AppName1', 'Component1' ] )
assert 'preset_team1Default' == findRecursive( input.presets, [ 'Team1', 'AppName3', 'Component1' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team3' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team2', 'AppName2', 'Component1' ] )
Upvotes: 1
Reputation: 171054
One way would be to use "inject" to walk along your keys, and keep track of the latest default seen... Something like this:
def value(Map presets, String... keys) {
keys.inject([pos: presets, result: presets.default]) { latest, current ->
def node = latest.pos[current]
if (node instanceof Map) {
[pos: node, result: node.default ?: latest.result]
} else if (node instanceof String) {
[pos: node, result: node]
} else if (node == null) {
[pos: node, result: latest.result]
} else {
throw new RuntimeException("No idea what to do with a ${node.class.simpleName}")
}
}.result
}
Then you can do (with the above example)
// Defaults
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
// Values
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'
Upvotes: 2