001// Generated by delombok at Sat Feb 25 17:58:34 UTC 2023 002package io.cui.tools.net; 003 004import java.net.IDN; 005import java.util.function.UnaryOperator; 006import java.util.regex.Pattern; 007import lombok.NonNull; 008 009/** 010 * <p> 011 * Utility class to handle IDN email addresses. 012 * </p> 013 * See 014 * <ul> 015 * <li> 016 * <a href="https://docs.oracle.com/javase/tutorial/i18n/network/idn.html">https://docs.oracle.com/ 017 * javase/tutorial/i18n/network/idn.html</a></li> 018 * <li> 019 * <a href="https://de.wikipedia.org/wiki/Internationalisierter_Domainname">https://de.wikipedia.org 020 * /wiki/Internationalisierter_Domainname</a></li> 021 * <li> 022 * <a href="https://en.wikipedia.org/wiki/Internationalized_domain_name">https://en.wikipedia.org/ 023 * wiki/Internationalized_domain_name</a></li> 024 * </ul> 025 * 026 * @author Matthias Walliczek 027 */ 028public final class IDNInternetAddress { 029 private static final Pattern addressPatternWithDisplayName = Pattern.compile("(.{0,64})<(.{1,64})@(.{1,64})>(.{0,64})"); 030 private static final Pattern addressPattern = Pattern.compile("(.{1,64})@(.{1,64})"); 031 032 /** 033 * Encode the domain part of an email address 034 * 035 * @param completeAddress the address to encode in RFC822 format 036 * @return the encoded address in RFC822 format 037 */ 038 public static String encode(@NonNull final String completeAddress) { 039 if (completeAddress == null) { 040 throw new java.lang.NullPointerException("completeAddress is marked non-null but is null"); 041 } 042 return encode(completeAddress, untrustedHtml -> untrustedHtml); 043 } 044 045 /** 046 * Encodes the given address and sanitizes the elements with the provided sanitizer. It takes 047 * care on the special elements like {@code <>} by not trying to sanitize them. 048 * 049 * @param completeAddress 050 * @param sanitizer to be passed as UnaryOperator 051 * @return the sanitized and encoded address. 052 */ 053 public static String encode(@NonNull final String completeAddress, UnaryOperator<String> sanitizer) { 054 if (completeAddress == null) { 055 throw new java.lang.NullPointerException("completeAddress is marked non-null but is null"); 056 } 057 var matcher = addressPatternWithDisplayName.matcher(completeAddress); 058 if (matcher.matches() && matcher.groupCount() == 4) { 059 return sanitizer.apply(matcher.group(1)) + "<" + sanitizer.apply(matcher.group(2)) + "@" + sanitizer.apply(IDN.toASCII(matcher.group(3))) + ">" + sanitizer.apply(matcher.group(4)); 060 } 061 matcher = addressPattern.matcher(completeAddress); 062 if (matcher.matches() && matcher.groupCount() == 2) { 063 return sanitizer.apply(matcher.group(1)) + "@" + sanitizer.apply(IDN.toASCII(matcher.group(2))); 064 } 065 return sanitizer.apply(completeAddress); 066 } 067 068 /** 069 * Decode the domain part of an email address 070 * 071 * @param completeAddress the address to decode in RFC822 format 072 * @return the decoded address in RFC822 format 073 */ 074 public static String decode(@NonNull final String completeAddress) { 075 if (completeAddress == null) { 076 throw new java.lang.NullPointerException("completeAddress is marked non-null but is null"); 077 } 078 return decode(completeAddress, untrustedHtml -> untrustedHtml); 079 } 080 081 /** 082 * Decodes the given address and sanitizes the elements with the provided sanitizer. It takes 083 * care on the special elements like <> by not trying to sanitize them. 084 * 085 * @param completeAddress 086 * @param sanitizer to be passed as UnaryOperator 087 * @return the sanitized and decoded address. 088 */ 089 public static String decode(@NonNull final String completeAddress, UnaryOperator<String> sanitizer) { 090 if (completeAddress == null) { 091 throw new java.lang.NullPointerException("completeAddress is marked non-null but is null"); 092 } 093 var matcher = addressPatternWithDisplayName.matcher(completeAddress); 094 if (matcher.matches() && matcher.groupCount() == 4) { 095 return sanitizer.apply(matcher.group(1)) + "<" + sanitizer.apply(matcher.group(2)) + "@" + sanitizer.apply(IDN.toUnicode(matcher.group(3))) + ">" + sanitizer.apply(matcher.group(4)); 096 } 097 matcher = addressPattern.matcher(completeAddress); 098 if (matcher.matches() && matcher.groupCount() == 2) { 099 return sanitizer.apply(matcher.group(1)) + "@" + sanitizer.apply(IDN.toUnicode(matcher.group(2))); 100 } 101 return sanitizer.apply(completeAddress); 102 } 103 104 @java.lang.SuppressWarnings("all") 105 @lombok.Generated 106 private IDNInternetAddress() { 107 throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated"); 108 } 109}