| 
68
 | 
     1 /*
 | 
| 
 | 
     2 Copyright (c) 2008  Franklin Schmidt <fschmidt@gmail.com>
 | 
| 
 | 
     3 
 | 
| 
 | 
     4 Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
| 
 | 
     5 of this software and associated documentation files (the "Software"), to deal
 | 
| 
 | 
     6 in the Software without restriction, including without limitation the rights
 | 
| 
 | 
     7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
| 
 | 
     8 copies of the Software, and to permit persons to whom the Software is
 | 
| 
 | 
     9 furnished to do so, subject to the following conditions:
 | 
| 
 | 
    10 
 | 
| 
 | 
    11 The above copyright notice and this permission notice shall be included in
 | 
| 
 | 
    12 all copies or substantial portions of the Software.
 | 
| 
 | 
    13 
 | 
| 
 | 
    14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
| 
 | 
    15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
| 
 | 
    16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
| 
 | 
    17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
| 
 | 
    18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
| 
 | 
    19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
| 
 | 
    20 THE SOFTWARE.
 | 
| 
 | 
    21 */
 | 
| 
 | 
    22 
 | 
| 
 | 
    23 package fschmidt.util.mail.javamail;
 | 
| 
 | 
    24 
 | 
| 
 | 
    25 import fschmidt.util.java.IoUtils;
 | 
| 
 | 
    26 import fschmidt.util.mail.AlternativeMultipartContent;
 | 
| 
 | 
    27 import fschmidt.util.mail.Content;
 | 
| 
 | 
    28 import fschmidt.util.mail.FileAttachmentContent;
 | 
| 
 | 
    29 import fschmidt.util.mail.HtmlTextContent;
 | 
| 
 | 
    30 import fschmidt.util.mail.Mail;
 | 
| 
 | 
    31 import fschmidt.util.mail.MailAddress;
 | 
| 
 | 
    32 import fschmidt.util.mail.MailAddressException;
 | 
| 
 | 
    33 import fschmidt.util.mail.MailEncodingException;
 | 
| 
 | 
    34 import fschmidt.util.mail.MailException;
 | 
| 
 | 
    35 import fschmidt.util.mail.MailParseException;
 | 
| 
 | 
    36 import fschmidt.util.mail.MixedMultipartContent;
 | 
| 
 | 
    37 import fschmidt.util.mail.MultipartContent;
 | 
| 
 | 
    38 import fschmidt.util.mail.PlainTextContent;
 | 
| 
 | 
    39 import fschmidt.util.mail.TextAttachmentContent;
 | 
| 
 | 
    40 import fschmidt.util.mail.TextContent;
 | 
| 
 | 
    41 import fschmidt.util.mail.UnsupportedContent;
 | 
| 
 | 
    42 
 | 
| 
 | 
    43 import javax.activation.CommandMap;
 | 
| 
 | 
    44 import javax.activation.MailcapCommandMap;
 | 
| 
 | 
    45 import javax.mail.Address;
 | 
| 
 | 
    46 import javax.mail.Message;
 | 
| 
 | 
    47 import javax.mail.MessagingException;
 | 
| 
 | 
    48 import javax.mail.Part;
 | 
| 
 | 
    49 import javax.mail.Session;
 | 
| 
 | 
    50 import javax.mail.internet.AddressException;
 | 
| 
 | 
    51 import javax.mail.internet.ContentType;
 | 
| 
 | 
    52 import javax.mail.internet.HeaderTokenizer;
 | 
| 
 | 
    53 import javax.mail.internet.InternetAddress;
 | 
| 
 | 
    54 import javax.mail.internet.MimeBodyPart;
 | 
| 
 | 
    55 import javax.mail.internet.MimeMessage;
 | 
| 
 | 
    56 import javax.mail.internet.MimeMultipart;
 | 
| 
 | 
    57 import javax.mail.internet.MimePart;
 | 
| 
 | 
    58 import javax.mail.internet.MimeUtility;
 | 
| 
 | 
    59 import javax.mail.internet.ParseException;
 | 
| 
 | 
    60 import java.io.ByteArrayInputStream;
 | 
| 
 | 
    61 import java.io.ByteArrayOutputStream;
 | 
| 
 | 
    62 import java.io.IOException;
 | 
| 
 | 
    63 import java.io.InputStream;
 | 
| 
 | 
    64 import java.io.InputStreamReader;
 | 
| 
 | 
    65 import java.io.UnsupportedEncodingException;
 | 
| 
 | 
    66 import java.util.Date;
 | 
| 
 | 
    67 import java.util.Enumeration;
 | 
| 
 | 
    68 
 | 
| 
 | 
    69 
 | 
