533 lines
16 KiB
Java
533 lines
16 KiB
Java
/**
|
|
* Copyright (c) 2019 John Groller
|
|
*
|
|
* WhatsInAName - John Groller
|
|
*/
|
|
/**
|
|
*
|
|
*/
|
|
package com.jkgroller.whatsinaname.service;
|
|
|
|
import java.util.List;
|
|
|
|
import org.apache.commons.lang3.CharUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import com.jkgroller.whatsinaname.service.to.IndividualNameFormatterRequestTO;
|
|
import com.jkgroller.whatsinaname.service.to.IndividualNameFormatterResponseTO;
|
|
|
|
/**
|
|
* @author john@grollerfamily.com
|
|
*
|
|
*/
|
|
@Service
|
|
public class IndividualNameFormatterServiceImpl implements IndividualNameFormatterService {
|
|
|
|
@Autowired
|
|
private List<String> names;
|
|
|
|
/**
|
|
* Comma constant.
|
|
*/
|
|
private static final String COMMA = ",";
|
|
|
|
/**
|
|
* Comma space constant.
|
|
*/
|
|
private static final String COMMA_SPACE = COMMA + StringUtils.SPACE;
|
|
|
|
/**
|
|
* Period constant.
|
|
*/
|
|
private static final String PERIOD = ".";
|
|
|
|
/**
|
|
* Period space constant.
|
|
*/
|
|
private static final String PERIOD_SPACE = PERIOD + StringUtils.SPACE;
|
|
|
|
/**
|
|
*
|
|
* Orchestrates all formatting and generating of names based on primary name.
|
|
*
|
|
*/
|
|
public IndividualNameFormatterResponseTO formatIndividualName(
|
|
IndividualNameFormatterRequestTO individualNameFormatterRequestTO) {
|
|
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO = properlyFormatPrimaryNameElements(
|
|
individualNameFormatterRequestTO);
|
|
|
|
individualrNameFormatterResponseTO.setPreferredName(individualNameFormatterRequestTO.getPreferredName());
|
|
|
|
individualrNameFormatterResponseTO.setSuffix(individualNameFormatterRequestTO.getSuffix());
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setFirstNameLastNameSuffix(generateFirstNameLastNameSuffix(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO.setFirstNameMiddleNameLastName(
|
|
generateFirstNameMiddleNameLastName(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setLastNameFirstName(generateLastNameFirstName(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO.setLastNameFirstNameMiddleInitial(
|
|
generateLastNameFirstNameMiddleInitial(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setPrefixFirstNameLastName(generatePrefixFirstNameLastName(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO.setPrefixFirstNameMiddleInitialLastName(
|
|
generatePrefixFirstNameMiddleInitialLastName(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setPrefixLastName(generatePrefixLastName(individualrNameFormatterResponseTO));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setFirstNameLastName(generateFirstNameLastName(individualrNameFormatterResponseTO));
|
|
|
|
return individualrNameFormatterResponseTO;
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Properly formats primary name elements... the elements from which all other
|
|
* name formats are derived: firstName, lastName, middleName, prefix.
|
|
*
|
|
* @param individualrNameFormatterRequestTO
|
|
* @return
|
|
*/
|
|
private IndividualNameFormatterResponseTO properlyFormatPrimaryNameElements(
|
|
IndividualNameFormatterRequestTO individualrNameFormatterRequestTO) {
|
|
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO = new IndividualNameFormatterResponseTO();
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setFirstName(properlyFormatNameElement(individualrNameFormatterRequestTO.getFirstName()));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setMiddleName(properlyFormatNameElement(individualrNameFormatterRequestTO.getMiddleName()));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setLastName(properlyFormatNameElement(individualrNameFormatterRequestTO.getLastName()));
|
|
|
|
individualrNameFormatterResponseTO
|
|
.setPrefix(properlyFormatNameElement(individualrNameFormatterRequestTO.getPrefix()));
|
|
|
|
return individualrNameFormatterResponseTO;
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Orchestrates formattting of the name by first checking for null, then
|
|
* checking for matching name in name list. If found, return that matching name.
|
|
* If not, properly capitalize name element and return.
|
|
*
|
|
* @param nameElement
|
|
* @return
|
|
*/
|
|
private String properlyFormatNameElement(String nameElement) {
|
|
|
|
if (StringUtils.isBlank(nameElement)) {
|
|
return null;
|
|
}
|
|
|
|
String matchingName = findMatchingName(nameElement);
|
|
|
|
if (null != matchingName) {
|
|
return matchingName;
|
|
}
|
|
|
|
return properlyCapitalizeNameElement(nameElement);
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Searches the names collection for a matching name element.
|
|
*
|
|
* If found, that matching name element is returned.
|
|
*
|
|
* @param nameElement
|
|
* @return
|
|
*/
|
|
private String findMatchingName(String nameElement) {
|
|
|
|
return names.stream().filter(s -> s.equalsIgnoreCase(nameElement)).findFirst().orElse(null);
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* If nameElement is not null, changes the value to all lower case, then checks
|
|
* the entire string to verify alpha. If it is, return it with the first letter
|
|
* capitalized.
|
|
*
|
|
* If it's not totally alpha things get interesting.
|
|
*
|
|
* The lowerCase string is converted to a char array, and the very first char
|
|
* converted to uppercase, provided it's alpha. Then, the char array is looped
|
|
* through, looking for non-alphanumeric values (for names it will likely be
|
|
* things like "'", "-", and " ". When non-alpha values are found, the char
|
|
* after them is capitalized. If the end of the array contains the non-alpha, it
|
|
* does not attempt a case change since that would cause an index out of bounds
|
|
* exception.
|
|
*
|
|
* @param nameElement
|
|
* @return
|
|
*/
|
|
private String properlyCapitalizeNameElement(String nameElement) {
|
|
|
|
if (StringUtils.isBlank(nameElement)) {
|
|
return null;
|
|
}
|
|
|
|
String lowerCaseNameElement = nameElement.toLowerCase();
|
|
|
|
if (StringUtils.isAlpha(lowerCaseNameElement)) {
|
|
return StringUtils.capitalize(lowerCaseNameElement);
|
|
}
|
|
|
|
char[] properlyCapitalizedNameElementChars = lowerCaseNameElement.toCharArray();
|
|
|
|
if (CharUtils.isAsciiAlpha(properlyCapitalizedNameElementChars[0])) {
|
|
properlyCapitalizedNameElementChars[0] = Character.toUpperCase(properlyCapitalizedNameElementChars[0]);
|
|
}
|
|
|
|
int properlyCapitalizedNameElementCharsLength = properlyCapitalizedNameElementChars.length;
|
|
|
|
for (int i = 0; i < properlyCapitalizedNameElementCharsLength; i++) {
|
|
if (!CharUtils.isAsciiAlpha(properlyCapitalizedNameElementChars[i])) {
|
|
if ((i + 1) < properlyCapitalizedNameElementCharsLength) {
|
|
properlyCapitalizedNameElementChars[i + 1] = Character
|
|
.toUpperCase(properlyCapitalizedNameElementChars[i + 1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return new String(properlyCapitalizedNameElementChars);
|
|
|
|
}
|
|
|
|
/**
|
|
* Generates name in the format <lastName>,<space><firstName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateLastNameFirstName(IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isFirstNameLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getLastName());
|
|
stringBuilder.append(COMMA_SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getFirstName());
|
|
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format
|
|
* <lastName>,<space><firstName><space><middleInitial><period>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateLastNameFirstNameMiddleInitial(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isFirstNameMiddleNameLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(generateLastNameFirstName(individualrNameFormatterResponseTO));
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getMiddleName().substring(0, 1).toUpperCase());
|
|
stringBuilder.append(PERIOD);
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format <firstName><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateFirstNameLastName(IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getFirstName());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getLastName());
|
|
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format <prefix><space><firstName><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generatePrefixFirstNameLastName(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isPrefixFirstNameLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getPrefix());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(generateFirstNameLastName(individualrNameFormatterResponseTO));
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format <prefix><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generatePrefixLastName(IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isPrefixLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getPrefix());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getLastName());
|
|
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format <firstName><space><lastName><space><suffix>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateFirstNameLastNameSuffix(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isFirstNameLastNameSuffixMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(generateFirstNameLastName(individualrNameFormatterResponseTO));
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getSuffix());
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format <firstName><space><middleName><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateFirstNameMiddleNameLastName(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isFirstNameMiddleNameLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getFirstName());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getMiddleName());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getLastName());
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format
|
|
* <firstName><space><middleInitial><period><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generateFirstNameMiddleInitialLastName(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getFirstName());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getMiddleName().substring(0, 1).toUpperCase());
|
|
stringBuilder.append(PERIOD_SPACE);
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getLastName());
|
|
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Generates name in the format
|
|
* <prefix><space><firstName><space><middleInitial><space><lastName>.
|
|
*
|
|
* Returns null if this can't be calculated.
|
|
*
|
|
*
|
|
* @param individualrNameFormatterResponseTO
|
|
* @return
|
|
*/
|
|
private String generatePrefixFirstNameMiddleInitialLastName(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
if (isPrefixFirstNameMiddleNameLastNameMissing(individualrNameFormatterResponseTO)) {
|
|
return null;
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.append(individualrNameFormatterResponseTO.getPrefix());
|
|
stringBuilder.append(StringUtils.SPACE);
|
|
stringBuilder.append(generateFirstNameMiddleInitialLastName(individualrNameFormatterResponseTO));
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of first and last names.
|
|
*
|
|
* True if either are missing. False if both are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isFirstNameLastNameMissing(IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return StringUtils.isBlank(individualrNameFormatterResponseTO.getFirstName())
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getLastName());
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of first, middle, and last names.
|
|
*
|
|
* True if any are missing. False if all are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isFirstNameMiddleNameLastNameMissing(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return isFirstNameLastNameMissing(individualrNameFormatterResponseTO)
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getMiddleName());
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of prefix, first, and last names.
|
|
*
|
|
* True if any are missing. False if all are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isPrefixFirstNameLastNameMissing(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return isFirstNameLastNameMissing(individualrNameFormatterResponseTO)
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getPrefix());
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of prefix, first, middle, and last names.
|
|
*
|
|
* True if any are missing. False if all are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isPrefixFirstNameMiddleNameLastNameMissing(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return isPrefixFirstNameLastNameMissing(individualrNameFormatterResponseTO)
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getMiddleName());
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of first and last names, and suffix.
|
|
*
|
|
* True if any are missing. False if all are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isFirstNameLastNameSuffixMissing(
|
|
IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return isFirstNameLastNameMissing(individualrNameFormatterResponseTO)
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getSuffix());
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks for the existence of prefix and last name.
|
|
*
|
|
* True if either are missing. False if both are present.
|
|
*
|
|
* @return
|
|
*/
|
|
private boolean isPrefixLastNameMissing(IndividualNameFormatterResponseTO individualrNameFormatterResponseTO) {
|
|
|
|
return StringUtils.isBlank(individualrNameFormatterResponseTO.getLastName())
|
|
|| StringUtils.isBlank(individualrNameFormatterResponseTO.getPrefix());
|
|
|
|
}
|
|
|
|
}
|