# 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](autoUpdate.md) 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 N<sub>A</sub> components while B has N<sub>B</sub> 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(N<sub>A</sub>-1) and B(0) ... B(N<sub>B</sub>-1).

The following rules apply when comparing these two versions:

1. 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 becomes 2.3.a. Boundaries between non-digits and digits are left intact, for example 2.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 becomes 1.0.head.
2. The version that has fewer components is filled up with components of value 0, so that both versions have the same number of components N = max(N<sub>A</sub>, N<sub>B</sub>).
3. 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:
4. Components that have leading non-numeric characters are considered as less than components with leading numeric characters. For example 2.3-pre < 2.3, because 2.3-pre is converted to 2.3.pre and 2.3 is converted to 2.3.0.
5. 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 to 0.
6. 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
```
