diff --git a/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java b/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java
index 178b3bbda3d..afce9bb5abd 100644
--- a/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java
+++ b/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * Copyright 2012-2015 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.
@@ -28,13 +28,31 @@ import org.springframework.util.StringUtils;
/**
* {@link PropertySource} that returns a random value for any property that starts with
- * {@literal "random."}. Return a {@code byte[]} unless the property name ends with
- * {@literal ".int} or {@literal ".long"}.
+ * {@literal "random."}. Where the "unqualified property name" is the portion of the
+ * requested property name beyond the "random." prefix, this {@link PropertySource}
+ * returns:
+ *
+ * - When {@literal "int"}, a random {@link Integer} value, restricted by an optionally
+ * specified range.
+ * - When {@literal "long"}, a random {@link Long} value, restricted by an optionally
+ * specified range.
+ * - Otherwise, a {@code byte[]}.
+ *
+ * The {@literal "random.int"} and {@literal "random.long"} properties supports a range
+ * suffix whose syntax is:
+ *
+ * {@code OPEN value (,max) CLOSE} where the {@code OPEN,CLOSE} are any character and
+ * {@code value,max} are integers. If {@code max} is provided then {@code value} is the
+ * minimum value and {@code max} is the maximum (exclusive).
+ *
*
* @author Dave Syer
+ * @author Matt Benson
*/
public class RandomValuePropertySource extends PropertySource {
+ private static final String PREFIX = "random.";
+
private static Log logger = LogFactory.getLog(RandomValuePropertySource.class);
public RandomValuePropertySource(String name) {
@@ -43,35 +61,66 @@ public class RandomValuePropertySource extends PropertySource {
@Override
public Object getProperty(String name) {
- if (!name.startsWith("random.")) {
+ if (!name.startsWith(PREFIX)) {
return null;
}
if (logger.isTraceEnabled()) {
logger.trace("Generating random property for '" + name + "'");
}
- if (name.endsWith("int")) {
+ return getRandomValue(name.substring(PREFIX.length()));
+ }
+
+ private Object getRandomValue(String type) {
+ if (type.equals("int")) {
return getSource().nextInt();
}
- if (name.startsWith("random.long")) {
+ if (type.equals("long")) {
return getSource().nextLong();
}
- if (name.startsWith("random.int") && name.length() > "random.int".length() + 1) {
- String range = name.substring("random.int".length() + 1);
- range = range.substring(0, range.length() - 1);
- return getNextInRange(range);
+ String range = getRange(type, "int");
+ if (range != null) {
+ return getNextIntInRange(range);
}
- byte[] bytes = new byte[32];
- getSource().nextBytes(bytes);
- return DigestUtils.md5DigestAsHex(bytes);
+ range = getRange(type, "long");
+ if (range != null) {
+ return getNextLongInRange(range);
+ }
+ return getRandomBytes();
+ }
+
+ private String getRange(String type, String prefix) {
+ if (type.startsWith(prefix)) {
+ int startIndex = prefix.length() + 1;
+ if (type.length() > startIndex) {
+ return type.substring(startIndex, type.length() - 1);
+ }
+ }
+ return null;
}
- private int getNextInRange(String range) {
+ private int getNextIntInRange(String range) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(range);
- Integer start = Integer.valueOf(tokens[0]);
+ int start = Integer.parseInt(tokens[0]);
if (tokens.length == 1) {
return getSource().nextInt(start);
}
- return start + getSource().nextInt(Integer.valueOf(tokens[1]) - start);
+ return start + getSource().nextInt(Integer.parseInt(tokens[1]) - start);
+ }
+
+ private long getNextLongInRange(String range) {
+ String[] tokens = StringUtils.commaDelimitedListToStringArray(range);
+ if (tokens.length == 1) {
+ return Math.abs(getSource().nextLong()) % Long.parseLong(tokens[0]);
+ }
+ long lowerBound = Long.parseLong(tokens[0]);
+ long upperBound = Long.parseLong(tokens[1]) - lowerBound;
+ return lowerBound + Math.abs(getSource().nextLong()) % upperBound;
+ }
+
+ private Object getRandomBytes() {
+ byte[] bytes = new byte[32];
+ getSource().nextBytes(bytes);
+ return DigestUtils.md5DigestAsHex(bytes);
}
public static void addToEnvironment(ConfigurableEnvironment environment) {
diff --git a/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java b/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java
index 79e8685db77..98dbc9fd126 100644
--- a/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * Copyright 2012-2015 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.
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue;
* Tests for {@link RandomValuePropertySource}.
*
* @author Dave Syer
+ * @author Matt Benson
*/
public class RandomValuePropertySourceTests {
@@ -52,6 +53,7 @@ public class RandomValuePropertySourceTests {
Integer value = (Integer) this.source.getProperty("random.int[4,10]");
assertNotNull(value);
assertTrue(value >= 4);
+ assertTrue(value < 10);
}
@Test
@@ -67,4 +69,18 @@ public class RandomValuePropertySourceTests {
assertNotNull(value);
}
+ @Test
+ public void longRange() {
+ Long value = (Long) this.source.getProperty("random.long[4,10]");
+ assertNotNull(value);
+ assertTrue(Long.toString(value), value >= 4L);
+ assertTrue(Long.toString(value), value < 10L);
+ }
+
+ @Test
+ public void longMax() {
+ Long value = (Long) this.source.getProperty("random.long(10)");
+ assertNotNull(value);
+ assertTrue(value < 10L);
+ }
}