Package ru.aristar.jnuget.files

Source Code of ru.aristar.jnuget.files.VersionRange

package ru.aristar.jnuget.files;

import java.io.Serializable;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ru.aristar.jnuget.Version;

/**
* Диапазон версий
*
* <p> 1.0 = 1.0 ≤ x</p>
* <p>(,1.0] = x ≤ 1.0</p>
* <p>(,1.0) = x < 1.0</p>
* <p>[1.0] = x == 1.0</p>
* <p>(1.0) = invalid</p>
* <p>(1.0,) = 1.0 < x</p>
* <p>(1.0,2.0) = 1.0< x < 2.0</p>
* <p>[1.0,2.0] = 1.0 ≤ x ≤ 2.0</p>
* <p>empty = latest version</p>.
*
* @author sviridov
*/
public class VersionRange implements Serializable{

    /**
     * Разделитель границ отрезка
     */
    public static final String BORDER_DELIMETER = ",";
    /**
     * Полный шаблон диапазона версий
     */
    public static final String FULL_VERSION_RANGE_PATTERN = "(?<leftBorder>[\\(\\[])(?<left>("
            + Version.VERSION_FORMAT + ")?)"
            + BORDER_DELIMETER
            + "(?<right>(" + Version.VERSION_FORMAT + ")?)(?<rightBorder>[\\)\\]])";
    /**
     * Шаблон фиксированной версии
     */
    public static final String FIXED_VERSION_RANGE_PATTERN = "\\[(" + Version.VERSION_FORMAT + ")\\]";
    /**
     * Версия на нижней границе
     */
    private Version lowVersion;
    /**
     * Тип нижней границы
     */
    private BorderType lowBorderType;
    /**
     * Тип верхней границы
     */
    private BorderType topBorderType;
    /**
     * Версия на верхней границе
     */
    private Version topVersion;

    /**
     * @return диапазон указывает на последнюю версию пакета
     */
    public boolean isLatestVersion() {
        return lowVersion == null && topVersion == null;
    }

    /**
     * @return диапазон указывает на конкретную версию пакета
     */
    public boolean isFixedVersion() {
        return lowVersion != null
                && topVersion != null
                && lowVersion.equals(topVersion);
    }

    /**
     * @return диапазон указывает на конкретную или большую версию пакета
     */
    public boolean isSimpleRange() {
        return topVersion == null
                && lowVersion != null
                && lowBorderType == BorderType.INCLUDE;
    }

    /**
     * Конструктор по умолчанию (все поля null)
     */
    public VersionRange() {
    }

    /**
     * @param lowVersion Версия на нижней границе
     * @param lowBorderType Тип нижней границы
     * @param topVersion Версия на верхней границе
     * @param topBorderType Тип верхней границы
     */
    public VersionRange(Version lowVersion, BorderType lowBorderType, Version topVersion, BorderType topBorderType) {
        this.lowVersion = lowVersion;
        this.lowBorderType = lowBorderType;
        this.topBorderType = topBorderType;
        this.topVersion = topVersion;
    }

    /**
     * Тип границы диапазона
     */
    public enum BorderType {

        /**
         * Граница включается
         */
        INCLUDE("[", "]"),
        /**
         * Граница исключается
         */
        EXCLUDE("(", ")");

        /**
         * Распознает тип границы
         *
         * @param borderSymbol
         * @return тип границы
         */
        private static BorderType getBorderType(String borderSymbol) {
            if (borderSymbol == null || borderSymbol.isEmpty()) {
                return null;
            } else if (borderSymbol.equals(INCLUDE.lowBorderSymbol)
                    || borderSymbol.equals(INCLUDE.topBorderSymbol)) {
                return INCLUDE;
            } else if (borderSymbol.equals(EXCLUDE.lowBorderSymbol)
                    || borderSymbol.equals(EXCLUDE.topBorderSymbol)) {
                return EXCLUDE;
            } else {
                return null;
            }
        }
        /**
         * Символ нижней границы
         */
        private final String lowBorderSymbol;
        /**
         * Символ верхней границы
         */
        private final String topBorderSymbol;

        /**
         * @param lowBorderSymbol символ, обозначающий нижнюю границу
         * @param topBorderSymbol символ, обозначающий верхнюю границу
         */
        private BorderType(String lowBorderSymbol, String topBorderSymbol) {
            this.lowBorderSymbol = lowBorderSymbol;
            this.topBorderSymbol = topBorderSymbol;
        }

        /**
         * @return Символ нижней границы
         */
        public String getLowBorderSymbol() {
            return lowBorderSymbol;
        }

        /**
         * @return Символ верхней границы
         */
        public String getTopBorderSymbol() {
            return topBorderSymbol;
        }
    }

    /**
     * @return Версия на нижней границе
     */
    public Version getLowVersion() {
        return lowVersion;
    }

