Skip to content

Commit 4a6e66f

Browse files
author
Phillip Webb
committed
Polish ConditionalOnJava
Apply formating and simplify the condition implementation. Delegate to Spring's JdkVersion class to obtain the running version.
1 parent 2df4ead commit 4a6e66f

File tree

3 files changed

+128
-78
lines changed

3 files changed

+128
-78
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
import java.lang.annotation.Target;
2323

2424
import org.springframework.context.annotation.Conditional;
25+
import org.springframework.core.JdkVersion;
2526
import org.springframework.util.Assert;
2627

2728
/**
2829
* {@link Conditional} that matches based on the JVM version the application is running
2930
* on.
30-
*
31+
*
3132
* @author Oliver Gierke
33+
* @author Phillip Webb
3234
* @since 1.1.0
3335
*/
3436
@Target({ ElementType.TYPE, ElementType.METHOD })
@@ -41,7 +43,6 @@
4143
* Configures whether the value configured in {@link #value()} shall be considered the
4244
* upper exclusive or lower inclusive boundary. Defaults to
4345
* {@link Range#EQUAL_OR_NEWER}.
44-
* @return the range of the version
4546
*/
4647
Range range() default Range.EQUAL_OR_NEWER;
4748

@@ -51,66 +52,91 @@
5152
*/
5253
JavaVersion value();
5354

55+
/**
56+
* Range options.
57+
*/
5458
public enum Range {
5559

56-
OLDER_THAN("older than %s"), EQUAL_OR_NEWER("%s or newer");
57-
58-
private final String message;
60+
/**
61+
* Equal to, or newer than the specified {@link JavaVersion}.
62+
*/
63+
EQUAL_OR_NEWER,
5964

60-
private Range(String message) {
61-
this.message = message;
62-
}
65+
/**
66+
* Older than the specified {@link JavaVersion}.
67+
*/
68+
OLDER_THAN;
6369

64-
public String getMessage(JavaVersion version) {
65-
return String.format(this.message, version);
66-
}
6770
}
6871

6972
/**
70-
* An enum to abstract major Java versions.
73+
* Java versions.
7174
*/
7275
public enum JavaVersion {
7376

74-
FIVE("1.5"), SIX("1.6"), SEVEN("1.7"), EIGHT("1.8"), NINE("1.9");
77+
/**
78+
* Java 1.6.
79+
*/
80+
SIX(JdkVersion.JAVA_16, "1.6"),
7581

76-
private String value;
82+
/**
83+
* Java 1.7.
84+
*/
85+
SEVEN(JdkVersion.JAVA_17, "1.7"),
7786

78-
private JavaVersion(String value) {
79-
this.value = value;
80-
}
87+
/**
88+
* Java 1.8.
89+
*/
90+
EIGHT(JdkVersion.JAVA_18, "1.8"),
8191

8292
/**
83-
* Returns the {@link JavaVersion} of the current runtime.
93+
* Java 1.9.
8494
*/
85-
public static JavaVersion fromRuntime() {
95+
NINE(JdkVersion.JAVA_19, "1.9");
8696

87-
String source = System.getProperty("java.version");
97+
private final int value;
8898

89-
for (JavaVersion version : JavaVersion.values()) {
90-
if (source.startsWith(version.value)) {
91-
return version;
92-
}
93-
}
99+
private final String name;
94100

95-
throw new IllegalArgumentException(String.format(
96-
"Could not detect Java version for %s.", source));
101+
private JavaVersion(int value, String name) {
102+
this.value = value;
103+
this.name = name;
97104
}
98105

99106
/**
100-
* Returns whether the given {@link JavaVersion} is considered equal or better
101-
* than the given one.
102-
*
103-
* @param version must not be {code null}.
107+
* Determines if this version is within the specified range of versions.
108+
* @param range the range
109+
* @param version the bounds of the range
110+
* @return if this version is within the specified range
104111
*/
105-
public boolean isEqualOrBetter(JavaVersion version) {
106-
107-
Assert.notNull(version, "Java version must not be null!");
108-
return this.value.compareTo(version.value) >= 0;
112+
public boolean isWithin(Range range, JavaVersion version) {
113+
Assert.notNull(range, "Range must not be null");
114+
Assert.notNull(version, "Version must not be null");
115+
switch (range) {
116+
case EQUAL_OR_NEWER:
117+
return this.value >= version.value;
118+
case OLDER_THAN:
119+
return this.value < version.value;
120+
}
121+
throw new IllegalStateException("Unknown range " + range);
109122
}
110123

111124
@Override
112125
public String toString() {
113-
return this.value;
126+
return this.name;
127+
}
128+
129+
/**
130+
* Returns the {@link JavaVersion} of the current runtime.
131+
*/
132+
public static JavaVersion getJavaVersion() {
133+
int version = JdkVersion.getMajorJavaVersion();
134+
for (JavaVersion candidate : JavaVersion.values()) {
135+
if (candidate.value == version) {
136+
return candidate;
137+
}
138+
}
139+
return SIX;
114140
}
115141
}
116142
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,35 @@
2626

2727
/**
2828
* {@link Condition} that checks for a required version of Java
29-
*
29+
*
3030
* @author Oliver Gierke
31+
* @author Phillip Webb
3132
* @see ConditionalOnJava
3233
* @since 1.1.0
3334
*/
3435
class OnJavaCondition extends SpringBootCondition {
3536

36-
private static final JavaVersion JVM_VERSION = JavaVersion.fromRuntime();
37-
private static final String MATCH_MESSAGE = "Required JVM version %s and found %s.";
38-
private static final String NO_MATCH_MESSAGE = "Required JVM version %s but found %s.";
37+
private static final JavaVersion JVM_VERSION = JavaVersion.getJavaVersion();
3938

4039
@Override
4140
public ConditionOutcome getMatchOutcome(ConditionContext context,
4241
AnnotatedTypeMetadata metadata) {
43-
4442
Map<String, Object> attributes = metadata
4543
.getAnnotationAttributes(ConditionalOnJava.class.getName());
46-
47-
JavaVersion version = (JavaVersion) attributes.get("value");
4844
Range range = (Range) attributes.get("range");
45+
JavaVersion version = (JavaVersion) attributes.get("value");
46+
return getMatchOutcome(range, JVM_VERSION, version);
47+
}
4948

50-
ConditionOutcome match = ConditionOutcome.match(//
51-
String.format(MATCH_MESSAGE, range.getMessage(version), JVM_VERSION));
52-
ConditionOutcome noMatch = ConditionOutcome.noMatch(//
53-
String.format(NO_MATCH_MESSAGE, range.getMessage(version), JVM_VERSION));
54-
55-
boolean equalOrBetter = JVM_VERSION.isEqualOrBetter(version);
49+
protected ConditionOutcome getMatchOutcome(Range range, JavaVersion runningVersion,
50+
JavaVersion version) {
51+
boolean match = runningVersion.isWithin(range, version);
52+
return new ConditionOutcome(match, getMessage(range, runningVersion, version));
53+
}
5654

57-
switch (range) {
58-
case OLDER_THAN:
59-
return equalOrBetter ? noMatch : match;
60-
case EQUAL_OR_NEWER:
61-
default:
62-
return equalOrBetter ? match : noMatch;
63-
}
55+
private String getMessage(Range range, JavaVersion runningVersion, JavaVersion version) {
56+
String expected = String.format(range == Range.EQUAL_OR_NEWER ? "%s or newer"
57+
: "older than %s", version);
58+
return "Required JVM version " + expected + " found " + runningVersion;
6459
}
6560
}

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,60 +24,97 @@
2424
import org.springframework.context.annotation.Bean;
2525
import org.springframework.context.annotation.Configuration;
2626

27+
import static org.hamcrest.Matchers.equalTo;
2728
import static org.hamcrest.Matchers.is;
2829
import static org.hamcrest.Matchers.iterableWithSize;
2930
import static org.junit.Assert.assertThat;
3031

3132
/**
3233
* Tests for {@link ConditionalOnJava}.
33-
*
34+
*
3435
* @author Oliver Gierke
36+
* @author Phillip Webb
3537
*/
3638
public class ConditionalOnJavaTests {
3739

3840
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
3941

42+
private final OnJavaCondition condition = new OnJavaCondition();
43+
4044
@Test
4145
public void doesNotMatchIfBetterVersionIsRequired() {
42-
43-
this.context.register(Java9Required.class);
44-
this.context.refresh();
45-
46+
registerAndRefresh(Java9Required.class);
4647
assertPresent(false);
4748
}
4849

4950
@Test
5051
public void doesNotMatchIfLowerIsRequired() {
51-
52-
this.context.register(Java5Required.class);
53-
this.context.refresh();
54-
52+
registerAndRefresh(Java5Required.class);
5553
assertPresent(false);
5654
}
5755

5856
@Test
5957
public void matchesIfVersionIsInRange() {
58+
registerAndRefresh(Java6Required.class);
59+
assertPresent(true);
60+
}
61+
62+
@Test
63+
public void boundsTests() throws Exception {
64+
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.SIX, true);
65+
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.SEVEN, true);
66+
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.SEVEN, JavaVersion.EIGHT, false);
67+
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.SIX, false);
68+
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.SEVEN, false);
69+
testBounds(Range.OLDER_THAN, JavaVersion.SEVEN, JavaVersion.EIGHT, true);
70+
}
71+
72+
@Test
73+
public void equalOrNewerMessage() throws Exception {
74+
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.EQUAL_OR_NEWER,
75+
JavaVersion.SEVEN, JavaVersion.SIX);
76+
assertThat(outcome.getMessage(), equalTo("Required JVM version "
77+
+ "1.6 or newer found 1.7"));
78+
}
79+
80+
@Test
81+
public void olderThanMessage() throws Exception {
82+
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.OLDER_THAN,
83+
JavaVersion.SEVEN, JavaVersion.SIX);
84+
assertThat(outcome.getMessage(), equalTo("Required JVM version "
85+
+ "older than 1.6 found 1.7"));
86+
}
6087

61-
this.context.register(Java6Required.class);
88+
private void testBounds(Range range, JavaVersion runningVersion, JavaVersion version,
89+
boolean expected) {
90+
ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion,
91+
version);
92+
assertThat(outcome.getMessage(), outcome.isMatch(), equalTo(expected));
93+
}
94+
95+
private void registerAndRefresh(Class<?> annotatedClasses) {
96+
this.context.register(annotatedClasses);
6297
this.context.refresh();
98+
}
6399

64-
assertPresent(true);
100+
private void assertPresent(boolean expected) {
101+
int expectedNumber = expected ? 1 : 0;
102+
Matcher<Iterable<String>> matcher = iterableWithSize(expectedNumber);
103+
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher));
65104
}
66105

67106
@Configuration
68107
@ConditionalOnJava(JavaVersion.NINE)
69108
static class Java9Required {
70-
71109
@Bean
72110
String foo() {
73111
return "foo";
74112
}
75113
}
76114

77115
@Configuration
78-
@ConditionalOnJava(value = JavaVersion.SIX, range = Range.OLDER_THAN)
116+
@ConditionalOnJava(range = Range.OLDER_THAN, value = JavaVersion.SIX)
79117
static class Java5Required {
80-
81118
@Bean
82119
String foo() {
83120
return "foo";
@@ -87,18 +124,10 @@ String foo() {
87124
@Configuration
88125
@ConditionalOnJava(JavaVersion.SIX)
89126
static class Java6Required {
90-
91127
@Bean
92128
String foo() {
93129
return "foo";
94130
}
95131
}
96132

97-
private void assertPresent(boolean expected) {
98-
99-
int expectedNumber = expected ? 1 : 0;
100-
Matcher<Iterable<String>> matcher = iterableWithSize(expectedNumber);
101-
102-
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher));
103-
}
104133
}

0 commit comments

Comments
 (0)