com.mooltiverse.oss.nyx.version.SemanticVersionPreReleaseIdentifier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java Show documentation
Show all versions of java Show documentation
com.mooltiverse.oss.nyx:java:3.0.6 All the Nyx Java artifacts
The newest version!
/*
* Copyright 2020 Mooltiverse
*
* 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 com.mooltiverse.oss.nyx.version;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
/**
* The specialization of a Prerelease version number as per Semantic Versioning 2.0.0.
*
* This identifier has a peculiar behavior as numeric parts are all parsed as integers. This is also helpful to remove any
* leading zeroes and allows bumping.
*
* Numeric identifiers allow bumping as well as string identifiers. When bumping a string identifier it's assumed that
* there is a numeric identifier after the string and that numeric identifier is the value to be bumped. If the string
* identifier doesn't have a numeric identifier next to it, the numeric identifier is appended, with its number starting
* with the default value.
*
* Examples:
*
* {@code 1.2.3-4} can bump the (anonymous) value at index {@code 0}, resulting in {@code 1.2.3-5}.
*
* {@code 1.2.3-alpha.4} can bump the named value {@code alpha}, resulting in {@code 1.2.3-alpha.5}. This
* is equivalent to bumping the value at index {@code 1} as it was anonymous.
*
* {@code 1.2.3-beta} can bump the named value {@code beta}, resulting in {@code 1.2.3-beta.0} (assuming
* the default start number is {@code 0}). This is equivalent to bumping the value at index {@code 1} as it
* was anonymous.
*
* {@code 1.2.3-beta} can bump the named value {@code gamma}, resulting in {@code 1.2.3-beta.gamma.0}.
*
* Similarly, {@code 1.2.3} can bump value anonymously the value at index {@code 0}, resulting in
* {@code 1.2.3-0} or the named value {@code pre}, resulting in {@code 1.2.3-pre.0}.
*/
class SemanticVersionPreReleaseIdentifier extends CompositeObjectIdentifier {
/**
* Serial version UID to comply with {@link java.io.Serializable}
*/
private static final long serialVersionUID = 1L;
/**
* Builds the pre-release identifier with the given values.
*
* @param children the children of this composite identifier. It can't be {@code null} or contain {@code null} values
*
* @throws NullPointerException if the given list of children is {@code null} or contains {@code null} values
* @throws IllegalArgumentException if the given list of children contains illegal values
*/
private SemanticVersionPreReleaseIdentifier(List children) {
super(DEFAULT_SEPARATOR, children);
}
/**
* Parses the given string and returns the new identifier modelling the single identifiers. Numeric parts are treated
* as integers and must be positive. If a numeric part is preceded by a string part then they both have the same name.
* String values produce identifiers with the same name as their value even when they aren't followed by a numeric part.
*
* @param multipleIdentifiers when {@code true} the given string is parsed as it (may) contain multiple
* identifiers, separated by the default separator, so this method may yield to multiple identifiers.
* When {@code false} the given string is expected to have a single identifier so if the given
* string has multiple identifiers an exception is thrown.
* @param s the string to parse
*
* @return the new identifier instance representing the given string.
*
* @throws NullPointerException if the given string is {@code null}
* @throws IllegalArgumentException if the given string contains illegal characters
*/
static SemanticVersionPreReleaseIdentifier valueOf(boolean multipleIdentifiers, String s) {
if (multipleIdentifiers)
return new SemanticVersionPreReleaseIdentifier(Parser.toIdentifiers(s, DEFAULT_SEPARATOR, UseIntegerIdentifiers.WHEN_POSSIBLE));
else return new SemanticVersionPreReleaseIdentifier(List.of(Parser.toIdentifier(s, UseIntegerIdentifiers.WHEN_POSSIBLE)));
}
/**
* Creates a new identifier instance with the given identifiers. When elements of the given list are {@link Integer}
* instances they are treated as numeric identifiers. All other object types are read using their {@link Object#toString()}
* method. If the string returned by {@link Object#toString()} can be parsed to a positive integer then it is converted
* to a numeric identifier, otherwise it's used as a {@link String}. Items cannot be all {@code null}.
* String representations of objects must not be empty or contain illegal characters while {@link Integer} must be positive.
*
* @param multipleIdentifiers when {@code true} the given string is parsed as it (may) contain multiple
* identifiers, separated by the default separator, so this method may yield to multiple identifiers.
* When {@code false} the given string is expected to have a single identifier so if the given
* string has multiple identifiers an exception is thrown.
* @param items the items to build the identifier with
*
* @return the new identifier instance representing the given string.
*
* @throws NullPointerException if the the isn't at least one parameter that is not {@code null}
* @throws IllegalArgumentException if the given identifiers are not legal instances, if
* numeric values are not positive integers or string values contain illegal characters or are empty.
*/
static SemanticVersionPreReleaseIdentifier valueOf(boolean multipleIdentifiers, Object... items) {
Objects.requireNonNull(items, "Can't build the list of identifiers from a null list");
if (items.length == 0)
throw new IllegalArgumentException("Can't build the list of identifiers from an empty list");
List identifiers = new ArrayList();
for (Object item: items) {
Objects.requireNonNull(item, "Can't build the list of identifiers from a list with null values");
if (multipleIdentifiers)
identifiers.addAll(Parser.toIdentifiers(item.toString(), DEFAULT_SEPARATOR, UseIntegerIdentifiers.WHEN_POSSIBLE));
else identifiers.add(Parser.toIdentifier(item.toString(), UseIntegerIdentifiers.WHEN_POSSIBLE));
}
return new SemanticVersionPreReleaseIdentifier(identifiers);
}
/**
* Returns a new identifier instance with the number identified by the given value bumped.
*
* If this identifier has no identifier that equals the given id, then the returned identifier version has all the
* previous identifiers followed by the two new identifiers: the given string and the following number
* {@code defaultNumber}.
*
* If this identifier already has a string identifier equal to the given id there are two options: if the selected
* identifier already has a numeric value that follows, the returned identifier will have that numeric identifier
* incremented by one; if the selected identifier doesn't have a numeric identifier that follows, a new numeric
* identifiers is added after the string with the initial value {@code defaultNumber}.
*
* If this identifier already has multiple identifiers that equal to the given value then all of them will be bumped.
* In case they have different numeric values (or missing) each occurrence is bumped independently according to the
* above rules.
*
* @param id the selector of the identifier to bump
* @param defaultNumber the default number to use when the given identifier doesn't have a numeric part following
* the string. This is usually set to {@code 0} or {@code 1}. It must be a non-negative integer.
*
* @return a new instance with the number identified by the given value bumped.
*
* @throws NullPointerException if {@code null} is passed
* @throws IllegalArgumentException if the given string is empty, contains illegal characters or represents a number
* or if {@code defaultNumber} is negative.
*/
SemanticVersionPreReleaseIdentifier bump(String id, int defaultNumber) {
Objects.requireNonNull(id, "Can't bump a null identifier");
if (id.isBlank())
throw new IllegalArgumentException("Can't bump an empty identifier");
if (defaultNumber < 0)
throw new IllegalArgumentException(String.format("Can't use a negative number for the default number to bump. '%d' was passed", defaultNumber));
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy