All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hasor.cobble.setting.provider.yaml.YamlSettingsReader Maven / Gradle / Ivy

The newest version!
/*
 *
 * * Copyright 2008-2016 the original author or authors.
 * *
 * * Licensed under the Apache License, Version 2.0 (the "License");
 * * you may not use this file except in compliance with the License.
 * * You may obtain a copy of the License at
 * *
 *      http://www.apache.org/licenses/LICENSE-2.0
 * *
 * * Unless required by applicable law or agreed to in writing, software
 * * distributed under the License is distributed on an "AS IS" BASIS,
 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * * See the License for the specific language governing permissions and
 * * limitations under the License.
 *
 */
package net.hasor.cobble.setting.provider.yaml;
import net.hasor.cobble.setting.SettingNode;
import net.hasor.cobble.setting.Settings;
import net.hasor.cobble.setting.data.TreeNode;
import net.hasor.cobble.setting.provider.SettingsReader;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 * @version : 2021-02-01
 * @author 赵永春 ([email protected])
 */
public class YamlSettingsReader implements SettingsReader {
    @Override
    public void readSetting(Reader reader, Settings readTo) throws IOException {
        Object yamlConfig = new Yaml().load(reader);
        loadYaml(readTo, yamlConfig);
    }

    protected void loadYaml(Settings readTo, Object yamlConfig) throws IOException {
        if (!(yamlConfig instanceof Map)) {
            throw new IOException("The first level of YAML must be Map.");
        }

        String namespace = Settings.DefaultNameSpace;
        TreeNode parentNode = new TreeNode("", namespace);

        TreeNode loadMap = loadMap((Map) yamlConfig);
        copyTreeNode(loadMap, parentNode);

        for (SettingNode node : parentNode.getSubNodes()) {
            readTo.addSetting(node.getName(), node, namespace);
        }
    }

    protected List loadList(List yamlConfig) {
        return yamlConfig.stream().map(yamlValue -> {
            TreeNode treeNode = new TreeNode("");
            if (yamlValue instanceof List) {
                throw new UnsupportedOperationException("Unsupported array/array struct.");
            } else if (yamlValue instanceof Map) {
                TreeNode loadMap = loadMap((Map) yamlValue);
                copyTreeNode(loadMap, treeNode);
            } else if (yamlValue != null) {
                treeNode.addValue(String.valueOf(yamlValue));
            }
            return treeNode;
        }).collect(Collectors.toList());
    }

    protected TreeNode loadMap(Map yamlConfig) {
        TreeNode mapNode = new TreeNode("");
        yamlConfig.forEach((key, value) -> {
            if (value instanceof List) {
                List treeNodes = loadList((List) value);
                for (TreeNode node : treeNodes) {
                    TreeNode newLast = mapNode.newLast(key);
                    copyTreeNode(node, newLast);
                }
            } else if (value instanceof Map) {
                TreeNode loadMap = loadMap((Map) value);
                mapNode.addNode(key, loadMap);
            } else if (value != null) {
                mapNode.addValue(key, String.valueOf(value));
            }
        });
        return mapNode;
    }

    private static void copyTreeNode(TreeNode form, TreeNode to) {
        for (String subValue : form.getValues()) {
            to.addValue(subValue);
        }
        for (TreeNode subItem : form.getSubNodes()) {
            to.addSubNode(subItem);
        }
    }
}