Симпатичный принт для заводного ConfigObject? - PullRequest
3 голосов
/ 26 октября 2011

У меня есть эта программа, которая создает файл конфигурации Groovy, используя ConfigObject. Как только ConfigObject настроен, он записывается в файл, используя:

myFile.withWriter {writer -> myConfigObject.writeTo(writer)}

Это приводит к тому, что каждое свойство ConfigObject записывается в одну строку. Так, например, карта будет напечатана как:

graphs=[["type":"std", "host":"localhost", "name":"cpurawlinux"], ["type":"std", "host":"localhost", "name":"memory"], ["type":"std", "host":"localhost", "name":"udp"] ... ]

, что совершенно не читается, если кто-то должен на это взглянуть. Есть ли способ получить более дружественный результат? Нечто подобное было бы замечательно:

graphs=[
    ["type":"std", "host":"localhost", "name":"cpurawlinux"],
    ["type":"std", "host":"localhost", "name":"memory"],
    ["type":"std", "host":"localhost", "name":"udp"]
    ...
]

Я знаю, что мог бы создать свой собственный writeTo, но разве в Groovy уже нет чего-то для этого?

Ответы [ 3 ]

1 голос
/ 07 мая 2013

если это кому-нибудь поможет, у меня был тот же вопрос и я написал это ... не очень (ха), но работает:

def prettyPrint(properties, level=1, stringBuilder = new StringBuilder()) {
    return properties.inject(stringBuilder) { sb, name, value ->
        sb.append("\n").append("\t" * level).append(name)
        if (!(value instanceof Map) && !(value instanceof List)) {
            return sb.append("=").append(value)
        } else {
            return prettyPrint(properties.getProperty(name), level+1, sb)
        }
    }
}
1 голос
/ 30 апреля 2016

Основано на ответе Майка выше:

def prettyPrint
prettyPrint = {obj, level = 0, sb = new StringBuilder() ->
    def indent = { lev -> sb.append("  " * lev) }
    if(obj instanceof Map){
        sb.append("{\n")
        obj.each{ name, value ->
            if(name.contains('.')) return // skip keys like "a.b.c", which are redundant
            indent(level+1).append(name)
            (value instanceof Map) ? sb.append(" ") : sb.append(" = ")
            prettyPrint(value, level+1, sb)
            sb.append("\n")
        }
        indent(level).append("}")
    }
    else if(obj instanceof List){
        sb.append("[\n")
        obj.each{ value ->
            indent(level+1)
            prettyPrint(value, level+1, sb).append(",")
            sb.append("\n")
        }
        indent(level).append("]")
    }
    else if(obj instanceof String){
        sb.append('"').append(obj).append('"')
    }
    else {
        sb.append(obj)
    }
}

Для ввода типа:

{
  grails {
    scaffolding {
      templates.domainSuffix = "Instance"
    }
    enable {
      native2ascii = true
      blah = [ 1, 2, 3 ]
    }
    mime.disable.accept.header.userAgents = [ "WebKit", "Presto", "Trident" ]
  }
}

Производит:

{
  grails {
    scaffolding {
      templates {
        domainSuffix = "Instance"
      }
    }
    enable {
      native2ascii = true
      blah = [
        1,
        2,
        3,
      ]
    }
    mime {
      disable {
        accept {
          header {
            userAgents = [
              "WebKit",
              "Presto",
              "Trident",
            ]
          }
        }
      }
    }
  }
}
1 голос
/ 26 октября 2011

К сожалению, вам нужно написать свой writeTo, как вы говорите.

Если у вас есть файл конфигурации со структурой вроде:

graphs {
  a=["type":"std", "host":"localhost", "name":"cpurawlinux"]
  b=["type":"std", "host":"localhost", "name":"memory"]
}

Тогда writeTo запишет его со структурой, но если ваш конфигурационный файл - это просто большой старый список вещей, он запишет его как большой старый список

...