diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index c74687d8b..90a1cc8dd 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -3,6 +3,7 @@ package org.hl7.fhir.utilities; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.utilities.npm.NpmPackage; @@ -216,13 +217,17 @@ public class VersionUtilities { } /** - * return true if the current version equals test, or later - * - * so if a feature is defined in 4.0, if (VersionUtilities.isThisOrLater("4.0", version))... + * return true if the current version equals test, or later, + * so if a feature is defined in 4.0, if (VersionUtilities.isThisOrLater("4.0", version)) + *

+ * This method tries to perform a numeric parse, so that 0.9 will be considered below 0.10 + * in accordance with SemVer. If either side contains a non-numeric character in a version string, a simple text + * compare will be done instead. + *

* - * @param test - * @param current - * @return + * @param test The value to compare to + * @param current The value being compared + * @return Is {@literal current} later or equal to {@literal test}? For example, if this = 0.5 and current = 0.6 this method will return true */ public static boolean isThisOrLater(String test, String current) { String t = getMajMin(test); @@ -230,8 +235,29 @@ public class VersionUtilities { if (c.compareTo(t) == 0) { return isMajMinOrLaterPatch(test, current); } - boolean ok = c.compareTo(t) >= 0; - return ok; + + String[] testParts = t.split("\\."); + String[] currentParts = c.split("\\."); + + for (int i = 0; i < Math.max(testParts.length, currentParts.length); i++) { + if (i == testParts.length) { + return true; + } else if (i == currentParts.length) { + return false; + } + String testPart = testParts[i]; + String currentPart = currentParts[i]; + if (testPart.equals(currentPart)) { + continue; + } + if (StringUtils.isNumeric(testPart) && StringUtils.isNumeric(currentPart)) { + return Integer.parseInt(currentPart) - Integer.parseInt(testPart) > 0; + } else { + return currentPart.compareTo(testPart) >= 0; + } + } + + return true; } /** diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java new file mode 100644 index 000000000..9d61ffc39 --- /dev/null +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/VersionUtilitiesTest.java @@ -0,0 +1,34 @@ +package org.hl7.fhir.utilities; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class VersionUtilitiesTest { + + @Test + public void isThisOrLater_Simple() { + assertTrue(VersionUtilities.isThisOrLater("0.1", "0.2")); + assertFalse(VersionUtilities.isThisOrLater("0.2", "0.1")); + } + + @Test + public void isThisOrLater_NeedNumericComparison() { + assertTrue(VersionUtilities.isThisOrLater("0.9", "0.10")); + assertFalse(VersionUtilities.isThisOrLater("0.10", "0.9")); + } + + @Test + public void isThisOrLater_DifferentLengths() { + assertTrue(VersionUtilities.isThisOrLater("0.9", "0.9.1")); + assertFalse(VersionUtilities.isThisOrLater("0.9.1", "0.9")); + } + + @Test + public void isThisOrLater_NonNumeric() { + assertTrue(VersionUtilities.isThisOrLater("0.A", "0.B")); + assertFalse(VersionUtilities.isThisOrLater("0.B", "0.A")); + } + + +} \ No newline at end of file