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;
|
1583
|
14 private static Pattern line = Pattern.compile("(?m)^.*$");
|
|
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 }
|