diff --git a/core/src/test/java/org/alfresco/util/VersionNumberTest.java b/core/src/test/java/org/alfresco/util/VersionNumberTest.java
index 3a1bd79b60..5699708bb2 100644
--- a/core/src/test/java/org/alfresco/util/VersionNumberTest.java
+++ b/core/src/test/java/org/alfresco/util/VersionNumberTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2010 Alfresco Software Limited.
+ * Copyright (C) 2005-2020 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -74,6 +74,22 @@ public class VersionNumberTest extends TestCase
{
// OK
}
+ try
+ {
+ new VersionNumber("1.2.3-M4");
+ fail("Should not have created an invalid version");
+ } catch (Exception exception)
+ {
+ // OK
+ }
+ try
+ {
+ new VersionNumber("1.2.3-A4");
+ fail("Should not have created an invalid version");
+ } catch (Exception exception)
+ {
+ // OK
+ }
}
public void testEquals()
diff --git a/repository/src/main/java/org/alfresco/repo/module/ModuleVersionNumber.java b/repository/src/main/java/org/alfresco/repo/module/ModuleVersionNumber.java
index b8c0728611..a73f84fdc0 100644
--- a/repository/src/main/java/org/alfresco/repo/module/ModuleVersionNumber.java
+++ b/repository/src/main/java/org/alfresco/repo/module/ModuleVersionNumber.java
@@ -1,34 +1,36 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2020 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
package org.alfresco.repo.module;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.alfresco.util.VersionNumber;
import org.apache.maven.artifact.versioning.ComparableVersion;
@@ -49,7 +51,11 @@ public class ModuleVersionNumber implements Externalizable
public static final ModuleVersionNumber VERSION_ZERO = new ModuleVersionNumber("0");;
public static final ModuleVersionNumber VERSION_BIG = new ModuleVersionNumber("999.999.999.99");
-
+
+ // Matches versions with 3 or 4 parts to their basic number such as 1.2.3 or 1.2.3.4
+ // that also optionally have a -A9 -M9 or -RC9 suffix whe 9 is an integer.
+ private static Pattern A_M_RC_VERSION_PATTERN = Pattern.compile("((\\d+\\.){2,3}\\d+)(-(A|M|RC)\\d+)?");
+
protected ComparableVersion delegate;
public ModuleVersionNumber()
@@ -67,11 +73,56 @@ public class ModuleVersionNumber implements Externalizable
this(versionCurrent.toString());
}
+ /**
+ * Now that we create internal releases of the form {@code M.m.r-M9} (milestone), {@code M.m.r-A9} (alpha) and
+ * {@code M.m.r-RC9} (release candidate) during development and testing, we need to ensure we can upgrade from any
+ * of these to any other, as they may occur in any order and also to the final external release {@code M.m.r}. We
+ * also will allow a change from the final release back to an internal one for regression testing.
+ *
+ * The code within {@link ModuleComponentHelper} which calls this method, checks if it is the same version
+ * ({@code 0}) and then if it is downgrading ({@code > 0}), so if they share the same {@code M.m.r} part matches
+ * AND is one of these formats, we return {@code <0}.
+ *
+ * @param installingVersion the new version
+ * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
+ * the specified object.
+ */
public int compareTo(ModuleVersionNumber installingVersion)
{
+ String thisVersion = toString();
+ String thatVersion = installingVersion.toString();
+ if (thisVersion.equals(thatVersion))
+ {
+ return 0;
+ }
+
+ String thisVersionWithoutSuffix = getVersionWithoutSuffix();
+ if (thisVersionWithoutSuffix != null)
+ {
+ String thatVersionWithoutSuffix = installingVersion.getVersionWithoutSuffix();
+ if (thisVersionWithoutSuffix.equals(thatVersionWithoutSuffix))
+ {
+ return -1;
+ }
+ }
+
return delegate.compareTo(installingVersion.delegate);
}
+ String getVersionWithoutSuffix()
+ {
+ String versionWithoutAMOrRc = null;
+ String fullVersion = toString();
+ Matcher matcher = A_M_RC_VERSION_PATTERN.matcher(fullVersion);
+ if (matcher.matches())
+ {
+ versionWithoutAMOrRc = matcher.group(1);
+ // matcher.group(3) would be the suffix, such as "-M4"
+ // matcher.group(4) would be the type of release: "RC", "A" or "M"
+ }
+ return versionWithoutAMOrRc;
+ }
+
@Override
public int hashCode()
{
@@ -114,6 +165,4 @@ public class ModuleVersionNumber implements Externalizable
String versionString = in.readUTF();
delegate = new ComparableVersion(versionString);
}
-
-
}
diff --git a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
index 6840d989e1..7b66418b17 100644
--- a/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
+++ b/repository/src/test/java/org/alfresco/AllUnitTestsSuite.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2017 Alfresco Software Limited
+ * Copyright (C) 2005 - 2020 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -79,6 +79,7 @@ import org.junit.runners.Suite;
org.alfresco.service.cmr.calendar.CalendarRecurrenceHelperTest.class,
org.alfresco.service.cmr.calendar.CalendarTimezoneHelperTest.class,
org.alfresco.tools.RenameUserTest.class,
+ org.alfresco.util.VersionNumberTest.class,
org.alfresco.util.FileNameValidatorTest.class,
org.alfresco.util.HttpClientHelperTest.class,
org.alfresco.util.JSONtoFmModelTest.class,
diff --git a/repository/src/test/java/org/alfresco/repo/module/ModuleVersionNumberTest.java b/repository/src/test/java/org/alfresco/repo/module/ModuleVersionNumberTest.java
index af609d6699..ac25191215 100644
--- a/repository/src/test/java/org/alfresco/repo/module/ModuleVersionNumberTest.java
+++ b/repository/src/test/java/org/alfresco/repo/module/ModuleVersionNumberTest.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2020 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -230,4 +230,87 @@ public class ModuleVersionNumberTest extends TestCase
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
return (ModuleVersionNumber) objectInputStream.readObject();
}
+
+ // Tests that we can strip the suffixes such as "-M2", "-A12" or "-RC2" from versions "7.0.0-M2", "6.2.2-A12", "7.0.1-RC2"
+ // The main version may contain 3 or 4 digit parts.
+ public void testGetVersionWithoutSuffix()
+ {
+ for (String[] pair: new String[][]
+ {{null, "1.2"},
+ {"1.2.3", "1.2.3"},
+ {"1.2.3.4", "1.2.3.4"},
+ {null, "1.2.3.4.5"},
+
+ {"1.2.3", "1.2.3-M4"},
+ {"1.2.3.4", "1.2.3.4-A56"},
+ {"1.2.3", "1.2.3-RC456"},
+ {"11.22.33.44", "11.22.33.44-A5"},
+
+ {null, "1.2.3-456"},
+ {null, "1.2.3-X12"},
+
+ {null, "1.2.5-A6-A6"},
+ {null, "1.2.3.4.5-A6"},
+ {null, "1.2-M3"},
+
+ {null, "1.2.3-RCA-45"},
+ {null, "1.2.3-AM4"},
+
+ {null, "1.2.3-A56A"},
+ })
+ {
+ String expected = pair[0];
+ String value = pair[1];
+ ModuleVersionNumber version = new ModuleVersionNumber(value);
+ String actual = version.getVersionWithoutSuffix();
+ assertEquals(expected, actual);
+ }
+ }
+
+ public void testInternalVersionsAreUpgrades()
+ {
+ for (String[] pair: new String[][]
+ // same base version with an optional special suffix (-A9, -M9, -RC9)
+ {{"upgrade", "7.0.0-A10", "7.0.0"},
+ {"upgrade", "7.0.0", "7.0.0-A11"},
+ {"upgrade", "7.0.0-A10", "7.0.0-A12"},
+ {"upgrade", "7.0.0-A13", "7.0.0-M1"},
+ {"upgrade", "7.0.0-A13", "7.0.0-RC1"},
+
+ // Just the same version
+ {"same", "7.0.0", "7.0.0"},
+ {"same", "7.0.0-A14", "7.0.0-A14"},
+
+ // Normal versions using standard maven compare
+ {"downgrade", "7.0.0", "6.2.3"},
+ {"upgrade", "6.2.3", "7.0.0"},
+
+ // standard maven compare - note sure these even make sense as these are not maven format versions!
+ {"upgrade", "7.0.0-A15", "7.0.0-1234"},
+ {"downgrade", "7.0.0-1234", "7.0.0-M2"},
+ {"downgrade", "7.0.0-Rubbish1", "7.0.0-M3"},
+ {"upgrade", "7.0.0-A16", "7.0.0-Rubbish2"}
+ })
+ {
+ String expected = pair[0];
+
+ String value1 = pair[1];
+ String value2 = pair[2];
+ ModuleVersionNumber thisVersion = new ModuleVersionNumber(value1);
+ ModuleVersionNumber thatVersion = new ModuleVersionNumber(value2);
+ int actual = thisVersion.compareTo(thatVersion);
+ if ("downgrade".equals(expected))
+ {
+ assertTrue("Expected "+thisVersion+" to be a downgrade "+thatVersion+" ("+actual+")", actual > 0);
+ }
+ else if ("same".equals(expected))
+ {
+ assertTrue("Expected "+thisVersion+" to be the same base version as "+thatVersion+" ("+actual+")", actual == 0);
+ }
+ else if ("upgrade".equals(expected))
+ {
+ assertTrue("Expected "+thisVersion+" to be an upgrade from "+thatVersion+" ("+actual+")", actual < 0);
+ }
+ }
+ }
}