You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by pa...@apache.org on 2017/04/28 14:27:16 UTC
[3/4] [text] TEXT-81: Add RandomStringGenerator (closes #36)
TEXT-81: Add RandomStringGenerator (closes #36)
add changes.xml entries for TEXT-81 and TEXT-36
fix checkstyle violations
other minimal clean-up
fix checkstyle
Project: http://git-wip-us.apache.org/repos/asf/commons-text/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-text/commit/c72a24bc
Tree: http://git-wip-us.apache.org/repos/asf/commons-text/tree/c72a24bc
Diff: http://git-wip-us.apache.org/repos/asf/commons-text/diff/c72a24bc
Branch: refs/heads/master
Commit: c72a24bc24f2650a71bee0418b2ee3609f297cdc
Parents: 8d14206
Author: Pascal Schumacher <pa...@gmx.net>
Authored: Mon Apr 24 22:28:09 2017 +0200
Committer: Pascal Schumacher <pa...@gmx.net>
Committed: Fri Apr 28 16:26:36 2017 +0200
----------------------------------------------------------------------
src/changes/changes.xml | 2 +
.../commons/text/RandomStringGenerator.java | 106 ++++++++-----------
.../apache/commons/text/TextRandomProvider.java | 4 +-
.../commons/text/RandomStringGeneratorTest.java | 66 ++++++------
4 files changed, 82 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-text/blob/c72a24bc/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cd59174..91067bb 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,6 +46,8 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="1.1" date="tbd" description="tbd">
+ <action issue="TEXT-81" type="add" dev="pschumacher" dev="djones">Add RandomStringGenerator</action>
+ <action issue="TEXT-36" type="add" dev="pschumacher" due-to="Raymond DeCampo">RandomStringGenerator: allow users to provide source of randomness</action>
<action issue="TEXT-76" type="fix" dev="kinow">Correct round issue in Jaro Winkler implementation</action>
<action issue="TEXT-72" type="fix" dev="chtompki">Similar to LANG-1025, clirr fails site build.</action>
</release>
http://git-wip-us.apache.org/repos/asf/commons-text/blob/c72a24bc/src/main/java/org/apache/commons/text/RandomStringGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/text/RandomStringGenerator.java b/src/main/java/org/apache/commons/text/RandomStringGenerator.java
index 7eb45d9..ab7fd9d 100644
--- a/src/main/java/org/apache/commons/text/RandomStringGenerator.java
+++ b/src/main/java/org/apache/commons/text/RandomStringGenerator.java
@@ -27,7 +27,12 @@ import java.util.concurrent.ThreadLocalRandom;
* callers to define the properties of the generator. See the documentation for the
* {@link Builder} class to see available properties.
* </p>
- *
+ * <pre>
+ * // Generates a 20 code point string, using only the letters a-z
+ * RandomStringGenerator generator = new RandomStringGenerator.Builder()
+ * .withinRange('a', 'z').build();
+ * String randomLetters = generator.generate(20);
+ * </pre>
* <pre>
* // Using Apache Commons RNG for randomness
* UniformRandomProvider rng = RandomSource.create(...);
@@ -36,14 +41,12 @@ import java.util.concurrent.ThreadLocalRandom;
* .withinRange('a', 'z')
* .usingRandom(rng::nextInt) // uses Java 8 syntax
* .build();
- * String random = generator.generate(20);
+ * String randomLetters = generator.generate(20);
* </pre>
- *
* <p>
* {@code RandomStringBuilder} instances are immutable and thread-safe.
* </p>
- *
- * @since 1.0
+ * @since 1.1
*/
public final class RandomStringGenerator {
@@ -52,10 +55,9 @@ public final class RandomStringGenerator {
private final Set<CharacterPredicate> inclusivePredicates;
private final TextRandomProvider random;
-
/**
* Constructs the generator.
- *
+ *
* @param minimumCodePoint
* smallest allowed code point (inclusive)
* @param maximumCodePoint
@@ -72,12 +74,11 @@ public final class RandomStringGenerator {
this.inclusivePredicates = inclusivePredicates;
this.random = random;
}
-
+
/**
- * Generates a random number within a range, using a
- * {@link ThreadLocalRandom} instance or the user-supplied source of
- * randomness.
- *
+ * Generates a random number within a range, using a {@link ThreadLocalRandom} instance
+ * or the user-supplied source of randomness.
+ *
* @param minInclusive
* the minimum value allowed
* @param maxInclusive
@@ -88,11 +89,9 @@ public final class RandomStringGenerator {
if (random != null) {
return random.nextInt(maxInclusive - minInclusive + 1) + minInclusive;
}
-
return ThreadLocalRandom.current().nextInt(minInclusive, maxInclusive + 1);
}
-
/**
* <p>
* Generates a random string, containing the specified number of code points.
@@ -109,19 +108,17 @@ public final class RandomStringGenerator {
* {@link Character} documentation to understand how Java stores Unicode
* values.
* </p>
- *
+ *
* @param length
* the number of code points to generate
* @return the generated string
* @throws IllegalArgumentException
* if {@code length < 0}
- * @since 1.0
*/
public String generate(final int length) {
if (length == 0) {
return "";
}
-
if (length < 0) {
throw new IllegalArgumentException(String.format("Length %d is smaller than zero.", length));
}
@@ -137,6 +134,7 @@ public final class RandomStringGenerator {
case Character.PRIVATE_USE:
case Character.SURROGATE:
continue;
+ default:
}
if (inclusivePredicates != null) {
@@ -159,52 +157,44 @@ public final class RandomStringGenerator {
return builder.toString();
}
-
-
+
/**
* <p>A builder for generating {@code RandomStringGenerator} instances.</p>
* <p>The behaviour of a generator is controlled by properties set by this
* builder. Each property has a default value, which can be overridden by
* calling the methods defined in this class, prior to calling {@link #build()}.</p>
- *
+ *
* <p>All the property setting methods return the {@code Builder} instance to allow for method chaining.</p>
- *
+ *
* <p>The minimum and maximum code point values are defined using {@link #withinRange(int, int)}. The
* default values are {@code 0} and {@link Character#MAX_CODE_POINT} respectively.</p>
- *
- * <p>The source of randomness can be set using {@link #usingRandom(TextRandomProvider) }, otherwise {@link ThreadLocalRandom}
- * is used.</p>
- *
- * <p>The type of code points returned can be filtered using {@link #filteredBy(CharacterPredicate...)},
- * which defines a collection of
- * tests that are applied to the randomly generated code points. The code points
- * will only be included in the result if they pass at least one of the tests.
+ *
+ * <p>The source of randomness can be set using {@link #usingRandom(TextRandomProvider)},
+ * otherwise {@link ThreadLocalRandom} is used.</p>
+ *
+ * <p>The type of code points returned can be filtered using {@link #filteredBy(CharacterPredicate...)},
+ * which defines a collection of tests that are applied to the randomly generated code points.
+ * The code points will only be included in the result if they pass at least one of the tests.
* Some commonly used predicates are provided by the {@link CharacterPredicates} enum.</p>
- *
+ *
* <p>This class is not thread safe.</p>
- * @since 1.0
+ * @since 1.1
*/
public static class Builder implements org.apache.commons.text.Builder<RandomStringGenerator> {
-
+
/**
* The default maximum code point allowed: {@link Character#MAX_CODE_POINT}
- * ({@value})
- *
- * @since 1.0
+ * ({@value}).
*/
public static final int DEFAULT_MAXIMUM_CODE_POINT = Character.MAX_CODE_POINT;
-
+
/**
- * The default string length produced by this builder: {@value}
- *
- * @since 1.0
+ * The default string length produced by this builder: {@value}.
*/
public static final int DEFAULT_LENGTH = 0;
/**
- * The default minimum code point allowed: {@value}
- *
- * @since 1.0
+ * The default minimum code point allowed: {@value}.
*/
public static final int DEFAULT_MINIMUM_CODE_POINT = 0;
@@ -212,14 +202,13 @@ public final class RandomStringGenerator {
private int maximumCodePoint = DEFAULT_MAXIMUM_CODE_POINT;
private Set<CharacterPredicate> inclusivePredicates;
private TextRandomProvider random;
-
-
+
/**
* <p>
- * Specifies the minimum and maximum code points allowed in the generated
- * string.
+ * Specifies the minimum and maximum code points allowed in the
+ * generated string.
* </p>
- *
+ *
* @param minimumCodePoint
* the smallest code point allowed (inclusive)
* @param maximumCodePoint
@@ -232,15 +221,16 @@ public final class RandomStringGenerator {
* if {@code minimumCodePoint < 0}
* @throws IllegalArgumentException
* if {@code minimumCodePoint > maximumCodePoint}
- * @since 1.0
*/
public Builder withinRange(final int minimumCodePoint, final int maximumCodePoint) {
if (minimumCodePoint > maximumCodePoint) {
throw new IllegalArgumentException(String.format(
- "Minimum code point %d is larger than maximum code point %d", minimumCodePoint, maximumCodePoint));
+ "Minimum code point %d is larger than maximum code point %d",
+ minimumCodePoint, maximumCodePoint));
}
if (minimumCodePoint < 0) {
- throw new IllegalArgumentException(String.format("Minimum code point %d is negative", minimumCodePoint));
+ throw new IllegalArgumentException(
+ String.format("Minimum code point %d is negative", minimumCodePoint));
}
if (maximumCodePoint > Character.MAX_CODE_POINT) {
throw new IllegalArgumentException(
@@ -251,23 +241,22 @@ public final class RandomStringGenerator {
this.maximumCodePoint = maximumCodePoint;
return this;
}
-
+
/**
* <p>
* Limits the characters in the generated string to those that match at
* least one of the predicates supplied.
* </p>
- *
+ *
* <p>
* Passing {@code null} or an empty array to this method will revert to the
* default behaviour of allowing any character. Multiple calls to this
* method will replace the previously stored predicates.
* </p>
- *
+ *
* @param predicates
* the predicates, may be {@code null} or empty
* @return {@code this}, to allow method chaining
- * @since 1.0
*/
public Builder filteredBy(final CharacterPredicate... predicates) {
if (predicates == null || predicates.length == 0) {
@@ -287,7 +276,7 @@ public final class RandomStringGenerator {
return this;
}
-
+
/**
* <p>
* Overrides the default source of randomness. It is highly
@@ -309,16 +298,15 @@ public final class RandomStringGenerator {
* .build();
* }
* </pre>
- *
+ *
* <p>
* Passing {@code null} to this method will revert to the default source of
* randomness.
* </p>
- *
+ *
* @param random
* the source of randomness, may be {@code null}
* @return {@code this}, to allow method chaining
- * @since 1.0
*/
public Builder usingRandom(final TextRandomProvider random) {
this.random = random;
@@ -327,11 +315,11 @@ public final class RandomStringGenerator {
/**
* <p>Builds the {@code RandomStringGenerator} using the properties specified.</p>
+ * @return the configured {@code RandomStringGenerator}
*/
@Override
public RandomStringGenerator build() {
return new RandomStringGenerator(minimumCodePoint, maximumCodePoint, inclusivePredicates, random);
}
-
}
}
http://git-wip-us.apache.org/repos/asf/commons-text/blob/c72a24bc/src/main/java/org/apache/commons/text/TextRandomProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/text/TextRandomProvider.java b/src/main/java/org/apache/commons/text/TextRandomProvider.java
index 4aecd72..98c5f2d 100644
--- a/src/main/java/org/apache/commons/text/TextRandomProvider.java
+++ b/src/main/java/org/apache/commons/text/TextRandomProvider.java
@@ -37,15 +37,15 @@ package org.apache.commons.text;
* .build();
* }
* </pre>
+ * @since 1.1
*/
public interface TextRandomProvider {
/**
- * Generates an int value between 0 (inclusive) and the specified value
+ * Generates an int value between 0 (inclusive) and the specified value
* (exclusive).
* @param max Bound on the random number to be returned. Must be positive.
* @return a random int value between 0 (inclusive) and n (exclusive).
- * @throws IllegalArgumentException - if max is negative
*/
int nextInt(int max);
}
http://git-wip-us.apache.org/repos/asf/commons-text/blob/c72a24bc/src/test/java/org/apache/commons/text/RandomStringGeneratorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/text/RandomStringGeneratorTest.java b/src/test/java/org/apache/commons/text/RandomStringGeneratorTest.java
index 0da2072..86537fa 100644
--- a/src/test/java/org/apache/commons/text/RandomStringGeneratorTest.java
+++ b/src/test/java/org/apache/commons/text/RandomStringGeneratorTest.java
@@ -25,10 +25,6 @@ import static org.junit.Assert.*;
*/
public class RandomStringGeneratorTest {
- private static int codePointLength(String s) {
- return s.codePointCount(0, s.length());
- }
-
private static final CharacterPredicate A_FILTER = new CharacterPredicate() {
@Override
public boolean test(int codePoint) {
@@ -44,13 +40,17 @@ public class RandomStringGeneratorTest {
};
@Test(expected = IllegalArgumentException.class)
- public void testInvalidLength() throws Exception {
+ public void testInvalidLength() {
RandomStringGenerator generator = new RandomStringGenerator.Builder().build();
generator.generate(-1);
}
+ private static int codePointLength(String s) {
+ return s.codePointCount(0, s.length());
+ }
+
@Test
- public void testSetLength() throws Exception {
+ public void testSetLength() {
final int length = 99;
RandomStringGenerator generator = new RandomStringGenerator.Builder().build();
String str = generator.generate(length);
@@ -58,34 +58,33 @@ public class RandomStringGeneratorTest {
}
@Test(expected = IllegalArgumentException.class)
- public void testBadMinimumCodePoint() throws Exception {
+ public void testBadMinimumCodePoint() {
new RandomStringGenerator.Builder().withinRange(-1, 1);
}
@Test(expected = IllegalArgumentException.class)
- public void testBadMaximumCodePoint() throws Exception {
+ public void testBadMaximumCodePoint() {
new RandomStringGenerator.Builder().withinRange(0, Character.MAX_CODE_POINT + 1);
}
@Test
- public void testWithinRange() throws Exception {
- final int length = 5000;
- final int minimumCodePoint = 'a';
- final int maximumCodePoint = 'z';
- RandomStringGenerator generator = new RandomStringGenerator.Builder().withinRange(minimumCodePoint,maximumCodePoint).build();
- String str = generator.generate(length);
-
- int i = 0;
- do {
- int codePoint = str.codePointAt(i);
- assertTrue(codePoint >= minimumCodePoint && codePoint <= maximumCodePoint);
- i += Character.charCount(codePoint);
- } while (i < str.length());
-
- }
+ public void testWithinRange() {
+ final int length = 5000;
+ final int minimumCodePoint = 'a';
+ final int maximumCodePoint = 'z';
+ RandomStringGenerator generator = new RandomStringGenerator.Builder().withinRange(minimumCodePoint,maximumCodePoint).build();
+ String str = generator.generate(length);
+
+ int i = 0;
+ do {
+ int codePoint = str.codePointAt(i);
+ assertTrue(codePoint >= minimumCodePoint && codePoint <= maximumCodePoint);
+ i += Character.charCount(codePoint);
+ } while (i < str.length());
+ }
@Test
- public void testNoLoneSurrogates() throws Exception {
+ public void testNoLoneSurrogates() {
final int length = 5000;
String str = new RandomStringGenerator.Builder().build().generate(length);
@@ -111,10 +110,9 @@ public class RandomStringGeneratorTest {
}
@Test
- public void testUsingRandom() throws Exception {
+ public void testUsingRandom() {
final char testChar = 'a';
final TextRandomProvider testRandom = new TextRandomProvider() {
- private static final long serialVersionUID = 1L;
@Override
public int nextInt(int n) {
@@ -129,7 +127,7 @@ public class RandomStringGeneratorTest {
}
@Test
- public void testMultipleFilters() throws Exception {
+ public void testMultipleFilters() {
String str = new RandomStringGenerator.Builder().withinRange('a','d')
.filteredBy(A_FILTER, B_FILTER).build().generate(5000);
@@ -150,12 +148,11 @@ public class RandomStringGeneratorTest {
}
@Test
- public void testNoPrivateCharacters() throws Exception {
+ public void testNoPrivateCharacters() {
final int startOfPrivateBMPChars = 0xE000;
// Request a string in an area of the Basic Multilingual Plane that is
- // largely
- // occupied by private characters
+ // largely occupied by private characters
String str = new RandomStringGenerator.Builder().withinRange(startOfPrivateBMPChars,
Character.MIN_SUPPLEMENTARY_CODE_POINT - 1).build().generate(5000);
@@ -173,8 +170,7 @@ public class RandomStringGeneratorTest {
}
@Test
- public void testRemoveFilters() throws Exception {
-
+ public void testRemoveFilters() {
RandomStringGenerator.Builder builder = new RandomStringGenerator.Builder().withinRange('a', 'z')
.filteredBy(A_FILTER);
@@ -192,7 +188,7 @@ public class RandomStringGeneratorTest {
}
@Test
- public void testChangeOfFilter() throws Exception {
+ public void testChangeOfFilter() {
RandomStringGenerator.Builder builder = new RandomStringGenerator.Builder().withinRange('a', 'z')
.filteredBy(A_FILTER);
String str = builder.filteredBy(B_FILTER).build().generate(100);
@@ -201,9 +197,9 @@ public class RandomStringGeneratorTest {
assertTrue(c == 'b');
}
}
-
+
@Test
- public void testZeroLength() throws Exception {
+ public void testZeroLength() {
RandomStringGenerator generator = new RandomStringGenerator.Builder().build();
assertEquals("", generator.generate(0));
}