| 
 | 
    70 public class MailImpl implements Mail {
 | 
| 
 | 
    71 	private static final Session nullSession = null;
 | 
| 
 | 
    72 
 | 
| 
 | 
    73 	class MyMimeMessage extends MimeMessage {
 | 
| 
 | 
    74 		MyMimeMessage() {
 | 
| 
 | 
    75 			super(nullSession);
 | 
| 
 | 
    76 		}
 | 
| 
 | 
    77 
 | 
| 
 | 
    78 		MyMimeMessage(InputStream is) throws MessagingException {
 | 
| 
 | 
    79 			super(nullSession,is);
 | 
| 
 | 
    80 		}
 | 
| 
 | 
    81 
 | 
| 
 | 
    82 		MyMimeMessage(MimeMessage msg) throws MessagingException {
 | 
| 
 | 
    83 			super(msg);
 | 
| 
 | 
    84 		}
 | 
| 
 | 
    85 
 | 
| 
 | 
    86 		void setSession(Session session) {
 | 
| 
 | 
    87 			this.session = session;
 | 
| 
 | 
    88 		}
 | 
| 
 | 
    89 
 | 
| 
 | 
    90 		protected void updateHeaders()
 | 
| 
 | 
    91 			throws MessagingException
 | 
| 
 | 
    92 		{
 | 
| 
 | 
    93 			super.updateHeaders();
 | 
| 
 | 
    94 			if( messageID != null )
 | 
| 
 | 
    95 				setHeader( "Message-ID", messageID );
 | 
| 
 | 
    96 		}
 | 
| 
 | 
    97 	}
 | 
| 
 | 
    98 
 | 
| 
 | 
    99 	final MyMimeMessage msg;
 | 
| 
 | 
   100 	private String messageID = null;
 | 
| 
 | 
   101 
 | 
| 
 | 
   102 	public MailImpl() {
 | 
| 
 | 
   103 		this.msg = new MyMimeMessage();
 | 
| 
 | 
   104 	}
 | 
| 
 | 
   105 
 | 
| 
 | 
   106 	public MailImpl(String rawInput) {
 | 
| 
 | 
   107 		try {
 | 
| 
 | 
   108 			this.msg = new MyMimeMessage(new ByteArrayInputStream(rawInput.getBytes("ISO-8859-1")));
 | 
| 
 | 
   109 		} catch (UnsupportedEncodingException e) {
 | 
| 
 | 
   110 			throw new RuntimeException(e);
 | 
| 
 | 
   111 		} catch(MessagingException e) {
 | 
| 
 | 
   112 			throw MailImpl.e(e);
 | 
| 
 | 
   113 		}
 | 
| 
 | 
   114 	}
 | 
| 
 | 
   115 
 | 
| 
 | 
   116 	MailImpl(MimeMessage msg) throws MessagingException {
 | 
| 
 | 
   117 		this.msg = new MyMimeMessage(msg);
 | 
| 
 | 
   118 	}
 | 
| 
 | 
   119 
 | 
| 
 | 
   120 	public String getType() {
 | 
| 
 | 
   121 		return "message";
 | 
| 
 | 
   122 	}
 | 
| 
 | 
   123 
 | 
| 
 | 
   124 	public String getSubtype() {
 | 
| 
 | 
   125 		return "rfc822";
 | 
| 
 | 
   126 	}
 | 
| 
 | 
   127 
 | 
| 
 | 
   128 	public Content getContent() throws MailException {
 | 
| 
 | 
   129 		try {
 | 
| 
 | 
   130             return getPart(msg);
 | 
| 
 | 
   131 		} catch(MessagingException e) {
 | 
| 
 | 
   132 			throw MailImpl.e(e);
 | 
| 
 | 
   133 		} catch(IOException e) {
 | 
| 
 | 
   134 			throw MailImpl.e(e);
 | 
| 
 | 
   135 		}
 | 
| 
 | 
   136 	}
 | 
| 
 | 
   137 
 | 
| 
 | 
   138 	private static Content getPart(Part part) throws MessagingException, IOException {
 | 
| 
 | 
   139 		String ct = part.getContentType().toLowerCase();
 | 
| 
 | 
   140 		int end = ct.indexOf(';');
 | 
| 
 | 
   141 		if( end != -1 )
 | 
| 
 | 
   142 			ct = ct.substring(0,end);
 | 
| 
 | 
   143 		String[] a = ct.split("/");
 | 
| 
 | 
   144 		if (a.length==0)
 | 
| 
 | 
   145 			return new UnsupportedContent(part.getInputStream(), null, null);
 | 
| 
 | 
   146 		String type = a[0];
 | 
| 
 | 
   147 		String subtype = a.length>1 ? a[1]:"";
 | 
| 
 | 
   148 		if( type.equals("text") ) {
 | 
| 
 | 
   149 		    String text = null;
 | 
| 
 | 
   150 		    Object obj;
 | 
| 
 | 
   151 			try {
 | 
| 
 | 
   152 				obj = part.getContent();
 | 
| 
 | 
   153 			} catch (UnsupportedEncodingException e) {
 | 
| 
 | 
   154 				obj = IoUtils.readAll(new InputStreamReader(part.getInputStream(), "ISO-8859-1"));
 | 
| 
 | 
   155 				if (!isAllAscii((String)obj))
 | 
| 
 | 
   156 					return new UnsupportedContent(obj, type, subtype);
 | 
| 
 | 
   157 			}
 | 
| 
 | 
   158 			if( Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) )
 | 
| 
 | 
   159 		    	return new FileAttachmentContentImpl((MimePart)part, type, subtype);
 | 
| 
 | 
   160 		    if( obj instanceof String ) {
 | 
| 
 | 
   161 		    	text = (String)obj;
 | 
| 
 | 
   162 		    } else if( obj instanceof InputStream ) {
 | 
| 
 | 
   163 		    	try {
 | 
| 
 | 
   164 		    		String charset = null;
 | 
| 
 | 
   165 		    		String filename = null;
 | 
| 
 | 
   166 		    		try {
 | 
| 
 | 
   167 		    			ContentType contentType = new ContentType(part.getContentType());
 | 
| 
 | 
   168 		    			charset = MimeUtility.javaCharset(contentType.getParameter("charset"));
 | 
| 
 | 
   169 		    			filename = contentType.getParameter("name");
 | 
| 
 | 
   170 		    		} catch (ParseException e) {}
 | 
| 
 | 
   171 		    		text = IoUtils.readAll(new InputStreamReader((InputStream)obj,charset!=null?charset:"ISO-8859-1"));
 | 
| 
 | 
   172 		    	} catch (IOException e) {
 | 
| 
 | 
   173 		    		return new UnsupportedContent(part.getInputStream(), type, subtype);
 | 
| 
 | 
   174 		    	} catch (MessagingException e) {
 | 
| 
 | 
   175 		    		return new UnsupportedContent(part.getInputStream(), type, subtype);
 | 
| 
 | 
   176 		    	}
 | 
| 
 | 
   177 		    } else {
 | 
| 
 | 
   178 		    	return new FileAttachmentContentImpl((MimePart)part, type, subtype);
 | 
| 
 | 
   179 		    }
 | 
| 
 | 
   180 			if( subtype.equals("plain") || subtype.equals(""))
 | 
| 
 | 
   181 				return new PlainTextContent(text);
 | 
| 
 | 
   182 			if( subtype.equals("html") )
 | 
| 
 | 
   183 				return new HtmlTextContent(text);
 | 
| 
 | 
   184 			return new TextContent(subtype,text);
 | 
| 
 | 
   185 		}
 | 
| 
 | 
   186 		if( type.equals("multipart") && part.getContent() instanceof MimeMultipart) {
 | 
| 
 | 
   187 			Content[] parts = getParts( (MimeMultipart)part.getContent() );
 | 
| 
 | 
   188 			if( subtype.equals("alternative") )
 | 
| 
 | 
   189 				return new AlternativeMultipartContent(parts);
 | 
| 
 | 
   190 			if( subtype.equals("mixed") )
 | 
| 
 | 
   191 				return new MixedMultipartContent(parts);
 | 
| 
 | 
   192 			if( subtype.equals("signed") )
 | 
| 
 | 
   193 				return new MixedMultipartContent(parts);
 | 
| 
 | 
   194 			return new MultipartContent(subtype,parts);
 | 
| 
 | 
   195 		}
 | 
| 
 | 
   196 		if( type.equals("message") && subtype.equals("rfc822") && part.getContent() instanceof MimeMessage) {
 | 
| 
 | 
   197 			MimeMessage mm = (MimeMessage)part.getContent();
 | 
| 
 | 
   198 			return new MailImpl(mm);
 | 
| 
 | 
   199 		}
 | 
| 
 | 
   200 		/*
 | 
| 
 | 
   201 		if( type.equals("application") ) {
 | 
| 
 | 
   202 			if( subtype.equals("pgp-signature") )
 | 
| 
 | 
   203 				return new PlainTextContent((String)obj);
 | 
| 
 | 
   204 				}
 | 
| 
 | 
   205 		*/
 | 
| 
 | 
   206 		return new FileAttachmentContentImpl((MimePart)part, type, subtype);
 | 
| 
 | 
   207 	}
 | 
