Version Numbers
Version numbers in install4j should be a sequence of version components separated by dots:
A.B.C...
where A, B, C are composed of alphanumeric characters without dots, for example 1
, 112
,
5-rc-9
or release
.
Version comparisons in the auto-update API
The auto-update API in the com.install4j.api.update
package has to determine whether a new version is greater than an installed version or not. Usually, the
getPossibleUpdateEntry()
method of the update descriptor is called to make that comparison:
UpdateDescriptor updateDescriptor = ...; if (updateDescriptor.getPossibleUpdateEntry() != null) { //TODO an update is available }
In its implementation, it calls
UpdateDescriptorEntry updateDescriptorEntry = ...; String installedVersion = context.getVersion(); if (updateDescriptorEntry.checkVersionCompatible(installedVersion)) { // TODO This entry has a version that is newer than the installed version }
The checkVersionCompatible
method checks if the supplied version
- is greater or equal than the minimum updatable version in the update descriptor entry (if defined)
- is less or equal than the maximum updatable version in the update descriptor entry (if defined)
- is less than the version of the new media file
Internally, it calls
if (UpdateChecker.isVersionGreaterThan(newVersion, installedVersion)) { // TODO newVersion is indeed greater than installedVersion }
to compare the version strings of the installed version with the new version in the update descriptor entry.
Comparison algorithm for versions
Let us call the two versions that should be compared A
and B
. A
has NA
components while B has NB
components.
Components are determined by splitting the version string with a java.util.StringTokenizer
and
a single dot as a delimiter. The components are denoted as A(0) ... A(NA-1)
and
B(0) ... B(NB-1)
.
The following rules apply when comparing these two versions:
-
Before the comparison, the following replacements are performed for both versions in this order:
-
When going from left to right, a boundary between digits and non-digits creates a new component, for example
2.3a
becomes2.3.a
. Boundaries between non-digits and digits are left intact, for example2.3.a4
. This means that non-numeric characters only appear as leading characters for each component. - After dots, any "-" and "_" characters are discarded.
-
All characters are converted to lower-case, for example
1.0-HEAD
becomes1.0.head
.
-
When going from left to right, a boundary between digits and non-digits creates a new component, for example
-
The version that has fewer components is filled up with components of value
0
, so that both versions have the same number of componentsN = max(NA, NB)
. -
The versions are compared from left to right, component by component. The version comparison is finished for
the first
K = 0 ... N-1
for which the components are not equal:B(K) > A(K) => B > A B(K) < A(K) => B < A
-
Components that have leading non-numeric characters are considered as less than components with leading numeric
characters. For example
2.3-pre < 2.3
, because2.3-pre
is converted to2.3.pre
and2.3
is converted to2.3.0
. -
If both components have a non-numeric part, version comparison is decided by their lexicographic comparison,
as performed by
String.compareTo(...)
. For example,2.Z3 > 2.X4
. If the non-numeric parts are equal, the numeric parts are compared where missing numeric parts are set to0
. - Otherwise the components are both numeric and can be compared numerically.
Some examples from the unit test for the version comparison method are:
1 < 2 1.1 < 2 1.1 < 1.2 1.1.0 < 1.1.1 9.0 < 10 1.6.0_4 < 1.6.0_22 1.6.0 < 1.6.0_22 1.6.0_4 < 1.6.1 1.0beta1 < 1.0beta2 1.0.beta1 < 1.0.beta2 A10 < A11 2.0 beta 1 < 2.0 2.0 beta 1 < 2.0.0 2.0 beta 1 < 2.0 beta 2 1.0rc1 < 1.0 1.0-rc1 < 1.0 1.0.rc1 < 1.0 1.0alpha < 1.0rc1 1.0alpha < 1.0alpha1 1.0alpha9 < 1.0alpha10 1.0alpha100 < 1.0.rc100 1.0.alpha < 1.0-rc z < 1 DEVELOP-HEAD130714193704 < DEVELOP-HEAD130714193705