forked from openhab/openhab-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[addonservices] Add version filtering (openhab#2811)
Signed-off-by: Jan N. Klug <github@klug.nrw> GitOrigin-RevId: 4577562
- Loading branch information
Showing
12 changed files
with
436 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
...ore.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/BundleVersion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.core.addon.marketplace; | ||
|
||
import java.util.Objects; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* The {@link BundleVersion} wraps a bundle version and provides a method to compare them | ||
* | ||
* @author Jan N. Klug - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class BundleVersion { | ||
private static final Pattern VERSION_PATTERN = Pattern.compile( | ||
"(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<micro>\\d+)(\\.((?<rc>RC)|(?<milestone>M))?(?<qualifier>\\d+))?"); | ||
public static final Pattern RANGE_PATTERN = Pattern.compile( | ||
"\\[(?<start>\\d+\\.\\d+(?<startmicro>\\.\\d+(\\.\\w+)?)?);(?<end>\\d+\\.\\d+(?<endmicro>\\.\\d+(\\.\\w+)?)?)(?<endtype>[)\\]])"); | ||
|
||
private final Logger logger = LoggerFactory.getLogger(BundleVersion.class); | ||
|
||
private final int major; | ||
private final int minor; | ||
private final int micro; | ||
private final @Nullable Long qualifier; | ||
|
||
public BundleVersion(String version) { | ||
Matcher matcher = VERSION_PATTERN.matcher(version); | ||
if (matcher.matches()) { | ||
this.major = Integer.parseInt(matcher.group("major")); | ||
this.minor = Integer.parseInt(matcher.group("minor")); | ||
this.micro = Integer.parseInt(matcher.group("micro")); | ||
String qualifier = matcher.group("qualifier"); | ||
if (qualifier != null) { | ||
long intQualifier = Long.parseLong(qualifier); | ||
if (matcher.group("rc") != null) { | ||
// we can safely assume that there are less than Integer.MAX_VALUE milestones | ||
// so RCs are always newer than milestones | ||
// since snapshot qualifiers are larger than 10*Integer.MAX_VALUE they are | ||
// still considered newer | ||
this.qualifier = intQualifier + Integer.MAX_VALUE; | ||
} else { | ||
this.qualifier = intQualifier; | ||
} | ||
} else { | ||
this.qualifier = null; | ||
} | ||
} else { | ||
throw new IllegalArgumentException("Input does not match pattern"); | ||
} | ||
} | ||
|
||
/** | ||
* Test if this version is within the provided range | ||
* | ||
* @param range a Maven like version range | ||
* @return {@code true} if this version is inside range, {@code false} otherwise | ||
* @throws IllegalArgumentException if {@code range} does not represent a valid range | ||
*/ | ||
public boolean inRange(@Nullable String range) throws IllegalArgumentException { | ||
if (range == null || range.isBlank()) { | ||
// if no range is given, we assume the range covers everything | ||
return true; | ||
} | ||
Matcher matcher = RANGE_PATTERN.matcher(range); | ||
if (!matcher.matches()) { | ||
throw new IllegalArgumentException(range + "is not a valid version range"); | ||
} | ||
String startString = matcher.group("startmicro") != null ? matcher.group("start") | ||
: matcher.group("start") + ".0"; | ||
BundleVersion startVersion = new BundleVersion(startString); | ||
if (this.compareTo(startVersion) < 0) { | ||
return false; | ||
} | ||
|
||
String endString = matcher.group("endmicro") != null ? matcher.group("end") : matcher.group("stop") + ".0"; | ||
boolean inclusive = "]".equals(matcher.group("endtype")); | ||
BundleVersion endVersion = new BundleVersion(endString); | ||
int comparison = this.compareTo(endVersion); | ||
return (inclusive && comparison == 0) || comparison < 0; | ||
} | ||
|
||
@Override | ||
public boolean equals(@Nullable Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
BundleVersion version = (BundleVersion) o; | ||
return major == version.major && minor == version.minor && micro == version.micro | ||
&& Objects.equals(qualifier, version.qualifier); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(major, minor, micro, qualifier); | ||
} | ||
|
||
/** | ||
* Compares two bundle versions | ||
* | ||
* @param other the other bundle version | ||
* @return a positive integer if this version is newer than the other version, a negative number if this version is | ||
* older than the other version and 0 if the versions are equal | ||
*/ | ||
public int compareTo(BundleVersion other) { | ||
int result = major - other.major; | ||
if (result != 0) { | ||
return result; | ||
} | ||
|
||
result = minor - other.minor; | ||
if (result != 0) { | ||
return result; | ||
} | ||
|
||
result = micro - other.micro; | ||
if (result != 0) { | ||
return result; | ||
} | ||
|
||
if (Objects.equals(qualifier, other.qualifier)) { | ||
return 0; | ||
} | ||
|
||
// the release is always newer than a milestone or snapshot | ||
if (qualifier == null) { // we are the release | ||
return 1; | ||
} | ||
if (other.qualifier == null) { // the other is the release | ||
return -1; | ||
} | ||
|
||
// both versions are milestones, we can compare them | ||
return Long.compare(qualifier, other.qualifier); | ||
} | ||
} |
Oops, something went wrong.