| 1583 | 1 package goodjava.mail; | 
|  | 2 | 
|  | 3 import java.util.Map; | 
| 1584 | 4 import java.util.Base64; | 
| 1585 | 5 import java.util.Random; | 
| 1583 | 6 import java.util.regex.Pattern; | 
|  | 7 import java.util.regex.Matcher; | 
|  | 8 import goodjava.util.GoodUtils; | 
|  | 9 | 
|  | 10 | 
|  | 11 public class Message { | 
| 1585 | 12 	final Map<String,String> headers; | 
|  | 13 	final Object content; | 
| 1588 | 14 	private static final Pattern line = Pattern.compile("(?m)^.*$"); | 
| 1583 | 15 | 
| 1587 | 16 	public Message(Map<String,String> headers,String content) { | 
|  | 17 		this.headers = headers; | 
|  | 18 		this.content = content; | 
|  | 19 	} | 
|  | 20 | 
|  | 21 	public Message(Map<String,String> headers,byte[] content) { | 
|  | 22 		this.headers = headers; | 
|  | 23 		this.content = content; | 
|  | 24 	} | 
|  | 25 | 
|  | 26 	public Message(Map<String,String> headers,Message[] content) { | 
| 1584 | 27 		this.headers = headers; | 
|  | 28 		this.content = content; | 
| 1583 | 29 	} | 
|  | 30 | 
| 1584 | 31 	private static void addBase64(StringBuilder sb,byte[] a) { | 
|  | 32 		String s = Base64.getEncoder().encodeToString(a); | 
|  | 33 		int n = s.length() - 76; | 
|  | 34 		int i; | 
|  | 35 		for( i=0; i<n; i+=76 ) { | 
|  | 36 			sb.append(s.substring(i,i+76)).append("\r\n"); | 
|  | 37 		} | 
|  | 38 		sb.append(s.substring(i)).append("\r\n"); | 
| 1583 | 39 	} | 
|  | 40 | 
| 1584 | 41 	public String toText() throws MailException { | 
| 1583 | 42 		StringBuilder sb = new StringBuilder(); | 
| 1584 | 43 		String contentType = null; | 
| 1583 | 44 		for( Map.Entry<String,String> entry : headers.entrySet() ) { | 
|  | 45 			String name = entry.getKey(); | 
| 1584 | 46 			String value = entry.getValue(); | 
| 1583 | 47 			if( name.equalsIgnoreCase("bcc") ) | 
|  | 48 				continue; | 
| 1584 | 49 			if( name.equalsIgnoreCase("content-type") ) { | 
|  | 50 				contentType = value; | 
|  | 51 				continue; | 
|  | 52 			} | 
| 1583 | 53 			sb.append( name ).append( ": " ).append( value ).append( "\r\n" ); | 
|  | 54 		} | 
| 1584 | 55 		if( content instanceof String ) { | 
|  | 56 			String s = (String)content; | 
| 1587 | 57 			if( contentType!=null ) | 
|  | 58 				sb.append( "Content-Type: " ).append( contentType ).append( "\r\n" ); | 
| 1584 | 59 			boolean isAscii = s.matches("\\p{ASCII}*"); | 
|  | 60 			if( !isAscii ) | 
|  | 61 				sb.append( "Content-Transfer-Encoding: base64\r\n" ); | 
|  | 62 			sb.append( "\r\n" ); | 
|  | 63 			if( isAscii ) { | 
|  | 64 				Matcher m = line.matcher(s); | 
|  | 65 				while( m.find() ) { | 
|  | 66 					sb.append(m.group()).append("\r\n"); | 
|  | 67 				} | 
|  | 68 			} else { | 
|  | 69 				addBase64( sb, GoodUtils.getBytes(s,"UTF-8") ); | 
| 1583 | 70 			} | 
| 1584 | 71 		} else if( content instanceof byte[] ) { | 
| 1587 | 72 			if( contentType!=null ) | 
|  | 73 				sb.append( "Content-Type: " ).append( contentType ).append( "\r\n" ); | 
| 1584 | 74 			sb.append( "Content-Transfer-Encoding: base64\r\n" ); | 
|  | 75 			sb.append( "\r\n" ); | 
|  | 76 			addBase64( sb, (byte[])content ); | 
| 1585 | 77 		} else if( content instanceof Message[] ) { | 
| 1587 | 78 			if( contentType==null ) | 
|  | 79 				throw new MailException("Content-Type must be defined for multipart"); | 
| 1585 | 80 			Message[] messages = (Message[])content; | 
|  | 81 			String[] texts = new String[messages.length]; | 
|  | 82 			StringBuilder allTextSb = new StringBuilder(); | 
|  | 83 			for( int i=0; i<messages.length; i++ ) { | 
|  | 84 				String text = messages[i].toText(); | 
|  | 85 				texts[i] = text; | 
|  | 86 				allTextSb.append(text); | 
|  | 87 			} | 
|  | 88 			String allText = allTextSb.toString(); | 
|  | 89 			String boundary; | 
|  | 90 			do { | 
|  | 91 				boundary = Long.toHexString(new Random().nextLong()); | 
|  | 92 			} while( allText.contains(boundary) ); | 
|  | 93 			sb.append( "Content-Type: " ).append( contentType ) | 
|  | 94 				.append( "; boundary=\"" ).append( boundary ).append( "\"\r\n" ); | 
|  | 95 			sb.append( "\r\n" ); | 
|  | 96 			for( String text : texts ) { | 
|  | 97 				sb.append( "--" ).append( boundary ).append( "\r\n" ); | 
|  | 98 				sb.append( text ); | 
|  | 99 				sb.append( "\r\n" ); | 
|  | 100 			} | 
|  | 101 			sb.append( "--" ).append( boundary ).append( "--\r\n" ); | 
| 1584 | 102 		} else | 
| 1587 | 103 			throw new RuntimeException(); | 
| 1583 | 104 		return sb.toString(); | 
|  | 105 	} | 
|  | 106 } |