This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-codec.git
The following commit(s) were added to refs/heads/master by this push:
new 077ba3d9 Add and use PhoneticEngine.Builder and deprecate old
constructors.
077ba3d9 is described below
commit 077ba3d9e115dfa93b794c445dc2aba5f51b9650
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Aug 6 10:56:39 2026 -0400
Add and use PhoneticEngine.Builder and deprecate old constructors.
- Javadoc
- Ternary return
- Formatting
---
src/changes/changes.xml | 3 +-
.../codec/language/bm/BeiderMorseEncoder.java | 109 ++++-----
.../commons/codec/language/bm/PhoneticEngine.java | 106 ++++++++-
.../language/bm/PhoneticEngineBuilderTest.java | 251 +++++++++++++++++++++
.../language/bm/PhoneticEnginePerformanceTest.java | 8 +-
.../language/bm/PhoneticEngineRegressionTest.java | 12 +-
6 files changed, 411 insertions(+), 78 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 90046f49..f4445b73 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -43,10 +43,11 @@ The <action> type attribute can be add,update,fix,remove.
<author>Apache Commons Developers</author>
</properties>
<body>
- <release version="1.22.2" date="YYYY-MM-DD" description="This is a feature
and maintenance release. Java 8 or later is required.">
+ <release version="1.23.0" date="YYYY-MM-DD" description="This is a feature
and maintenance release. Java 8 or later is required.">
<!-- FIX -->
<action type="fix" dev="ggregory" due-to="Yu Bao, Gary Gregory">Optimize
PhoneticEngine.encode(String, LanguageSet) for speed.</action>
<!-- ADD -->
+ <action type="add" dev="ggregory" due-to="Gary Gregory">Add and use
PhoneticEngine.Builder and deprecate old constructors.</action>
<!-- UPDATE -->
</release>
<release version="1.22.1" date="2026-07-27" description="This is a feature
and maintenance release. Java 8 or later is required.">
diff --git
a/src/main/java/org/apache/commons/codec/language/bm/BeiderMorseEncoder.java
b/src/main/java/org/apache/commons/codec/language/bm/BeiderMorseEncoder.java
index 58043771..1c2da755 100644
--- a/src/main/java/org/apache/commons/codec/language/bm/BeiderMorseEncoder.java
+++ b/src/main/java/org/apache/commons/codec/language/bm/BeiderMorseEncoder.java
@@ -23,50 +23,41 @@ import org.apache.commons.codec.StringEncoder;
/**
* Encodes strings into their Beider-Morse phonetic encoding.
* <p>
- * Beider-Morse phonetic encodings are optimized for family names. However,
they may be useful for a wide range of
- * words.
+ * Beider-Morse phonetic encodings are optimized for family names. However,
they may be useful for a wide range of words.
* </p>
* <p>
- * This encoder is intentionally mutable to allow dynamic configuration
through bean properties. As such, it is mutable,
- * and may not be thread-safe. If you require a guaranteed thread-safe
encoding then use {@link PhoneticEngine}
- * directly.
+ * This encoder is intentionally mutable to allow dynamic configuration
through bean properties. As such, it is mutable, and may not be thread-safe. If
you
+ * require a guaranteed thread-safe encoding then use {@link PhoneticEngine}
directly.
* </p>
* <h2>Encoding overview</h2>
* <p>
- * Beider-Morse phonetic encodings is a multi-step process. Firstly, a table
of rules is consulted to guess what
- * language the word comes from. For example, if it ends in "{@code ault}"
then it infers that the word is French.
- * Next, the word is translated into a phonetic representation using a
language-specific phonetics table. Some runs of
- * letters can be pronounced in multiple ways, and a single run of letters may
be potentially broken up into phonemes at
- * different places, so this stage results in a set of possible
language-specific phonetic representations. Lastly, this
- * language-specific phonetic representation is processed by a table of rules
that re-writes it phonetically taking into
- * account systematic pronunciation differences between languages, to move it
towards a pan-indo-european phonetic
- * representation. Again, sometimes there are multiple ways this could be done
and sometimes things that can be
- * pronounced in several ways in the source language have only one way to
represent them in this average phonetic
- * language, so the result is again a set of phonetic spellings.
+ * Beider-Morse phonetic encodings is a multi-step process. Firstly, a table
of rules is consulted to guess what language the word comes from. For example,
if
+ * it ends in "{@code ault}" then it infers that the word is French. Next, the
word is translated into a phonetic representation using a language-specific
+ * phonetics table. Some runs of letters can be pronounced in multiple ways,
and a single run of letters may be potentially broken up into phonemes at
different
+ * places, so this stage results in a set of possible language-specific
phonetic representations. Lastly, this language-specific phonetic
representation is
+ * processed by a table of rules that re-writes it phonetically taking into
account systematic pronunciation differences between languages, to move it
towards a
+ * pan-indo-european phonetic representation. Again, sometimes there are
multiple ways this could be done and sometimes things that can be pronounced in
several
+ * ways in the source language have only one way to represent them in this
average phonetic language, so the result is again a set of phonetic spellings.
* </p>
* <p>
- * Some names are treated as having multiple parts. This can be due to two
things. Firstly, they may be hyphenated. In
- * this case, each individual hyphenated word is encoded, and then these are
combined end-to-end for the final encoding.
- * Secondly, some names have standard prefixes, for example, "{@code Mac/Mc}"
in Scottish (English) names. As
- * sometimes it is ambiguous whether the prefix is intended or is an accident
of the spelling, the word is encoded once
- * with the prefix and once without it. The resulting encoding contains one
and then the other result.
+ * Some names are treated as having multiple parts. This can be due to two
things. Firstly, they may be hyphenated. In this case, each individual
hyphenated
+ * word is encoded, and then these are combined end-to-end for the final
encoding. Secondly, some names have standard prefixes, for example, "{@code
Mac/Mc}" in
+ * Scottish (English) names. As sometimes it is ambiguous whether the prefix
is intended or is an accident of the spelling, the word is encoded once with the
+ * prefix and once without it. The resulting encoding contains one and then
the other result.
* </p>
* <h2>Encoding format</h2>
* <p>
- * Individual phonetic spellings of an input word are represented in upper-
and lower-case roman characters. Where there
- * are multiple possible phonetic representations, these are joined with a
pipe ({@code |}) character. If multiple
- * hyphenated words where found, or if the word may contain a name prefix,
each encoded word is placed in ellipses and
- * these blocks are then joined with hyphens. For example, "{@code d'ortley}"
has a possible prefix. The form
- * without prefix encodes to "{@code ortlaj|ortlej}", while the form with
prefix encodes to "
- * {@code dortlaj|dortlej}". Thus, the full, combined encoding is "{@code
(ortlaj|ortlej)-(dortlaj|dortlej)}".
+ * Individual phonetic spellings of an input word are represented in upper-
and lower-case roman characters. Where there are multiple possible phonetic
+ * representations, these are joined with a pipe ({@code |}) character. If
multiple hyphenated words where found, or if the word may contain a name
prefix, each
+ * encoded word is placed in ellipses and these blocks are then joined with
hyphens. For example, "{@code d'ortley}" has a possible prefix. The form without
+ * prefix encodes to "{@code ortlaj|ortlej}", while the form with prefix
encodes to " {@code dortlaj|dortlej}". Thus, the full, combined encoding is
+ * "{@code (ortlaj|ortlej)-(dortlaj|dortlej)}".
* </p>
* <p>
- * The encoded forms are often quite a bit longer than the input strings. This
is because a single input may have many
- * potential phonetic interpretations. For example, "{@code Renault}" encodes
to "
- * {@code rYnDlt|rYnalt|rYnult|rinDlt|rinalt|rinult}". The {@code APPROX}
rules will tend to produce larger
- * encodings as they consider a wider range of possible, approximate phonetic
interpretations of the original word.
- * Down-stream applications may wish to further process the encoding for
indexing or lookup purposes, for example, by
- * splitting on pipe ({@code |}) and indexing under each of these alternatives.
+ * The encoded forms are often quite a bit longer than the input strings. This
is because a single input may have many potential phonetic interpretations. For
+ * example, "{@code Renault}" encodes to " {@code
rYnDlt|rYnalt|rYnult|rinDlt|rinalt|rinult}". The {@code APPROX} rules will tend
to produce larger encodings as
+ * they consider a wider range of possible, approximate phonetic
interpretations of the original word. Down-stream applications may wish to
further process the
+ * encoding for indexing or lookup purposes, for example, by splitting on pipe
({@code |}) and indexing under each of these alternatives.
* </p>
* <p>
* <strong>Note</strong>: this version of the Beider-Morse encoding is
equivalent with v3.4 of the reference implementation.
@@ -80,12 +71,11 @@ import org.apache.commons.codec.StringEncoder;
* @since 1.6
*/
public class BeiderMorseEncoder implements StringEncoder {
-
// Implementation note: This class is a spring-friendly facade to
PhoneticEngine. It allows read/write configuration
// of an immutable PhoneticEngine instance that will be delegated to for
the actual encoding.
// a cached object
- private PhoneticEngine engine = new PhoneticEngine(NameType.GENERIC,
RuleType.APPROX, true);
+ private PhoneticEngine engine = PhoneticEngine.builder().get();
/**
* Constructs a new instance.
@@ -104,10 +94,7 @@ public class BeiderMorseEncoder implements StringEncoder {
@Override
public String encode(final String source) throws EncoderException {
- if (source == null) {
- return null;
- }
- return this.engine.encode(source);
+ return source != null ? engine.encode(source) : null;
}
/**
@@ -116,7 +103,7 @@ public class BeiderMorseEncoder implements StringEncoder {
* @return The NameType currently being used.
*/
public NameType getNameType() {
- return this.engine.getNameType();
+ return engine.getNameType();
}
/**
@@ -125,71 +112,53 @@ public class BeiderMorseEncoder implements StringEncoder {
* @return The RuleType currently being used.
*/
public RuleType getRuleType() {
- return this.engine.getRuleType();
+ return engine.getRuleType();
}
/**
- * Discovers if multiple possible encodings are concatenated.
+ * Tests if multiple possible encodings are concatenated.
*
* @return true if multiple encodings are concatenated, false if just the
first one is returned.
*/
public boolean isConcat() {
- return this.engine.isConcat();
+ return engine.isConcat();
}
/**
* Sets how multiple possible phonetic encodings are combined.
*
- * @param concat
- * true if multiple encodings are to be combined with a '|',
false if just the first one is
- * to be considered.
+ * @param concat true if multiple encodings are to be combined with a '|',
false if just the first one is to be considered.
*/
public void setConcat(final boolean concat) {
- this.engine = new PhoneticEngine(this.engine.getNameType(),
- this.engine.getRuleType(),
- concat,
- this.engine.getMaxPhonemes());
+ engine =
PhoneticEngine.builder().setAll(engine).setConcat(concat).get();
}
/**
* Sets the number of maximum of phonemes that shall be considered by the
engine.
*
- * @param maxPhonemes
- * the maximum number of phonemes returned by the engine.
+ * @param maxPhonemes the maximum number of phonemes returned by the
engine.
* @since 1.7
*/
public void setMaxPhonemes(final int maxPhonemes) {
- this.engine = new PhoneticEngine(this.engine.getNameType(),
- this.engine.getRuleType(),
- this.engine.isConcat(),
- maxPhonemes);
+ engine =
PhoneticEngine.builder().setAll(engine).setMaxPhonemes(maxPhonemes).get();
}
/**
- * Sets the type of name. Use {@link NameType#GENERIC} unless you
specifically want phonetic encodings
- * optimized for Ashkenazi or Sephardic Jewish family names.
+ * Sets the type of name. Use {@link NameType#GENERIC} unless you
specifically want phonetic encodings optimized for Ashkenazi or Sephardic
Jewish family
+ * names.
*
- * @param nameType
- * the NameType in use.
+ * @param nameType the NameType in use.
*/
public void setNameType(final NameType nameType) {
- this.engine = new PhoneticEngine(nameType,
- this.engine.getRuleType(),
- this.engine.isConcat(),
- this.engine.getMaxPhonemes());
+ engine =
PhoneticEngine.builder().setAll(engine).setNameType(nameType).get();
}
/**
* Sets the rule type to apply. This will widen or narrow the range of
phonetic encodings considered.
*
- * @param ruleType
- * {@link RuleType#APPROX} or {@link RuleType#EXACT} for
approximate or exact phonetic matches.
+ * @param ruleType {@link RuleType#APPROX} or {@link RuleType#EXACT} for
approximate or exact phonetic matches.
*/
public void setRuleType(final RuleType ruleType) {
- this.engine = new PhoneticEngine(this.engine.getNameType(),
- ruleType,
- this.engine.isConcat(),
- this.engine.getMaxPhonemes());
+ engine =
PhoneticEngine.builder().setAll(engine).setRuleType(ruleType).get();
}
-
}
diff --git
a/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java
b/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java
index f208a561..5e70ecfe 100644
--- a/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java
+++ b/src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -55,8 +56,91 @@ import org.apache.commons.codec.language.bm.Rule.Phoneme;
public class PhoneticEngine {
/**
- * Utility for manipulating a set of phonemes as they are being built up.
Not intended for use outside this package, and probably not outside the
- * {@link PhoneticEngine} class.
+ * Builder for a PhoneticEngine.
+ *
+ * @since 1.23.0
+ */
+ public static class Builder implements Supplier<PhoneticEngine> {
+
+ private NameType nameType = NameType.GENERIC;
+
+ private RuleType ruleType = RuleType.APPROX;
+
+ private boolean concat = true;
+
+ private int maxPhonemes = DEFAULT_MAX_PHONEMES;
+
+ private Builder() {
+ // empty
+ }
+
+ @Override
+ public PhoneticEngine get() {
+ return new PhoneticEngine(this);
+ }
+
+ /**
+ * Sets all the properties of this builder to match those of the given
engine.
+ *
+ * @param engine The engine to copy properties from.
+ * @return This builder.
+ */
+ public Builder setAll(final PhoneticEngine engine) {
+ this.nameType = engine.getNameType();
+ this.ruleType = engine.getRuleType();
+ this.concat = engine.isConcat();
+ this.maxPhonemes = engine.getMaxPhonemes();
+ return this;
+ }
+
+ /**
+ * Sets whether the engine will concatenate multiple encodings.
+ *
+ * @param concat Whether the engine will concatenate multiple
encodings.
+ * @return This builder.
+ */
+ public Builder setConcat(final boolean concat) {
+ this.concat = concat;
+ return this;
+ }
+
+ /**
+ * Sets maximum number of phonemes the engine will handle.
+ *
+ * @param maxPhonemes The maximum number of phonemes the engine will
handle.
+ * @return This builder.
+ */
+ public Builder setMaxPhonemes(final int maxPhonemes) {
+ this.maxPhonemes = maxPhonemes;
+ return this;
+ }
+
+ /**
+ * Sets the name type for the engine to be built.
+ *
+ * @param nameType The type of names the engine will use.
+ * @return This builder.
+ */
+ public Builder setNameType(final NameType nameType) {
+ this.nameType = nameType;
+ return this;
+ }
+
+ /**
+ * Sets the rule type for the engine to be built.
+ *
+ * @param ruleType The type of rules the engine will use.
+ * @return This builder.
+ */
+ public Builder setRuleType(final RuleType ruleType) {
+ this.ruleType = ruleType;
+ return this;
+ }
+ }
+
+ /**
+ * Manipulates a set of phonemes as they are being built up. Not intended
for use outside this package, and probably not outside the {@link
PhoneticEngine}
+ * class.
*
* @since 1.6
*/
@@ -233,6 +317,16 @@ public class PhoneticEngine {
new HashSet<>(Arrays.asList("da", "dal", "de", "del", "dela",
"de la", "della", "des", "di", "do", "dos", "du", "van", "von"))));
}
+ /**
+ * Creates a new builder for a PhoneticEngine.
+ *
+ * @return a new builder for a PhoneticEngine.
+ * @since 1.23.0
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
/**
* Joins some strings with an internal separator.
*
@@ -254,13 +348,19 @@ public class PhoneticEngine {
private final int maxPhonemes;
+ private PhoneticEngine(final Builder builder) {
+ this(builder.nameType, builder.ruleType, builder.concat,
builder.maxPhonemes);
+ }
+
/**
* Generates a new, fully-configured phonetic engine.
*
* @param nameType the type of names it will use.
* @param ruleType the type of rules it will apply.
* @param concatenate if it will concatenate multiple encodings.
+ * @deprecated Use {@link #builder()} instead.
*/
+ @Deprecated
public PhoneticEngine(final NameType nameType, final RuleType ruleType,
final boolean concatenate) {
this(nameType, ruleType, concatenate, DEFAULT_MAX_PHONEMES);
}
@@ -273,7 +373,9 @@ public class PhoneticEngine {
* @param concatenate if it will concatenate multiple encodings.
* @param maxPhonemes the maximum number of phonemes that will be handled.
* @since 1.7
+ * @deprecated Use {@link #builder()} instead.
*/
+ @Deprecated
public PhoneticEngine(final NameType nameType, final RuleType ruleType,
final boolean concatenate, final int maxPhonemes) {
if (ruleType == RuleType.RULES) {
throw new IllegalArgumentException("ruleType must not be " +
RuleType.RULES);
diff --git
a/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineBuilderTest.java
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineBuilderTest.java
new file mode 100644
index 00000000..23cafb67
--- /dev/null
+++
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineBuilderTest.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * https://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.apache.commons.codec.language.bm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link PhoneticEngine.Builder}.
+ *
+ * @since 1.23.0
+ */
+class PhoneticEngineBuilderTest {
+
+ /**
+ * Tests that the builder produces a non-null {@link PhoneticEngine}.
+ */
+ @Test
+ void testBuilderGet() {
+ final PhoneticEngine engine = PhoneticEngine.builder().get();
+ assertNotNull(engine);
+ }
+
+ /**
+ * Tests that {@link PhoneticEngine#builder()} returns a non-null builder.
+ */
+ @Test
+ void testBuilderNotNull() {
+ assertNotNull(PhoneticEngine.builder());
+ }
+
+ /**
+ * Tests that successive calls to {@link PhoneticEngine#builder()} return
distinct builder instances.
+ */
+ @Test
+ void testBuilderReturnsNewInstance() {
+ assertNotSame(PhoneticEngine.builder(), PhoneticEngine.builder());
+ }
+
+ /**
+ * Tests the default values of the builder.
+ */
+ @Test
+ void testDefaultValues() {
+ final PhoneticEngine engine = PhoneticEngine.builder().get();
+ assertEquals(NameType.GENERIC, engine.getNameType());
+ assertEquals(RuleType.APPROX, engine.getRuleType());
+ assertTrue(engine.isConcat());
+ assertEquals(20, engine.getMaxPhonemes());
+ }
+
+ /**
+ * Tests that the builder produces engines that encode correctly
(ASHKENAZI/APPROX/concat).
+ */
+ @Test
+ void testEngineEncodeAshkenaziApprox() {
+ // @formatter:off
+ final PhoneticEngine engine = PhoneticEngine.builder()
+ .setNameType(NameType.ASHKENAZI)
+ .setRuleType(RuleType.APPROX)
+ .setConcat(true)
+ .setMaxPhonemes(10)
+ .get();
+ // @formatter:on
+ final String result = engine.encode("Renault");
+ assertEquals("rYnDlt|rYnalt|rYnult|rinDlt|rinalt|rinolt|rinult",
result);
+ }
+
+ /**
+ * Tests that the builder produces engines that encode correctly
(GENERIC/APPROX/concat).
+ */
+ @Test
+ void testEngineEncodeGenericApprox() {
+ // @formatter:off
+ final PhoneticEngine engine = PhoneticEngine.builder()
+ .setNameType(NameType.GENERIC)
+ .setRuleType(RuleType.APPROX)
+ .setConcat(true)
+ .setMaxPhonemes(10)
+ .get();
+ // @formatter:on
+ final String result = engine.encode("Renault");
+ assertEquals("rinD|rinDlt|rina|rinalt|rino|rinolt|rinu|rinult",
result);
+ }
+
+ /**
+ * Tests that the builder produces engines that encode correctly
(GENERIC/EXACT/concat).
+ */
+ @Test
+ void testEngineEncodeGenericExact() {
+ // @formatter:off
+ final PhoneticEngine engine = PhoneticEngine.builder()
+ .setNameType(NameType.GENERIC)
+ .setRuleType(RuleType.EXACT)
+ .setConcat(true)
+ .setMaxPhonemes(10)
+ .get();
+ // @formatter:on
+ final String result = engine.encode("SntJohn-Smith");
+ assertEquals("sntjonsmit", result);
+ }
+
+ /**
+ * Tests that a builder-created engine is not the same instance when built
twice.
+ */
+ @Test
+ void testGetReturnsDifferentInstances() {
+ final PhoneticEngine.Builder builder = PhoneticEngine.builder();
+ final PhoneticEngine engine1 = builder.get();
+ final PhoneticEngine engine2 = builder.get();
+ assertNotSame(engine1, engine2);
+ }
+
+ /**
+ * Tests method chaining: all setters return the same builder instance.
+ */
+ @Test
+ void testMethodChaining() {
+ // @formatter:off
+ final PhoneticEngine.Builder builder = PhoneticEngine.builder();
+ assertNotNull(builder
+ .setNameType(NameType.SEPHARDIC)
+ .setRuleType(RuleType.APPROX)
+ .setConcat(true)
+ .setMaxPhonemes(15)
+ .get());
+ // @formatter:on
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setAll(PhoneticEngine)} copies all
properties.
+ */
+ @Test
+ void testSetAll() {
+ // @formatter:off
+ final PhoneticEngine original = PhoneticEngine.builder()
+ .setNameType(NameType.ASHKENAZI)
+ .setRuleType(RuleType.EXACT)
+ .setConcat(false)
+ .setMaxPhonemes(5)
+ .get();
+ // @formatter:on
+ final PhoneticEngine copy =
PhoneticEngine.builder().setAll(original).get();
+ assertEquals(original.getNameType(), copy.getNameType());
+ assertEquals(original.getRuleType(), copy.getRuleType());
+ assertEquals(original.isConcat(), copy.isConcat());
+ assertEquals(original.getMaxPhonemes(), copy.getMaxPhonemes());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setConcat(boolean)} with {@code
false}.
+ */
+ @Test
+ void testSetConcatFalse() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setConcat(false).get();
+ assertFalse(engine.isConcat());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setConcat(boolean)} with {@code
true}.
+ */
+ @Test
+ void testSetConcatTrue() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setConcat(true).get();
+ assertTrue(engine.isConcat());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setMaxPhonemes(int)}.
+ */
+ @Test
+ void testSetMaxPhonemes() {
+ final int maxPhonemes = 10;
+ final PhoneticEngine engine =
PhoneticEngine.builder().setMaxPhonemes(maxPhonemes).get();
+ assertEquals(maxPhonemes, engine.getMaxPhonemes());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setMaxPhonemes(int)} with {@link
Integer#MAX_VALUE}.
+ */
+ @Test
+ void testSetMaxPhonemesMaxValue() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setMaxPhonemes(Integer.MAX_VALUE).get();
+ assertEquals(Integer.MAX_VALUE, engine.getMaxPhonemes());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setNameType(NameType)} with
ASHKENAZI.
+ */
+ @Test
+ void testSetNameTypeAshkenazi() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setNameType(NameType.ASHKENAZI).get();
+ assertEquals(NameType.ASHKENAZI, engine.getNameType());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setNameType(NameType)}.
+ */
+ @Test
+ void testSetNameTypeGeneric() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setNameType(NameType.GENERIC).get();
+ assertEquals(NameType.GENERIC, engine.getNameType());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setNameType(NameType)} with
SEPHARDIC.
+ */
+ @Test
+ void testSetNameTypeSephardic() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setNameType(NameType.SEPHARDIC).get();
+ assertEquals(NameType.SEPHARDIC, engine.getNameType());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setRuleType(RuleType)} with APPROX.
+ */
+ @Test
+ void testSetRuleTypeApprox() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setRuleType(RuleType.APPROX).get();
+ assertEquals(RuleType.APPROX, engine.getRuleType());
+ }
+
+ /**
+ * Tests {@link PhoneticEngine.Builder#setRuleType(RuleType)} with EXACT.
+ */
+ @Test
+ void testSetRuleTypeExact() {
+ final PhoneticEngine engine =
PhoneticEngine.builder().setRuleType(RuleType.EXACT).get();
+ assertEquals(RuleType.EXACT, engine.getRuleType());
+ }
+}
diff --git
a/src/test/java/org/apache/commons/codec/language/bm/PhoneticEnginePerformanceTest.java
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEnginePerformanceTest.java
index 3f942187..5ec64a56 100644
---
a/src/test/java/org/apache/commons/codec/language/bm/PhoneticEnginePerformanceTest.java
+++
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEnginePerformanceTest.java
@@ -124,7 +124,13 @@ class PhoneticEnginePerformanceTest {
@Test
void test() {
- final PhoneticEngine engine = new PhoneticEngine(NameType.GENERIC,
RuleType.APPROX, true);
+ // @formatter:off
+ final PhoneticEngine engine = PhoneticEngine.builder()
+ .setNameType(NameType.GENERIC)
+ .setRuleType(RuleType.APPROX)
+ .setConcat(true)
+ .get();
+ // @formatter:on
final String input = "Angelo";
final long startMillis = System.currentTimeMillis();
for (int i = 0; i < LOOP; i++) {
diff --git
a/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineRegressionTest.java
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineRegressionTest.java
index 488ab3d0..0d598c55 100644
---
a/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineRegressionTest.java
+++
b/src/test/java/org/apache/commons/codec/language/bm/PhoneticEngineRegressionTest.java
@@ -42,9 +42,6 @@ class PhoneticEngineRegressionTest {
* regressions in Commons-Codec.
*/
private static String encode(final Map<String, String> args, final boolean
concat, final String input) {
- final Languages.LanguageSet languageSet;
- final PhoneticEngine engine;
-
// PhoneticEngine = NameType + RuleType + concat
// we use common-codec's defaults: GENERIC + APPROX + true
final String nameTypeArg = args.get("nameType");
@@ -53,9 +50,16 @@ class PhoneticEngineRegressionTest {
final String ruleTypeArg = args.get("ruleType");
final RuleType ruleType = ruleTypeArg == null ? RuleType.APPROX :
RuleType.valueOf(ruleTypeArg);
- engine = new PhoneticEngine(nameType, ruleType, concat);
+ // @formatter:off
+ final PhoneticEngine engine = PhoneticEngine.builder()
+ .setNameType(nameType)
+ .setRuleType(ruleType)
+ .setConcat(concat)
+ .get();
+ // @formatter:on
// LanguageSet: defaults to automagic, otherwise a comma-separated
list.
+ final Languages.LanguageSet languageSet;
final String languageSetArg = args.get("languageSet");
if (languageSetArg == null || languageSetArg.equals("auto")) {
languageSet = null;