in src/main/java/org/apache/commons/codec/language/bm/PhoneticEngine.java [312:353]
private PhonemeBuilder applyFinalRules(final PhonemeBuilder phonemeBuilder,
final Map<String, List<Rule>> finalRules) {
Objects.requireNonNull(finalRules, "finalRules");
if (finalRules.isEmpty()) {
return phonemeBuilder;
}
final Map<Rule.Phoneme, Rule.Phoneme> phonemes = new TreeMap<>(Rule.Phoneme.COMPARATOR);
phonemeBuilder.getPhonemes().forEach(phoneme -> {
PhonemeBuilder subBuilder = PhonemeBuilder.empty(phoneme.getLanguages());
final String phonemeText = phoneme.getPhonemeText().toString();
for (int i = 0; i < phonemeText.length();) {
final RulesApplication rulesApplication = new RulesApplication(finalRules, phonemeText, subBuilder, i, maxPhonemes).invoke();
final boolean found = rulesApplication.isFound();
subBuilder = rulesApplication.getPhonemeBuilder();
if (!found) {
// not found, appending as-is
subBuilder.append(phonemeText.subSequence(i, i + 1));
}
i = rulesApplication.getI();
}
// the phonemes map orders the phonemes only based on their text, but ignores the language set
// when adding new phonemes, check for equal phonemes and merge their language set, otherwise
// phonemes with the same text but different language set get lost
subBuilder.getPhonemes().forEach(newPhoneme -> {
if (phonemes.containsKey(newPhoneme)) {
final Rule.Phoneme oldPhoneme = phonemes.remove(newPhoneme);
final Rule.Phoneme mergedPhoneme = oldPhoneme.mergeWithLanguage(newPhoneme.getLanguages());
phonemes.put(mergedPhoneme, mergedPhoneme);
} else {
phonemes.put(newPhoneme, newPhoneme);
}
});
});
return new PhonemeBuilder(phonemes.keySet());
}