yaml和properties java实现互转

yaml 和 properties 格式最大的区别在于,properties 是单层map格式。而yaml 是多层嵌套map格式。spring有snakeyaml实现了把多层map输出城yaml文件格式。这部分逻辑不用重写。实现的关键在于单层map如何转多层。多层如何转成单层。直接上代码。主要逻辑2个递归。

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.list.GrowthList;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
public class YamlParser {
	private static final Logger logger = LoggerFactory.getLogger(YamlParser.class);

	/**
	 * yml文件流转成单层map
	 * 转Properties 改变了顺序
	 * 
	 * @param yamlContent
	 * @return
	 */
	public static Map<String, Object> yamlToFlattenedMap(String yamlContent) {
		Yaml yaml = createYaml();
		Map<String, Object> map=new HashMap<>();
		for (Object object : yaml.loadAll(yamlContent)) {
			if (object != null) {
				map = asMap(object);
				map=getFlattenedMap(map);
			}
		}
		return map;
	}

	/**
	 * yml文件流转成多次嵌套map
	 * 
	 * @param yamlContent
	 * @return
	 */
	public static Map<String, Object> yamlToMultilayerMap(String yamlContent) {
		Yaml yaml = createYaml();
		Map<String, Object> result = new LinkedHashMap<>();
		for (Object object : yaml.loadAll(yamlContent)) {
			if (object != null) {
				result.putAll(asMap(object));
			}
		}
		return result;
	}

	/**
	 * 多次嵌套map转成yml
	 * 
	 * @param yamlContent
	 * @return
	 */
	public static String multilayerMapToYaml(Map<String, Object> map) {
		Yaml yaml = createYaml();
		return yaml.dumpAsMap(map);
	}

	/**
	 * 单层map转成yml
	 * 
	 * @param yamlContent
	 * @return
	 */
	public static String flattenedMapToYaml(Map<String, Object> map) {
		Yaml yaml = createYaml();
		return yaml.dumpAsMap(flattenedMapToMultilayerMap(map));
	}

	/**
	 * 单层map转换多层map
	 * 
	 * @param map
	 * @return
	 */
	private static Map<String, Object> flattenedMapToMultilayerMap(Map<String, Object> map) {
		Map<String, Object> result = getMultilayerMap(map);
		return result;
	}

	private static Yaml createYaml() {
		return new Yaml(new Constructor());
	}

	@SuppressWarnings("unchecked")
	private static Map<String, Object> asMap(Object object) {
		Map<String, Object> result = new LinkedHashMap<>();
		if (!(object instanceof Map)) {
			result.put("document", object);
			return result;
		}

		Map<Object, Object> map = (Map<Object, Object>) object;
		for (Map.Entry<Object, Object> entry : map.entrySet()) {
			Object value = entry.getValue();
			if (value instanceof Map) {
				value = asMap(value);
			}
			Object key = entry.getKey();
			if (key instanceof CharSequence) {
				result.put(key.toString(), value);
			} else {
				result.put("[" + key.toString() + "]", value);
			}
		}
		return result;
	}

