From 4a6e66fe8bbd74f0526dce04d3bdbfcbe8e42bdd Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 6 Jun 2014 22:24:32 -0700 Subject: [PATCH] Polish ConditionalOnJava Apply formating and simplify the condition implementation. Delegate to Spring's JdkVersion class to obtain the running version. --- .../condition/ConditionalOnJava.java | 98 ++++++++++++------- .../condition/OnJavaCondition.java | 35 +++---- .../condition/ConditionalOnJavaTests.java | 73 +++++++++----- 3 files changed, 128 insertions(+), 78 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java index 141b7ad425..6e63ef0412 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java @@ -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; } } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java index c0e0e77c3c..9f2265e66e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java @@ -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 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; } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java index 132077f141..6a4886fe32 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java @@ -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> 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> matcher = iterableWithSize(expectedNumber); - - assertThat(this.context.getBeansOfType(String.class).values(), is(matcher)); - } }