| 
 | 
   208 
 | 
| 
 | 
   209 	private static Content[] getParts(MimeMultipart mp) throws MessagingException, IOException {
 | 
| 
 | 
   210 		Content[] parts = new Content[mp.getCount()];
 | 
| 
 | 
   211 		for( int i=0; i<parts.length; i++ ) {
 | 
| 
 | 
   212 			parts[i] = getPart(mp.getBodyPart(i));
 | 
| 
 | 
   213 		}
 | 
| 
 | 
   214 		return parts;
 | 
| 
 | 
   215 	}
 | 
| 
 | 
   216 
 | 
| 
 | 
   217 	private static boolean isAllAscii(String s) {
 | 
| 
 | 
   218 		for (int i=0;i<s.length();i++) 
 | 
| 
 | 
   219 			if (nonascii((int)s.charAt(i))) return false;
 | 
| 
 | 
   220 		return true;
 | 
| 
 | 
   221 	}
 | 
| 
 | 
   222 	
 | 
| 
 | 
   223 	// copied from javamail
 | 
| 
 | 
   224 	private static boolean nonascii(int b) {
 | 
| 
 | 
   225     	return b >= 0177 || (b < 040 && b != '\r' && b != '\n' && b != '\t');
 | 
| 
 | 
   226     }
 | 
