How to create a DSL Groovy config file using an arbitrary Map (dynamic object)

826 views Asked by At

How do I convert an arbitrary Groovy map / list to the config style DSL syntax that Groovy provides?

Example:

def config = [
    'test': 'lalala',
    'nestedObject': [
        foo1: 'foo1 val',
        foo2: 'foo2 val',
        nested2: [
            anInt: 5,
            anArray: ['a', 'b', 'c'],
            anIntArray: [1, 2, 3]
        ]
    ]
]

To something like:

test = 'lalala'
nestedObject {
    foo1 = 'foo1 val'
    foo2 = 'foo2 val'
    nested2 {
        anInt = 5
        anArray = ['a', 'b', 'c']
        anIntArray = [1, 2, 3]
    }
}

UPDATE:

2

There are 2 answers

1
Roger Glover On BEST ANSWER

If you know the nested Map structure in advance, your solution will work. If you need to do this on an unknown arbitrary nested Map structure, try something like this:

import groovy.util.ConfigObject

def mapToConfig
mapToConfig = { Map map ->
    map.collectEntries { k, v ->
        v instanceof Map ? [(k):mapToConfig(v)] : [(k):v]
    } as ConfigObject
}

Given your input and the above closure definition, the following print statement:

println mapToConfig(config).prettyPrint()

Yields this output:

test='lalala'
nestedObject {
    foo1='foo1 val'
    foo2='foo2 val'
    nested2 {
        anInt=5
        anArray=['a', 'b', 'c']
        anIntArray=[1, 2, 3]
    }
}
0
Vahid Pazirandeh On

Just convert each Map into a ConfigObject and then pretty-print it:

import groovy.util.ConfigObject

def config = [
    'test': 'lalala',
    'nestedObject': [
        foo1: 'foo1 val',
        foo2: 'foo2 val',
        nested2: [
            anInt: 5,
            anArray: ['a', 'b', 'c'],
            anIntArray: [1, 2, 3]
        ] as ConfigObject
    ] as ConfigObject
] as ConfigObject

println config.prettyPrint()

All credit goes to: How to create ConfigObject using only nested maps in Grails?

(I just wanted people to know you can do this outside of Grails and initially I didn't realize how the pretty printing was invoked. I was confused with JsonOutput.prettyPrint())

Thanks @Steinar