package com.tyndalehouse.step.core.utils.language.transliteration; import java.util.Arrays; import java.util.List; /** * Replaces a single character with a set of options * * @author chrisburrell * */ public class StringToStringRule implements TransliterationRule { private final char[] s; private final String[] options; /** * @param c the base character * @param cs the set of characters to match */ public StringToStringRule(final String c, final String[] cs) { this.s = c.toCharArray(); this.options = cs.clone(); } @Override public void expand(final List<TransliterationOption> prefixes, final char[] word, final int position) { // do a string comparison, linearly if (!isMatched(word, position)) { return; } final int nextPosition = position + this.s.length; final int size = prefixes.size(); for (int ii = 0; ii < size; ii++) { final TransliterationOption translitOption = prefixes.get(ii); if (translitOption.getNextValidPosition() != position) { // pass rule doesn't apply to this case continue; } final StringBuilder currentPrefix = translitOption.getOption(); // add an option to each prefix for (int jj = 0; jj < this.options.length; jj++) { // re-use the same string builder if it's the last one prefixes.add(new TransliterationOption(nextPosition, new StringBuilder(currentPrefix) .append(this.options[jj]))); } } } /** * @param word the current word * @param position the position in the word we're at * @return true if we've matched the string */ private boolean isMatched(final char[] word, final int position) { if (word.length - position < this.s.length) { // the remainder of the word is shorter than the rule match, so no match return false; } int ii = position; for (int matchingPosition = 0; matchingPosition < this.s.length; matchingPosition++) { if (word[ii++] != this.s[matchingPosition]) { // didn't match return false; } } return true; } @Override public String toString() { final StringBuilder value = new StringBuilder(32); value.append("Matches: "); value.append(this.s); value.append(" expands with "); value.append(Arrays.toString(this.options)); return value.toString(); } }