| 
 | 
   227 
 | 
| 
 | 
   228 	public void setContent(Content content) throws MailException {
 | 
| 
 | 
   229 		try {
 | 
| 
 | 
   230 			setPart(msg,content);
 | 
| 
 | 
   231 		} catch(MessagingException e) {
 | 
| 
 | 
   232 			throw MailImpl.e(e);
 | 
| 
 | 
   233 		}
 | 
| 
 | 
   234 	}
 | 
| 
 | 
   235 
 | 
| 
 | 
   236 	private final static String defaultCharset = MimeUtility.quote(
 | 
| 
 | 
   237 			MimeUtility.mimeCharset(MimeUtility.getDefaultJavaCharset()),
 | 
| 
 | 
   238 			HeaderTokenizer.MIME);
 | 
| 
 | 
   239 	
 | 
| 
 | 
   240 	private static void setPart(Part part,Content content) throws MessagingException {
 | 
| 
 | 
   241 		if( content instanceof PlainTextContent ) {
 | 
| 
 | 
   242 			TextContent textContent = (TextContent)content;
 | 
| 
 | 
   243 			// Using part.setContent breaks the encoding of non-ascii email
 | 
| 
 | 
   244 			// because com.sun.mail.handlers.text_plain assumes us-ascii charset
 | 
| 
 | 
   245 			// if charset is not specified. Part.setText handles this correctly.
 | 
| 
 | 
   246 			part.setText( textContent.getText() );
 | 
| 
 | 
   247 			return;
 | 
| 
 | 
   248 		}
 | 
| 
 | 
   249 		if( content instanceof TextAttachmentContent ) {
 | 
| 
 | 
   250 			TextAttachmentContent textContent = (TextAttachmentContent)content;
 | 
| 
 | 
   251 			// Use same logic as javamail MimeBodyPart.setText() to determine charset
 | 
| 
 | 
   252 			String charset = isAllAscii(textContent.getText())?"us-ascii":defaultCharset;
 | 
| 
 | 
   253 			part.setContent( textContent.getText(), content.getType()+'/'+content.getSubtype()+"; charset="+charset);
 | 
| 
 | 
   254 			part.setFileName( textContent.getFilename() );
 | 
| 
 | 
   255 			return;
 | 
| 
 | 
   256 		}
 | 
| 
 | 
   257 		if( content instanceof FileAttachmentContent ) {
 | 
| 
 | 
   258 			FileAttachmentContent fileContent = (FileAttachmentContent)content;
 | 
| 
 | 
   259 			byte[] contents = new byte[0];
 | 
| 
 | 
   260 			InputStream is = fileContent.getInputStream();
 | 
| 
 | 
   261 			try {
 | 
| 
 | 
   262 				contents = IoUtils.readAll(is);
 | 
| 
 | 
   263 			} catch (IOException e) {
 | 
| 
 | 
   264 				throw new RuntimeException(e);
 | 
| 
 | 
   265 			} finally {
 | 
| 
 | 
   266 				try {
 | 
| 
 | 
   267 					is.close();
 | 
| 
 | 
   268 				} catch (IOException e) {
 | 
| 
 | 
   269 					throw new RuntimeException(e);
 | 
| 
 | 
   270 				}
 | 
| 
 | 
   271 			}
 | 
| 
 | 
   272 			part.setContent( contents, content.getType()+'/'+content.getSubtype());
 | 
| 
 | 
   273 			part.setFileName( fileContent.getFileName() );
 | 
| 
 | 
   274 			return;
 | 
| 
 | 
   275 		}
 | 
| 
 | 
   276 		if( content instanceof TextContent ) {
 | 
| 
 | 
   277 			TextContent textContent = (TextContent)content;
 | 
| 
 | 
   278 			// Use same logic as javamail MimeBodyPart.setText() to determine charset
 | 
| 
 | 
   279 			String charset = isAllAscii(textContent.getText())?"us-ascii":defaultCharset;
 | 
| 
 | 
   280 			part.setContent( textContent.getText(), content.getType()+'/'+content.getSubtype()+"; charset="+charset);
 | 
| 
 | 
   281 			return;
 | 
| 
 | 
   282 		}
 | 
| 
 | 
   283 		if( content instanceof MultipartContent ) {
 | 
| 
 | 
   284 			part.setContent( makeMimeMultipart((MultipartContent)content) );
 | 
| 
 | 
   285 			return;
 | 
| 
 | 
   286 		}
 | 
| 
 | 
   287 		if( content instanceof MailImpl ) {
 | 
| 
 | 
   288 			MailImpl mail = (MailImpl)content;
 | 
| 
 | 
   289 			part.setContent( mail.msg, "message/rfc822" );
 | 
| 
 | 
   290 			part.setDisposition(Part.ATTACHMENT);
 | 
| 
 | 
   291 			return;
 | 
| 
 | 
   292 		}
 | 
| 
 | 
   293 		throw new UnsupportedOperationException("content class "+content.getClass());
 | 
| 
 | 
   294 	}
 | 
