diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/versioning/FourNumberVersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/FourNumberVersioningSystem.java
new file mode 100644
index 00000000..95d22d57
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/FourNumberVersioningSystem.java
@@ -0,0 +1,157 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.versioning;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+
+/**
+ * Represents a four-numbered versioning system, where an application or work is versioning by four arbitrary numbers.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class FourNumberVersioningSystem implements VersioningSystem {
+ /**
+ * Contains the 1. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 1. number vector.
+ *
+ * @return 1. number vector
+ * @since 1-alpha1
+ */
+ private final int number1;
+
+ /**
+ * Contains the 2. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 2. number vector.
+ *
+ * @return 2. number vector
+ * @since 1-alpha1
+ */
+ private final int number2;
+
+ /**
+ * Contains the 3. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 3. number vector.
+ *
+ * @return 3. number vector
+ * @since 1-alpha1
+ */
+ private final int number3;
+
+ /**
+ * Contains the 4. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 4. number vector.
+ *
+ * @return 4. number vector
+ * @since 1-alpha1
+ */
+ private final int number4;
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "n4";
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versionString version string to parse
+ * @throws InvalidVersionStringException if the version string is invalid
+ */
+ public FourNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
+ String[] separatorList = new String[]{ ".", "-" };
+ String separator = Miscellaneous.getSeparator(versionString, separatorList, 3);
+
+ // Escape separator or throw error if invalid
+ switch (separator) {
+ case "." -> separator = "\\.";
+ case null -> throw new InvalidVersionStringException(this, versionString, "No matching separator could be found. Required are either three dots ('.') or hyphens ('-').");
+ default -> {}
+ }
+
+ // Split the version string at every separator
+ String[] versionStringSplit = versionString.split(separator);
+
+ // Convert to integers
+ try {
+ this.number1 = Integer.parseUnsignedInt(versionStringSplit[0]);
+ this.number2 = Integer.parseUnsignedInt(versionStringSplit[1]);
+ this.number3 = Integer.parseUnsignedInt(versionStringSplit[2]);
+ this.number4 = Integer.parseUnsignedInt(versionStringSplit[3]);
+ } catch (NumberFormatException exception) {
+ throw new InvalidVersionStringException(this, versionString, "Failed converting one of the vectors to an integer.", exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Range(from = 0, to = 2)
+ @Override
+ public int compare(@NotNull VersioningSystem versionInterface) throws IncompatibleVersioningSystemException {
+ if (versionInterface instanceof FourNumberVersioningSystem version) {
+ if (version.getNumber1() < number1)
+ return 0;
+ if (version.getNumber1() > number1)
+ return 2;
+
+ if (version.getNumber2() < number2)
+ return 0;
+ if (version.getNumber2() > number2)
+ return 2;
+
+ if (version.getNumber3() < number3)
+ return 0;
+ if (version.getNumber3() > number3)
+ return 2;
+
+ if (version.getNumber4() < number4)
+ return 0;
+ if (version.getNumber4() > number4)
+ return 2;
+
+ return 1;
+
+ } else
+ throw new IncompatibleVersioningSystemException(this, versionInterface);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/versioning/SemanticVersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/SemanticVersioningSystem.java
new file mode 100644
index 00000000..e90e03eb
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/SemanticVersioningSystem.java
@@ -0,0 +1,226 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.versioning;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Range;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represents the semantic versioning system (version 2.0.0), where an application or work is versioning by a MAJOR version, a MINOR version, a PATCH version and optionally, a pre-release vector and a build number.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class SemanticVersioningSystem implements VersioningSystem {
+ /**
+ * Contains the MAJOR vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the MAJOR vector.
+ *
+ * @return MAJOR vector
+ * @since 1-alpha1
+ */
+ private final int major;
+
+ /**
+ * Contains the MINOR vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the MINOR vector.
+ *
+ * @return MINOR vector
+ * @since 1-alpha1
+ */
+ private final int minor;
+
+ /**
+ * Contains the PATCH vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the PATCH vector.
+ *
+ * @return PATCH vector
+ * @since 1-alpha1
+ */
+ private final int patch;
+
+ /**
+ * Contains the PRERELEASE vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the PRERELEASE vector.
+ *
+ * @return PRERELEASE vector
+ * @since 1-alpha1
+ */
+ @Nullable
+ private final String prerelease;
+
+ /**
+ * Contains the BUILD vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the BUILD vector.
+ *
+ * @return BUILD vector
+ * @since 1-alpha1
+ */
+ private final int build;
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "Semantic";
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versionString version string to parse
+ * @throws InvalidVersionStringException if the version string is invalid
+ */
+ public SemanticVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
+ String[] separatorList = new String[]{ "." };
+ String separator = Miscellaneous.getSeparator(versionString, separatorList, 2);
+
+ // Escape separator or throw error if invalid
+ switch (separator) {
+ case "." -> separator = "\\.";
+ case null -> throw new InvalidVersionStringException(this, versionString, "No matching separator could be found. Required are two dots ('.').");
+ default -> {}
+ }
+
+ // Split the version string at every separator
+ List versionStringSplit = new ArrayList<>(Arrays.stream(versionString.split(separator)).toList());
+
+ // Get pre-release and build vectors
+ String build = null;
+ String prerelease = null;
+ if (versionStringSplit.get(2).contains("+")) { // Build vector
+ int position = versionStringSplit.get(2).indexOf("+");
+ build = versionStringSplit.get(2).substring(position + 1);
+ versionStringSplit.set(2, versionStringSplit.get(2).substring(0, position));
+ }
+ if (versionStringSplit.get(2).contains("-")) {
+ int position = versionStringSplit.get(2).indexOf("-");
+ prerelease = versionStringSplit.get(2).substring(position + 1);
+ versionStringSplit.set(2, versionStringSplit.get(2).substring(0, position));
+ }
+
+ // Convert to integers
+ try {
+ this.major = Integer.parseUnsignedInt(versionStringSplit.get(0));
+ this.minor = Integer.parseUnsignedInt(versionStringSplit.get(1));
+ this.patch = Integer.parseUnsignedInt(versionStringSplit.get(2));
+ this.prerelease = prerelease;
+ if (build == null)
+ this.build = 0;
+ else
+ this.build = Integer.parseUnsignedInt(build);
+ } catch (NumberFormatException exception) {
+ throw new InvalidVersionStringException(this, versionString, "Failed converting one of the vectors to an integer.", exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Range(from = 0, to = 2)
+ @Override
+ public int compare(@NotNull VersioningSystem versionInterface) throws IncompatibleVersioningSystemException {
+ if (versionInterface instanceof SemanticVersioningSystem version) {
+ if (version.getMajor() < major)
+ return 0;
+ if (version.getMajor() > major)
+ return 2;
+
+ if (version.getMinor() < minor)
+ return 0;
+ if (version.getMinor() > minor)
+ return 2;
+
+ if (version.getPatch() < patch)
+ return 0;
+ if (version.getPatch() > patch)
+ return 2;
+
+ if (version.getPrerelease() == null && prerelease != null)
+ return 2;
+ else if (version.getPrerelease() != null && prerelease == null)
+ return 0;
+ else if (version.getPrerelease() != null)
+ switch (prerelease) {
+ case "alpha" -> {
+ switch (version.getPrerelease()) {
+ case "beta", "releasecandidate", "release-candidate", "rc" -> {
+ return 2;
+ }
+ }
+ }
+ case "beta" -> {
+ switch (version.getPrerelease()) {
+ case "alpha" -> {
+ return 0;
+ }
+ case "releasecandidate", "release-candidate", "rc" -> {
+ return 2;
+ }
+ }
+ }
+ case "releasecandidate", "release-candidate", "rc" -> {
+ switch (version.getPrerelease()) {
+ case "alpha", "beta" -> {
+ return 0;
+ }
+ }
+ }
+ }
+
+ if (version.getBuild() < build)
+ return 0;
+ if (version.getBuild() > build)
+ return 2;
+
+ return 1;
+
+ } else
+ throw new IncompatibleVersioningSystemException(this, versionInterface);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/versioning/StarOpenSourceVersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/StarOpenSourceVersioningSystem.java
new file mode 100644
index 00000000..1b92c6db
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/StarOpenSourceVersioningSystem.java
@@ -0,0 +1,266 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.versioning;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.base.types.VersionType;
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Range;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Represents the StarOpenSource versioning system (version 2), where an application or work is versioning by a VERSION vector, a TYPE version type, a TYPERELEASE vector and optionally, a fork vector and a companion vector.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class StarOpenSourceVersioningSystem implements VersioningSystem {
+ /**
+ * Contains the VERSION vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the VERSION vector.
+ *
+ * @return VERSION vector
+ * @since 1-alpha1
+ */
+ private final int version;
+
+ /**
+ * Contains the TYPE vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the TYPE vector.
+ *
+ * @return TYPE vector
+ * @since 1-alpha1
+ */
+ private final VersionType type;
+
+ /**
+ * Contains the TYPERELEASE vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the TYPERELEASE vector.
+ *
+ * @return TYPERELEASE vector
+ * @since 1-alpha1
+ */
+ private final int typerelease;
+
+ /**
+ * Contains the COMPANION vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the COMPANION vector.
+ *
+ * @return COMPANION vector
+ * @since 1-alpha1
+ */
+ @Nullable
+ private final String companion;
+
+ /**
+ * Contains the FORK vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the FORK vector.
+ *
+ * @return FORK vector
+ * @since 1-alpha1
+ */
+ private final String fork;
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "StarOpenSource";
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versionString version string to parse
+ * @throws InvalidVersionStringException if the version string is invalid
+ */
+ public StarOpenSourceVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
+ // Split the version string at every separator
+ StringBuilder charSequence = new StringBuilder();
+ /*
+ * 0 = 'v'
+ * 1 = version vector
+ * 3 = type vector
+ * 4 = typerelease vector
+ * 5 = companion vector
+ * 6 = fork vector
+ */
+ int parsingId = 0;
+ List versionStringSplit = new ArrayList<>();
+ String companion = null;
+ String fork = null;
+
+ // Iterate through all chraracters
+ for (Character character : versionString.toCharArray()) {
+ switch (parsingId) {
+ case 0 -> { // 'v' character
+ if (character != 'v')
+ throw new InvalidVersionStringException(this, versionString, "Does not start with the character 'v'");
+ parsingId++;
+ }
+ case 1 -> { // Version vector
+ if (character == '-') {
+ versionStringSplit.add(charSequence.toString());
+ charSequence = new StringBuilder();
+ parsingId++;
+ } else
+ charSequence.append(character);
+ }
+ case 2 -> { // Type vector
+ charSequence.append(character);
+
+ if (charSequence.toString().equals("alpha") || charSequence.toString().equals("beta") || charSequence.toString().equals("release")) {
+ versionStringSplit.add(charSequence.toString());
+ charSequence = new StringBuilder();
+ parsingId++;
+ } else if (versionStringSplit.size() == 2 && versionStringSplit.get(1).contains("releasec") && charSequence.toString().equals("andidate")) {
+ versionStringSplit.set(1, versionStringSplit.get(1) + charSequence);
+ charSequence = new StringBuilder();
+ parsingId++;
+ }
+ }
+ case 3 -> { // Typerelease vector
+ if (character == '-' || character == '+') {
+ versionStringSplit.add(charSequence.toString());
+ charSequence = new StringBuilder();
+ parsingId++;
+ if (character == '+')
+ parsingId++;
+ } else
+ if (character == 'c' && versionStringSplit.get(1).equals("release")) {
+ versionStringSplit.set(1, versionStringSplit.get(1) + character);
+ parsingId--;
+ } else
+ charSequence.append(character);
+ }
+ case 4 -> { // Fork vector
+ if (character == '+') {
+ fork = charSequence.toString();
+ charSequence = new StringBuilder();
+ parsingId++;
+ } else
+ charSequence.append(character);
+ }
+ case 5 -> // Companion vector
+ charSequence.append(character);
+ }
+ }
+
+ switch (parsingId) {
+ case 0, 1, 2 -> throw new InvalidVersionStringException(this, versionString, "Required vectors not found");
+ case 3 -> {
+ if (charSequence.isEmpty())
+ throw new InvalidVersionStringException(this, versionString, "Required vectors not found");
+ else {
+ if (versionStringSplit.size() == 2 && versionStringSplit.get(1).contains("releasec") && charSequence.toString().equals("andidate")) {
+ versionStringSplit.set(1, versionStringSplit.get(1) + charSequence);
+ } else
+ versionStringSplit.add(charSequence.toString());
+ }
+ }
+ case 5 -> {
+ if (charSequence.isEmpty())
+ throw new InvalidVersionStringException(this, versionString, "Fork vector not found");
+ else
+ fork = charSequence.toString();
+ }
+ case 6 -> {
+ if (charSequence.isEmpty())
+ throw new InvalidVersionStringException(this, versionString, "Companion vector not found");
+ else
+ companion = charSequence.toString();
+ }
+ }
+
+ // Rewrite type
+ if (versionStringSplit.get(1).equals("releasecandidate"))
+ versionStringSplit.set(1, "RELEASE_CANDIDATE");
+ else
+ versionStringSplit.set(1, versionStringSplit.get(1).toUpperCase(Locale.ROOT));
+
+
+ // Update variables
+ try {
+ this.version = Integer.parseUnsignedInt(versionStringSplit.get(0));
+ this.type = VersionType.valueOf(versionStringSplit.get(1));
+ this.typerelease = Integer.parseUnsignedInt(versionStringSplit.get(2));
+ this.companion = companion;
+ this.fork = fork;
+ } catch (NumberFormatException exception) {
+ throw new InvalidVersionStringException(this, versionString, "Failed converting one of the vectors to an integer.", exception);
+ }
+
+ if (this.version == 0)
+ throw new InvalidVersionStringException(this, versionString, "The version vector must start at 1.");
+ }
+
+ /** {@inheritDoc} */
+ @Range(from = 0, to = 2)
+ @Override
+ public int compare(@NotNull VersioningSystem versionInterface) throws IncompatibleVersioningSystemException {
+ if (versionInterface instanceof StarOpenSourceVersioningSystem versionCompare) {
+ if (versionCompare.getVersion() < this.version)
+ return 0;
+ if (versionCompare.getVersion() > this.version)
+ return 2;
+
+ if (type.compareTo(versionCompare.getType()) > 0)
+ return 0;
+ if (type.compareTo(versionCompare.getType()) < 0)
+ return 2;
+
+ if (versionCompare.getTyperelease() < typerelease)
+ return 0;
+ if (versionCompare.getTyperelease() > typerelease)
+ return 2;
+
+ return 1;
+
+ } else
+ throw new IncompatibleVersioningSystemException(this, versionInterface);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/versioning/ThreeNumberVersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/ThreeNumberVersioningSystem.java
new file mode 100644
index 00000000..fa1cfe7e
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/ThreeNumberVersioningSystem.java
@@ -0,0 +1,138 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.versioning;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+
+/**
+ * Represents a three-numbered versioning system, where an application or work is versioning by three arbitrary numbers.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class ThreeNumberVersioningSystem implements VersioningSystem {
+ /**
+ * Contains the 1. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 1. number vector.
+ *
+ * @return 1. number vector
+ * @since 1-alpha1
+ */
+ private final int number1;
+
+ /**
+ * Contains the 2. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 2. number vector.
+ *
+ * @return 2. number vector
+ * @since 1-alpha1
+ */
+ private final int number2;
+
+ /**
+ * Contains the 3. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 3. number vector.
+ *
+ * @return 3. number vector
+ * @since 1-alpha1
+ */
+ private final int number3;
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "n3";
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versionString version string to parse
+ * @throws InvalidVersionStringException if the version string is invalid
+ */
+ public ThreeNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
+ String[] separatorList = new String[]{ ".", "-" };
+ String separator = Miscellaneous.getSeparator(versionString, separatorList, 2);
+
+ // Escape separator or throw error if invalid
+ switch (separator) {
+ case "." -> separator = "\\.";
+ case null -> throw new InvalidVersionStringException(this, versionString, "No matching separator could be found. Required are either two dots ('.') or hyphens ('-').");
+ default -> {}
+ }
+
+ // Split the version string at every separator
+ String[] versionStringSplit = versionString.split(separator);
+
+ // Convert to integers
+ try {
+ this.number1 = Integer.parseUnsignedInt(versionStringSplit[0]);
+ this.number2 = Integer.parseUnsignedInt(versionStringSplit[1]);
+ this.number3 = Integer.parseUnsignedInt(versionStringSplit[2]);
+ } catch (NumberFormatException exception) {
+ throw new InvalidVersionStringException(this, versionString, "Failed converting one of the vectors to an integer.", exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Range(from = 0, to = 2)
+ @Override
+ public int compare(@NotNull VersioningSystem versionInterface) throws IncompatibleVersioningSystemException {
+ if (versionInterface instanceof ThreeNumberVersioningSystem version) {
+ if (version.getNumber1() < number1)
+ return 0;
+ if (version.getNumber1() > number1)
+ return 2;
+
+ if (version.getNumber2() < number2)
+ return 0;
+ if (version.getNumber2() > number2)
+ return 2;
+
+ if (version.getNumber3() < number3)
+ return 0;
+ if (version.getNumber3() > number3)
+ return 2;
+
+ return 1;
+
+ } else
+ throw new IncompatibleVersioningSystemException(this, versionInterface);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/versioning/TwoNumberVersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/TwoNumberVersioningSystem.java
new file mode 100644
index 00000000..da87d6b7
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/versioning/TwoNumberVersioningSystem.java
@@ -0,0 +1,119 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.versioning;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+
+/**
+ * Represents a two-numbered versioning system, where an application or work is versioning by two arbitrary numbers.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class TwoNumberVersioningSystem implements VersioningSystem {
+ /**
+ * Contains the 1. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 1. number vector.
+ *
+ * @return 1. number vector
+ * @since 1-alpha1
+ */
+ private final int number1;
+
+ /**
+ * Contains the 2. number vector.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the 2. number vector.
+ *
+ * @return 2. number vector
+ * @since 1-alpha1
+ */
+ private final int number2;
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "n2";
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versionString version string to parse
+ * @throws InvalidVersionStringException if the version string is invalid
+ */
+ public TwoNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
+ String[] separatorList = new String[]{ ".", "-" };
+ String separator = Miscellaneous.getSeparator(versionString, separatorList, 1);
+
+ // Escape separator or throw error if invalid
+ switch (separator) {
+ case "." -> separator = "\\.";
+ case null -> throw new InvalidVersionStringException(this, versionString, "No matching separator could be found. Required are either one dot ('.') or hyphen ('-').");
+ default -> {}
+ }
+
+ // Split the version string at every separator
+ String[] versionStringSplit = versionString.split(separator);
+
+ // Convert to integers
+ try {
+ this.number1 = Integer.parseUnsignedInt(versionStringSplit[0]);
+ this.number2 = Integer.parseUnsignedInt(versionStringSplit[1]);
+ } catch (NumberFormatException exception) {
+ throw new InvalidVersionStringException(this, versionString, "Failed converting one of the vectors to an integer.", exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Range(from = 0, to = 2)
+ @Override
+ public int compare(@NotNull VersioningSystem versionInterface) throws IncompatibleVersioningSystemException {
+ if (versionInterface instanceof TwoNumberVersioningSystem version) {
+ if (version.getNumber1() < number1)
+ return 0;
+ if (version.getNumber1() > number1)
+ return 2;
+
+ if (version.getNumber2() < number2)
+ return 0;
+ if (version.getNumber2() > number2)
+ return 2;
+
+ return 1;
+
+ } else
+ throw new IncompatibleVersioningSystemException(this, versionInterface);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/exceptions/IncompatibleVersioningSystemException.java b/base/src/main/java/de/staropensource/sosengine/base/exceptions/IncompatibleVersioningSystemException.java
new file mode 100644
index 00000000..f2c46818
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/exceptions/IncompatibleVersioningSystemException.java
@@ -0,0 +1,34 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.exceptions;
+
+import de.staropensource.sosengine.base.types.VersioningSystem;
+
+/**
+ * Represents an exception caused by supplying an invalid or unexpected versioning system.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused" })
+public class IncompatibleVersioningSystemException extends Exception {
+ public IncompatibleVersioningSystemException(VersioningSystem required, VersioningSystem found) {
+ super("The versioning system " + required + " is incompatible with " + found);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/exceptions/InvalidVersionStringException.java b/base/src/main/java/de/staropensource/sosengine/base/exceptions/InvalidVersionStringException.java
new file mode 100644
index 00000000..a58d7b43
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/exceptions/InvalidVersionStringException.java
@@ -0,0 +1,101 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.exceptions;
+
+import de.staropensource.sosengine.base.types.VersioningSystem;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+
+/**
+ * Represents an exception caused by an invalid version string.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public class InvalidVersionStringException extends Exception {
+ /**
+ * Contains the throwable supplied to the constructor.
+ *
+ * @since 1-alpha1
+ *
+ * -- GETTER --
+ * Returns the throwable supplied by the constructor.
+ *
+ * @return throwable
+ * @since 1-alpha1
+ */
+ @Nullable
+ Throwable throwable;
+
+ /**
+ * Constructor.
+ *
+ * @param versioningSystem versioning system that is unable to parse version strings
+ * @param versionString version string {@code a}
+ * @param message some error message
+ * @param throwable throwable that caused the parsing error
+ * @since 1-alpha1
+ */
+ public InvalidVersionStringException(@NotNull VersioningSystem versioningSystem, @NotNull String versionString, @NotNull String message, @NotNull Throwable throwable) {
+ super("Versioning system " + versioningSystem.getName() + " can't parse version string \"" + versionString + "\": " + message);
+ this.throwable = throwable;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versioningSystem versioning system that is unable to parse version strings
+ * @param versionString version string {@code a}
+ * @param message some error message
+ * @since 1-alpha1
+ */
+ public InvalidVersionStringException(@NotNull VersioningSystem versioningSystem, @NotNull String versionString, @NotNull String message) {
+ super("Versioning system " + versioningSystem.getName() + " can't parse version string \"" + versionString + "\": " + message);
+ throwable = null;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versioningSystem versioning system that is unable to parse version strings
+ * @param versionString version string {@code a}
+ * @param throwable throwable that caused the parsing error
+ * @since 1-alpha1
+ */
+ public InvalidVersionStringException(@NotNull VersioningSystem versioningSystem, @NotNull String versionString, @NotNull Throwable throwable) {
+ super("Versioning system " + versioningSystem.getName() + " can't parse version string \"" + versionString + "\"");
+ this.throwable = throwable;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param versioningSystem versioning system that is unable to parse version strings
+ * @param versionString version string {@code a}
+ * @since 1-alpha1
+ */
+ public InvalidVersionStringException(@NotNull VersioningSystem versioningSystem, @NotNull String versionString) {
+ super("Versioning system " + versioningSystem.getName() + " can't parse version string \"" + versionString + "\"");
+ this.throwable = null;
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/types/VersionType.java b/base/src/main/java/de/staropensource/sosengine/base/types/VersionType.java
index 2b8ac4b7..4d543169 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/types/VersionType.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/types/VersionType.java
@@ -20,10 +20,12 @@
package de.staropensource.sosengine.base.types;
import de.staropensource.sosengine.base.data.info.EngineInformation;
+import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem;
/**
- * Provides all available version types.
+ * Provides all available version types specified in the StarOpenSource Versioning System v2.
*
+ * @see StarOpenSourceVersioningSystem
* @see EngineInformation#versioningType
* @since 1-alpha0
*/
diff --git a/base/src/main/java/de/staropensource/sosengine/base/types/VersioningSystem.java b/base/src/main/java/de/staropensource/sosengine/base/types/VersioningSystem.java
new file mode 100644
index 00000000..48a668cc
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/types/VersioningSystem.java
@@ -0,0 +1,50 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.types;
+
+import de.staropensource.sosengine.base.exceptions.IncompatibleVersioningSystemException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+
+/**
+ * An interface used for implementing different versioning systems.
+ *
+ * @since 1-alpha1
+ */
+@SuppressWarnings({ "unused" })
+public interface VersioningSystem {
+ /**
+ * Returns the name of this versioning system.
+ *
+ * @since 1-alpha1
+ */
+ @NotNull
+ String getName();
+
+ /**
+ * Compares a version with another version.
+ *
+ * @param version the version to compare against
+ * @return smaller = {@code 0}, equal = {@code 1}, bigger = {@code 2}
+ * @since 1-alpha1
+ */
+ @Range(from = 0, to = 2)
+ int compare(@NotNull VersioningSystem version) throws IncompatibleVersioningSystemException;
+}
diff --git a/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/FourNumberVersioningSystemTest.java b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/FourNumberVersioningSystemTest.java
new file mode 100644
index 00000000..92c57cd0
--- /dev/null
+++ b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/FourNumberVersioningSystemTest.java
@@ -0,0 +1,74 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.srctests.data.versioning;
+
+import de.staropensource.sosengine.base.data.versioning.FourNumberVersioningSystem;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.unittests.UnitLogger;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests the class {@link FourNumberVersioningSystem}.
+ */
+@SuppressWarnings({ "unused" })
+@DisplayName("SemanticVersioningSystem")
+public class FourNumberVersioningSystemTest {
+ /**
+ * The unit logger for this instance.
+ */
+ private static final UnitLogger logger = new UnitLogger(FourNumberVersioningSystemTest.class);
+ private static final Logger log = LoggerFactory.getLogger(FourNumberVersioningSystemTest.class);
+
+ /**
+ * Tests the method {@code compare}.
+ */
+ @ParameterizedTest
+ @DisplayName("compare")
+ @CsvSource({
+ "1.1.0.0, 1.0.0.1, 0",
+ "1.1.0.0, 1.0.1.0, 0",
+ "1.1.0.0, 1.0.1.1, 0",
+ "1.1.0.0, 1.1.0.0, 1",
+ "1.1.0.0, 1.1.0.1, 2",
+ "1.1.0.0, 1.1.1.0, 2",
+ "1.1.0.0, 1.1.1.1, 2",
+ })
+ void testCompare(String a, String b, int expected) throws Throwable {
+ logger.testCall("testCompare", a, b, expected);
+
+ try {
+ assertEquals(expected, new FourNumberVersioningSystem(a).compare(new FourNumberVersioningSystem(b)));
+ } catch (InvalidVersionStringException exception) {
+ logger.error("Got InvalidVersionStringException: " + exception.getMessage());
+ if (exception.getThrowable() != null) {
+ logger.error("Original stack trace:");
+ throw exception.getThrowable();
+ }
+ fail("Got InvalidVersionStringException");
+ }
+ }
+}
diff --git a/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/SemanticVersioningSystemTest.java b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/SemanticVersioningSystemTest.java
new file mode 100644
index 00000000..e2d5766f
--- /dev/null
+++ b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/SemanticVersioningSystemTest.java
@@ -0,0 +1,79 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.srctests.data.versioning;
+
+import de.staropensource.sosengine.base.data.versioning.SemanticVersioningSystem;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.unittests.UnitLogger;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests the class {@link SemanticVersioningSystem}.
+ */
+@SuppressWarnings({ "unused" })
+@DisplayName("SemanticVersioningSystem")
+public class SemanticVersioningSystemTest {
+ /**
+ * The unit logger for this instance.
+ */
+ private static final UnitLogger logger = new UnitLogger(SemanticVersioningSystemTest.class);
+ private static final Logger log = LoggerFactory.getLogger(SemanticVersioningSystemTest.class);
+
+ /**
+ * Tests the method {@code compare}.
+ */
+ @ParameterizedTest
+ @DisplayName("compare")
+ @CsvSource({
+ "1.1.0, 1.0.1, 0",
+ "1.1.0-beta, 1.1.0-alpha, 0",
+ "1.1.0-beta+2, 1.1.0-alpha+2, 0",
+ "1.1.0+4, 1.1.0+3, 0",
+ "1.1.0, 1.1.0, 1",
+ "1.1.0-rc, 1.1.0-rc, 1",
+ "1.1.0-rc+6, 1.1.0-rc+6, 1",
+ "1.1.0+4, 1.1.0+4, 1",
+ "1.1.0, 1.1.1, 2",
+ "1.1.0-alpha, 1.1.0-beta, 2",
+ "1.1.0-alpha+2, 1.1.0-alpha+3, 2",
+ "1.1.0+5, 1.1.0+6, 2",
+ })
+ void testCompare(String a, String b, int expected) throws Throwable {
+ logger.testCall("testCompare", a, b, expected);
+
+ try {
+ assertEquals(expected, new SemanticVersioningSystem(a).compare(new SemanticVersioningSystem(b)));
+ } catch (InvalidVersionStringException exception) {
+ logger.error("Got InvalidVersionStringException: " + exception.getMessage());
+ if (exception.getThrowable() != null) {
+ logger.error("Original stack trace:");
+ throw exception.getThrowable();
+ }
+ fail("Got InvalidVersionStringException");
+ }
+ }
+}
diff --git a/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/StarOpenSourceVersioningSystemTest.java b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/StarOpenSourceVersioningSystemTest.java
new file mode 100644
index 00000000..93d19407
--- /dev/null
+++ b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/StarOpenSourceVersioningSystemTest.java
@@ -0,0 +1,75 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.srctests.data.versioning;
+
+import de.staropensource.sosengine.base.data.versioning.SemanticVersioningSystem;
+import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.unittests.UnitLogger;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests the class {@link SemanticVersioningSystem}.
+ */
+@SuppressWarnings({ "unused" })
+@DisplayName("SemanticVersioningSystem")
+public class StarOpenSourceVersioningSystemTest {
+ /**
+ * The unit logger for this instance.
+ */
+ private static final UnitLogger logger = new UnitLogger(StarOpenSourceVersioningSystemTest.class);
+
+ /**
+ * Tests the method {@code compare}.
+ */
+ @ParameterizedTest
+ @DisplayName("compare")
+ @CsvSource({
+ "v1-releasecandidate7, v1-beta5, 0",
+ "v2-release5, v2-release4, 0",
+ "v4-alpha0, v3-alpha0, 0",
+ "v1-release5, v1-release5, 1",
+ "v5-beta0-somefork, v5-beta0, 1",
+ "v1-beta0+companion, v1-beta0-fork, 1",
+ "v9-beta6-fork+comp, v9-beta6-dork+homp, 1",
+ "v5-beta5, v5-beta6, 2",
+ "v6-release0, v7-release0, 2",
+ "v9-beta5, v9-releasecandidate1, 2",
+ })
+ void testCompare(String a, String b, int expected) throws Throwable {
+ logger.testCall("testCompare", a, b, expected);
+
+ try {
+ assertEquals(expected, new StarOpenSourceVersioningSystem(a).compare(new StarOpenSourceVersioningSystem(b)));
+ } catch (InvalidVersionStringException exception) {
+ logger.error("Got InvalidVersionStringException: " + exception.getMessage());
+ if (exception.getThrowable() != null) {
+ logger.error("Original stack trace:");
+ throw exception.getThrowable();
+ }
+ fail("Got InvalidVersionStringException");
+ }
+ }
+}
diff --git a/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/ThreeNumberVersioningSystemTest.java b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/ThreeNumberVersioningSystemTest.java
new file mode 100644
index 00000000..cab8198b
--- /dev/null
+++ b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/ThreeNumberVersioningSystemTest.java
@@ -0,0 +1,70 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.srctests.data.versioning;
+
+import de.staropensource.sosengine.base.data.versioning.ThreeNumberVersioningSystem;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.unittests.UnitLogger;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests the class {@link ThreeNumberVersioningSystem}.
+ */
+@SuppressWarnings({ "unused" })
+@DisplayName("SemanticVersioningSystem")
+public class ThreeNumberVersioningSystemTest {
+ /**
+ * The unit logger for this instance.
+ */
+ private static final UnitLogger logger = new UnitLogger(ThreeNumberVersioningSystemTest.class);
+ private static final Logger log = LoggerFactory.getLogger(ThreeNumberVersioningSystemTest.class);
+
+ /**
+ * Tests the method {@code compare}.
+ */
+ @ParameterizedTest
+ @DisplayName("compare")
+ @CsvSource({
+ "1.1.0, 1.0.1, 0",
+ "1.1.0, 1.1.0, 1",
+ "1.1.0, 1.1.1, 2",
+ })
+ void testCompare(String a, String b, int expected) throws Throwable {
+ logger.testCall("testCompare", a, b, expected);
+
+ try {
+ assertEquals(expected, new ThreeNumberVersioningSystem(a).compare(new ThreeNumberVersioningSystem(b)));
+ } catch (InvalidVersionStringException exception) {
+ logger.error("Got InvalidVersionStringException: " + exception.getMessage());
+ if (exception.getThrowable() != null) {
+ logger.error("Original stack trace:");
+ throw exception.getThrowable();
+ }
+ fail("Got InvalidVersionStringException");
+ }
+ }
+}
diff --git a/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/TwoNumberVersioningSystemTest.java b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/TwoNumberVersioningSystemTest.java
new file mode 100644
index 00000000..e1394e16
--- /dev/null
+++ b/base/src/test/java/de/staropensource/sosengine/base/srctests/data/versioning/TwoNumberVersioningSystemTest.java
@@ -0,0 +1,70 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.srctests.data.versioning;
+
+import de.staropensource.sosengine.base.data.versioning.TwoNumberVersioningSystem;
+import de.staropensource.sosengine.base.exceptions.InvalidVersionStringException;
+import de.staropensource.sosengine.unittests.UnitLogger;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests the class {@link TwoNumberVersioningSystem}.
+ */
+@SuppressWarnings({ "unused" })
+@DisplayName("SemanticVersioningSystem")
+public class TwoNumberVersioningSystemTest {
+ /**
+ * The unit logger for this instance.
+ */
+ private static final UnitLogger logger = new UnitLogger(TwoNumberVersioningSystemTest.class);
+ private static final Logger log = LoggerFactory.getLogger(TwoNumberVersioningSystemTest.class);
+
+ /**
+ * Tests the method {@code compare}.
+ */
+ @ParameterizedTest
+ @DisplayName("compare")
+ @CsvSource({
+ "1.5, 1.0, 0",
+ "1.5, 1.5, 1",
+ "1.5, 2.0, 2",
+ })
+ void testCompare(String a, String b, int expected) throws Throwable {
+ logger.testCall("testCompare", a, b, expected);
+
+ try {
+ assertEquals(expected, new TwoNumberVersioningSystem(a).compare(new TwoNumberVersioningSystem(b)));
+ } catch (InvalidVersionStringException exception) {
+ logger.error("Got InvalidVersionStringException: " + exception.getMessage());
+ if (exception.getThrowable() != null) {
+ logger.error("Original stack trace:");
+ throw exception.getThrowable();
+ }
+ fail("Got InvalidVersionStringException");
+ }
+ }
+}