001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.util.common.string; 018 019import com.echothree.model.control.contact.common.ContactOptions; 020import com.echothree.model.control.contact.common.PostalAddressElementTypes; 021import com.echothree.model.control.contact.common.transfer.ContactPostalAddressTransfer; 022import com.echothree.model.control.contact.common.transfer.PostalAddressLineTransfer; 023import com.echothree.model.control.geo.common.GeoCodeAliasTypes; 024import com.echothree.model.control.geo.common.GeoOptions; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Set; 028 029public class ContactPostalAddressUtils { 030 031 private ContactPostalAddressUtils() { 032 super(); 033 } 034 035 private static class ContactPostalAddressUtilsHolder { 036 static ContactPostalAddressUtils instance = new ContactPostalAddressUtils(); 037 } 038 039 public static ContactPostalAddressUtils getInstance() { 040 return ContactPostalAddressUtilsHolder.instance; 041 } 042 043 public Set<String> addOptions(Set<String> options) { 044 options.add(ContactOptions.PostalAddressFormatIncludeLines); 045 options.add(ContactOptions.PostalAddressLineIncludeElements); 046 options.add(GeoOptions.CountryIncludeAliases); 047 options.add(GeoOptions.StateIncludeAliases); 048 049 return options; 050 } 051 052 private String getCountryAlias(final String geoCodeAliasTypeName, final ContactPostalAddressTransfer contactPostalAddress) { 053 String addition; 054 var country = contactPostalAddress.getCountryGeoCode(); 055 056 if(country == null) { 057 throw new IllegalArgumentException("CountryGeoCode is not available to get " + geoCodeAliasTypeName + " Alias on ContactPostalAddress TO"); 058 } else { 059 var geoCodeAliases = country.getGeoCodeAliases(); 060 061 if(geoCodeAliases == null) { 062 throw new IllegalArgumentException("CountryIncludeAliases is a required Option to format ContactPostalAddress TO"); 063 } else { 064 var geoCodeAlias = geoCodeAliases.getMap().get(geoCodeAliasTypeName); 065 066 if(geoCodeAlias == null) { 067 throw new IllegalArgumentException(geoCodeAliasTypeName + " Alias is not available on ContactPostalAddress TO"); 068 } else { 069 addition = geoCodeAlias.getAlias(); 070 } 071 } 072 } 073 074 return addition; 075 } 076 077 private String getLineElementAddition(final ContactPostalAddressTransfer contactPostalAddress, final String postalAddressElementTypeName) { 078 String addition = null; 079 080 if(postalAddressElementTypeName.equals(PostalAddressElementTypes.PERSONAL_TITLE.name())) { 081 var personalTitle = contactPostalAddress.getPersonalTitle(); 082 083 if(personalTitle != null) { 084 addition = personalTitle.getDescription(); 085 } 086 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.FIRST_NAME.name())) { 087 addition = contactPostalAddress.getFirstName(); 088 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.MIDDLE_NAME.name())) { 089 addition = contactPostalAddress.getMiddleName(); 090 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.LAST_NAME.name())) { 091 addition = contactPostalAddress.getLastName(); 092 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.NAME_SUFFIX.name())) { 093 var nameSuffix = contactPostalAddress.getNameSuffix(); 094 095 if(nameSuffix != null) { 096 addition = nameSuffix.getDescription(); 097 } 098 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COMPANY_NAME.name())) { 099 addition = contactPostalAddress.getCompanyName(); 100 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ATTENTION.name())) { 101 addition = contactPostalAddress.getAttention(); 102 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_1.name())) { 103 addition = contactPostalAddress.getAddress1(); 104 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_2.name())) { 105 addition = contactPostalAddress.getAddress2(); 106 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_3.name())) { 107 addition = contactPostalAddress.getAddress3(); 108 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.CITY.name())) { 109 var city = contactPostalAddress.getCityGeoCode(); 110 111 addition = city == null? contactPostalAddress.getCity(): city.getDescription(); 112 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTY.name())) { 113 var county = contactPostalAddress.getCountyGeoCode(); 114 115 if(county != null) { 116 addition = county.getDescription(); 117 } 118 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.STATE.name())) { 119 var state = contactPostalAddress.getStateGeoCode(); 120 121 addition = state == null? contactPostalAddress.getState(): state.getDescription(); 122 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.STATE_POSTAL_2_LETTER.name())) { 123 var state = contactPostalAddress.getStateGeoCode(); 124 125 if(state == null) { 126 throw new IllegalArgumentException("StateGeoCode is not available to get STATE_POSTAL_2_LETTER Alias on ContactPostalAddress TO"); 127 } else { 128 var geoCodeAliases = state.getGeoCodeAliases(); 129 130 if(geoCodeAliases == null) { 131 throw new IllegalArgumentException("StateIncludeAliases is a required Option to format ContactPostalAddress TO"); 132 } else { 133 var geoCodeAlias = geoCodeAliases.getMap().get(GeoCodeAliasTypes.POSTAL_2_LETTER.name()); 134 135 if(geoCodeAlias == null) { 136 throw new IllegalArgumentException("STATE_POSTAL_2_LETTER Alias is not available on ContactPostalAddress TO"); 137 } else { 138 addition = geoCodeAlias.getAlias(); 139 } 140 } 141 } 142 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.POSTAL_CODE.name())) { 143 var postalCode = contactPostalAddress.getPostalCodeGeoCode(); 144 145 addition = postalCode == null? contactPostalAddress.getPostalCode(): postalCode.getDescription(); 146 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY.name())) { 147 addition = contactPostalAddress.getCountryGeoCode().getDescription(); 148 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_3_NUMBER.name())) { 149 addition = getCountryAlias(GeoCodeAliasTypes.ISO_3_NUMBER.name(), contactPostalAddress); 150 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_3_LETTER.name())) { 151 addition = getCountryAlias(GeoCodeAliasTypes.ISO_3_LETTER.name(), contactPostalAddress); 152 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_2_LETTER.name())) { 153 addition = getCountryAlias(GeoCodeAliasTypes.ISO_2_LETTER.name(), contactPostalAddress); 154 } 155 156 return addition == null? "": addition; 157 } 158 159 private StringBuilder formatContactPostalAddressLine(final ContactPostalAddressTransfer contactPostalAddress, final PostalAddressLineTransfer postalAddressLine) { 160 var postalAddressLineElements = postalAddressLine.getPostalAddressLineElements(); 161 var lineAddition = new StringBuilder(); 162 163 postalAddressLineElements.getList().forEach((postalAddressLineElement) -> { 164 var lineElement = getLineElementAddition(contactPostalAddress, postalAddressLineElement.getPostalAddressElementType().getPostalAddressElementTypeName()); 165 var lineElementHasLength = lineElement.length() != 0; 166 boolean alwaysIncludePrefix = postalAddressLineElement.getAlwaysIncludePrefix(); 167 boolean alwaysIncludeSuffix = postalAddressLineElement.getAlwaysIncludeSuffix(); 168 var addedToLine = false; 169 if (lineElementHasLength || alwaysIncludePrefix || alwaysIncludeSuffix) { 170 var prefix = postalAddressLineElement.getPrefix(); 171 var suffix = postalAddressLineElement.getSuffix(); 172 if(prefix != null && (lineElementHasLength || alwaysIncludePrefix)) { 173 lineAddition.append(prefix); 174 addedToLine = true; 175 } 176 if(lineElement.length() > 0) { 177 lineAddition.append(lineElement); 178 addedToLine = true; 179 } 180 if(suffix != null && (lineElementHasLength || alwaysIncludeSuffix)) { 181 lineAddition.append(suffix); 182 addedToLine = true; 183 } 184 if (addedToLine) { 185 lineAddition.append(' '); 186 } 187 } 188 }); 189 190 return lineAddition; 191 } 192 193 public List<String> formatContactPostalAddress(final ContactPostalAddressTransfer contactPostalAddress) { 194 var postalAddressFormat = contactPostalAddress.getCountryGeoCode().getPostalAddressFormat(); 195 var postalAddressLines = postalAddressFormat.getPostalAddressLines(); 196 List<String> result; 197 198 if(postalAddressLines == null) { 199 throw new IllegalArgumentException("PostalAddressFormatIncludeLines is a required Option to format ContactPostalAddress TO"); 200 } else { 201 result = new ArrayList<>(postalAddressLines.getSize()); 202 203 for(var postalAddressLine: postalAddressLines.getList()) { 204 var resultLine = new StringBuilder(); 205 var postalAddressLineElements = postalAddressLine.getPostalAddressLineElements(); 206 207 if(postalAddressLineElements == null) { 208 throw new IllegalArgumentException("PostalAddressLineIncludeElements is a required Option to format ContactPostalAddress TO"); 209 } else { 210 resultLine.append(formatContactPostalAddressLine(contactPostalAddress, postalAddressLine)); 211 212 var resultLineHasLength = resultLine.length() != 0; 213 if(resultLineHasLength || !postalAddressLine.getCollapseIfEmpty()) { 214 boolean alwaysIncludePrefix = postalAddressLine.getAlwaysIncludePrefix(); 215 boolean alwaysIncludeSuffix = postalAddressLine.getAlwaysIncludeSuffix(); 216 217 if(resultLineHasLength || alwaysIncludePrefix || alwaysIncludeSuffix) { 218 var prefix = postalAddressLine.getPrefix(); 219 var suffix = postalAddressLine.getSuffix(); 220 221 if(prefix != null && (resultLineHasLength || alwaysIncludePrefix)) { 222 resultLine = new StringBuilder(prefix).append(' ').append(resultLine); 223 } 224 225 if(suffix != null && (resultLineHasLength || alwaysIncludeSuffix)) { 226 resultLine.append(suffix); 227 } 228 } 229 230 result.add(resultLine.toString().trim()); 231 } 232 } 233 } 234 } 235 236 return result; 237 } 238 239}