| 
 | 
   295 
 | 
| 
 | 
   296 	private static MimeMultipart makeMimeMultipart(MultipartContent mc) throws MessagingException {
 | 
| 
 | 
   297 		MimeMultipart mp = new MimeMultipart(mc.getSubtype());
 | 
| 
 | 
   298 		Content[] parts = mc.getParts();
 | 
| 
 | 
   299 		for( int i=0; i<parts.length; i++ ) {
 | 
| 
 | 
   300 			MimeBodyPart mbp = new MimeBodyPart();
 | 
| 
 | 
   301 			setPart(mbp,parts[i]);
 | 
| 
 | 
   302 			mp.addBodyPart(mbp);
 | 
| 
 | 
   303 		}
 | 
| 
 | 
   304 		return mp;
 | 
| 
 | 
   305 	}
 | 
| 
 | 
   306 		
 | 
| 
 | 
   307 	public String getSubject() throws MailException {
 | 
| 
 | 
   308 		try {
 | 
| 
 | 
   309 			return msg.getSubject();
 | 
| 
 | 
   310 		} catch(MessagingException e) {
 | 
| 
 | 
   311 			throw MailImpl.e(e);
 | 
| 
 | 
   312 		}
 | 
| 
 | 
   313 	}
 | 
| 
 | 
   314 
 | 
| 
 | 
   315 	public void setSubject(String subject) throws MailException {
 | 
| 
 | 
   316 		try {
 | 
| 
 | 
   317 			msg.setSubject(subject);
 | 
| 
 | 
   318 		} catch(MessagingException e) {
 | 
| 
 | 
   319 			throw MailImpl.e(e);
 | 
| 
 | 
   320 		}
 | 
| 
 | 
   321 	}
 | 
| 
 | 
   322 
 | 
| 
 | 
   323 	static InternetAddress addr(MailAddress addr)
 | 
| 
 | 
   324 		throws MessagingException, UnsupportedEncodingException
 | 
| 
 | 
   325 	{
 | 
| 
 | 
   326 		return addr.getDisplayName() == null
 | 
| 
 | 
   327 			? new InternetAddress(addr.getAddrSpec())
 | 
| 
 | 
   328 			: new InternetAddress(addr.getAddrSpec(),addr.getDisplayName())
 | 
| 
 | 
   329 		;
 | 
| 
 | 
   330 	}
 | 
| 
 | 
   331 
 | 
| 
 | 
   332 	static InternetAddress[] addr(MailAddress[] addrs)
 | 
| 
 | 
   333 		throws MessagingException, UnsupportedEncodingException
 | 
| 
 | 
   334 	{
 | 
| 
 | 
   335 		InternetAddress[] a = new InternetAddress[addrs.length];
 | 
| 
 | 
   336 		for( int i=0; i<addrs.length; i++ ) {
 | 
| 
 | 
   337 			a[i] = addr(addrs[i]);
 | 
| 
 | 
   338 		}
 | 
| 
 | 
   339 		return a;
 | 
| 
 | 
   340 	}
 | 
| 
 | 
   341 
 | 
| 
 | 
   342 	static MailAddress addr(Address a) {
 | 
| 
 | 
   343 		if( a==null )
 | 
| 
 | 
   344 			return null;
 | 
| 
 | 
   345 		InternetAddress addr = (InternetAddress)a;
 | 
| 
 | 
   346 		return addr.getPersonal() == null
 | 
| 
 | 
   347 			? new MailAddress(addr.getAddress())
 | 
| 
 | 
   348 			: new MailAddress(addr.getAddress(),addr.getPersonal())
 | 
| 
 | 
   349 		;
 | 
| 
 | 
   350 	}
 | 
| 
 | 
   351 
 | 
| 
 | 
   352 	private static MailAddress[] addr(Address[] a) {
 | 
| 
 | 
   353 		if( a==null )
 | 
| 
 | 
   354 			return new MailAddress[0];
 | 
| 
 | 
   355 		MailAddress[] ma = new MailAddress[a.length];
 | 
| 
 | 
   356 		for( int i=0; i<a.length; i++ ) {
 | 
| 
 | 
   357 			ma[i] = addr(a[i]);
 | 
| 
 | 
   358 		}
 | 
| 
 | 
   359 		return ma;
 | 
| 
 | 
   360 	}
 | 
| 
 | 
   361 
 | 
| 
 | 
   362 	public MailAddress getFrom() throws MailException {
 | 
| 
 | 
   363 		try {
 | 
| 
 | 
   364 			Address[] addrs = msg.getFrom();
 | 
| 
 | 
   365 			if( addrs==null || addrs.length==0 )
 | 
| 
 | 
   366 				throw new MailAddressException("number of from addresses is 0");
 | 
| 
 | 
   367 			//if( addrs.length > 1 )
 | 
| 
 | 
   368 			//	log.warn("number of from addresses is "+addrs.length);
 | 
| 
 | 
   369 			return addr(addrs[0]);
 | 
| 
 | 
   370 		} catch(MessagingException e) {
 | 
| 
 | 
   371 			throw MailImpl.e(e);
 | 
| 
 | 
   372 		}
 | 
| 
 | 
   373 	}
 | 
