ninja.leaping.permissionsex.backend.file.SchemaMigrations.java Source code

Java tutorial

Introduction

Here is the source code for ninja.leaping.permissionsex.backend.file.SchemaMigrations.java

Source

/**
 * PermissionsEx
 * Copyright (C) zml and PermissionsEx contributors
 *
 * 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 ninja.leaping.permissionsex.backend.file;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.transformation.ConfigurationTransformation;
import ninja.leaping.configurate.transformation.TransformAction;
import ninja.leaping.permissionsex.backend.ConversionUtils;
import ninja.leaping.permissionsex.logging.TranslatableLogger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static ninja.leaping.configurate.transformation.ConfigurationTransformation.WILDCARD_OBJECT;
import static ninja.leaping.permissionsex.util.Translations.t;

public class SchemaMigrations {
    public static final int LATEST_VERSION = 4;

    private SchemaMigrations() {
    }

    private static ConfigurationTransformation.Builder tBuilder() {
        return ConfigurationTransformation.builder();
    }

    static ConfigurationTransformation versionedMigration(final TranslatableLogger logger) {
        return ConfigurationTransformation.versionedBuilder().setVersionKey("schema-version")
                .addVersion(LATEST_VERSION, threeToFour()).addVersion(3, twoTo3()).addVersion(2, oneTo2(logger))
                .addVersion(1, initialTo1()).build();
    }

    static ConfigurationTransformation threeToFour() {
        return ConfigurationTransformation.chain(tBuilder()
                .addAction(new Object[] { "worlds", WILDCARD_OBJECT, "inheritance" }, (inputPath, valueAtPath) -> {
                    try {
                        valueAtPath.setValue(Lists.transform(valueAtPath.getList(TypeToken.of(String.class)),
                                input -> "world:" + input));
                    } catch (ObjectMappingException e) {
                        throw new RuntimeException(e);
                    }

                    return new Object[] { "context-inheritance", "world:" + inputPath.get(1) };
                }).build(), tBuilder().addAction(new Object[] { "worlds" }, (inputPath, valueAtPath) -> {
                    valueAtPath.setValue(null);
                    return null;
                }).build());
    }

    static ConfigurationTransformation twoTo3() {
        final Map<String, List<Map.Entry<String, Integer>>> convertedRanks = new HashMap<>();
        return ConfigurationTransformation
                .chain(tBuilder().addAction(new Object[] { WILDCARD_OBJECT }, (nodePath, configurationNode) -> {
                    if (configurationNode.hasMapChildren()) {
                        String lastPath = nodePath.get(0).toString();
                        if (lastPath.endsWith("s")) {
                            lastPath = lastPath.substring(0, lastPath.length() - 1);
                        }
                        return new Object[] { "subjects", lastPath };
                    } else {
                        return null;
                    }
                }).build(), tBuilder().addAction(new Object[] { "subjects", "group", WILDCARD_OBJECT },
                        (nodePath, configurationNode) -> {
                            for (ConfigurationNode child : configurationNode.getChildrenList()) {
                                if (child.getNode(FileSubjectData.KEY_CONTEXTS).isVirtual()
                                        || child.getNode(FileSubjectData.KEY_CONTEXTS).getChildrenMap().isEmpty()) {
                                    ConfigurationNode optionsNode = child.getNode("options");
                                    if (optionsNode.isVirtual()) {
                                        return null;
                                    }
                                    ConfigurationNode rank = optionsNode.getNode("rank");
                                    if (!rank.isVirtual()) {
                                        final String rankLadder = optionsNode.getNode("rank-ladder")
                                                .getString("default");
                                        List<Map.Entry<String, Integer>> tempVals = convertedRanks
                                                .get(rankLadder.toLowerCase());
                                        if (tempVals == null) {
                                            tempVals = new ArrayList<>();
                                            convertedRanks.put(rankLadder.toLowerCase(), tempVals);
                                        }
                                        tempVals.add(Maps.immutableEntry(configurationNode.getKey().toString(),
                                                rank.getInt()));
                                        rank.setValue(null);
                                        optionsNode.getNode("rank-ladder").setValue(null);
                                        if (optionsNode.getChildrenMap().isEmpty()) {
                                            optionsNode.setValue(null);
                                        }
                                    }

                                }
                            }
                            return null;
                        }).build(), tBuilder().addAction(new Object[0], (nodePath, configurationNode) -> {
                            for (Map.Entry<String, List<Map.Entry<String, Integer>>> ent : convertedRanks
                                    .entrySet()) {
                                Collections.sort(ent.getValue(), (a, b) -> b.getValue().compareTo(a.getValue()));
                                ConfigurationNode ladderNode = configurationNode
                                        .getNode(FileDataStore.KEY_RANK_LADDERS, ent.getKey());
                                for (Map.Entry<String, Integer> grp : ent.getValue()) {
                                    ladderNode.getAppendedNode().setValue("group:" + grp.getKey());
                                }
                            }
                            return null;
                        }).build());
    }

    static ConfigurationTransformation oneTo2(final TranslatableLogger logger) {
        return ConfigurationTransformation.chain(tBuilder()
                .addAction(new Object[] { WILDCARD_OBJECT, WILDCARD_OBJECT }, (nodePath, configurationNode) -> {
                    Object value = configurationNode.getValue();
                    configurationNode.setValue(null);
                    configurationNode.getAppendedNode().setValue(value);
                    return null;
                }).build(), tBuilder().addAction(new Object[] { WILDCARD_OBJECT, WILDCARD_OBJECT, 0, "worlds" },
                        (nodePath, configurationNode) -> {
                            ConfigurationNode entityNode = configurationNode.getParent().getParent();
                            for (Map.Entry<Object, ? extends ConfigurationNode> ent : configurationNode
                                    .getChildrenMap().entrySet()) {
                                entityNode.getAppendedNode().setValue(ent.getValue())
                                        .getNode(FileSubjectData.KEY_CONTEXTS, "world").setValue(ent.getKey());

                            }
                            configurationNode.setValue(null);
                            return null;
                        }).build(),
                tBuilder().addAction(
                        new Object[] { WILDCARD_OBJECT, WILDCARD_OBJECT, WILDCARD_OBJECT, "permissions" },
                        (nodePath, configurationNode) -> {
                            List<String> existing = configurationNode.getList(Object::toString);
                            if (!existing.isEmpty()) {
                                configurationNode.setValue(ImmutableMap.of());
                            }
                            for (String permission : existing) {
                                int value = permission.startsWith("-") ? -1 : 1;
                                if (value < 0) {
                                    permission = permission.substring(1);
                                }
                                if (permission.equals("*")) {
                                    configurationNode.getParent().getNode("permissions-default").setValue(value);
                                    continue;
                                }
                                permission = ConversionUtils.convertLegacyPermission(permission);
                                if (permission.contains("*")) {
                                    logger.warn(t("The permission at %s contains a now-illegal character '*'",
                                            Arrays.toString(configurationNode.getPath())));
                                }
                                configurationNode.getNode(permission).setValue(value);
                            }
                            if (configurationNode.getChildrenMap().isEmpty()) {
                                configurationNode.setValue(null);
                            }
                            return null;
                        }).addAction(new Object[] { "users", WILDCARD_OBJECT, WILDCARD_OBJECT, "group" },
                                (nodePath, configurationNode) -> {
                                    Object[] retPath = nodePath.getArray();
                                    retPath[retPath.length - 1] = "parents";
                                    for (ConfigurationNode child : configurationNode.getChildrenList()) {
                                        child.setValue("group:" + child.getValue());
                                    }
                                    return retPath;
                                })
                        .addAction(new Object[] { "groups", WILDCARD_OBJECT, WILDCARD_OBJECT, "inheritance" },
                                (nodePath, configurationNode) -> {
                                    Object[] retPath = nodePath.getArray();
                                    retPath[retPath.length - 1] = "parents";
                                    for (ConfigurationNode child : configurationNode.getChildrenList()) {
                                        child.setValue("group:" + child.getValue());
                                    }
                                    return retPath;
                                })
                        .addAction(new Object[] { "groups", WILDCARD_OBJECT, WILDCARD_OBJECT },
                                (inputPath, valueAtPath) -> {
                                    ConfigurationNode defaultNode = valueAtPath.getNode("options", "default");
                                    if (!defaultNode.isVirtual()) {
                                        if (defaultNode.getBoolean()) {
                                            ConfigurationNode addToNode = null;
                                            final ConfigurationNode defaultsParent = valueAtPath.getParent()
                                                    .getParent().getParent().getNode("systems", "default");
                                            for (ConfigurationNode node : defaultsParent.getChildrenList()) {
                                                if (Objects.equal(
                                                        node.getNode(FileSubjectData.KEY_CONTEXTS).getValue(),
                                                        valueAtPath.getNode(FileSubjectData.KEY_CONTEXTS)
                                                                .getValue())) {
                                                    addToNode = node;
                                                    break;
                                                }
                                            }
                                            if (addToNode == null) {
                                                addToNode = defaultsParent.getAppendedNode();
                                            }
                                            addToNode.getNode("parents").getAppendedNode()
                                                    .setValue("group:" + valueAtPath.getParent().getKey());
                                        }
                                        defaultNode.setValue(null);
                                        final ConfigurationNode optionsNode = valueAtPath.getNode("options");
                                        if (optionsNode.getChildrenMap().isEmpty()) {
                                            optionsNode.setValue(null);
                                        }
                                    }
                                    return null;
                                })
                        .build());
    }

    private static final TransformAction MOVE_PREFIX_SUFFIX_ACTION = (nodePath, configurationNode) -> {
        final ConfigurationNode prefixNode = configurationNode.getNode("prefix");
        if (!prefixNode.isVirtual()) {
            configurationNode.getNode("options", "prefix").setValue(prefixNode);
            prefixNode.setValue(null);
        }

        final ConfigurationNode suffixNode = configurationNode.getNode("suffix");
        if (!suffixNode.isVirtual()) {
            configurationNode.getNode("options", "suffix").setValue(suffixNode);
            suffixNode.setValue(null);
        }

        final ConfigurationNode defaultNode = configurationNode.getNode("default");
        if (!defaultNode.isVirtual()) {
            configurationNode.getNode("options", "default").setValue(defaultNode);
            defaultNode.setValue(null);
        }
        return null;
    };

    static ConfigurationTransformation initialTo1() {
        return ConfigurationTransformation.builder()
                .addAction(new Object[] { WILDCARD_OBJECT, WILDCARD_OBJECT }, MOVE_PREFIX_SUFFIX_ACTION)
                .addAction(new Object[] { WILDCARD_OBJECT, WILDCARD_OBJECT, "worlds", WILDCARD_OBJECT },
                        MOVE_PREFIX_SUFFIX_ACTION)
                .build();
    }
}