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

com.github.sviperll.maven.plugin.versioning.VersionComponent Maven / Gradle / Ivy

/*
 * Copyright 2015 Victor Nazarov .
 */
package com.github.sviperll.maven.plugin.versioning;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
 * @author Victor Nazarov <[email protected]>
 */
abstract class VersionComponent implements Comparable {

    static VersionComponent numbers(VersionSchema schema, int[] numbers) {
        return new NumbersVersionComponent(schema, numbers);
    }

    static VersionComponent suffix(VersionSchema schema, String suffix) {
        boolean isPredecessorSuffix = schema.isPredecessorSuffix(suffix);
        boolean isFinalComponent = schema.isFinalSuffix(suffix);
        return new SuffixVersionComponent(schema, suffix, isPredecessorSuffix, isFinalComponent);
    }

    static VersionComponent finalVersionComponent(VersionSchema schema) {
        return suffix(schema, schema.getCanonicalFinalSuffix());
    }

    private final VersionSchema schema;

    private VersionComponent(VersionSchema schema) {
        this.schema = schema;
    }

    abstract boolean isNumbers();
    abstract boolean isSuffix();
    abstract boolean isPredecessorSuffix();
    abstract boolean isFinalComponent();
    abstract int[] getNumbers();
    abstract String getSuffixString();

    VersionSchema schema() {
        return schema;
    }

    boolean allowsMoreComponents() {
        return !isFinalComponent();
    }

    VersionComponentInstance withTheSameSeparator(VersionComponentInstance component) {
        return component.withTheSameSeparator(this);
    }

    List nextNumbersComponentVariants(int minDepth, int maxDepth) {
        return nextNumbersComponentVariants(minDepth, maxDepth, false);
    }
    private List nextNumbersComponentVariants(int minDepth, int maxDepth, boolean goesDeeper) {
        List result = new ArrayList();
        int[] numbers = getNumbers();
        int reachableDepth = goesDeeper ? maxDepth : Math.min(numbers.length, maxDepth);
        for (int depth = minDepth; depth <= reachableDepth; depth++) {
            for (int i = 0; i < depth; i++) {
                int[] variant = Arrays.copyOf(numbers, depth);
                variant[i] = i < numbers.length ? numbers[i] + 1 : 1;
                for (int j = i + 1; j < depth; j++)
                    variant[j] = 0;
                result.add(VersionComponent.numbers(schema, variant));
            }
        }
        return result;
    }

    List deepNextNumbersComponentVariants(int minDepth, int maxDepth) {
        return nextNumbersComponentVariants(minDepth, maxDepth, true);
    }

    String defaultSeparator() {
        return isSuffix() && getCanonicalSuffixString().isEmpty() ? "" : "-";
    }

    String getCanonicalSuffixString() {
        return schema.getCanonicalSuffix(getSuffixString());
    }

    boolean isLessThanOrEqualsToFinal() {
        return compareTo(schema.finalVersionComponent()) <= 0;
    }

    @Override
    public final int compareTo(final VersionComponent that) {
        if (this.schema != that.schema)
            throw new IllegalStateException("Comparison of version component with different suffix schema");
        if (this.isPredecessorSuffix()) {
            if (!that.isPredecessorSuffix())
                return -1;
            else {
                return this.schema.compareSuffixes(this.getSuffixString(), that.getSuffixString());
            }
        } else if (this.isFinalComponent()) {
            if (that.isPredecessorSuffix())
                return 1;
            else if (that.isFinalComponent())
                return 0;
            else
                return -1;
        } else if (this.isNumbers()) {
            if (that.isPredecessorSuffix() || that.isFinalComponent())
                return 1;
            else if (that.isNumbers()) {
                int[] thisNumbers = this.getNumbers();
                int[] thatNumbers = that.getNumbers();
                for (int i = 0; ; i++) {
                    if (i >= thisNumbers.length && i >= thatNumbers.length)
                        break;
                    else if (i >= thisNumbers.length)
                        return -1;
                    else if (i >= thatNumbers.length)
                        return 1;
                    else {
                        int thisElement = thisNumbers[i];
                        int thatElement = thatNumbers[i];
                        int result = thisElement < thatElement ? -1 : (thisElement == thatElement ? 0 : 1);
                        if (result != 0)
                            return result;
                    }
                }
                return 0;
            } else
                return -1;
            
        } else {
            if (that.isPredecessorSuffix() || that.isFinalComponent() || that.isNumbers())
                return 1;
            else
                return schema.compareSuffixes(this.getSuffixString(), that.getSuffixString());
        }
    }

    @Override
    public final int hashCode() {
        if (isNumbers()) {
            int[] numbers = getNumbers();
            int result = 6;
            for (int i = 0; i < numbers.length; i++) {
                result = result * 37 + numbers[i];
            }
            return result;
        } else {
            if (isPredecessorSuffix())
                return (1 * 37 + schema.hashCode()) * 37 + getCanonicalSuffixString().hashCode();
            else if (isFinalComponent())
                return 2 * 37 + schema.hashCode();
            else
                return (3 * 37 + schema.hashCode()) * 37 + getCanonicalSuffixString().hashCode();
        }
    }

    @Override
    public final String toString() {
        if (isNumbers()) {
            StringBuilder builder = new StringBuilder();
            int[] numbers = getNumbers();
            if (numbers.length > 0) {
                builder.append(numbers[0]);
                for (int i = 1; i < numbers.length; i++) {
                    builder.append('.');
                    builder.append(numbers[i]);
                }
            }
            return builder.toString();
        } else {
            return getSuffixString();
        }
    }

    @Override
    public final boolean equals(Object thatObject) {
        if (this == thatObject)
            return true;
        else if (!(thatObject instanceof VersionComponent))
            return false;
        else {
            VersionComponent that = (VersionComponent)thatObject;
            return this.compareTo(that) == 0;
        }
    }

    private static class SuffixVersionComponent extends VersionComponent {

        private final boolean isPredecessorSuffix;
        private final boolean isFinalComponent;
        private final String suffix;

        public SuffixVersionComponent(VersionSchema schema, String suffix, boolean isPredecessorSuffix, boolean isFinalComponent) {
            super(schema);
            this.isPredecessorSuffix = isPredecessorSuffix;
            this.isFinalComponent = isFinalComponent;
            this.suffix = suffix;
        }

        @Override
        boolean isNumbers() {
            return false;
        }

        @Override
        boolean isSuffix() {
            return true;
        }

        @Override
        boolean isPredecessorSuffix() {
            return isPredecessorSuffix;
        }

        @Override
        boolean isFinalComponent() {
            return isFinalComponent;
        }
                            
        @Override
        int[] getNumbers() {
            throw new UnsupportedOperationException();
        }

        @Override
        String getSuffixString() {
            return suffix;
        }
    }

    private static class NumbersVersionComponent extends VersionComponent {

        private final int[] numbers;

        public NumbersVersionComponent(VersionSchema schema, int[] numbers) {
            super(schema);
            this.numbers = numbers;
        }

        @Override
        boolean isNumbers() {
            return true;
        }

        @Override
        boolean isSuffix() {
            return false;
        }

        @Override
        boolean isPredecessorSuffix() {
            return false;
        }

        @Override
        boolean isFinalComponent() {
            return false;
        }

        @Override
        int[] getNumbers() {
            return numbers;
        }

        @Override
        String getSuffixString() {
            throw new UnsupportedOperationException();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy