如何使用gradle任务将.yml转换为.properties?

时间:2018-03-10 10:22:10

标签: spring spring-boot gradle yaml

Spring唯一支持的i18n格式是.properties和.xml,但它并不是最佳选择。 我想要的是拥有一个复杂的Yaml文件(messages.yml和messages_xx.yml),它在Gradle任务中转换为.properties,这样我就可以在Build任务之前对它进行排队。

例如,messages.yml看起来像:

group1:
  group2:
    group3:
      message1: hello
      message2: how are you?
    group4:
      message3: good
  group5:
    group6:
      message4: let's party

输出.properties将是:

group1.group2.group3.message1: hello
group1.group2.group3.message2: how are you?
group1.group2.group4.message3: good
group1.group5.group6.message4: let's party

有没有办法实现这个目标? 我没有找到现有的转换器。

4 个答案:

答案 0 :(得分:2)

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.TreeMap;

import org.yaml.snakeyaml.Yaml;


public class YamlBackToProperties {
    public static void main(String[] args) throws IOException {

        Yaml yaml = new Yaml();
        try (InputStream in = Files.newInputStream(Paths.get("test.yml"))) {

            TreeMap<String, Map<String, Object>> config = yaml.loadAs(in, TreeMap.class);
            System.out.println(String.format("%s%n\nConverts to Properties:%n%n%s", config.toString(), toProperties(config)));
        }
    }

    private static String toProperties(TreeMap<String, Map<String, Object>> config) {

        StringBuilder sb = new StringBuilder();

        for (String key : config.keySet()) {

            sb.append(toString(key, config.get(key)));
        }

        return sb.toString();
    }

    private static String toString(String key, Map<String, Object> map) {

        StringBuilder sb = new StringBuilder();

        for (String mapKey : map.keySet()) {

            if (map.get(mapKey) instanceof Map) {
                sb.append(toString(String.format("%s.%s", key, mapKey), (Map<String, Object>) map.get(mapKey)));
            } else {
                sb.append(String.format("%s.%s=%s%n", key, mapKey, map.get(mapKey).toString()));
            }
        }

        return sb.toString();
    }
}

答案 1 :(得分:2)

对第一个答案进行了一些更改。现在适用于所有情况:

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.TreeMap;

import org.yaml.snakeyaml.Yaml;


public class YamlConverter {
    public static void main(String[] args) throws IOException {

        Yaml yaml = new Yaml();
        try (InputStream in = Files.newInputStream(Paths.get("yourpath/application.yml"))) {

            TreeMap<String, Map<String, Object>> config = yaml.loadAs(in, TreeMap.class);
            System.out.println(String.format("%s%n\nConverts to Properties:%n%n%s", config.toString(), toProperties(config)));
        }
    }

    private static String toProperties(TreeMap<String, Map<String, Object>> config) {

        StringBuilder sb = new StringBuilder();

        for (String key : config.keySet()) {

                sb.append(toString(key, config.get(key)));

        }

        return sb.toString();
    }

    private static String toString(String key, Object mapr) {

        StringBuilder sb = new StringBuilder();

        if(!(mapr instanceof Map)) {
            sb.append(key+"="+mapr+"\n");
            return sb.toString();
        }

        Map<String, Object> map = (Map<String, Object>)mapr;

        for (String mapKey : map.keySet()) {

            if (map.get(mapKey) instanceof Map) {
                sb.append(toString(key+"."+mapKey, map.get(mapKey)));
            } else {
                sb.append(String.format("%s.%s=%s%n", key, mapKey, map.get(mapKey).toString()));
            }
        }

        return sb.toString();
    }
}

答案 2 :(得分:0)

您可以尝试这样

package com.example.yaml;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.yaml.snakeyaml.Yaml;

public class YamlConfigRunner {
public static void main(String[] args) throws IOException {
    if( args.length != 1 ) {
        System.out.println( "Usage: <file.yml>" );
        return;
    }

    Yaml yaml = new Yaml();  
    try( InputStream in = Files.newInputStream( Paths.get( args[ 0 ] ) ) ) {
        Configuration config = yaml.loadAs( in, Configuration.class );
        System.out.println( config.toString() );
    }
}
}

参考:https://dzone.com/articles/using-yaml-java-application

答案 3 :(得分:0)

这是Kotlin中的直接实现:

一旦您拥有带有解析的Yaml的地图,只需调用flatten()

fun flatten(map: Map<String, *>): MutableMap<String, Any> {
    val processed = mutableMapOf<String, Any>()
    map.forEach { key, value ->
        doFlatten(key, value as Any, processed)
    }
    return processed
}

fun doFlatten(parentKey: String, value: Any, processed: MutableMap<String, Any>) {
    if (value is Map<*, *>) {
        value.forEach {
            doFlatten("$parentKey.${it.key}", it.value as Any, processed)
        }
    } else {
        processed[parentKey] = value
    }
}