001 package railo.runtime.net.mail; 002 003 import railo.commons.lang.StringUtil; 004 import railo.runtime.exp.PageException; 005 import railo.runtime.op.Caster; 006 import railo.runtime.op.Decision; 007 import railo.runtime.type.Array; 008 import railo.runtime.type.Struct; 009 import railo.runtime.type.util.ListUtil; 010 011 import java.io.UnsupportedEncodingException; 012 import java.net.IDN; 013 import java.util.ArrayList; 014 import java.util.Iterator; 015 016 import javax.mail.internet.AddressException; 017 import javax.mail.internet.InternetAddress; 018 import javax.mail.internet.MimeUtility; 019 020 public final class MailUtil { 021 022 public static String encode(String text,String encoding) throws UnsupportedEncodingException { 023 //print.ln(StringUtil.changeCharset(text,encoding)); 024 return MimeUtility.encodeText(text,encoding,"Q"); 025 } 026 027 public static String decode(String text) throws UnsupportedEncodingException { 028 return MimeUtility.decodeText(text); 029 } 030 031 032 033 public static InternetAddress toInternetAddress(Object emails) throws MailException, UnsupportedEncodingException, PageException { 034 035 if ( emails instanceof String ) 036 return parseEmail( emails ); 037 038 InternetAddress[] addresses = toInternetAddresses( emails ); 039 if ( addresses != null && addresses.length > 0 ) 040 return addresses[0]; 041 042 return null; 043 } 044 045 046 public static InternetAddress[] toInternetAddresses(Object emails) throws MailException, UnsupportedEncodingException, PageException { 047 048 if (emails instanceof String ) 049 return fromList((String) emails); 050 051 else if ( Decision.isArray(emails) ) 052 return fromArray(Caster.toArray(emails)); 053 054 else if ( Decision.isStruct(emails) ) 055 return new InternetAddress[]{ fromStruct(Caster.toStruct(emails)) }; 056 057 else 058 throw new MailException("e-mail defintions must be one of the following types [string,array,struct], not ["+emails.getClass().getName()+"]"); 059 } 060 061 062 private static InternetAddress[] fromArray(Array array) throws MailException, PageException, UnsupportedEncodingException { 063 064 Iterator it = array.valueIterator(); 065 Object el; 066 ArrayList<InternetAddress> pairs = new ArrayList(); 067 068 while(it.hasNext()){ 069 el=it.next(); 070 if ( Decision.isStruct( el ) ) { 071 072 pairs.add( fromStruct(Caster.toStruct(el)) ); 073 } 074 else { 075 076 InternetAddress addr = parseEmail( Caster.toString(el) ); 077 if ( addr != null ) 078 pairs.add( addr ); 079 } 080 } 081 082 return pairs.toArray( new InternetAddress[ pairs.size() ] ); 083 } 084 085 086 private static InternetAddress fromStruct( Struct sct ) throws MailException, UnsupportedEncodingException { 087 088 String name = Caster.toString(sct.get("label",null),null); 089 if ( name == null ) 090 name=Caster.toString(sct.get("name",null),null); 091 092 String email = Caster.toString(sct.get("email",null),null); 093 if ( email == null ) 094 email = Caster.toString(sct.get("e-mail",null),null); 095 if ( email == null ) 096 email = Caster.toString(sct.get("mail",null),null); 097 098 if( StringUtil.isEmpty(email) ) 099 throw new MailException("missing e-mail definition in struct"); 100 101 if(name==null) name=""; 102 103 return new InternetAddress( email, name ); 104 } 105 106 107 private static InternetAddress[] fromList( String strEmails ) { 108 109 if ( StringUtil.isEmpty( strEmails, true ) ) 110 return new InternetAddress[0]; 111 112 Array raw = ListUtil.listWithQuotesToArray(strEmails, ",;", "\""); 113 114 Iterator<Object> it = raw.valueIterator(); 115 ArrayList<InternetAddress> al = new ArrayList(); 116 117 while( it.hasNext() ) { 118 119 InternetAddress addr = parseEmail( it.next() ); 120 121 if( addr != null ) 122 al.add( addr ); 123 } 124 125 return al.toArray( new InternetAddress[ al.size() ] ); 126 } 127 128 129 /** 130 * returns true if the passed value is a in valid email address format 131 * @param value 132 * @return 133 */ 134 public static boolean isValidEmail( Object value ) { 135 136 return ( parseEmail( value ) != null ); 137 } 138 139 140 /** 141 * returns an InternetAddress object or null if the parsing fails. to be be used in multiple places. 142 * @param value 143 * @return 144 */ 145 public static InternetAddress parseEmail( Object value ) { 146 147 String str = Caster.toString( value, "" ); 148 149 if ( str.indexOf( '@' ) > -1 ) { 150 151 try { 152 153 InternetAddress addr = new InternetAddress( str ); 154 fixIDN( addr ); 155 return addr; 156 } 157 catch ( AddressException ex ) {} 158 } 159 160 return null; 161 } 162 163 164 /** 165 * converts IDN to ASCII if needed 166 * @param addr 167 */ 168 public static void fixIDN( InternetAddress addr ) { 169 170 String address = addr.getAddress(); 171 int pos = address.indexOf( '@' ); 172 173 if ( pos > 0 && pos < address.length() - 1 ) { 174 175 String domain = address.substring( pos + 1 ); 176 177 if ( !StringUtil.isAscii( domain ) ) { 178 179 domain = IDN.toASCII( domain ); 180 addr.setAddress( address.substring( 0, pos ) + "@" + domain ); 181 } 182 } 183 } 184 185 }