| 
 | 
   374 
 | 
| 
 | 
   375 	public void setFrom(MailAddress address) throws MailException {
 | 
| 
 | 
   376 		try {
 | 
| 
 | 
   377 			msg.setFrom(addr(address));
 | 
| 
 | 
   378 		} catch(MessagingException e) {
 | 
| 
 | 
   379 			throw MailImpl.e(e);
 | 
| 
 | 
   380 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   381 			throw new MailException(e);
 | 
| 
 | 
   382 		}
 | 
| 
 | 
   383 	}
 | 
| 
 | 
   384 
 | 
| 
 | 
   385 	public MailAddress getSender() throws MailException {
 | 
| 
 | 
   386 		try {
 | 
| 
 | 
   387 			return addr(msg.getSender());
 | 
| 
 | 
   388 		} catch(MessagingException e) {
 | 
| 
 | 
   389 			throw MailImpl.e(e);
 | 
| 
 | 
   390 		}
 | 
| 
 | 
   391 	}
 | 
| 
 | 
   392 
 | 
| 
 | 
   393 	public void setSender(MailAddress address) throws MailException {
 | 
| 
 | 
   394 		try {
 | 
| 
 | 
   395 			msg.setSender(addr(address));
 | 
| 
 | 
   396 		} catch(MessagingException e) {
 | 
| 
 | 
   397 			throw MailImpl.e(e);
 | 
| 
 | 
   398 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   399 			throw new MailException(e);
 | 
| 
 | 
   400 		}
 | 
| 
 | 
   401 	}
 | 
| 
 | 
   402 
 | 
| 
 | 
   403 	public MailAddress[] getReplyTo() throws MailException {
 | 
| 
 | 
   404 		try {
 | 
| 
 | 
   405 			String replyTo = msg.getHeader("Reply-To", ",");
 | 
| 
 | 
   406 			return (replyTo == null) ? null : addr(InternetAddress.parse(replyTo));
 | 
| 
 | 
   407 		} catch(MessagingException e) {
 | 
| 
 | 
   408 			throw MailImpl.e(e);
 | 
| 
 | 
   409 		}
 | 
| 
 | 
   410 	}
 | 
| 
 | 
   411 
 | 
| 
 | 
   412 	public void setReplyTo(MailAddress... addresses) throws MailException {
 | 
| 
 | 
   413 		try {
 | 
| 
 | 
   414 			msg.setReplyTo(addr(addresses));
 | 
| 
 | 
   415 		} catch(MessagingException e) {
 | 
| 
 | 
   416 			throw MailImpl.e(e);
 | 
| 
 | 
   417 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   418 			throw new MailException(e);
 | 
| 
 | 
   419 		}
 | 
| 
 | 
   420 	}
 | 
| 
 | 
   421 
 | 
| 
 | 
   422 	public MailAddress[] getTo() throws MailException {
 | 
| 
 | 
   423 		try {
 | 
| 
 | 
   424 			return addr(msg.getRecipients(Message.RecipientType.TO));
 | 
| 
 | 
   425 		} catch(MessagingException e) {
 | 
| 
 | 
   426 			throw MailImpl.e(e);
 | 
| 
 | 
   427 		}
 | 
| 
 | 
   428 	}
 | 
| 
 | 
   429 
 | 
| 
 | 
   430 	public MailAddress[] getCc() throws MailException {
 | 
| 
 | 
   431 		try {
 | 
| 
 | 
   432 			return addr(msg.getRecipients(Message.RecipientType.CC));
 | 
| 
 | 
   433 		} catch(MessagingException e) {
 | 
| 
 | 
   434 			throw MailImpl.e(e);
 | 
| 
 | 
   435 		}
 | 
| 
 | 
   436 	}
 | 
| 
 | 
   437 
 | 
| 
 | 
   438 	public MailAddress[] getBcc() throws MailException {
 | 
| 
 | 
   439 		try {
 | 
| 
 | 
   440 			return addr(msg.getRecipients(Message.RecipientType.BCC));
 | 
| 
 | 
   441 		} catch(MessagingException e) {
 | 
| 
 | 
   442 			throw MailImpl.e(e);
 | 
| 
 | 
   443 		}
 | 
| 
 | 
   444 	}
 | 
| 
 | 
   445 
 | 
| 
 | 
   446 	public void setTo(MailAddress... addresses) throws MailException {
 | 
| 
 | 
   447 		try {
 | 
| 
 | 
   448 			msg.setRecipients(Message.RecipientType.TO,addr(addresses));
 | 
| 
 | 
   449 		} catch(MessagingException e) {
 | 
| 
 | 
   450 			throw MailImpl.e(e);
 | 
| 
 | 
   451 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   452 			throw new MailException(e);
 | 
| 
 | 
   453 		}
 | 
| 
 | 
   454 	}
 | 
