whats-in-a-name/src/main/java/com/jkgroller/whatsinaname/service/IndividualNameFormatterServiceImpl.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());
}
}