/** * 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 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 ,. * * 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 * ,. * * 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 . * * 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 . * * 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 . * * 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 . * * 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 . * * 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 * . * * 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 * . * * 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()); } }