| 
 | 
   455 
 | 
| 
 | 
   456 	public void setCc(MailAddress... addresses) throws MailException {
 | 
| 
 | 
   457 		try {
 | 
| 
 | 
   458 			msg.setRecipients(Message.RecipientType.CC,addr(addresses));
 | 
| 
 | 
   459 		} catch(MessagingException e) {
 | 
| 
 | 
   460 			throw MailImpl.e(e);
 | 
| 
 | 
   461 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   462 			throw new MailException(e);
 | 
| 
 | 
   463 		}
 | 
| 
 | 
   464 	}
 | 
| 
 | 
   465 
 | 
| 
 | 
   466 	public void setBcc(MailAddress... addresses) throws MailException {
 | 
| 
 | 
   467 		try {
 | 
| 
 | 
   468 			msg.setRecipients(Message.RecipientType.BCC,addr(addresses));
 | 
| 
 | 
   469 		} catch(MessagingException e) {
 | 
| 
 | 
   470 			throw MailImpl.e(e);
 | 
| 
 | 
   471 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   472 			throw new MailException(e);
 | 
| 
 | 
   473 		}
 | 
| 
 | 
   474 	}
 | 
| 
 | 
   475 
 | 
| 
 | 
   476 	public String[] getHeader(String name) throws MailException {
 | 
| 
 | 
   477 		try {
 | 
| 
 | 
   478 			return msg.getHeader(name);
 | 
| 
 | 
   479 		} catch(MessagingException e) {
 | 
| 
 | 
   480 			throw MailImpl.e(e);
 | 
| 
 | 
   481 		}
 | 
| 
 | 
   482 	}
 | 
| 
 | 
   483 
 | 
| 
 | 
   484 	public void setHeader(String name,String... values) throws MailException {
 | 
| 
 | 
   485 		try {
 | 
| 
 | 
   486 			if( values==null ) {
 | 
| 
 | 
   487 				msg.removeHeader(name);
 | 
| 
 | 
   488 			} else {
 | 
| 
 | 
   489 				msg.setHeader(name,values[0]);
 | 
| 
 | 
   490 				for( int i=1; i<values.length; i++ ) {
 | 
| 
 | 
   491 					msg.addHeader(name,values[i]);
 | 
| 
 | 
   492 				}
 | 
| 
 | 
   493 			}
 | 
| 
 | 
   494 		} catch(MessagingException e) {
 | 
| 
 | 
   495 			throw MailImpl.e(e);
 | 
| 
 | 
   496 		}
 | 
| 
 | 
   497 	}
 | 
| 
 | 
   498 
 | 
| 
 | 
   499 	public void setHeader(String name, MailAddress address) throws MailException {
 | 
| 
 | 
   500 		try {
 | 
| 
 | 
   501 			msg.setHeader(name, addr(address).toString());
 | 
| 
 | 
   502 		} catch(MessagingException e) {
 | 
| 
 | 
   503 			throw MailImpl.e(e);
 | 
| 
 | 
   504 		} catch(UnsupportedEncodingException e) {
 | 
| 
 | 
   505 			throw new MailException(e);
 | 
| 
 | 
   506 		}
 | 
| 
 | 
   507 	}
 | 
| 
 | 
   508 
 | 
| 
 | 
   509 	public String getMessageID() throws MailException {
 | 
| 
 | 
   510 		try {
 | 
| 
 | 
   511 			if( messageID != null )
 | 
| 
 | 
   512 				return messageID;
 | 
| 
 | 
   513 			return msg.getMessageID();
 | 
| 
 | 
   514 		} catch(MessagingException e) {
 | 
| 
 | 
   515 			throw MailImpl.e(e);
 | 
| 
 | 
   516 		}
 | 
| 
 | 
   517 	}
 | 
| 
 | 
   518 
 | 
| 
 | 
   519 	public void setMessageID(String messageID) throws MailException {
 | 
| 
 | 
   520 		this.messageID = messageID;
 | 
| 
 | 
   521 	}
 | 
| 
 | 
   522 
 | 
| 
 | 
   523 	public Date getSentDate() throws MailException {
 | 
| 
 | 
   524 		try {
 | 
| 
 | 
   525 			return msg.getSentDate();
 | 
| 
 | 
   526 		} catch(MessagingException e) {
 | 
| 
 | 
   527 			throw MailImpl.e(e);
 | 
| 
 | 
   528 		}
 | 
| 
 | 
   529 	}
 | 
| 
 | 
   530 
 | 
| 
 | 
   531 	public void setSentDate(Date sentDate) throws MailException {
 | 
| 
 | 
   532 		try {
 | 
| 
 | 
   533 			msg.setSentDate(sentDate);
 | 
| 
 | 
   534 		} catch(MessagingException e) {
 | 
| 
 | 
   535 			throw MailImpl.e(e);
 | 
| 
 | 
   536 		}
 | 
| 
 | 
   537 	}
 | 
| 
 | 
   538 
 | 
| 
 | 
   539 	public String getRawInput() throws MailException {
 | 
| 
 | 
   540 		try {
 | 
| 
 | 
   541 			ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
| 
 | 
   542 			msg.writeTo(out);
 | 
| 
 | 
   543 			return out.toString("ISO-8859-1");
 | 
| 
 | 
   544 		} catch(MessagingException e) {
 | 
| 
 | 
   545 			throw MailImpl.e(e);
 | 
| 
 | 
   546 		} catch(IOException e) {
 | 
| 
 | 
   547 			throw new MailException(e);
 | 
| 
 | 
   548 		}
 | 
| 
 | 
   549 	}
 | 
| 
 | 
   550 
 | 
| 
 | 
   551 	public String toString() {
 | 
| 
 | 
   552 		try {
 | 
| 
 | 
   553 			StringBuilder buf = new StringBuilder();
 | 
| 
 | 
   554 			for( Enumeration en=msg.getAllHeaderLines(); en.hasMoreElements(); ) {
 | 
| 
 | 
   555 				String header = (String)en.nextElement();
 | 
| 
 | 
   556 				buf.append(header).append("\n");
 | 
| 
 | 
   557 			}
 | 
| 
 | 
   558 			buf.append("\n");
 | 
| 
 | 
   559 			buf.append(getContent());
 | 
| 
 | 
   560 			return buf.toString();
 | 
| 
 | 
   561 		} catch(MessagingException e) {
 | 
| 
 | 
   562 			throw new RuntimeException(e);
 | 
| 
 | 
   563 		}
 | 
| 
 | 
   564 	}
 | 
| 
 | 
   565 
 | 
| 
 | 
   566 
 | 
| 
 | 
   567 	// exception handling
 | 
| 
 | 
   568 
 | 
| 
 | 
   569 	static MailException e(MessagingException e) {
 | 
| 
 | 
   570 		return e(e.getMessage(),e);
 | 
| 
 | 
   571 	}
 | 
| 
 | 
   572 
 | 
| 
 | 
   573 	static MailException e(String msg,AddressException e) {
 | 
| 
 | 
   574 		return new MailAddressException(msg,e);
 | 
| 
 | 
   575 	}
 | 
| 
 | 
   576 
 | 
| 
 | 
   577 	static MailException e(String msg,MessagingException e) {
 | 
| 
 | 
   578 		if( e instanceof AddressException )
 | 
| 
 | 
   579 			return e(msg,(AddressException)e);
 | 
| 
 | 
   580 		else if(e instanceof ParseException )
 | 
| 
 | 
   581 			return e(msg,(ParseException)e);
 | 
| 
 | 
   582 		if (msg!=null && msg.startsWith("Missing start boundary"))
 | 
| 
 | 
   583 			return new MailParseException(msg,e);
 | 
| 
 | 
   584 		Exception e2 = e.getNextException();
 | 
| 
 | 
   585 		return e2==null ? new MailException(msg,e) : e(msg,e2);
 | 
| 
 | 
   586 	}
 | 
| 
 | 
   587 
 | 
| 
 | 
   588 	static MailException e(String msg,Exception e) {
 | 
| 
 | 
   589 		if( e instanceof MessagingException )
 | 
| 
 | 
   590 			return e(msg,(MessagingException)e);
 | 
| 
 | 
   591 		return new MailException(msg,e);
 | 
| 
 | 
   592 	}
 | 
| 
 | 
   593 	
 | 
| 
 | 
   594 	static MailException e(String msg,ParseException e) {
 | 
| 
 | 
   595 		return new MailParseException(msg,e);
 | 
| 
 | 
   596 	}
 | 
| 
 | 
   597 	
 | 
| 
 | 
   598 	static MailException e(IOException e) {
 | 
| 
 | 
   599 		return e(e.getMessage(),e);
 | 
| 
 | 
   600 	}
 | 
| 
 | 
   601 
 | 
| 
 | 
   602 	static MailException e(String msg,IOException e) {
 | 
| 
 | 
   603 		if ( e instanceof UnsupportedEncodingException )
 | 
| 
 | 
   604 			return e(msg,(UnsupportedEncodingException)e);
 | 
| 
 | 
   605 		if (msg!=null && msg.startsWith("Unknown encoding"))
 | 
| 
 | 
   606 			return new MailEncodingException(msg,e);
 | 
| 
 | 
   607 		return new MailException(msg,e);
 | 
| 
 | 
   608 	}
 | 
| 
 | 
   609 	
 | 
| 
 | 
   610 	static MailException e(String msg,UnsupportedEncodingException e) {
 | 
| 
 | 
   611 		return new MailEncodingException(msg,e);
 | 
| 
 | 
   612 	}		
 | 
| 
 | 
   613 
 | 
| 
 | 
   614 	static {
 | 
| 
 | 
   615 		MailcapCommandMap mcm = (MailcapCommandMap)CommandMap.getDefaultCommandMap();
 | 
| 
 | 
   616 		mcm.addMailcap("text/x-aol; ; x-java-content-handler=com.sun.mail.handlers.text_plain");
 | 
| 
 | 
   617 	}
 | 
| 
 | 
   618 }
 |