
de.knightsoftnet.validators.shared.util.AbstractPhoneNumberUtil Maven / Gradle / Ivy
/*
* 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
*
* http://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 de.knightsoftnet.validators.shared.util;
import de.knightsoftnet.validators.shared.data.CountryEnum;
import de.knightsoftnet.validators.shared.data.PhoneAreaCodeData;
import de.knightsoftnet.validators.shared.data.PhoneCountryCodeData;
import de.knightsoftnet.validators.shared.data.PhoneCountryData;
import de.knightsoftnet.validators.shared.data.PhoneNumberData;
import de.knightsoftnet.validators.shared.data.PhoneNumberExtendedInterface;
import de.knightsoftnet.validators.shared.data.PhoneNumberInterface;
import de.knightsoftnet.validators.shared.data.ValidationInterface;
import de.knightsoftnet.validators.shared.data.ValueWithPos;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
/**
* Abstract Phone Number Util, format and parse phone numbers.
*
* @author Manfred Tremmel
*
*/
@SuppressWarnings("CPD-START")
public abstract class AbstractPhoneNumberUtil {
private static final String EXTENSION_SEPARATOR = "-";
protected final PhoneCountryConstantsProvider phoneCountryConstantsProvider;
protected PhoneCountryData defaultCountryData;
protected AbstractPhoneNumberUtil(
final PhoneCountryConstantsProvider phoneCountryConstantsProvider) {
this(null, phoneCountryConstantsProvider);
}
/**
* constructor with default country.
*
* @param countryCode iso code of country
*/
protected AbstractPhoneNumberUtil(final String countryCode,
final PhoneCountryConstantsProvider honeCountryConstantsProvider) {
super();
phoneCountryConstantsProvider = honeCountryConstantsProvider;
this.setCountryCode(countryCode, Locale.ROOT);
}
/**
* set country code.
*
* @param countryCode iso code of country
*/
public final void setCountryCode(final String countryCode) {
this.setCountryCode(countryCode, Locale.ROOT);
}
/**
* set country code.
*
* @param countryCode iso code of country
* @param locale locale to read properties in the correct language
*/
protected final void setCountryCode(final String countryCode, final Locale locale) {
if (StringUtils.isEmpty(countryCode)) {
defaultCountryData = null;
} else {
defaultCountryData = phoneCountryConstantsProvider.getPhoneCountryConstants(locale)
.getCountriesMap().get(countryCode);
}
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @return PhoneNumberData
*/
public PhoneNumberData parsePhoneNumber(final String phoneNumber) {
return (PhoneNumberData) this.parsePhoneNumber(phoneNumber, new PhoneNumberData(),
defaultCountryData);
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string with length
* @return PhoneNumberData with length
*/
public ValueWithPos parsePhoneNumber(final ValueWithPos phoneNumber) {
return this.parsePhoneNumber(phoneNumber, new PhoneNumberData(), defaultCountryData);
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param countryCode iso code of country
* @return PhoneNumberData
*/
public PhoneNumberData parsePhoneNumber(final String phoneNumber, final String countryCode) {
return this.parsePhoneNumber(phoneNumber, countryCode, Locale.ROOT);
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param countryCode iso code of country
* @param locale locale to read properties in the correct language
* @return PhoneNumberData
*/
public PhoneNumberData parsePhoneNumber(final String phoneNumber, final String countryCode,
final Locale locale) {
return (PhoneNumberData) this.parsePhoneNumber(phoneNumber, new PhoneNumberData(),
phoneCountryConstantsProvider.getPhoneCountryConstants(locale).getCountriesMap()
.get(StringUtils.defaultString(countryCode)));
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param countryCode iso code of country
* @return PhoneNumberData
*/
public ValueWithPos parsePhoneNumber(final ValueWithPos phoneNumber,
final String countryCode) {
return this.parsePhoneNumber(phoneNumber, countryCode, Locale.ROOT);
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param countryCode iso code of country
* @param locale locale to read properties in the correct language
* @return PhoneNumberData
*/
public ValueWithPos parsePhoneNumber(final ValueWithPos phoneNumber,
final String countryCode, final Locale locale) {
return this.parsePhoneNumber(phoneNumber, new PhoneNumberData(),
phoneCountryConstantsProvider.getPhoneCountryConstants(locale).getCountriesMap()
.get(StringUtils.defaultString(countryCode)));
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param phoneNumberData phone number data to fill
* @return PhoneNumberData, the same as in second parameter
*/
public PhoneNumberInterface parsePhoneNumber(final String phoneNumber,
final PhoneNumberInterface phoneNumberData) {
return this.parsePhoneNumber(phoneNumber, phoneNumberData, defaultCountryData);
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param phoneNumberData phone number data to fill
* @param countryData country data
* @return PhoneNumberData, the same as in second parameter
*/
public PhoneNumberInterface parsePhoneNumber(final String phoneNumber,
final PhoneNumberInterface phoneNumberData, final PhoneCountryData countryData) {
if (phoneNumber == null) {
return null;
}
final ValueWithPos formatedValue =
this.parsePhoneNumber(new ValueWithPos<>(phoneNumber, -1), phoneNumberData, countryData);
return formatedValue.getValue();
}
/**
* parse phone number.
*
* @param phoneNumber phone number as string
* @param phoneNumberData phone number data to fill
* @param countryData country data
* @return PhoneNumberData, the same as in second parameter
*/
public ValueWithPos parsePhoneNumber(final ValueWithPos phoneNumber,
final PhoneNumberInterface phoneNumberData, final PhoneCountryData countryData) {
if (phoneNumber == null || phoneNumberData == null) {
return null;
}
int cursorpos = phoneNumber.getPos();
int cursorpossub = 0;
for (int pos = 0; pos < cursorpos && pos < StringUtils.length(phoneNumber.getValue()); pos++) {
final char character = phoneNumber.getValue().charAt(pos);
if (character < '0' || character > '9') {
cursorpossub++;
}
}
cursorpos -= cursorpossub;
boolean needsAreaCode = false;
int minLength = 2;
int maxLength = 15;
phoneNumberData.setCountryCode(null);
phoneNumberData.setAreaCode(null);
phoneNumberData.setLineNumber(null);
phoneNumberData.setExtension(null);
final StringBuilder cleanupString = new StringBuilder(phoneNumber.getValue().length());
final boolean containsMinus = StringUtils.contains(phoneNumber.getValue(), '-');
boolean hasSeperator = false;
for (final char character : StringUtils.reverse(phoneNumber.getValue()).toCharArray()) {
switch (character) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
cleanupString.append(character);
break;
case '-':
if (!hasSeperator) {
cleanupString.append(character);
hasSeperator = true;
}
break;
case ' ':
if (!hasSeperator && !containsMinus && cleanupString.length() <= 5) {
cleanupString.append('-');
hasSeperator = true;
}
break;
default:
// ignore all other characters
break;
}
}
String phoneNumberWork = StringUtils.reverse(cleanupString.toString());
if (countryData != null) {
if (StringUtils.isNotEmpty(countryData.getExitCode())
&& phoneNumberWork.startsWith(countryData.getExitCode())) {
phoneNumberWork = phoneNumberWork.substring(countryData.getExitCode().length());
cursorpos -= countryData.getExitCode().length();
} else if (StringUtils.isNotEmpty(countryData.getTrunkCode())
&& phoneNumberWork.startsWith(countryData.getTrunkCode())) {
phoneNumberWork = countryData.getCountryCodeData().getCountryCode()
+ phoneNumberWork.substring(countryData.getTrunkCode().length());
if (cursorpos >= countryData.getTrunkCode().length()) {
cursorpos -= countryData.getTrunkCode().length();
cursorpos += StringUtils.length(countryData.getCountryCodeData().getCountryCode());
}
}
}
for (final PhoneCountryCodeData countryCode : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (phoneNumberWork.startsWith(countryCode.getCountryCode())) {
phoneNumberData.setCountryCode(countryCode.getCountryCode());
maxLength -= StringUtils.length(countryCode.getCountryCode());
if (phoneNumberData instanceof PhoneNumberExtendedInterface) {
((PhoneNumberExtendedInterface) phoneNumberData)
.setCountryName(countryCode.getCountryCodeName());
}
phoneNumberWork = phoneNumberWork.substring(countryCode.getCountryCode().length());
if (phoneNumberWork.startsWith(EXTENSION_SEPARATOR)) {
phoneNumberWork = phoneNumberWork.substring(1);
}
if (countryCode.getPhoneCountryData() != null) {
needsAreaCode = countryCode.getPhoneCountryData().isAreaCodeMustBeFilled();
if (StringUtils.isNotEmpty(countryCode.getPhoneCountryData().getTrunkCode())
&& phoneNumberWork.startsWith(countryCode.getPhoneCountryData().getTrunkCode())) {
phoneNumberWork = phoneNumberWork
.substring(countryCode.getPhoneCountryData().getTrunkCode().length());
if (cursorpos >= countryCode.getPhoneCountryData().getTrunkCode().length()) {
cursorpos -= countryCode.getPhoneCountryData().getTrunkCode().length();
}
}
}
for (final PhoneAreaCodeData areaCode : countryCode.getAreaCodeData()) {
if (areaCode.isRegEx() && phoneNumberWork.matches("^" + areaCode.getAreaCode() + ".*")) {
final String areaCodeRemember = phoneNumberWork;
phoneNumberWork =
phoneNumberWork.replaceFirst(areaCode.getAreaCode(), StringUtils.EMPTY);
phoneNumberData.setAreaCode(areaCodeRemember.substring(0,
areaCodeRemember.length() - phoneNumberWork.length()));
if (phoneNumberData instanceof PhoneNumberExtendedInterface) {
((PhoneNumberExtendedInterface) phoneNumberData).setAreaName(areaCode.getAreaName());
}
minLength = areaCode.getMinLength();
maxLength = areaCode.getMaxLength();
break;
} else if (!areaCode.isRegEx() && phoneNumberWork.startsWith(areaCode.getAreaCode())) {
phoneNumberData.setAreaCode(areaCode.getAreaCode());
if (phoneNumberData instanceof PhoneNumberExtendedInterface) {
((PhoneNumberExtendedInterface) phoneNumberData).setAreaName(areaCode.getAreaName());
}
phoneNumberWork = phoneNumberWork.substring(areaCode.getAreaCode().length());
minLength = areaCode.getMinLength();
maxLength = areaCode.getMaxLength();
break;
}
}
if (phoneNumberWork.startsWith(EXTENSION_SEPARATOR)) {
phoneNumberWork = phoneNumberWork.substring(1);
}
if (phoneNumberWork.contains(EXTENSION_SEPARATOR)) {
final String[] splitedPhoneNumber = phoneNumberWork.split(EXTENSION_SEPARATOR);
phoneNumberData.setLineNumber(splitedPhoneNumber[0]);
if (splitedPhoneNumber.length > 1) {
phoneNumberData.setExtension(splitedPhoneNumber[1]);
}
} else {
phoneNumberData.setLineNumber(phoneNumberWork);
}
break;
}
}
if (phoneNumberData instanceof ValidationInterface
&& phoneCountryConstantsProvider.hasPhoneCountryConstants()) {
int callNummerLength = StringUtils.length(phoneNumberData.getLineNumber());
int completeNumberLength = callNummerLength;
if (StringUtils.isNotEmpty(phoneNumberData.getExtension())) {
// if we do have extensions, phone number including extension may be longer then allowed
// number, but at least one digit counts
callNummerLength++;
completeNumberLength += StringUtils.length(phoneNumberData.getExtension());
}
((ValidationInterface) phoneNumberData)
.setValid(StringUtils.isNotEmpty(phoneNumberData.getCountryCode())
&& StringUtils.isNotEmpty(phoneNumberData.getLineNumber())
&& (StringUtils.isNotEmpty(phoneNumberData.getAreaCode()) || !needsAreaCode)
&& (callNummerLength >= minLength && callNummerLength <= maxLength
|| completeNumberLength >= minLength && completeNumberLength <= maxLength));
}
if (cursorpos < 0) {
cursorpos = 0;
} else {
final int calculatedlength = StringUtils.length(phoneNumberData.getCountryCode())
+ StringUtils.length(phoneNumberData.getAreaCode())
+ StringUtils.length(phoneNumberData.getLineNumber())
+ StringUtils.length(phoneNumberData.getExtension());
if (cursorpos > calculatedlength) {
cursorpos = calculatedlength;
}
}
return new ValueWithPos<>(new PhoneNumberData(phoneNumberData), cursorpos);
}
/**
* format phone number in E123 format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatE123(final String phoneNumber) {
return this.formatE123(this.parsePhoneNumber(phoneNumber), defaultCountryData);
}
/**
* format phone number in E123 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatE123WithPos(this.parsePhoneNumber(phoneNumber), defaultCountryData),
phoneNumber);
}
/**
* format phone number in E123 format.
*
* @param phoneNumber phone number as String to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatE123(final String phoneNumber, final String countryCode) {
return this.formatE123(this.parsePhoneNumber(phoneNumber), phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountriesMap().get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in E123 format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatE123(final PhoneNumberInterface phoneNumberData) {
return this.formatE123(phoneNumberData, defaultCountryData);
}
/**
* format phone number in E123 format.
*
* @param phoneNumberData phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatE123(final PhoneNumberInterface phoneNumberData,
final String countryCode) {
return this.formatE123(phoneNumberData, phoneCountryConstantsProvider.getPhoneCountryConstants()
.getCountriesMap().get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in E123 format.
*
* @param phoneNumberData phone number to format
* @param countryData country data
* @return formated phone number as String
*/
public final String formatE123(final PhoneNumberInterface phoneNumberData,
final PhoneCountryData countryData) {
if (phoneNumberData != null && countryData != null && StringUtils.equals(
countryData.getCountryCodeData().getCountryCode(), phoneNumberData.getCountryCode())) {
return this.formatE123National(phoneNumberData);
} else {
return this.formatE123International(phoneNumberData);
}
}
/**
* format phone number in E123 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123WithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatE123WithPos(this.parsePhoneNumber(phoneNumber, countryCode),
phoneCountryConstantsProvider.getPhoneCountryConstants().getCountriesMap()
.get(StringUtils.defaultString(countryCode))),
phoneNumber);
}
/**
* format phone number in E123 format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @param countryData country data
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123WithPos(
final ValueWithPos phoneNumberData, final PhoneCountryData countryData) {
if (phoneNumberData != null && countryData != null
&& StringUtils.equals(countryData.getCountryCodeData().getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
return this.formatE123NationalWithPos(phoneNumberData);
} else {
return this.formatE123InternationalWithPos(phoneNumberData);
}
}
/**
* format phone number in E123 international format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatE123International(final String phoneNumber) {
return this.formatE123International(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in E123 international format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatE123International(final String phoneNumber, final String countryCode) {
return this.formatE123International(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in E123 international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123International(
final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatE123InternationalWithPos(this.parsePhoneNumber(phoneNumber)), phoneNumber);
}
/**
* format phone number in E123 international format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatE123International(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
resultNumber.append('+').append(phoneNumberData.getCountryCode()).append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode()).append(' ');
}
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in E123 international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123InternationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatE123InternationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in E123 international format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123InternationalWithPos(
final ValueWithPos phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (phoneNumberData == null) {
return null;
}
final int cursor =
formatE123orDin5008InternationalWithPosWithoutExtension(phoneNumberData, resultNumber);
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())
&& StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
resultNumber.append(phoneNumberData.getValue().getExtension());
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
private int formatE123orDin5008InternationalWithPosWithoutExtension(
final ValueWithPos phoneNumberData, final StringBuilder resultNumber) {
int cursor = phoneNumberData.getPos();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
cursor++;
resultNumber.append('+').append(phoneNumberData.getValue().getCountryCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
resultNumber.append(phoneNumberData.getValue().getAreaCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
}
resultNumber.append(phoneNumberData.getValue().getLineNumber());
}
return cursor;
}
/**
* format phone number in E123 national format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatE123National(final String phoneNumber) {
return this.formatE123National(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in E123 national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123National(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(this.formatE123NationalWithPos(this.parsePhoneNumber(phoneNumber)),
phoneNumber);
}
/**
* format phone number in E123 national format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatE123National(final String phoneNumber, final String countryCode) {
return this.formatE123National(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in E123 national format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatE123National(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(), phoneNumberData.getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return this.formatE123International(phoneNumberData);
}
resultNumber.append('(').append(phoneCountryData.getTrunkCode());
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode());
}
resultNumber.append(") ");
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append(' ');
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in E123 national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123NationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatE123NationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in E123 national format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatE123NationalWithPos(
final ValueWithPos phoneNumberData) {
if (phoneNumberData == null) {
return null;
}
int cursor = phoneNumberData.getPos();
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return this.formatE123InternationalWithPos(phoneNumberData);
}
if (cursor > 0) {
cursor -= StringUtils.length(phoneNumberData.getValue().getCountryCode());
cursor += StringUtils.length(phoneCountryData.getTrunkCode());
}
cursor++;
resultNumber.append('(').append(phoneCountryData.getTrunkCode());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
resultNumber.append(phoneNumberData.getValue().getAreaCode());
}
if (resultNumber.length() <= cursor) {
cursor += 2;
}
resultNumber.append(") ");
resultNumber.append(phoneNumberData.getValue().getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
resultNumber.append(phoneNumberData.getValue().getExtension());
}
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in DIN 5008 format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatDin5008(final String phoneNumber) {
return this.formatDin5008(this.parsePhoneNumber(phoneNumber), defaultCountryData);
}
/**
* format phone number in DIN 5008 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatDin5008WithPos(this.parsePhoneNumber(phoneNumber), defaultCountryData),
phoneNumber);
}
/**
* format phone number in DIN 5008 format.
*
* @param phoneNumber phone number as String to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatDin5008(final String phoneNumber, final String countryCode) {
return this.formatDin5008(this.parsePhoneNumber(phoneNumber), phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountriesMap().get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in DIN 5008 format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatDin5008(final PhoneNumberInterface phoneNumberData) {
return this.formatDin5008(phoneNumberData, defaultCountryData);
}
/**
* format phone number in DIN 5008 format.
*
* @param phoneNumberData phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatDin5008(final PhoneNumberInterface phoneNumberData,
final String countryCode) {
return this.formatDin5008(phoneNumberData, phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountriesMap().get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in DIN 5008 format.
*
* @param phoneNumberData phone number to format
* @param countryData country data
* @return formated phone number as String
*/
public final String formatDin5008(final PhoneNumberInterface phoneNumberData,
final PhoneCountryData countryData) {
if (phoneNumberData != null && StringUtils.equals(
countryData.getCountryCodeData().getCountryCode(), phoneNumberData.getCountryCode())) {
return this.formatDin5008National(phoneNumberData);
} else {
return this.formatDin5008International(phoneNumberData);
}
}
/**
* format phone number in DIN 5008 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008WithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatDin5008WithPos(this.parsePhoneNumber(phoneNumber, countryCode),
phoneCountryConstantsProvider.getPhoneCountryConstants().getCountriesMap()
.get(StringUtils.defaultString(countryCode))),
phoneNumber);
}
/**
* format phone number in DIN 5008 format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @param countryData country data
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008WithPos(
final ValueWithPos phoneNumberData, final PhoneCountryData countryData) {
if (phoneNumberData != null && countryData != null
&& StringUtils.equals(countryData.getCountryCodeData().getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
return this.formatDin5008NationalWithPos(phoneNumberData);
} else {
return this.formatDin5008InternationalWithPos(phoneNumberData);
}
}
/**
* format phone number in DIN 5008 international format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatDin5008International(final String phoneNumber) {
return this.formatDin5008International(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in DIN 5008 international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008International(
final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatDin5008InternationalWithPos(this.parsePhoneNumber(phoneNumber)), phoneNumber);
}
/**
* format phone number in DIN 5008 international format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatDin5008International(final String phoneNumber,
final String countryCode) {
return this.formatDin5008International(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in DIN 5008 international format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatDin5008International(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
resultNumber.append('+').append(phoneNumberData.getCountryCode()).append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode()).append(' ');
}
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append('-');
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in DIN 5008 international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008InternationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatDin5008InternationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in DIN 5008 international format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008InternationalWithPos(
final ValueWithPos phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (phoneNumberData == null) {
return null;
}
int cursor =
formatE123orDin5008InternationalWithPosWithoutExtension(phoneNumberData, resultNumber);
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())
&& StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
resultNumber.append(phoneNumberData.getValue().getExtension());
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in DIN 5008 national format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatDin5008National(final String phoneNumber) {
return this.formatDin5008National(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in DIN 5008 national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008National(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatDin5008NationalWithPos(this.parsePhoneNumber(phoneNumber)), phoneNumber);
}
/**
* format phone number in DIN 5008 national format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatDin5008National(final String phoneNumber, final String countryCode) {
return this.formatDin5008National(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in DIN 5008 national format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatDin5008National(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(), phoneNumberData.getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return this.formatDin5008International(phoneNumberData);
}
resultNumber.append(phoneCountryData.getTrunkCode());
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode());
}
resultNumber.append(' ');
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append('-');
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in DIN 5008 national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008NationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatDin5008NationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in DIN 5008 national format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatDin5008NationalWithPos(
final ValueWithPos phoneNumberData) {
if (phoneNumberData == null) {
return null;
}
int cursor = phoneNumberData.getPos();
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return this.formatDin5008InternationalWithPos(phoneNumberData);
}
if (cursor > 0) {
cursor -= StringUtils.length(phoneNumberData.getValue().getCountryCode());
cursor += StringUtils.length(phoneCountryData.getTrunkCode());
}
resultNumber.append(phoneCountryData.getTrunkCode());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
resultNumber.append(phoneNumberData.getValue().getAreaCode());
}
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
resultNumber.append(phoneNumberData.getValue().getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
resultNumber.append(phoneNumberData.getValue().getExtension());
}
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in RFC 3966 format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatRfc3966(final String phoneNumber) {
return this.formatRfc3966(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in RFC 3966 format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatRfc3966(final String phoneNumber, final String countryCode) {
return this.formatRfc3966(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in RFC 3966 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatRfc3966(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(this.formatRfc3966WithPos(this.parsePhoneNumber(phoneNumber)),
phoneNumber);
}
/**
* format phone number in RFC 3966 format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatRfc3966(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
resultNumber.append('+').append(phoneNumberData.getCountryCode()).append('-');
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode()).append('-');
}
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in RFC 3966 format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatRfc3966WithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatRfc3966WithPos(this.parsePhoneNumber(phoneNumber, countryCode)), phoneNumber);
}
/**
* format phone number in RFC 3966 format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatRfc3966WithPos(
final ValueWithPos phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (phoneNumberData == null) {
return null;
}
final int cursor = formatRfc3966orUrlWithPosWithoutExtension(phoneNumberData, resultNumber);
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())
&& StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
resultNumber.append(phoneNumberData.getValue().getExtension());
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
private int formatRfc3966orUrlWithPosWithoutExtension(
final ValueWithPos phoneNumberData, final StringBuilder resultNumber) {
int cursor = phoneNumberData.getPos();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
cursor++;
resultNumber.append('+').append(phoneNumberData.getValue().getCountryCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
resultNumber.append(phoneNumberData.getValue().getAreaCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
}
resultNumber.append(phoneNumberData.getValue().getLineNumber());
}
return cursor;
}
/**
* format phone number in Microsoft canonical address format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatMs(final String phoneNumber) {
return this.formatMs(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in Microsoft canonical address format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatMs(final String phoneNumber, final String countryCode) {
return this.formatMs(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in Microsoft canonical address format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatMs(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(this.formatMsWithPos(this.parsePhoneNumber(phoneNumber)),
phoneNumber);
}
/**
* format phone number in Microsoft canonical address format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatMs(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
resultNumber.append('+').append(phoneNumberData.getCountryCode()).append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append('(').append(phoneNumberData.getAreaCode()).append(") ");
}
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append(" - ");
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in Microsoft canonical address format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatMsWithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatMsWithPos(this.parsePhoneNumber(phoneNumber, countryCode)), phoneNumber);
}
/**
* format phone number in Microsoft canonical address format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatMsWithPos(
final ValueWithPos phoneNumberData) {
if (phoneNumberData == null) {
return null;
}
int cursor = phoneNumberData.getPos();
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
cursor++;
resultNumber.append('+').append(phoneNumberData.getValue().getCountryCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('(').append(phoneNumberData.getValue().getAreaCode());
if (resultNumber.length() <= cursor) {
cursor += 2;
}
resultNumber.append(") ");
}
resultNumber.append(phoneNumberData.getValue().getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor += 3;
}
resultNumber.append(" - ");
resultNumber.append(phoneNumberData.getValue().getExtension());
}
}
if (cursor < 0) {
cursor = 0;
} else if (cursor > resultNumber.length()) {
cursor = resultNumber.length();
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in URL format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatUrl(final String phoneNumber) {
return this.formatUrl(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in URL format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatUrl(final String phoneNumber, final String countryCode) {
return this.formatUrl(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in URL format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatUrl(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(this.formatUrlWithPos(this.parsePhoneNumber(phoneNumber)),
phoneNumber);
}
/**
* format phone number in URL format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatUrl(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
resultNumber.append('+').append(phoneNumberData.getCountryCode());
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append('-');
resultNumber.append(phoneNumberData.getAreaCode());
}
resultNumber.append('-');
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append('-');
resultNumber.append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in URL format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatUrlWithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatUrlWithPos(this.parsePhoneNumber(phoneNumber, countryCode)), phoneNumber);
}
/**
* format phone number in URL format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatUrlWithPos(
final ValueWithPos phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (phoneNumberData == null) {
return null;
}
int cursor = formatRfc3966orUrlWithPosWithoutExtension(phoneNumberData, resultNumber);
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())
&& StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
resultNumber.append(phoneNumberData.getValue().getExtension());
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in Common format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatCommon(final String phoneNumber) {
return this.formatCommon(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in common format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommon(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatCommonWithPos(this.parsePhoneNumber(phoneNumber), defaultCountryData),
phoneNumber);
}
/**
* format phone number in common format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatCommon(final PhoneNumberInterface phoneNumberData) {
return this.formatCommon(phoneNumberData, defaultCountryData);
}
/**
* format phone number in common format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatCommon(final String phoneNumber, final String countryCode) {
return this.formatCommon(this.parsePhoneNumber(phoneNumber, countryCode),
phoneCountryConstantsProvider.getPhoneCountryConstants().getCountriesMap()
.get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in common format.
*
* @param phoneNumberData phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatCommon(final PhoneNumberInterface phoneNumberData,
final String countryCode) {
return this.formatCommon(phoneNumberData, phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountriesMap().get(StringUtils.defaultString(countryCode)));
}
/**
* format phone number in common format.
*
* @param phoneNumberData phone number to format
* @param countryData country data
* @return formated phone number as String
*/
public final String formatCommon(final PhoneNumberInterface phoneNumberData,
final PhoneCountryData countryData) {
if (phoneNumberData != null && countryData != null && StringUtils.equals(
countryData.getCountryCodeData().getCountryCode(), phoneNumberData.getCountryCode())) {
return this.formatCommonNational(phoneNumberData);
} else {
return this.formatCommonInternational(phoneNumberData);
}
}
/**
* format phone number in common format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonWithPos(final ValueWithPos phoneNumber,
final String countryCode) {
return valueWithPosDefaults(
this.formatCommonWithPos(this.parsePhoneNumber(phoneNumber, countryCode),
phoneCountryConstantsProvider.getPhoneCountryConstants().getCountriesMap()
.get(StringUtils.defaultString(countryCode))),
phoneNumber);
}
/**
* format phone number in common format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @param countryData country data
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonWithPos(
final ValueWithPos phoneNumberData, final PhoneCountryData countryData) {
if (phoneNumberData != null && countryData != null
&& StringUtils.equals(countryData.getCountryCodeData().getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
return this.formatCommonNationalWithPos(phoneNumberData);
} else {
return this.formatCommonInternationalWithPos(phoneNumberData);
}
}
/**
* format phone number in Common international format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatCommonInternational(final String phoneNumber) {
return this.formatCommonInternational(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in common international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonInternational(
final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatCommonInternationalWithPos(this.parsePhoneNumber(phoneNumber)), phoneNumber);
}
/**
* format phone number in common international format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatCommonInternational(final String phoneNumber,
final String countryCode) {
return this.formatCommonInternational(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in Common international format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatCommonInternational(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(), phoneNumberData.getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return null;
}
resultNumber.append('+').append(phoneNumberData.getCountryCode()).append(' ');
resultNumber.append('(').append(phoneCountryData.getTrunkCode()).append(')');
if (StringUtils.isNotBlank(phoneNumberData.getAreaCode())) {
resultNumber.append(phoneNumberData.getAreaCode()).append(' ');
}
resultNumber.append(phoneNumberData.getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append('-').append(phoneNumberData.getExtension());
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in common international format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonInternationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatCommonInternationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in common international format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonInternationalWithPos(
final ValueWithPos phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (phoneNumberData == null) {
return null;
}
int cursor = phoneNumberData.getPos();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return null;
}
cursor++;
resultNumber.append('+').append(phoneNumberData.getValue().getCountryCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
if (resultNumber.length() <= cursor) {
cursor += 2;
}
resultNumber.append('(').append(phoneCountryData.getTrunkCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(')');
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
resultNumber.append(phoneNumberData.getValue().getAreaCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
}
resultNumber.append(phoneNumberData.getValue().getLineNumber());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append('-');
resultNumber.append(phoneNumberData.getValue().getExtension());
}
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
/**
* format phone number in Common national format.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as String
*/
public final String formatCommonNational(final String phoneNumber) {
return this.formatCommonNational(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in common national format.
*
* @param phoneNumber phone number to format
* @param countryCode iso code of country
* @return formated phone number as String
*/
public final String formatCommonNational(final String phoneNumber, final String countryCode) {
return this.formatCommonNational(this.parsePhoneNumber(phoneNumber, countryCode));
}
/**
* format phone number in common national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonNational(final ValueWithPos phoneNumber) {
return valueWithPosDefaults(
this.formatCommonNationalWithPos(this.parsePhoneNumber(phoneNumber)), phoneNumber);
}
/**
* format phone number in Common national format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as String
*/
public final String formatCommonNational(final PhoneNumberInterface phoneNumberData) {
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData)) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(), phoneNumberData.getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return null;
}
resultNumber.append(phoneCountryData.getTrunkCode()).append(' ');
resultNumber.append(this.groupIntoParts(phoneNumberData.getAreaCode(), 2));
resultNumber.append(" / ");
resultNumber.append(this.groupIntoParts(phoneNumberData.getLineNumber(), 2));
if (StringUtils.isNotBlank(phoneNumberData.getExtension())) {
resultNumber.append(" - ");
resultNumber.append(this.groupIntoParts(phoneNumberData.getExtension(), 2));
}
}
return StringUtils.trimToNull(resultNumber.toString());
}
/**
* format phone number in common national format with cursor position handling.
*
* @param phoneNumber phone number as String to format with cursor position
* @param countryCode iso code of country
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonNationalWithPos(
final ValueWithPos phoneNumber, final String countryCode) {
return valueWithPosDefaults(
this.formatCommonNationalWithPos(this.parsePhoneNumber(phoneNumber, countryCode)),
phoneNumber);
}
/**
* format phone number in common national format with cursor position handling.
*
* @param phoneNumberData phone number to format with cursor position
* @return formated phone number as String with new cursor position
*/
public final ValueWithPos formatCommonNationalWithPos(
final ValueWithPos phoneNumberData) {
if (phoneNumberData == null) {
return null;
}
int cursor = phoneNumberData.getPos();
final StringBuilder resultNumber = new StringBuilder();
if (isPhoneNumberNotEmpty(phoneNumberData.getValue())) {
PhoneCountryData phoneCountryData = null;
for (final PhoneCountryCodeData country : phoneCountryConstantsProvider
.getPhoneCountryConstants().getCountryCode()) {
if (StringUtils.equals(country.getCountryCode(),
phoneNumberData.getValue().getCountryCode())) {
phoneCountryData = country.getPhoneCountryData();
break;
}
}
if (phoneCountryData == null) {
return null;
}
if (cursor > 0) {
cursor -= StringUtils.length(phoneNumberData.getValue().getCountryCode());
cursor += StringUtils.length(phoneCountryData.getTrunkCode());
}
resultNumber.append(phoneCountryData.getTrunkCode());
if (resultNumber.length() <= cursor) {
cursor++;
}
resultNumber.append(' ');
if (StringUtils.isNotBlank(phoneNumberData.getValue().getAreaCode())) {
final ValueWithPos areaCode = this.groupIntoParts(
new ValueWithPos<>(phoneNumberData.getValue().getAreaCode(), cursor),
resultNumber.length(), 2);
cursor = areaCode.getPos();
resultNumber.append(areaCode.getValue());
}
if (resultNumber.length() <= cursor) {
cursor += 3;
}
resultNumber.append(" / ");
final ValueWithPos lineNumber = this.groupIntoParts(
new ValueWithPos<>(phoneNumberData.getValue().getLineNumber(), cursor),
resultNumber.length(), 2);
cursor = lineNumber.getPos();
resultNumber.append(lineNumber.getValue());
if (StringUtils.isNotBlank(phoneNumberData.getValue().getExtension())) {
if (resultNumber.length() <= cursor) {
cursor += 3;
}
resultNumber.append(" - ");
final ValueWithPos extension = this.groupIntoParts(
new ValueWithPos<>(phoneNumberData.getValue().getExtension(), cursor),
resultNumber.length(), 2);
cursor = extension.getPos();
resultNumber.append(extension.getValue());
}
}
return new ValueWithPos<>(StringUtils.trimToNull(resultNumber.toString()), cursor);
}
private ValueWithPos groupIntoParts(final ValueWithPos string, final int length,
final int blockLength) {
if (string == null || string.getValue() == null) {
return new ValueWithPos<>(StringUtils.EMPTY, blockLength);
}
final StringBuilder formatedSb = new StringBuilder();
int pos = 0;
for (final char charCode : string.getValue().toCharArray()) {
if (CharUtils.isAsciiNumeric(charCode)) {
if (pos > 0 && pos % blockLength == 0) {
if (formatedSb.length() + length <= string.getPos()) {
string.setPos(string.getPos() + 1);
}
formatedSb.append(' ');
}
formatedSb.append(charCode);
pos++;
}
}
string.setValue(formatedSb.toString());
return string;
}
private String groupIntoParts(final String string, final int blockLength) {
if (string == null) {
return StringUtils.EMPTY;
}
final StringBuilder formatedSb = new StringBuilder();
int pos = 0;
for (final char charCode : string.toCharArray()) {
if (CharUtils.isAsciiNumeric(charCode)) {
if (pos > 0 && pos % blockLength == 0) {
formatedSb.append(' ');
}
formatedSb.append(charCode);
pos++;
}
}
return formatedSb.toString();
}
private ValueWithPos valueWithPosDefaults(final ValueWithPos formatValueWithPos,
final ValueWithPos defaultNumber) {
if (formatValueWithPos != null && (StringUtils.isEmpty(formatValueWithPos.getValue()) //
|| StringUtils.startsWith(defaultNumber.getValue(), formatValueWithPos.getValue())
&& !Character.isDigit(defaultNumber.getValue()
.charAt(StringUtils.length(defaultNumber.getValue()) - 1)))) {
formatValueWithPos.setValue(defaultNumber.getValue());
formatValueWithPos.setPos(defaultNumber.getPos());
}
if (defaultNumber != null) {
formatValueWithPos.setOriginalValue(defaultNumber.getValue());
}
return formatValueWithPos;
}
/**
* format phone number to index.
*
* @param phoneNumber phone number as String to format
* @return formated phone number as Long
*/
public final Long formatIndex(final String phoneNumber) {
return this.formatIndex(this.parsePhoneNumber(phoneNumber));
}
/**
* format phone number in URL format.
*
* @param phoneNumberData phone number to format
* @return formated phone number as Long
*/
public final Long formatIndex(final PhoneNumberInterface phoneNumberData) {
if (isPhoneNumberNotEmpty(phoneNumberData)) {
return Long.valueOf(StringUtils.defaultString(phoneNumberData.getCountryCode())
+ StringUtils.defaultString(phoneNumberData.getAreaCode())
+ StringUtils.defaultString(phoneNumberData.getLineNumber())
+ StringUtils.defaultString(phoneNumberData.getExtension()));
}
return null;
}
/**
* check if phone number is empty.
*
* @param phoneNumberData phone number to check
* @return true if number is empty
*/
public final boolean isPhoneNumberEmpty(final PhoneNumberInterface phoneNumberData) {
return phoneNumberData == null || StringUtils.isBlank(phoneNumberData.getCountryCode())
|| StringUtils.isBlank(phoneNumberData.getLineNumber());
}
/**
* check if phone number is not empty.
*
* @param phoneNumberData phone number to check
* @return true if number is not empty
*/
public final boolean isPhoneNumberNotEmpty(final PhoneNumberInterface phoneNumberData) {
return !isPhoneNumberEmpty(phoneNumberData);
}
/**
* get suggestions.
*
* @param search search string
* @param limit limit entries
* @return list of phone number data
*/
public final List getSuggstions(final String search, final int limit) {
return this.getSuggstions(search, limit, Locale.ROOT);
}
/**
* get suggestions.
*
* @param search search string
* @param limit limit entries
* @param locale locale
* @return list of phone number data
*/
public final List getSuggstions(final String search, final int limit,
final Locale locale) {
final List suggestList = new ArrayList<>(limit);
final String cleanedPhoneNumber = cleanString(search);
PhoneCountryCodeData foundCounty = null;
final List possibleCountries = new ArrayList<>(limit);
for (final PhoneCountryCodeData countryCode : phoneCountryConstantsProvider
.getPhoneCountryConstants(locale).getCountryCode()) {
if (cleanedPhoneNumber.startsWith(countryCode.getCountryCode())) {
foundCounty = countryCode;
break;
}
if (countryCode.getCountryCode().startsWith(cleanedPhoneNumber)) {
possibleCountries.add(countryCode);
}
}
if (foundCounty == null) {
// we don't have found a matching country, show possible countries
for (final PhoneCountryCodeData country : possibleCountries) {
final PhoneNumberData entry = new PhoneNumberData();
entry.setCountryCode(country.getCountryCode());
entry.setCountryName(country.getCountryCodeName());
suggestList.add(entry);
}
} else {
// we do have a country, search for possible area codes
final String phoneNumberWork =
StringUtils.substring(cleanedPhoneNumber, foundCounty.getCountryCode().length());
for (final PhoneAreaCodeData areaCode : foundCounty.getAreaCodeData()) {
if (!areaCode.isRegEx() && areaCode.getAreaCode().startsWith(phoneNumberWork)) {
final PhoneNumberData entry = new PhoneNumberData();
entry.setCountryCode(foundCounty.getCountryCode());
entry.setCountryName(foundCounty.getCountryCodeName());
entry.setAreaCode(areaCode.getAreaCode());
entry.setAreaName(areaCode.getAreaName());
suggestList.add(entry);
}
}
}
Collections.sort(suggestList, new PhoneNumberSuggestComperator());
if (suggestList.size() >= limit) {
return suggestList.subList(0, limit);
}
return suggestList;
}
/**
* detect country code for given phone number.
*
* @param phoneNumber phone number as String to detect country code
* @return country enum with country code
*/
public final CountryEnum detectCountryCode(final String phoneNumber) {
return this.detectCountryCode(this.parsePhoneNumber(phoneNumber));
}
/**
* detect country code for given phone number.
*
* @param phoneNumberData phone number to detect country code fro
* @return country enum with country code
*/
public final CountryEnum detectCountryCode(final PhoneNumberInterface phoneNumberData) {
if (phoneNumberData == null || phoneNumberData.getCountryCode() == null) {
return null;
}
switch (phoneNumberData.getCountryCode()) {
case "1":
switch (StringUtils.defaultString(phoneNumberData.getAreaCode())) {
case "242":
return CountryEnum.BS;
case "246":
return CountryEnum.BB;
case "264":
return CountryEnum.AI;
case "268":
return CountryEnum.AG;
case "284":
return CountryEnum.VG;
case "340":
return CountryEnum.VI;
case "345":
return CountryEnum.KY;
case "441":
return CountryEnum.BM;
case "473":
return CountryEnum.GD;
case "649":
return CountryEnum.TC;
case "664":
return CountryEnum.MS;
case "670":
return CountryEnum.MP;
case "671":
return CountryEnum.GU;
case "684":
return CountryEnum.AS;
case "721":
return CountryEnum.SX;
case "758":
return CountryEnum.LC;
case "767":
return CountryEnum.DM;
case "784":
return CountryEnum.VC;
case "787":
case "939":
return CountryEnum.PR;
case "809":
case "829":
case "849":
return CountryEnum.DO;
case "868":
return CountryEnum.TT;
case "869":
return CountryEnum.KN;
case "876":
return CountryEnum.JM;
case "204":
case "226":
case "236":
case "249":
case "250":
case "289":
case "306":
case "343":
case "365":
case "403":
case "416":
case "418":
case "431":
case "437":
case "438":
case "450":
case "506":
case "514":
case "519":
case "579":
case "581":
case "587":
case "600":
case "604":
case "613":
case "639":
case "647":
case "705":
case "709":
case "778":
case "780":
case "782":
case "807":
case "819":
case "867":
case "873":
case "902":
case "905":
return CountryEnum.CA;
default:
return CountryEnum.US;
}
case "599":
if ("9".equals(phoneNumberData.getAreaCode())) {
return CountryEnum.CW;
}
return CountryEnum.BQ;
case "7":
if (StringUtils.startsWith(phoneNumberData.getAreaCode(), "6")
|| StringUtils.startsWith(phoneNumberData.getAreaCode(), "7")) {
return CountryEnum.KZ;
}
return CountryEnum.RU;
default:
final Optional countryCodeData =
phoneCountryConstantsProvider.getPhoneCountryConstants().getCountryCode().stream()
.filter(entry -> entry.getCountryCode()
.equals(StringUtils.defaultString(phoneNumberData.getCountryCode())))
.findFirst();
if (countryCodeData.isPresent()) {
final String phoneCountryCode =
countryCodeData.get().getPhoneCountryData().getCountryCode();
if (phoneCountryCode.length() == 2) {
return CountryEnum.valueOf(phoneCountryCode);
}
}
return null;
}
}
private String cleanString(final String phoneNumber) {
final StringBuilder cleanupString = new StringBuilder(phoneNumber.length());
for (final char character : phoneNumber.toCharArray()) {
if (character >= '0' && character <= '9') {
cleanupString.append(character);
}
}
return cleanupString.toString();
}
public boolean isInitialized() {
return phoneCountryConstantsProvider.hasPhoneCountryConstants();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy