Polish ConditionalOnJava
Apply formating and simplify the condition implementation. Delegate to Spring's JdkVersion class to obtain the running version.
This commit is contained in:
parent
2df4ead4d6
commit
4a6e66fe8b
|
@ -22,13 +22,15 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.core.JdkVersion;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link Conditional} that matches based on the JVM version the application is running
|
||||
* on.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Phillip Webb
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
|
@ -41,7 +43,6 @@ public @interface ConditionalOnJava {
|
|||
* Configures whether the value configured in {@link #value()} shall be considered the
|
||||
* upper exclusive or lower inclusive boundary. Defaults to
|
||||
* {@link Range#EQUAL_OR_NEWER}.
|
||||
* @return the range of the version
|
||||
*/
|
||||
Range range() default Range.EQUAL_OR_NEWER;
|
||||
|
||||
|
@ -51,66 +52,91 @@ public @interface ConditionalOnJava {
|
|||
*/
|
||||
JavaVersion value();
|
||||
|
||||
/**
|
||||
* Range options.
|
||||
*/
|
||||
public enum Range {
|
||||
|
||||
OLDER_THAN("older than %s"), EQUAL_OR_NEWER("%s or newer");
|
||||
/**
|
||||
* Equal to, or newer than the specified {@link JavaVersion}.
|
||||
*/
|
||||
EQUAL_OR_NEWER,
|
||||
|
||||
private final String message;
|
||||
/**
|
||||
* Older than the specified {@link JavaVersion}.
|
||||
*/
|
||||
OLDER_THAN;
|
||||
|
||||
private Range(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage(JavaVersion version) {
|
||||
return String.format(this.message, version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum to abstract major Java versions.
|
||||
* Java versions.
|
||||
*/
|
||||
public enum JavaVersion {
|
||||
|
||||
FIVE("1.5"), SIX("1.6"), SEVEN("1.7"), EIGHT("1.8"), NINE("1.9");
|
||||
/**
|
||||
* Java 1.6.
|
||||
*/
|
||||
SIX(JdkVersion.JAVA_16, "1.6"),
|
||||
|
||||
private String value;
|
||||
/**
|
||||
* Java 1.7.
|
||||
*/
|
||||
SEVEN(JdkVersion.JAVA_17, "1.7"),
|
||||
|
||||
private JavaVersion(String value) {
|
||||
/**
|
||||
* Java 1.8.
|
||||
*/
|
||||
EIGHT(JdkVersion.JAVA_18, "1.8"),
|
||||
|
||||
/**
|
||||
* Java 1.9.
|
||||
*/
|
||||
NINE(JdkVersion.JAVA_19, "1.9");
|
||||
|
||||
private final int value;
|
||||
|
||||
private final String name;
|
||||
|
||||
private JavaVersion(int value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this version is within the specified range of versions.
|
||||
* @param range the range
|
||||
* @param version the bounds of the range
|
||||
* @return if this version is within the specified range
|
||||
*/
|
||||
public boolean isWithin(Range range, JavaVersion version) {
|
||||
Assert.notNull(range, "Range must not be null");
|
||||
Assert.notNull(version, "Version must not be null");
|
||||
switch (range) {
|
||||
case EQUAL_OR_NEWER:
|
||||
return this.value >= version.value;
|
||||
case OLDER_THAN:
|
||||
return this.value < version.value;
|
||||
}
|
||||
throw new IllegalStateException("Unknown range " + range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link JavaVersion} of the current runtime.
|
||||
*/
|
||||
public static JavaVersion fromRuntime() {
|
||||
|
||||
String source = System.getProperty("java.version");
|
||||
|
||||
for (JavaVersion version : JavaVersion.values()) {
|
||||
if (source.startsWith(version.value)) {
|
||||
return version;
|
||||
public static JavaVersion getJavaVersion() {
|
||||
int version = JdkVersion.getMajorJavaVersion();
|
||||
for (JavaVersion candidate : JavaVersion.values()) {
|
||||
if (candidate.value == version) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Could not detect Java version for %s.", source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link JavaVersion} is considered equal or better
|
||||
* than the given one.
|
||||
*
|
||||
* @param version must not be {code null}.
|
||||
*/
|
||||
public boolean isEqualOrBetter(JavaVersion version) {
|
||||
|
||||
Assert.notNull(version, "Java version must not be null!");
|
||||
return this.value.compareTo(version.value) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
return SIX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,40 +26,35 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
|||
|
||||
/**
|
||||
* {@link Condition} that checks for a required version of Java
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Phillip Webb
|
||||
* @see ConditionalOnJava
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class OnJavaCondition extends SpringBootCondition {
|
||||
|
||||
private static final JavaVersion JVM_VERSION = JavaVersion.fromRuntime();
|
||||
private static final String MATCH_MESSAGE = "Required JVM version %s and found %s.";
|
||||
private static final String NO_MATCH_MESSAGE = "Required JVM version %s but found %s.";
|
||||
private static final JavaVersion JVM_VERSION = JavaVersion.getJavaVersion();
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
|
||||
Map<String, Object> attributes = metadata
|
||||
.getAnnotationAttributes(ConditionalOnJava.class.getName());
|
||||
|
||||
JavaVersion version = (JavaVersion) attributes.get("value");
|
||||
Range range = (Range) attributes.get("range");
|
||||
JavaVersion version = (JavaVersion) attributes.get("value");
|
||||
return getMatchOutcome(range, JVM_VERSION, version);
|
||||
}
|
||||
|
||||
ConditionOutcome match = ConditionOutcome.match(//
|
||||
String.format(MATCH_MESSAGE, range.getMessage(version), JVM_VERSION));
|
||||
ConditionOutcome noMatch = ConditionOutcome.noMatch(//
|
||||
String.format(NO_MATCH_MESSAGE, range.getMessage(version), JVM_VERSION));
|
||||
protected ConditionOutcome getMatchOutcome(Range range, JavaVersion runningVersion,
|
||||
JavaVersion version) {
|
||||
boolean match = runningVersion.isWithin(range, version);
|
||||
return new ConditionOutcome(match, getMessage(range, runningVersion, version));
|
||||
}
|
||||
|
||||
boolean equalOrBetter = JVM_VERSION.isEqualOrBetter(version);
|
||||
|
||||
switch (range) {
|
||||
case OLDER_THAN:
|
||||
return equalOrBetter ? noMatch : match;
|
||||
case EQUAL_OR_NEWER:
|
||||
default:
|
||||
return equalOrBetter ? match : noMatch;
|
||||
}
|
||||
private String getMessage(Range range, JavaVersion runningVersion, JavaVersion version) {
|
||||
String expected = String.format(range == Range.EQUAL_OR_NEWER ? "%s or newer"
|
||||
: "older than %s", version);
|
||||
return "Required JVM version " + expected + " found " + runningVersion;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,50 +24,88 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.iterableWithSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnJava}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ConditionalOnJavaTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
private final OnJavaCondition condition = new OnJavaCondition();
|
||||
|
||||
@Test
|
||||
public void doesNotMatchIfBetterVersionIsRequired() {
|
||||
|
||||
this.context.register(Java9Required.class);
|
||||
this.context.refresh();
|
||||
|
||||
registerAndRefresh(Java9Required.class);
|
||||
assertPresent(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotMatchIfLowerIsRequired() {
|
||||
|
||||
this.context.register(Java5Required.class);
|
||||
this.context.refresh();
|
||||
|
||||
registerAndRefresh(Java5Required.class);
|
||||
assertPresent(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesIfVersionIsInRange() {
|
||||
|
||||
this.context.register(Java6Required.class);
|
||||
this.context.refresh();
|
||||
|
||||
registerAndRefresh(Java6Required.class);
|
||||
assertPresent(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boundsTests() throws Exception {
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.SIX, true);
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.SEVEN, true);
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.EIGHT, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.SIX, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.SEVEN, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.EIGHT, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalOrNewerMessage() throws Exception {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.EQUAL_OR_NEWER,
|
||||
JavaVersion.SEVEN, JavaVersion.SIX);
|
||||
assertThat(outcome.getMessage(), equalTo("Required JVM version "
|
||||
+ "1.6 or newer found 1.7"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void olderThanMessage() throws Exception {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.OLDER_THAN,
|
||||
JavaVersion.SEVEN, JavaVersion.SIX);
|
||||
assertThat(outcome.getMessage(), equalTo("Required JVM version "
|
||||
+ "older than 1.6 found 1.7"));
|
||||
}
|
||||
|
||||
private void testBounds(Range range, JavaVersion runningVersion, JavaVersion version,
|
||||
boolean expected) {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion,
|
||||
version);
|
||||
assertThat(outcome.getMessage(), outcome.isMatch(), equalTo(expected));
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?> annotatedClasses) {
|
||||
this.context.register(annotatedClasses);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private void assertPresent(boolean expected) {
|
||||
int expectedNumber = expected ? 1 : 0;
|
||||
Matcher<Iterable<String>> matcher = iterableWithSize(expectedNumber);
|
||||
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(JavaVersion.NINE)
|
||||
static class Java9Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
|
@ -75,9 +113,8 @@ public class ConditionalOnJavaTests {
|
|||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(value = JavaVersion.SIX, range = Range.OLDER_THAN)
|
||||
@ConditionalOnJava(range = Range.OLDER_THAN, value = JavaVersion.SIX)
|
||||
static class Java5Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
|
@ -87,18 +124,10 @@ public class ConditionalOnJavaTests {
|
|||
@Configuration
|
||||
@ConditionalOnJava(JavaVersion.SIX)
|
||||
static class Java6Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
private void assertPresent(boolean expected) {
|
||||
|
||||
int expectedNumber = expected ? 1 : 0;
|
||||
Matcher<Iterable<String>> matcher = iterableWithSize(expectedNumber);
|
||||
|
||||
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue