private Pattern internationalPrefix;
private StringBuffer prefixBeforeNationalNumber;
private StringBuffer nationalNumber;
- private static Pattern UNSUPPORTED_SYNTAX_PATTERN = Pattern.compile("\\|");
+ private final Pattern UNSUPPORTED_SYNTAX = Pattern.compile("[*#;,a-zA-Z]");
+ private final Pattern CHARACTER_CLASS_PATTERN = Pattern.compile("\\[([^\\[\\]])*\\]");
+ private final Pattern STANDALONE_DIGIT_PATTERN = Pattern.compile("\\d(?=[^,}][^,}])");
/**
* Constructs a light-weight formatter which does no formatting, but outputs exactly what is
String numberPattern = format.getPattern();
// The formatter doesn't format numbers when numberPattern contains "|", e.g.
- // (20|3)\d{4,5}. In those cases we quickly return.
- Matcher unsupportedSyntax = UNSUPPORTED_SYNTAX_PATTERN.matcher(numberPattern);
- if (unsupportedSyntax.find()) {
+ // (20|3)\d{4}. In those cases we quickly return.
+ if (numberPattern.indexOf('|') != -1) {
return false;
}
// Replace anything in the form of [..] with \d
- numberPattern = numberPattern.replaceAll("\\[([^\\[\\]])*\\]","\\\\d");
+ numberPattern = CHARACTER_CLASS_PATTERN.matcher(numberPattern).replaceAll("\\\\d");
// Replace any standalone digit (not the one in d{}) with \d
- numberPattern = numberPattern.replaceAll("\\d(?=[^,}])", "\\\\d");
+ numberPattern = STANDALONE_DIGIT_PATTERN.matcher(numberPattern).replaceAll("\\\\d");
formattingTemplate = getFormattingTemplate(numberPattern, numberFormat);
return true;
* Clears the internal state of the formatter, so it could be reused.
*/
public void clear() {
- accruedInput = new StringBuffer();
- accruedInputWithoutFormatting = new StringBuffer();
- currentOutput = new StringBuffer();
+ accruedInput.setLength(0);
+ accruedInputWithoutFormatting.setLength(0);
+ currentOutput.setLength(0);
lastMatchPosition = 0;
- prefixBeforeNationalNumber = new StringBuffer();
- nationalNumber = new StringBuffer();
+ prefixBeforeNationalNumber.setLength(0);
+ nationalNumber.setLength(0);
ableToFormat = true;
isInternationalFormatting = false;
if (!currentMetaData.equals(defaultMetaData)) {
public String inputDigit(char nextChar) {
accruedInput.append(nextChar);
// * and # are normally used in mobile codes, which we do not format.
- if (nextChar == '*' || nextChar == '#' || Character.isLetter(nextChar)) {
+ if (UNSUPPORTED_SYNTAX.matcher(Character.toString(nextChar)).matches()) {
ableToFormat = false;
}
if (!ableToFormat) {
* It returns true for all other cases.
*/
private boolean extractIddAndValidCountryCode() {
- nationalNumber = new StringBuffer();
+ nationalNumber.setLength(0);
Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting);
if (iddMatcher.lookingAt()) {
isInternationalFormatting = true;
prefixBeforeNationalNumber.append(countryCode).append(" ");
}
} else {
- nationalNumber = new StringBuffer(accruedInputWithoutFormatting);
+ nationalNumber.setLength(0);
+ nationalNumber.append(accruedInputWithoutFormatting);
}
return true;
}
assertEquals("650 253 2", formatter.inputDigit('2'));
assertEquals("650 253 22", formatter.inputDigit('2'));
assertEquals("650 253 222", formatter.inputDigit('2'));
- assertEquals("650 253 2222", formatter.inputDigit('2'));
+ // No more formatting when semicolon is entered.
+ assertEquals("650253222;", formatter.inputDigit(';'));
+ assertEquals("650253222;2", formatter.inputDigit('2'));
formatter.clear();
assertEquals("6", formatter.inputDigit('6'));
assertEquals("800 MY AP", formatter.inputDigit('P'));
assertEquals("800 MY APP", formatter.inputDigit('P'));
assertEquals("800 MY APPL", formatter.inputDigit('L'));
- assertEquals("800 MY APPLE", formatter.inputDigit('E'));
+ assertEquals("800 MY APPLE", formatter.inputDigit('E'));
}
public void testAsYouTypeFormatterGBFixedLine() {
assertEquals("0301", formatter.inputDigit('1'));
assertEquals("03012", formatter.inputDigit('2'));
assertEquals("030 123", formatter.inputDigit('3'));
- assertEquals("030 1234", formatter.inputDigit('4'));
+ assertEquals("030 1234", formatter.inputDigit('4'));
}
public void testAsYouTypeFormatterAR() {