    /**
     * @param lowVersion Версия на нижней границе
     */
    public void setLowVersion(Version lowVersion) {
        this.lowVersion = lowVersion;
    }

    /**
     * @return Версия на верхней границе
     */
    public Version getTopVersion() {
        return topVersion;
    }

    /**
     * @param topVersion Версия на верхней границе
     */
    public void setTopVersion(Version topVersion) {
        this.topVersion = topVersion;
    }

    /**
     * @return Тип нижней границы
     */
    public BorderType getLowBorderType() {
        return lowBorderType;
    }

    /**
     * @param lowBorderType Тип нижней границы
     */
    public void setLowBorderType(BorderType lowBorderType) {
        this.lowBorderType = lowBorderType;
    }

    /**
     * @return Тип верхней границы
     */
    public BorderType getTopBorderType() {
        return topBorderType;
    }

    /**
     * @param topBorderType Тип верхней границы
     */
    public void setTopBorderType(BorderType topBorderType) {
        this.topBorderType = topBorderType;
    }

    /**
     * @return строковое представление диапазона версий
     */
    @Override
    public String toString() {
        if (isLatestVersion()) {
            return "";
        }

        if (isFixedVersion()) {
            return "[" + topVersion.toString() + "]";
        }

        if (isSimpleRange()) {
            return lowVersion.toString();
        }

        StringBuilder builder = new StringBuilder();
        if (lowVersion != null) {
            builder.append(lowBorderType.lowBorderSymbol);
            builder.append(lowVersion.toString());
        } else {
            builder.append(BorderType.EXCLUDE.lowBorderSymbol);
        }
        builder.append(BORDER_DELIMETER);
        if (topVersion != null) {
            builder.append(topVersion.toString());
            builder.append(topBorderType.topBorderSymbol);
        } else {
            builder.append(BorderType.EXCLUDE.topBorderSymbol);
        }
        return builder.toString();
    }

    /**
     * Распознает строку и возвращает диапазон версий
     *
     * @param versionRangeString строка диапазона версий
     * @return диапазон версий
     * @throws NugetFormatException некорректный формат версии
     */
    public static VersionRange parse(String versionRangeString) throws NugetFormatException {
        if (versionRangeString == null || versionRangeString.isEmpty()) {
            return new VersionRange();
        }
        if (Version.isValidVersionString(versionRangeString)) {
            Version version = Version.parse(versionRangeString);
            return new VersionRange(version, BorderType.INCLUDE, null, null);
        }

        Pattern fixedVersionPattern = Pattern.compile("^" + FIXED_VERSION_RANGE_PATTERN + "$");
        Matcher fixedVersionMatcher = fixedVersionPattern.matcher(versionRangeString);
        if (fixedVersionMatcher.matches()) {
            Version version = Version.parse(fixedVersionMatcher.group(1));
            return new VersionRange(version, BorderType.INCLUDE, version, BorderType.INCLUDE);
        }

        Pattern pattern = Pattern.compile("^" + FULL_VERSION_RANGE_PATTERN + "$");
        Matcher matcher = pattern.matcher(versionRangeString);
        if (matcher.matches()) {
            Version lowVersion = null;
            BorderType lowBorder = null;
            String lowVersionString = matcher.group("left");
            if (!lowVersionString.isEmpty()) {
                lowVersion = Version.parse(lowVersionString);
                lowBorder = BorderType.getBorderType(matcher.group("leftBorder"));
            }
            Version topVersion = null;
            BorderType topBorder = null;
            String topVersionString = matcher.group("right");
            if (!topVersionString.isEmpty()) {
                topVersion = Version.parse(topVersionString);
                topBorder = BorderType.getBorderType(matcher.group("rightBorder"));
            }
            return new VersionRange(lowVersion, lowBorder, topVersion, topBorder);
        }
        return null;
    }

    /**
     * @param obj объект, с которым производится сравнение
     * @return true, если диапазоны версий идентичны
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final VersionRange other = (VersionRange) obj;
        if (!Objects.equals(this.lowVersion, other.lowVersion)) {
            return false;
        }
        if (this.lowBorderType != other.lowBorderType) {
            return false;
        }
        if (this.topBorderType != other.topBorderType) {
            return false;
        }
        if (!Objects.equals(this.topVersion, other.topVersion)) {
            return false;
        }
        return true;
    }

    /**
     * @return HASH код объекта
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + Objects.hashCode(this.lowVersion);
        hash = 59 * hash + (this.lowBorderType != null ? this.lowBorderType.hashCode() : 0);
        hash = 59 * hash + (this.topBorderType != null ? this.topBorderType.hashCode() : 0);
        hash = 59 * hash + Objects.hashCode(this.topVersion);
        return hash;
    }
}
TOP

Related Classes of ru.aristar.jnuget.files.VersionRange

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.