Merge
This commit is contained in:
commit
4130468fcd
@ -1112,7 +1112,62 @@ public class Runtime {
|
||||
* @return The Version of the given string
|
||||
*/
|
||||
public static Version parse(String s) {
|
||||
return VersionBuilder.parse(s);
|
||||
if (s == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
// Shortcut to avoid initializing VersionPattern when creating
|
||||
// major version constants during startup
|
||||
if (isSimpleNumber(s)) {
|
||||
return new Version(List.of(Integer.parseInt(s)),
|
||||
Optional.empty(), Optional.empty(), Optional.empty());
|
||||
}
|
||||
Matcher m = VersionPattern.VSTR_PATTERN.matcher(s);
|
||||
if (!m.matches())
|
||||
throw new IllegalArgumentException("Invalid version string: '"
|
||||
+ s + "'");
|
||||
|
||||
// $VNUM is a dot-separated list of integers of arbitrary length
|
||||
List<Integer> version = new ArrayList<>();
|
||||
for (String i : m.group(VersionPattern.VNUM_GROUP).split("\\."))
|
||||
version.add(Integer.parseInt(i));
|
||||
|
||||
Optional<String> pre = Optional.ofNullable(
|
||||
m.group(VersionPattern.PRE_GROUP));
|
||||
|
||||
String b = m.group(VersionPattern.BUILD_GROUP);
|
||||
// $BUILD is an integer
|
||||
Optional<Integer> build = (b == null)
|
||||
? Optional.empty()
|
||||
: Optional.of(Integer.parseInt(b));
|
||||
|
||||
Optional<String> optional = Optional.ofNullable(
|
||||
m.group(VersionPattern.OPT_GROUP));
|
||||
|
||||
// empty '+'
|
||||
if ((m.group(VersionPattern.PLUS_GROUP) != null)
|
||||
&& !build.isPresent()) {
|
||||
if (optional.isPresent()) {
|
||||
if (pre.isPresent())
|
||||
throw new IllegalArgumentException("'+' found with"
|
||||
+ " pre-release and optional components:'" + s
|
||||
+ "'");
|
||||
} else {
|
||||
throw new IllegalArgumentException("'+' found with neither"
|
||||
+ " build or optional components: '" + s + "'");
|
||||
}
|
||||
}
|
||||
return new Version(version, pre, build, optional);
|
||||
}
|
||||
|
||||
private static boolean isSimpleNumber(String s) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
char lowerBound = (i > 0) ? '0' : '1';
|
||||
if (c < lowerBound || c > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1441,86 +1496,26 @@ public class Runtime {
|
||||
}
|
||||
}
|
||||
|
||||
private static class VersionBuilder {
|
||||
private static class VersionPattern {
|
||||
// $VNUM(-$PRE)?(\+($BUILD)?(\-$OPT)?)?
|
||||
// RE limits the format of version strings
|
||||
// ([1-9][0-9]*(?:(?:\.0)*\.[1-9][0-9]*)*)(?:-([a-zA-Z0-9]+))?(?:(\+)(0|[1-9][0-9]*)?)?(?:-([-a-zA-Z0-9.]+))?
|
||||
|
||||
private static final String VNUM
|
||||
= "(?<VNUM>[1-9][0-9]*(?:(?:\\.0)*\\.[1-9][0-9]*)*)";
|
||||
private static final String VNUM_GROUP = "VNUM";
|
||||
|
||||
private static final String PRE = "(?:-(?<PRE>[a-zA-Z0-9]+))?";
|
||||
private static final String PRE_GROUP = "PRE";
|
||||
|
||||
private static final String BUILD
|
||||
= "(?:(?<PLUS>\\+)(?<BUILD>0|[1-9][0-9]*)?)?";
|
||||
private static final String PLUS_GROUP = "PLUS";
|
||||
private static final String BUILD_GROUP = "BUILD";
|
||||
|
||||
private static final String OPT = "(?:-(?<OPT>[-a-zA-Z0-9.]+))?";
|
||||
private static final String OPT_GROUP = "OPT";
|
||||
|
||||
private static final String VSTR_FORMAT
|
||||
= "^" + VNUM + PRE + BUILD + OPT + "$";
|
||||
private static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT);
|
||||
|
||||
/**
|
||||
* Constructs a valid <a href="verStr">version string</a> containing
|
||||
* a <a href="#verNum">version number</a> followed by pre-release and
|
||||
* build information.
|
||||
*
|
||||
* @param s
|
||||
* A string to be interpreted as a version
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the given string cannot be interpreted as a valid
|
||||
* version
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If {@code s} is {@code null}
|
||||
*
|
||||
* @throws NumberFormatException
|
||||
* If an element of the version number or the build number
|
||||
* cannot be represented as an {@link Integer}
|
||||
*/
|
||||
static Version parse(String s) {
|
||||
if (s == null)
|
||||
throw new NullPointerException();
|
||||
static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT);
|
||||
|
||||
Matcher m = VSTR_PATTERN.matcher(s);
|
||||
if (!m.matches())
|
||||
throw new IllegalArgumentException("Invalid version string: '"
|
||||
+ s + "'");
|
||||
|
||||
// $VNUM is a dot-separated list of integers of arbitrary length
|
||||
List<Integer> version = new ArrayList<>();
|
||||
for (String i : m.group(VNUM_GROUP).split("\\."))
|
||||
version.add(Integer.parseInt(i));
|
||||
|
||||
Optional<String> pre = Optional.ofNullable(m.group(PRE_GROUP));
|
||||
|
||||
String b = m.group(BUILD_GROUP);
|
||||
// $BUILD is an integer
|
||||
Optional<Integer> build = (b == null)
|
||||
? Optional.empty()
|
||||
: Optional.of(Integer.parseInt(b));
|
||||
|
||||
Optional<String> optional = Optional.ofNullable(m.group(OPT_GROUP));
|
||||
|
||||
// empty '+'
|
||||
if ((m.group(PLUS_GROUP) != null) && !build.isPresent()) {
|
||||
if (optional.isPresent()) {
|
||||
if (pre.isPresent())
|
||||
throw new IllegalArgumentException("'+' found with"
|
||||
+ " pre-release and optional components:'" + s
|
||||
+ "'");
|
||||
} else {
|
||||
throw new IllegalArgumentException("'+' found with neither"
|
||||
+ " build or optional components: '" + s + "'");
|
||||
}
|
||||
}
|
||||
return new Version(version, pre, build, optional);
|
||||
}
|
||||
static final String VNUM_GROUP = "VNUM";
|
||||
static final String PRE_GROUP = "PRE";
|
||||
static final String PLUS_GROUP = "PLUS";
|
||||
static final String BUILD_GROUP = "BUILD";
|
||||
static final String OPT_GROUP = "OPT";
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user