001// -------------------------------------------------------------------------------- 002// Copyright 2002-2024 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.PostalAddressFormatTransfer; 023import com.echothree.model.control.contact.common.transfer.PostalAddressLineElementTransfer; 024import com.echothree.model.control.contact.common.transfer.PostalAddressLineTransfer; 025import com.echothree.model.control.geo.common.GeoConstants; 026import com.echothree.model.control.geo.common.GeoOptions; 027import com.echothree.model.control.geo.common.transfer.CityTransfer; 028import com.echothree.model.control.geo.common.transfer.CountryTransfer; 029import com.echothree.model.control.geo.common.transfer.CountyTransfer; 030import com.echothree.model.control.geo.common.transfer.GeoCodeAliasTransfer; 031import com.echothree.model.control.geo.common.transfer.PostalCodeTransfer; 032import com.echothree.model.control.geo.common.transfer.StateTransfer; 033import com.echothree.model.control.party.common.transfer.NameSuffixTransfer; 034import com.echothree.model.control.party.common.transfer.PersonalTitleTransfer; 035import com.echothree.util.common.transfer.ListWrapper; 036import com.echothree.util.common.transfer.MapWrapper; 037import java.util.ArrayList; 038import java.util.List; 039import java.util.Set; 040 041public class ContactPostalAddressUtils { 042 043 private ContactPostalAddressUtils() { 044 super(); 045 } 046 047 private static class ContactPostalAddressUtilsHolder { 048 static ContactPostalAddressUtils instance = new ContactPostalAddressUtils(); 049 } 050 051 public static ContactPostalAddressUtils getInstance() { 052 return ContactPostalAddressUtilsHolder.instance; 053 } 054 055 public Set<String> addOptions(Set<String> options) { 056 options.add(ContactOptions.PostalAddressFormatIncludeLines); 057 options.add(ContactOptions.PostalAddressLineIncludeElements); 058 options.add(GeoOptions.CountryIncludeAliases); 059 options.add(GeoOptions.StateIncludeAliases); 060 061 return options; 062 } 063 064 private String getCountryAlias(final String geoCodeAliasTypeName, final ContactPostalAddressTransfer contactPostalAddress) { 065 String addition; 066 CountryTransfer country = contactPostalAddress.getCountryGeoCode(); 067 068 if(country == null) { 069 throw new IllegalArgumentException("CountryGeoCode is not available to get " + geoCodeAliasTypeName + " Alias on ContactPostalAddress TO"); 070 } else { 071 MapWrapper<GeoCodeAliasTransfer> geoCodeAliases = country.getGeoCodeAliases(); 072 073 if(geoCodeAliases == null) { 074 throw new IllegalArgumentException("CountryIncludeAliases is a required Option to format ContactPostalAddress TO"); 075 } else { 076 GeoCodeAliasTransfer geoCodeAlias = geoCodeAliases.getMap().get(geoCodeAliasTypeName); 077 078 if(geoCodeAlias == null) { 079 throw new IllegalArgumentException(geoCodeAliasTypeName + " Alias is not available on ContactPostalAddress TO"); 080 } else { 081 addition = geoCodeAlias.getAlias(); 082 } 083 } 084 } 085 086 return addition; 087 } 088 089 private String getLineElementAddition(final ContactPostalAddressTransfer contactPostalAddress, final String postalAddressElementTypeName) { 090 String addition = null; 091 092 if(postalAddressElementTypeName.equals(PostalAddressElementTypes.PERSONAL_TITLE.name())) { 093 PersonalTitleTransfer personalTitle = contactPostalAddress.getPersonalTitle(); 094 095 if(personalTitle != null) { 096 addition = personalTitle.getDescription(); 097 } 098 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.FIRST_NAME.name())) { 099 addition = contactPostalAddress.getFirstName(); 100 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.MIDDLE_NAME.name())) { 101 addition = contactPostalAddress.getMiddleName(); 102 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.LAST_NAME.name())) { 103 addition = contactPostalAddress.getLastName(); 104 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.NAME_SUFFIX.name())) { 105 NameSuffixTransfer nameSuffix = contactPostalAddress.getNameSuffix(); 106 107 if(nameSuffix != null) { 108 addition = nameSuffix.getDescription(); 109 } 110 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COMPANY_NAME.name())) { 111 addition = contactPostalAddress.getCompanyName(); 112 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ATTENTION.name())) { 113 addition = contactPostalAddress.getAttention(); 114 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_1.name())) { 115 addition = contactPostalAddress.getAddress1(); 116 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_2.name())) { 117 addition = contactPostalAddress.getAddress2(); 118 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.ADDRESS_3.name())) { 119 addition = contactPostalAddress.getAddress3(); 120 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.CITY.name())) { 121 CityTransfer city = contactPostalAddress.getCityGeoCode(); 122 123 addition = city == null? contactPostalAddress.getCity(): city.getDescription(); 124 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTY.name())) { 125 CountyTransfer county = contactPostalAddress.getCountyGeoCode(); 126 127 if(county != null) { 128 addition = county.getDescription(); 129 } 130 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.STATE.name())) { 131 StateTransfer state = contactPostalAddress.getStateGeoCode(); 132 133 addition = state == null? contactPostalAddress.getState(): state.getDescription(); 134 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.STATE_POSTAL_2_LETTER.name())) { 135 StateTransfer state = contactPostalAddress.getStateGeoCode(); 136 137 if(state == null) { 138 throw new IllegalArgumentException("StateGeoCode is not available to get STATE_POSTAL_2_LETTER Alias on ContactPostalAddress TO"); 139 } else { 140 MapWrapper<GeoCodeAliasTransfer> geoCodeAliases = state.getGeoCodeAliases(); 141 142 if(geoCodeAliases == null) { 143 throw new IllegalArgumentException("StateIncludeAliases is a required Option to format ContactPostalAddress TO"); 144 } else { 145 GeoCodeAliasTransfer geoCodeAlias = geoCodeAliases.getMap().get(GeoConstants.GeoCodeAliasType_POSTAL_2_LETTER); 146 147 if(geoCodeAlias == null) { 148 throw new IllegalArgumentException("STATE_POSTAL_2_LETTER Alias is not available on ContactPostalAddress TO"); 149 } else { 150 addition = geoCodeAlias.getAlias(); 151 } 152 } 153 } 154 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.POSTAL_CODE.name())) { 155 PostalCodeTransfer postalCode = contactPostalAddress.getPostalCodeGeoCode(); 156 157 addition = postalCode == null? contactPostalAddress.getPostalCode(): postalCode.getDescription(); 158 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY.name())) { 159 addition = contactPostalAddress.getCountryGeoCode().getDescription(); 160 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_3_NUMBER.name())) { 161 addition = getCountryAlias(GeoConstants.GeoCodeAliasType_ISO_3_NUMBER, contactPostalAddress); 162 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_3_LETTER.name())) { 163 addition = getCountryAlias(GeoConstants.GeoCodeAliasType_ISO_3_LETTER, contactPostalAddress); 164 } else if(postalAddressElementTypeName.equals(PostalAddressElementTypes.COUNTRY_ISO_2_LETTER.name())) { 165 addition = getCountryAlias(GeoConstants.GeoCodeAliasType_ISO_2_LETTER, contactPostalAddress); 166 } 167 168 return addition == null? "": addition; 169 } 170 171 private StringBuilder formatContactPostalAddressLine(final ContactPostalAddressTransfer contactPostalAddress, final PostalAddressLineTransfer postalAddressLine) { 172 ListWrapper<PostalAddressLineElementTransfer> postalAddressLineElements = postalAddressLine.getPostalAddressLineElements(); 173 StringBuilder lineAddition = new StringBuilder(); 174 175 postalAddressLineElements.getList().stream().forEach((postalAddressLineElement) -> { 176 String lineElement = getLineElementAddition(contactPostalAddress, postalAddressLineElement.getPostalAddressElementType().getPostalAddressElementTypeName()); 177 boolean lineElementHasLength = lineElement.length() != 0; 178 boolean alwaysIncludePrefix = postalAddressLineElement.getAlwaysIncludePrefix(); 179 boolean alwaysIncludeSuffix = postalAddressLineElement.getAlwaysIncludeSuffix(); 180 boolean addedToLine = false; 181 if (lineElementHasLength || alwaysIncludePrefix || alwaysIncludeSuffix) { 182 String prefix = postalAddressLineElement.getPrefix(); 183 String suffix = postalAddressLineElement.getSuffix(); 184 if(prefix != null && (lineElementHasLength || alwaysIncludePrefix)) { 185 lineAddition.append(prefix); 186 addedToLine = true; 187 } 188 if(lineElement.length() > 0) { 189 lineAddition.append(lineElement); 190 addedToLine = true; 191 } 192 if(suffix != null && (lineElementHasLength || alwaysIncludeSuffix)) { 193 lineAddition.append(suffix); 194 addedToLine = true; 195 } 196 if (addedToLine) { 197 lineAddition.append(' '); 198 } 199 } 200 }); 201 202 return lineAddition; 203 } 204 205 public List<String> formatContactPostalAddress(final ContactPostalAddressTransfer contactPostalAddress) { 206 PostalAddressFormatTransfer postalAddressFormat = contactPostalAddress.getCountryGeoCode().getPostalAddressFormat(); 207 ListWrapper<PostalAddressLineTransfer> postalAddressLines = postalAddressFormat.getPostalAddressLines(); 208 List<String> result = null; 209 210 if(postalAddressLines == null) { 211 throw new IllegalArgumentException("PostalAddressFormatIncludeLines is a required Option to format ContactPostalAddress TO"); 212 } else { 213 result = new ArrayList<>(postalAddressLines.getSize()); 214 215 for(PostalAddressLineTransfer postalAddressLine: postalAddressLines.getList()) { 216 StringBuilder resultLine = new StringBuilder(); 217 ListWrapper<PostalAddressLineElementTransfer> postalAddressLineElements = postalAddressLine.getPostalAddressLineElements(); 218 219 if(postalAddressLineElements == null) { 220 throw new IllegalArgumentException("PostalAddressLineIncludeElements is a required Option to format ContactPostalAddress TO"); 221 } else { 222 resultLine.append(formatContactPostalAddressLine(contactPostalAddress, postalAddressLine)); 223 224 boolean resultLineHasLength = resultLine.length() != 0; 225 if(resultLineHasLength || !postalAddressLine.getCollapseIfEmpty()) { 226 boolean alwaysIncludePrefix = postalAddressLine.getAlwaysIncludePrefix(); 227 boolean alwaysIncludeSuffix = postalAddressLine.getAlwaysIncludeSuffix(); 228 229 if(resultLineHasLength || alwaysIncludePrefix || alwaysIncludeSuffix) { 230 String prefix = postalAddressLine.getPrefix(); 231 String suffix = postalAddressLine.getSuffix(); 232 233 if(prefix != null && (resultLineHasLength || alwaysIncludePrefix)) { 234 resultLine = new StringBuilder(prefix).append(' ').append(resultLine); 235 } 236 237 if(suffix != null && (resultLineHasLength || alwaysIncludeSuffix)) { 238 resultLine.append(suffix); 239 } 240 } 241 242 result.add(resultLine.toString().trim()); 243 } 244 } 245 } 246 } 247 248 return result; 249 } 250 251}