Polish ConditionalOnJava

Apply formating and simplify the condition implementation. Delegate
to Spring's JdkVersion class to obtain the running version.
pull/1050/merge
Phillip Webb 11 years ago
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");
private final String message;
/**
* Equal to, or newer than the specified {@link JavaVersion}.
*/
EQUAL_OR_NEWER,
private Range(String message) {
this.message = message;
}
/**
* Older than the specified {@link JavaVersion}.
*/
OLDER_THAN;
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) {
this.value = value;
}
/**
* Java 1.8.
*/
EIGHT(JdkVersion.JAVA_18, "1.8"),
/**
* Returns the {@link JavaVersion} of the current runtime.
* Java 1.9.
*/
public static JavaVersion fromRuntime() {
NINE(JdkVersion.JAVA_19, "1.9");
String source = System.getProperty("java.version");
private final int value;
for (JavaVersion version : JavaVersion.values()) {
if (source.startsWith(version.value)) {
return version;
}
}
private final String name;
throw new IllegalArgumentException(String.format(
"Could not detect Java version for %s.", source));
private JavaVersion(int value, String name) {
this.value = value;
this.name = name;
}
/**
* Returns whether the given {@link JavaVersion} is considered equal or better
* than the given one.
*
* @param version must not be {code null}.
* 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 isEqualOrBetter(JavaVersion version) {
Assert.notNull(version, "Java version must not be null!");
return this.value.compareTo(version.value) >= 0;
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.value;
return this.name;
}
/**
* Returns the {@link JavaVersion} of the current runtime.
*/
public static JavaVersion getJavaVersion() {
int version = JdkVersion.getMajorJavaVersion();
for (JavaVersion candidate : JavaVersion.values()) {
if (candidate.value == version) {
return candidate;
}
}
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));
boolean equalOrBetter = JVM_VERSION.isEqualOrBetter(version);
protected ConditionOutcome getMatchOutcome(Range range, JavaVersion runningVersion,
JavaVersion version) {
boolean match = runningVersion.isWithin(range, version);
return new ConditionOutcome(match, getMessage(range, runningVersion, 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() {
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"));
}
this.context.register(Java6Required.class);
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();
}
assertPresent(true);
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…
Cancel
Save