Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
*/
package org.apache.maven.toolchain;

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import java.util.Locale;
import java.util.Objects;

import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.VersionScheme;

/**
*
Expand All @@ -38,16 +41,17 @@ public static RequirementMatcher createVersionMatcher(String provideValue) {
}

private static final class ExactMatcher implements RequirementMatcher {

private String provides;
private final String provides;

private ExactMatcher(String provides) {
this.provides = provides;
}

@Override
public boolean matches(String requirement) {
return provides.equalsIgnoreCase(requirement);
return Objects.equals(
provides != null ? provides.toLowerCase(Locale.ENGLISH) : null,
requirement != null ? requirement.toLowerCase(Locale.ENGLISH) : null);
}

@Override
Expand All @@ -57,31 +61,76 @@ public String toString() {
}

private static final class VersionMatcher implements RequirementMatcher {
DefaultArtifactVersion version;
private final String version;

private VersionMatcher(String version) {
this.version = new DefaultArtifactVersion(version);
this.version = version;
}

@Override
public boolean matches(String requirement) {
try {
VersionRange range = VersionRange.createFromVersionSpec(requirement);
if (range.hasRestrictions()) {
return range.containsVersion(version);
String r = requirement != null ? requirement.toLowerCase(Locale.ENGLISH) : null;
String v = version != null ? version.toLowerCase(Locale.ENGLISH) : null;
if (v == null && r == null) {
return true; // null == null
}
if (v == null || r == null) {
return false; // null != non-null
}
if (v.equals(r)) {
return true; // str == str (ignoring case)
}
return matchesRequirement(v, r);
}

private static final VersionScheme VERSION_SCHEME = new GenericVersionScheme();

private static boolean matchesRequirement(String version, String requirement) {
// if requirement is not a version range itself
if (!requirement.contains("[") && !requirement.contains("(") && !requirement.contains(",")) {
boolean interval = false;
boolean included = false;
if (requirement.endsWith("+")) {
interval = true;
included = true;
requirement = requirement.substring(0, requirement.length() - 1);
} else if (requirement.endsWith("-")) {
interval = true;
requirement = requirement.substring(0, requirement.length() - 1);
}
if (!interval) {
return version.startsWith(requirement + "."); // "11" -> "11.xxx"
} else {
return range.getRecommendedVersion().compareTo(version) == 0;
try {
if (included) {
return VERSION_SCHEME
.parseVersionRange("[" + requirement + ",)")
.containsVersion(VERSION_SCHEME.parseVersion(version)); // "11+" -> "[11,)"
} else {
return VERSION_SCHEME
.parseVersionRange("(," + requirement + ")")
.containsVersion(VERSION_SCHEME.parseVersion(version)); // "11-" -> "(,11)"
}
} catch (InvalidVersionSpecificationException e) {
// nope; GenericVersionScheme never throes but we need to make compiler happy
throw new RuntimeException(e);
}
}
} else {
try {
return VERSION_SCHEME
.parseVersionRange(requirement)
.containsVersion(VERSION_SCHEME.parseVersion(version)); // "range" -> "range"
} catch (InvalidVersionSpecificationException e) {
// nope; GenericVersionScheme never throes but we need to make compiler happy
throw new RuntimeException(e);
}
} catch (InvalidVersionSpecificationException ex) {
// TODO error reporting
ex.printStackTrace();
return false;
}
}

@Override
public String toString() {
return version.toString();
return version;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*/
package org.apache.maven.toolchain;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -50,17 +54,56 @@ public void testCreateExactMatcher() {
public void testCreateVersionMatcher() {
RequirementMatcher matcher;
matcher = RequirementMatcherFactory.createVersionMatcher("1.5.2");
assertFalse(matcher.matches("1.5"));
assertTrue(matcher.matches("1"));
assertTrue(matcher.matches("1.5"));
assertTrue(matcher.matches("1.5.2"));
assertFalse(matcher.matches("[1.4,1.5)"));
assertFalse(matcher.matches("[1.5,1.5.2)"));
assertFalse(matcher.matches("(1.5.2,1.6)"));
assertTrue(matcher.matches("(1.4,1.5.2]"));
assertTrue(matcher.matches("(1.5,)"));

assertTrue(matcher.matches("1.5+"));
assertFalse(matcher.matches("1.5-"));

assertFalse(matcher.matches("1.6+"));
assertTrue(matcher.matches("1.6-"));

assertEquals("1.5.2", matcher.toString());

// Ensure it is not printed as 1.5.0
matcher = RequirementMatcherFactory.createVersionMatcher("1.5");
assertEquals("1.5", matcher.toString());
}

@Test
public void testCreateVersionMatcherWithJavaVersions() {
RequirementMatcher java25 = RequirementMatcherFactory.createVersionMatcher("25.0.2");
RequirementMatcher java21 = RequirementMatcherFactory.createVersionMatcher("21.0.10");
RequirementMatcher java17 = RequirementMatcherFactory.createVersionMatcher("17.0.18");
RequirementMatcher java11 = RequirementMatcherFactory.createVersionMatcher("11.0.30");
RequirementMatcher java8 = RequirementMatcherFactory.createVersionMatcher("1.8.0_482");
List<RequirementMatcher> matchers = Arrays.asList(java25, java21, java17, java11, java8);

testMatch("11", matchers, java11);
testMatch("11+", matchers, java25, java21, java17, java11);
testMatch("11-", matchers, java8);
testMatch("[11,21)", matchers, java17, java11);
testMatch("1.8", matchers, java8);
testMatch("1.8+", matchers, java25, java21, java17, java11, java8);
testMatch("8", matchers);
testMatch("8+", matchers, java25, java21, java17, java11);
}

private static void testMatch(
String requirement, Collection<RequirementMatcher> allMatchers, RequirementMatcher... requiredMatchers) {
int matches = 0;
for (RequirementMatcher matcher : allMatchers) {
if (matcher.matches(requirement)) {
matches++;
assertTrue(Arrays.asList(requiredMatchers).contains(matcher));
}
}
assertEquals(matches, requiredMatchers.length);
}
}