	private static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
		Map<String, Object> result = new LinkedHashMap<>();
		buildFlattenedMap(result, source, null);
		return result;
	}

	private static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
		for (Map.Entry<String, Object> entry : source.entrySet()) {
			String key = entry.getKey();
			if (!StringUtils.isBlank(path)) {
				if (key.startsWith("[")) {
					key = path + key;
				} else {
					key = path + '.' + key;
				}
			}
			Object value = entry.getValue();
			if (value instanceof String) {
				result.put(key, value);
			} else if (value instanceof Map) {
				@SuppressWarnings("unchecked")
				Map<String, Object> map = (Map<String, Object>) value;
				buildFlattenedMap(result, map, key);
			} else if (value instanceof Collection) {
				@SuppressWarnings("unchecked")
				Collection<Object> collection = (Collection<Object>) value;
				int count = 0;
				for (Object object : collection) {
					buildFlattenedMap(result, Collections.singletonMap("[" + (count++) + "]", object), key);
				}
			} else {
				result.put(key, (value != null ? value.toString() : ""));
			}
		}
	}

	private static Map<String, Object> getMultilayerMap(Map<String, Object> source) {
		Map<String, Object> rootResult = new LinkedHashMap<>();
		for (Map.Entry<String, Object> entry : source.entrySet()) {
			String key = entry.getKey();
			buildMultilayerMap(rootResult, key,entry.getValue());
		}
		return rootResult;
	}

	@SuppressWarnings("unchecked")
	private static void buildMultilayerMap(Map<String, Object> parent, String path,Object value) {
		String[] keys = StringUtils.split(path,".");
		String key = keys[0];
		if (key.endsWith("]")) {
            String listKey=key.substring(0,key.indexOf("["));
            String listPath=path.substring(key.indexOf("["));
            List<Object> chlid =  bulidChlidList(parent, listKey);
            buildMultilayerList(chlid, listPath, value);
		}else{
			if (keys.length == 1) {
				parent.put(key, stringToObj(value.toString()));
			}else{
				String newpath = path.substring(path.indexOf(".") + 1);
				Map<String, Object> chlid = bulidChlidMap(parent, key);;
				buildMultilayerMap(chlid, newpath,value);
			}
		}
	}
	
	
	@SuppressWarnings("unchecked")
	private static void buildMultilayerList(List<Object> parent,String path,Object value) {
		String[] keys = StringUtils.split(path,".");
		String key = keys[0];
		int index=Integer.valueOf(key.replace("[", "").replace("]", ""));
		if (keys.length == 1) {
			parent.add(index,stringToObj(value.toString()));
		} else {
			String newpath = path.substring(path.indexOf(".") + 1);
			Map<String, Object> chlid = bulidChlidMap(parent, index);;
			buildMultilayerMap(chlid, newpath, value);
		}
	}
	
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> bulidChlidMap(Map<String, Object> parent,String key){
		if (parent.containsKey(key)) {
			return (Map<String, Object>) parent.get(key);
		} else {
			Map<String, Object> chlid = new LinkedHashMap<>(16);
			parent.put(key, chlid);
			return chlid;
		}
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> bulidChlidMap(List<Object> parent,int index){
		Map<String, Object> chlid = null;
		try{
			Object obj=parent.get(index);
			if(null != obj){
				chlid = (Map<String, Object>)obj;
			}
		}catch(Exception e){
			logger.warn("get list error");
		}

		if (null == chlid) {
			chlid = new LinkedHashMap<>(16);
			parent.add(index,chlid);
		}
		return chlid;
	}

	@SuppressWarnings("unchecked")
	private static List<Object> bulidChlidList(Map<String, Object> parent,String key){
		if (parent.containsKey(key)) {
		   return (List<Object>) parent.get(key);
		} else {
			List<Object> chlid = new GrowthList(16);
			parent.put(key, chlid);
			return chlid;
		}
	}
	
	private static Object stringToObj(String obj){
		Object result=null;
		if(obj.equals("true") || obj.equals("false")){
			result=Boolean.valueOf(obj);
		}else if(isBigDecimal(obj)){
			if(obj.indexOf(".") == -1){
				result=Long.valueOf(obj.toString());
			}else{
				result=Double.valueOf(obj.toString());
			}
		}else{
			result=obj;
		}
		return result;
	}
	

public static boolean isBigDecimal(String str){
    	if(str==null || str.trim().length() == 0){
    		return false;
    	}
    	char[] chars = str.toCharArray();
    	int sz = chars.length;
    	int i = (chars[0] == '-') ? 1 : 0;
    	if(i == sz) return false;
    	
    	if(chars[i] == '.') return false;//除了负号,第一位不能为'小数点'
    	
    	boolean radixPoint = false;
    	for(; i < sz; i++){
    		if(chars[i] == '.'){
    			if(radixPoint) return false;
    			radixPoint = true;
    		}else if(!(chars[i] >= '0' && chars[i] <= '9')){
    			return false;
    		}
    	}
    	return true;
}
	
	
	public static void main(String[] args) throws IOException {
		File file = new File(YamlParser.class.getResource("/").getFile() + "test.yml");
		String content = Files.toString(file, Charsets.UTF_8);
		Map<String, Object> a= YamlParser.yamlToFlattenedMap(content);
		System.out.println(a);

		Map<String, Object> b = YamlParser.yamlToMultilayerMap(content);
		System.out.println(b);
		
	
		String c = YamlParser.multilayerMapToYaml(b);
		System.out.println(c);
		String d = YamlParser.flattenedMapToYaml(a);
		System.out.println(d);
		
	}
	
	

}

你可能感兴趣的:(java)