de.caff.version

## Class SemVer

- java.lang.Object
- - de.caff.version.SemVer

- All Implemented Interfaces:
    java.lang.Comparable<SemVer>

      public class SemVer
      extends java.lang.Object
      implements java.lang.Comparable<SemVer>

  Semantic version.

  This follows Semantic Versioning 2.0.0.

  Please note that camparison and hash/equals are not always in sync what they consider equal. While comparison ignores `the build metadata`, `equals(Object)` and `hashCode()` take it into account. Use the `compareTo(SemVer, Comparator)` with a string comparator which considers different strings different (e.g. `String.compareTo(String)`) to get a way of sorting consistent to hash/equals. Or use `equalsIgnoreBuild(SemVer)` which ignrores the build number.

  This class is deliberately not serializable. Use an intermediate string representation instead.

  This class is immutable.

  Since:
    December 24, 2021
  Author:
    Rammi

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `SemVer.Prerelease` Prerelease indicator.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `(package private) static java.util.regex.Pattern` | `SEP_DOT` Separator pattern for splitting at dots.
    `static SemVer` | `VERSION_0_0_1`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `SemVer(int major, int minor, int patch)` Constructor.
    `SemVer(int major, int minor, int patch, SemVer.Prerelease prerelease)` Constructor including prerelease data.
    `SemVer(int major, int minor, int patch, SemVer.Prerelease prerelease, java.lang.String buildString)` Constructor.
    `SemVer(int major, int minor, int patch, java.lang.String buildString)` Constructor including build metadata.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `int` | `compareTo(SemVer o)` Compare this semantic version with another.
    `int` | `compareTo(SemVer otherVersion, java.util.Comparator<? super Indexable<java.lang.String>> buildCompare)` Compare this with another version, but don't ignore the build metadata.
    `boolean` | `equals(java.lang.Object o)`
    `boolean` | `equalsIgnoreBuild(SemVer other)` Equality check ignoring the build metadata.
    `Indexable<java.lang.String>` | `getBuildMetaData()` Get the build metadata.
    `java.lang.String` | `getBuildString()` Get the build metadata as one string.
    `int` | `getMajor()` Get the major number.
    `int` | `getMinor()` Get the minor number.
    `int` | `getPatch()` Get the patch number.
    `SemVer.Prerelease` | `getPrerelease()` Get the prerelease number.
    `int` | `hashCode()`
    `int` | `hashCodeIgnoreBuild()` Get a hash code ignoring the build metadata.
    `boolean` | `isNewerThan(SemVer otherVersion)` Is this version newer than the other version?
    `SemVer` | `nextMajor()` Get the next semantic version number when increasing the major version.
    `SemVer` | `nextMinor()` Get the next semantic version number when increasing the minor version.
    `SemVer` | `nextPatch()` Get the next semantic version number when increasing the patch version.
    `static SemVer` | `parse(java.lang.String versionString)` Parse a semantic version.
    `java.lang.String` | `toString()`
    `SemVer` | `withBuild(Indexable<java.lang.String> buildMetaData)` Get the same version as this. but with different build metadata.
    `SemVer` | `withBuildString(java.lang.String build)` Get the same version as this. but with different build metadata.
    `SemVer` | `withNoBuild()` Get the same version as this, but with no build metadata.
    `SemVer` | `withPrerelease(SemVer.Prerelease prerelease)` Get the same version as this. but with a different prerelease.
    `SemVer` | `withPrereleaseFromString(java.lang.String prerelease)` Get the same version as this, but with a different prerelease.

    - ### Methods inherited from class java.lang.Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### SEP_DOT

          static final java.util.regex.Pattern SEP_DOT

      Separator pattern for splitting at dots.

    - #### VERSION_0_0_1

          public static final SemVer VERSION_0_0_1

  - ### Constructor Detail

    - #### SemVer

          public SemVer(int major,
                        int minor,
                        int patch)

      Constructor. This will create a regular semantic version with neither prerelease not build metadata.
      Parameters:
        `major` - non-negative major version
        `minor` - non-negative minor version
        `patch` - non-negative patch version
      Throws:
        `java.lang.IllegalArgumentException` - if any version number is negative

    - #### SemVer

          public SemVer(int major,
                        int minor,
                        int patch,
                        @Nullable
                        SemVer.Prerelease prerelease)

      Constructor including prerelease data.
      Parameters:
        `major` - non-negative major version
        `minor` - non-negative minor version
        `patch` - non-negative patch version
        `prerelease` - prerelease data, none if `null`
      Throws:
        `java.lang.IllegalArgumentException` - if any version number is negative

    - #### SemVer

          public SemVer(int major,
                        int minor,
                        int patch,
                        @Nullable
                        java.lang.String buildString)

      Constructor including build metadata.
      Parameters:
        `major` - non-negative major version
        `minor` - non-negative minor version
        `patch` - non-negative patch version
        `buildString` - build metadata, may only contain ASCII letters, ASCII digits and both '.' and '-'
      Throws:
        `java.lang.IllegalArgumentException` - if any version number is negative, or `build` contains illegal characters

    - #### SemVer

          public SemVer(int major,
                        int minor,
                        int patch,
                        @Nullable
                        SemVer.Prerelease prerelease,
                        @Nullable
                        java.lang.String buildString)

      Constructor.
      Parameters:
        `major` - non-negative major version
        `minor` - non-negative minor version
        `patch` - non-negative patch version
        `prerelease` - prerelease data, none if `null`
        `buildString` - build metadata, may only contain ASCII letters, ASCII digits and both '.' and '-'

  - ### Method Detail

    - #### getMajor

          public int getMajor()

      Get the major number. The major number is most significant and is usually changed. Version `0` is considered unstable, any changes might occur in the versioned API. Major number is increased when there are incompatible API changes.
      Returns:
        positive major number, or `0` indicating an unstable initial development version

    - #### getMinor

          public int getMinor()

      Get the minor number. The minor number is increased when there are API additions or new deprecation markings, but the API stays backward-compatible.
      Returns:
        minor number, positive or `0`

    - #### getPatch

          public int getPatch()

      Get the patch number. The patch number is increased on internal bugfixes, when not API changes are implemented.
      Returns:
        patch number

    - #### getPrerelease

          @Nullable
          public SemVer.Prerelease getPrerelease()

      Get the prerelease number. Any semantic version with a non-null prerelease is before the same version with no prerelease.
      Returns:
        prerelease, or `null` if this is no prerelease

    - #### getBuildMetaData

          @NotNull
          public Indexable<java.lang.String> getBuildMetaData()

      Get the build metadata. The build metadata is related to, but not part of the semantic version. It has no influence on sorting.
      Returns:
        build metadata, empty if no metadata is attached
      See Also:
        `getBuildString()`

    - #### getBuildString

          @Nullable
          public java.lang.String getBuildString()

      Get the build metadata as one string. The build metadata is related to, but not part of the semantic version. It has no influence on sorting.
      Returns:
        build metadata, or `null` if no metadata is attached
      See Also:
        `getBuildMetaData()`

    - #### nextMajor

          @NotNull
          public SemVer nextMajor()

      Get the next semantic version number when increasing the major version.
      Returns:
        next major version, with zero minor and zero patch version, and neither prerelease indicator nor build metadata
      Throws:
        `java.lang.ArithmeticException` - if the increasing would overflow an integer

    - #### nextMinor

          @NotNull
          public SemVer nextMinor()

      Get the next semantic version number when increasing the minor version.
      Returns:
        next minor version, with same major version and zero patch version, and neither prerelease indicator nor build metadata
      Throws:
        `java.lang.ArithmeticException` - if the increasing would overflow an integer

    - #### nextPatch

          @NotNull
          public SemVer nextPatch()

      Get the next semantic version number when increasing the patch version.
      Returns:
        next patch version, with same major and minor version, and neither prerelease indicator nor build metadata
      Throws:
        `java.lang.ArithmeticException` - if the increasing would overflow an integer

    - #### withPrerelease

          @NotNull
          public SemVer withPrerelease(@Nullable
                                                SemVer.Prerelease prerelease)

      Get the same version as this. but with a different prerelease.
      Parameters:
        `prerelease` - prerelease
      Returns:
        this version with the given prerelease, same major, minor and patch version, but no build metadata

    - #### withPrereleaseFromString

          @NotNull
          public SemVer withPrereleaseFromString(@Nullable
                                                          java.lang.String prerelease)

      Get the same version as this, but with a different prerelease.
      Parameters:
        `prerelease` - prerelease as string
      Returns:
        this version with the given prerelease

    - #### withNoBuild

          @NotNull
          public SemVer withNoBuild()

      Get the same version as this, but with no build metadata.
      Returns:
        this version without the build metadata

    - #### withBuildString

          @NotNull
          public SemVer withBuildString(@NotNull
                                                 java.lang.String build)

      Get the same version as this. but with different build metadata.
      Parameters:
        `build` - build metadata, must contain only ASCII letters, digits, and both `'.'` and `'-'`
      Returns:
        this version with the given build metadata, and same major, minor and patch version, and the same prerelease
      Throws:
        `java.lang.IllegalArgumentException` - if `build` contains illegal characters

    - #### withBuild

          public SemVer withBuild(@NotNull
                                  Indexable<java.lang.String> buildMetaData)

      Get the same version as this. but with different build metadata.
      Parameters:
        `buildMetaData` - build metadata, must contain only ASCII letters, digits, and both `'.'` and `'-'`
      Returns:
        this version with the given build metadata, and same major, minor and patch version, and the same prerelease
      Throws:
        `java.lang.IllegalArgumentException` - if `build` contains illegal characters

    - #### equals

          public boolean equals(java.lang.Object o)

      Overrides:
        `equals` in class `java.lang.Object`

    - #### equalsIgnoreBuild

          public boolean equalsIgnoreBuild(SemVer other)

      Equality check ignoring the build metadata. This is similar to `equals(Object)`, but does not care for the `build metadata`.
      Parameters:
        `other` - other version
      Returns:
        `true` if this and the other version have the same major, minor and patch version, and same prerelease data
        `false` otherwise

    - #### hashCode

          public int hashCode()

      Overrides:
        `hashCode` in class `java.lang.Object`

    - #### hashCodeIgnoreBuild

          public int hashCodeIgnoreBuild()

      Get a hash code ignoring the build metadata. This is similar to `hashCode()`, but does not use the `build metadata`.
      Returns:
        hash code

    - #### compareTo

          public int compareTo(@NotNull
                               SemVer o)

      Compare this semantic version with another. According to the definition this completely ignores the `build metadata`. If you need sorting which includes it use `compareTo(SemVer, Comparator)` instead.
      Specified by:
        `compareTo` in interface `java.lang.Comparable<SemVer>`
      Parameters:
        `o` - other semantic version
      Returns:
        negative if `this < o`,
        positive if `this > o`, or
        `0` if (@code this == o}

    - #### compareTo

          public int compareTo(@NotNull
                               SemVer otherVersion,
                               @NotNull
                               java.util.Comparator<? super Indexable<java.lang.String>> buildCompare)

      Compare this with another version, but don't ignore the build metadata. The `compare method` ignores the `build metadata`, while this falls back to compare it if all other properties are equal.
      Parameters:
        `otherVersion` - other version to compare
        `buildCompare` - comparator called if all other properties are equal, will not receive `null` values but empty strings instead
      Returns:
        negative if `this < o`,
        positive if `this > o`, or
        `0` if (@code this == o}

    - #### isNewerThan

          public boolean isNewerThan(@NotNull
                                     SemVer otherVersion)

      Is this version newer than the other version?
      Parameters:
        `otherVersion` - other version
      Returns:
        `true` if this version is newer, `false` if this is older or the same version

    - #### toString

          public java.lang.String toString()

      Overrides:
        `toString` in class `java.lang.Object`

    - #### parse

          @Nullable
          public static SemVer parse(@NotNull
                                               java.lang.String versionString)

      Parse a semantic version.
      Parameters:
        `versionString` - string representation of a semantic version
      Returns:
        semantic version, or `null` if `versionString` does not represent a valid semantic version