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

org.flywaydb.core.internal.resource.ResourceNameParser Maven / Gradle / Ivy

There is a newer version: 10.15.2
Show newest version
/*
 * Copyright (C) Red Gate Software Ltd 2010-2024
 *
 * 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 org.flywaydb.core.internal.resource;

import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.configuration.Configuration;
import org.flywaydb.core.extensibility.ResourceType;
import org.flywaydb.core.extensibility.ResourceTypeProvider;
import org.flywaydb.core.internal.util.Pair;
import org.flywaydb.core.internal.util.StringUtils;

import java.util.*;

public class ResourceNameParser {
    private final Configuration configuration;
    private final List> prefixes;

    public ResourceNameParser(Configuration configuration) {
        this.configuration = configuration;
        // Versioned and Undo migrations are named in the form prefixVERSIONseparatorDESCRIPTIONsuffix
        // Repeatable migrations and callbacks are named in the form prefixSeparatorDESCRIPTIONsuffix
        prefixes = populatePrefixes(configuration);
    }

    public ResourceName parse(String resourceName) {
        return parse(resourceName, configuration.getSqlMigrationSuffixes());
    }

    public ResourceName parse(String resourceName, String[] suffixes) {
        // Strip off suffixes
        Pair suffixResult = stripSuffix(resourceName, suffixes);

        // Find the appropriate prefix
        Pair prefix = findPrefix(suffixResult.getLeft(), prefixes);
        if (prefix != null) {

            // Strip off prefix
            Pair prefixResult = stripPrefix(suffixResult.getLeft(), prefix.getLeft());
            String name = prefixResult.getRight();
            Pair splitName = StringUtils.splitAtFirstSeparator(name, configuration.getSqlMigrationSeparator());
            boolean isValid = true;
            String validationMessage = "";
            String exampleDescription = ("".equals(splitName.getRight())) ? "description" : splitName.getRight();

            // Validate the name
            if (!prefix.getRight().isVersioned()) {
                // Must not have a version (that is, something before the separator)
                if (!"".equals(splitName.getLeft())) {
                    isValid = false;
                    validationMessage = "Invalid repeatable migration / callback name format: " + resourceName
                            + " (It cannot contain a version and should look like this: "
                            + prefixResult.getLeft() + configuration.getSqlMigrationSeparator() + exampleDescription + suffixResult.getRight() + ")";
                }
            } else {
                // Must have a version (that is, something before the separator)
                if ("".equals(splitName.getLeft())) {
                    isValid = false;
                    validationMessage = "Invalid versioned migration name format: " + resourceName
                            + " (It must contain a version and should look like this: "
                            + prefixResult.getLeft() + "1.2" + configuration.getSqlMigrationSeparator() + exampleDescription + suffixResult.getRight() + ")";
                } else {
                    // ... and that must be a legitimate version
                    try {
                        MigrationVersion.fromVersion(splitName.getLeft());
                    } catch (Exception e) {
                        isValid = false;
                        validationMessage = "Invalid versioned migration name format: " + resourceName
                                + " (could not recognise version number " + splitName.getLeft() + ")";
                    }
                }
            }

            String description = splitName.getRight().replace("_", " ");
            return new ResourceName(prefixResult.getLeft(), splitName.getLeft(),
                                    configuration.getSqlMigrationSeparator(), description, splitName.getRight(), suffixResult.getRight(),
                                    isValid, validationMessage);
        }

        // Didn't match any prefix
        return ResourceName.invalid("Unrecognised migration name format: " + resourceName);
    }

    private Pair findPrefix(String nameWithoutSuffix, List> prefixes) {
        for (Pair prefix : prefixes) {
            if (nameWithoutSuffix.startsWith(prefix.getLeft())) {
                return prefix;
            }
        }
        return null;
    }

    private Pair stripSuffix(String name, String[] suffixes) {
        for (String suffix : suffixes) {
            if (name.toUpperCase().endsWith(suffix.toUpperCase())) {
                return Pair.of(name.substring(0, name.length() - suffix.length()), name.substring(name.length() - suffix.length()));
            }
        }
        return Pair.of(name, "");
    }

    private Pair stripPrefix(String fileName, String prefix) {
        if (fileName.startsWith(prefix)) {
            return Pair.of(prefix, fileName.substring(prefix.length()));
        }
        return null;
    }

    private List> populatePrefixes(Configuration configuration) {
        List> prefixes = new ArrayList<>();

        configuration.getPluginRegister().getPlugins(ResourceTypeProvider.class)
                .forEach(resourceTypeProvider -> prefixes.addAll(resourceTypeProvider.getPrefixTypePairs(configuration)));

        Comparator> prefixComparator = (p1, p2) -> {
            // Sort most-hard-to-match first; that is, in descending order of prefix length
            return p2.getLeft().length() - p1.getLeft().length();
        };

        prefixes.sort(prefixComparator);
        return prefixes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy