Browse Source

Add @ConditionalOnJava

Added a new @ConditionalOnJava annotation that allows to conditionally
enable configuration based on the Java version that is running. 

The annotation currently supports two modes of restricting Java versions:
the default mode checks for a Java version equal or better than the
requested one. Beyond that it can be configured to only match if Java
version is older than the configured one.
pull/1049/head
Oliver Gierke 12 years ago committed by Andy Wilkinson
parent
commit
30bef1e95e
  1. 116
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJava.java
  2. 65
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnJavaCondition.java
  3. 104
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnJavaTests.java

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

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.condition;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Conditional;
import org.springframework.util.Assert;
/**
* {@link Conditional} that matches based on the JVM version the application is running
* on.
*
* @author Oliver Gierke
* @since 1.1.0
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnJavaCondition.class)
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;
/**
* The {@link JavaVersion} to check for. Use {@link #range()} to specify whether the
* configured value is an upper-exclusive or lower-inclusive boundary.
*/
JavaVersion value();
public enum Range {
OLDER_THAN("older than %s"), EQUAL_OR_NEWER("%s or newer");
private final String message;
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.
*/
public enum JavaVersion {
FIVE("1.5"), SIX("1.6"), SEVEN("1.7"), EIGHT("1.8"), NINE("1.9");
private String value;
private JavaVersion(String value) {
this.value = value;
}
/**
* 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;
}
}
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;
}
}
}

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

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.condition;
import java.util.Map;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.Range;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* {@link Condition} that checks for a required version of Java
*
* @author Oliver Gierke
* @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.";
@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");
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);
switch (range) {
case OLDER_THAN:
return equalOrBetter ? noMatch : match;
case EQUAL_OR_NEWER:
default:
return equalOrBetter ? match : noMatch;
}
}
}

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

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.condition;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.Range;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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
*/
public class ConditionalOnJavaTests {
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void doesNotMatchIfBetterVersionIsRequired() {
this.context.register(Java9Required.class);
this.context.refresh();
assertPresent(false);
}
@Test
public void doesNotMatchIfLowerIsRequired() {
this.context.register(Java5Required.class);
this.context.refresh();
assertPresent(false);
}
@Test
public void matchesIfVersionIsInRange() {
this.context.register(Java6Required.class);
this.context.refresh();
assertPresent(true);
}
@Configuration
@ConditionalOnJava(JavaVersion.NINE)
static class Java9Required {
@Bean
String foo() {
return "foo";
}
}
@Configuration
@ConditionalOnJava(value = JavaVersion.SIX, range = Range.OLDER_THAN)
static class Java5Required {
@Bean
String foo() {
return "foo";
}
}
@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