001    /*
002     * Copyright (c) 2009 The openGion Project.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific language
014     * governing permissions and limitations under the License.
015     */
016    package org.opengion.fukurou.mail;
017    
018    import org.opengion.fukurou.util.LogWriter;
019    
020    import java.io.UnsupportedEncodingException;
021    import java.util.Properties;
022    import java.util.Date;
023    
024    import javax.activation.FileDataSource;
025    import javax.activation.DataHandler;
026    import javax.mail.internet.InternetAddress;
027    import javax.mail.internet.AddressException;
028    import javax.mail.internet.MimeMessage;
029    import javax.mail.internet.MimeMultipart;
030    import javax.mail.internet.MimeBodyPart;
031    import javax.mail.internet.MimeUtility;
032    import javax.mail.Authenticator;                                // 5.8.7.1 (2015/05/22)
033    import javax.mail.PasswordAuthentication;               // 5.8.7.1 (2015/05/22)
034    import javax.mail.Store;
035    import javax.mail.Transport;
036    import javax.mail.Session;
037    import javax.mail.Message;
038    import javax.mail.MessagingException;
039    import javax.mail.IllegalWriteException;
040    
041    /**
042     * MailTX ã¯ã€?¼³?­?´?°ãƒ—ロトコルã«ã‚ˆã‚‹ãƒ¡ãƒ¼ãƒ«é€ä¿¡ãƒ—ログラãƒ?§ã™ã?
043     *
044     * E-Mail ã§æ—¥æœ¬èªžã‚’é€ä¿¡ã™ã‚‹å ´åˆã?ISO-2022-JP(JISコーãƒ?化ã—ã¦ã€?bit ã§
045     * エンコードã—ã¦é€ä¿¡ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ãŒã€Windowsç³»ã®ç‰¹æ®Šæ–‡å­—ã‚„ã€unicodeã¨
046     * æ–?­—ã?マッピングãŒç•°ãªã‚‹æ–‡å­—ãªã©ãŒã?æ–?­—化ã‘ã—ã¾ã™ã?
047     * 対応方法ã¨ã—ã¦ã¯ã€?
048     * ?‘.Windows-31J + 8bit é€ä¿¡
049     * ?’.ISO-2022-JP ã«ç‹¬è‡ªå¤‰æ› + 7bit é€ä¿¡
050     * ã®æ–¹æ³•ãŒã‚りã¾ã™ã?
051     * 今回ã€ã“ã®?’ã¤ã®æ–¹æ³•ã«ã¤ã?¦ã€å¯¾å¿œã„ãŸã—ã¾ã—ãŸã€?
052     *
053     * @version  4.0
054     * @author   Kazuhiko Hasegawa
055     * @since    JDK5.0,
056     */
057    public class MailTX {
058            private static final String CR = System.getProperty("line.separator");
059            private static final String AUTH_PBS   = "POP_BEFORE_SMTP";             // 5.4.3.2
060            private static final String AUTH_SMTPA = "SMTP_AUTH";                   // 5.4.3.2  5.8.7.1復活
061    
062            /** メーラーã®åç§°  {@value} */
063            public static final String MAILER = "Hayabusa Mail Ver 4.0";
064    
065            private final String    charset  ;      // Windwos-31J , MS932 , ISO-2022-JP
066            private String[]        filename = null;
067            private String          message  = null;
068            private Session         session  = null;
069            private MimeMultipart mmPart = null;
070            private MimeMessage     mimeMsg  = null;
071            private MailCharset     mcSet    = null;
072    
073            /**
074             * メールサーãƒã?ã¨ãƒ?ƒ•ォルト文字エンコーãƒ?‚£ãƒ³ã‚°ã‚’指定ã—ã¦ã€ã‚ªãƒ–ジェクトを構築ã—ã¾ã™ã?
075             *
076             * ãƒ?ƒ•ォルト文字エンコーãƒ?‚£ãƒ³ã‚°ã¯ã€ISO-2022-JP ã§ã™ã?
077             *
078             * @param       host    メールサーãƒã?
079             * @throws      IllegalArgumentException 引数ã?null ã®å ´åˆã?
080             */
081            public MailTX( final String host ) {
082                    this( host,"ISO-2022-JP" );
083            }
084    
085            /**
086             * メールサーãƒã?ã¨ãƒ?ƒ•ォルト文字エンコーãƒ?‚£ãƒ³ã‚°ã‚’指定ã—ã¦ã€ã‚ªãƒ–ジェクトを構築ã—ã¾ã™ã?
087             *
088             * æ–?­—エンコーãƒ?‚£ãƒ³ã‚°ã«ã¯ã€Windwos-31J , MS932 , ISO-2022-JP を指定ã§ãã¾ã™ã?
089             *
090             * @og.rev 5.4.3.2 (2012/01/06) èªè¨¼å¯¾å¿œã?ãŸã‚
091             * @og.rev 5.8.1.1 (2014/11/14) èªè¨¼ãƒã?ト追åŠ?
092             *
093             * @param       host    メールサーãƒã?
094             * @param       charset æ–?­—エンコーãƒ?‚£ãƒ³ã‚°
095             * @throws      IllegalArgumentException 引数ã?null ã®å ´åˆã?
096             */
097            public MailTX( final String host , final String charset ) {
098    //              this( host,charset,null,null,null,null );
099                    this( host,charset,null,null,null,null,null );
100            }
101    
102            /**
103             * メールサーãƒã?ã¨æ–?­—エンコーãƒ?‚£ãƒ³ã‚°ã‚’指定ã—ã¦ã€ã‚ªãƒ–ジェクトを構築ã—ã¾ã™ã?
104             * èªè¨¼ã‚’行ã†å ´åˆã?èªè¨¼æ–¹æ³•ã‚’æŒ?®šã—ã¾ã™ã?
105             *
106             * æ–?­—エンコーãƒ?‚£ãƒ³ã‚°ã«ã¯ã€Windwos-31J , MS932 , ISO-2022-JP を指定ã§ãã¾ã™ã?
107             *
108             * @og.rev 5.1.9.0 (2010/08/01) mail.smtp.localhostã®è¨­å®šè¿½åŠ?
109             * @og.rev 5.4.3.2 (2012/01/06) èªè¨¼å¯¾å¿?POP Before SMTP)。引数?“ã¤è¿½åŠ?å°?¥çš?«ã¯Authentication対応ï¼?
110             * @og.rev 5.8.1.1 (2014/11/14) èªè¨¼ãƒã?ト追åŠ?
111             * @og.rev 5.8.7.1 (2015/05/22) SMTP Auth対�
112             *
113             * @param       host    メールサーãƒã?
114             * @param       charset æ–?­—エンコーãƒ?‚£ãƒ³ã‚°
115             * @param       smtpPort        SMTPãƒã?ãƒ?
116             * @param       authType        èªè¨¼æ–¹æ³?5.4.3.2
117             * @param       authPort        èªè¨¼ãƒã?ãƒ?5.4.3.2
118             * @param       authUser        èªè¨¼ãƒ¦ãƒ¼ã‚¶ 5.4.3.2
119             * @param       authPass        èªè¨¼ãƒ‘スワーãƒ?5.4.3.2
120             * @throws      IllegalArgumentException 引数ã?null ã®å ´åˆã?
121             */
122    //      public MailTX( final String host , final String charset, final String port
123    //                              ,final String auth, final String user, final String pass) {
124            public MailTX( final String host , final String charset, final String smtpPort
125                                    ,final String authType, final String authPort, final String authUser, final String authPass) {
126                    if( host == null ) {
127                            String errMsg = "host ã« null ã¯ã‚»ãƒ?ƒˆå‡ºæ¥ã¾ã›ã‚“ã€?;
128                            throw new IllegalArgumentException( errMsg );
129                    }
130    
131                    if( charset == null ) {
132                            String errMsg = "charset ã« null ã¯ã‚»ãƒ?ƒˆå‡ºæ¥ã¾ã›ã‚“ã€?;
133                            throw new IllegalArgumentException( errMsg );
134                    }
135    
136                    this.charset = charset;
137    
138                    mcSet = MailCharsetFactory.newInstance( charset );
139    
140                    Properties prop = new Properties();
141                    prop.setProperty("mail.mime.charset", charset);
142                    prop.setProperty("mail.mime.decodetext.strict", "false");
143                    prop.setProperty("mail.mime.address.strict", "false");
144                    prop.setProperty("mail.smtp.host", host);
145                    // 5.1.9.0 (2010/08/01) 設定追�
146                    prop.setProperty("mail.smtp.localhost", host);
147                    prop.setProperty("mail.host", host);    // MEssage-ID ã®è¨­å®šã«åˆ©ç”¨
148                    // 5.4.3.2 ãƒã?ト追åŠ?
149    //              if( port != null && port.length() > 0 ){
150    //                      prop.setProperty("mail.smtp.port", port);               // MEssage-ID ã®è¨­å®šã«åˆ©ç”¨
151    //              }
152                    if( smtpPort != null && smtpPort.length() > 0 ){
153                            prop.setProperty("mail.smtp.port", smtpPort);   // MEssage-ID ã®è¨­å®šã«åˆ©ç”¨
154                    }
155    
156                    // SMTP Auth対�5.8.7.1 (2015/05/22)
157                    Authenticator myAuth = null;
158                    if( AUTH_SMTPA.equals( authType ) ) {
159                            prop.setProperty("mail.smtp.auth", "true" );
160                            myAuth = new Authenticator() {                                  // 5.8.7.1 (2015/05/22) SMTPèªè¨¼ç”¨ã‚¯ãƒ©ã‚¹
161                                    @Override
162                                    protected PasswordAuthentication getPasswordAuthentication() {
163                                            return new PasswordAuthentication( authUser,authPass );
164                                    }
165                            };
166                    }
167                    session = Session.getInstance( prop, myAuth );
168    
169                    // POP before SMTPèªè¨¼å‡¦ç?5.4.3.2
170    //              if(AUTH_PBS.equals( auth )){
171                    if(AUTH_PBS.equals( authType )){
172                            try{
173                                    // 5.8.1.1 (2014/11/14) èªè¨¼ãƒã?ト追åŠ?
174                                    int aPort = (authPass == null || authPass.isEmpty()) ? -1 : Integer.parseInt(authPort) ;
175                                    Store store = session.getStore("pop3");
176    //                              store.connect(host,-1,user,pass);                               // åŒä¸??ストã¨ã™ã‚‹
177                                    store.connect(host,aPort,authUser,authPass);    // 5.8.1.1 (2014/11/14) èªè¨¼ãƒã?ト追åŠ?
178                                    store.close();
179                            }
180                            catch(MessagingException ex){
181    //                              String errMsg = "POP3 Auth Exception: "+ host + "/" + user;
182                                    String errMsg = "POP3 Auth Exception: "+ host + "/" + authUser;
183                                    throw new RuntimeException( errMsg,ex );
184                            }
185                    }
186                    
187                    mimeMsg = new MimeMessage(session);
188            }
189    
190            /**
191             * メールをé?ä¿¡ã—ã¾ã™ã?
192             *
193             */
194            public void sendmail() {
195                    try {
196                            mimeMsg.setSentDate( new Date() );
197    
198                            if( filename == null || filename.length == 0 ) {
199                                    mcSet.setTextContent( mimeMsg,message );
200                            }
201                            else {
202                                    mmPart = new MimeMultipart();
203                                    mimeMsg.setContent( mmPart );
204                                    // ãƒ?‚­ã‚¹ãƒˆæœ¬ä½“ã?登録
205                                    addMmpText( message );
206    
207                                    // 添付ファイルã®ç™»éŒ²
208                                    for( int i=0; i<filename.length; i++ ) {
209                                            addMmpFile( filename[i] );
210                                    }
211                            }
212    
213                            mimeMsg.setHeader("X-Mailer", MAILER );
214                            mimeMsg.setHeader("Content-Transfer-Encoding", mcSet.getBit() );
215                            Transport.send( mimeMsg );
216    
217                    }
218                    catch( AddressException ex ) {
219                            String errMsg = "Address Exception: ";
220                            throw new RuntimeException( errMsg,ex );
221                    }
222                    catch ( MessagingException mex ) {
223                            String errMsg = "MessagingException: ";
224                            throw new RuntimeException( errMsg,mex );
225                    }
226            }
227    
228            /**
229             * MimeMessageをリセãƒ?ƒˆã—ã¾ã™ã?
230             *
231             * sendmail() ã§ãƒ¡ãƒ¼ãƒ«ã‚’é?信後ã?ã‚»ãƒ?‚·ãƒ§ãƒ³ã‚’é–‰ã˜ãšã«åˆ¥ã®ãƒ¡ãƒ¼ãƒ«ã‚’é?ä¿¡ã™ã‚‹å ´åˆã?
232             * リセãƒ?ƒˆã—ã¦ã‹ã‚‰ã€å„種パラメータをå?設定ã—ã¦ãã ã•ã„ã€?
233             * ãã?å ´åˆã?ã€ã™ã¹ã¦ã®ãƒ‘ラメータãŒå?期化ã•れã¦ã?¾ã™ã?ã§ã€ã‚‚ã?¸?º¦
234             * 設定ã—ãªãŠã™å¿?¦ãŒã‚りã¾ã™ã?
235             *
236             */
237            public void reset() {
238                    mimeMsg = new MimeMessage(session);
239            }
240    
241            /**
242             * é€ä¿¡å…??¦?²?¯?­)アドレスをセãƒ?ƒˆã—ã¾ã™ã?
243             *
244             * @param   from é€ä¿¡å…??¦?²?¯?­)アドレス
245             */
246            public void setFrom( final String from ) {
247                    try {
248                            if( from != null ) {
249                                    mimeMsg.setFrom( getAddress( from ) );
250                            }
251                    } catch( AddressException ex ) {
252                            String errMsg = "Address Exception: ";
253                            throw new RuntimeException( errMsg,ex );
254                    } catch ( MessagingException mex ) {
255                            String errMsg = "MessagingException: ";
256                            throw new RuntimeException( errMsg,mex );
257                    }
258            }
259    
260            /**
261             * é€ä¿¡å…??´?¯)アドレスé…å?ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
262             *
263             * @param   to é€ä¿¡å…??´?¯)アドレスé…å?
264             */
265            public void setTo( final String[] to ) {
266                    try {
267                            if( to != null ) {
268                                    mimeMsg.setRecipients( Message.RecipientType.TO, getAddress( to ) );
269                            }
270                    } catch( AddressException ex ) {
271                            String errMsg = "Address Exception: ";
272                            throw new RuntimeException( errMsg,ex );
273                    } catch ( MessagingException mex ) {
274                            String errMsg = "MessagingException: ";
275                            throw new RuntimeException( errMsg,mex );
276                    }
277            }
278    
279            /**
280             * é€ä¿¡å…??£?£)アドレスé…å?ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
281             *
282             * @param   cc é€ä¿¡å…??£?£)アドレスé…å?
283             */
284            public void setCc( final String[] cc ) {
285                    try {
286                            if( cc != null ) {
287                                    mimeMsg.setRecipients( Message.RecipientType.CC, getAddress( cc ) );
288                            }
289                    } catch( AddressException ex ) {
290                            String errMsg = "Address Exception: ";
291                            throw new RuntimeException( errMsg,ex );
292                    } catch ( MessagingException mex ) {
293                            String errMsg = "MessagingException: ";
294                            throw new RuntimeException( errMsg,mex );
295                    }
296            }
297    
298            /**
299             * é€ä¿¡å…??¢?£?£)アドレスé…å?ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
300             *
301             * @param   bcc é€ä¿¡å…??¢?£?£)アドレスé…å?
302             */
303            public void setBcc( final String[] bcc ) {
304                    try {
305                            if( bcc != null ) {
306                                    mimeMsg.setRecipients( Message.RecipientType.BCC, getAddress( bcc ) );
307                            }
308                    } catch( AddressException ex ) {
309                            String errMsg = "Address Exception: ";
310                            throw new RuntimeException( errMsg,ex );
311                    } catch ( MessagingException mex ) {
312                            String errMsg = "MessagingException: ";
313                            throw new RuntimeException( errMsg,mex );
314                    }
315            }
316    
317            /**
318             * é€ä¿¡å…??´?¯)アドレスé…å?をクリアã—ã¾ã™ã?
319             * @og.rev 4.3.6.0 (2009/04/01) æ–°è¦è¿½åŠ?
320             *
321             */
322            public void clearTo() {
323                    try {
324                            mimeMsg.setRecipients( Message.RecipientType.TO, (InternetAddress[])null );
325                    } catch( IllegalWriteException ex ) {
326                            String errMsg = "Address Exception: ";
327                            throw new RuntimeException( errMsg,ex );
328                    } catch( IllegalStateException ex ) {
329                            String errMsg = "Address Exception: ";
330                            throw new RuntimeException( errMsg,ex );
331                    } catch ( MessagingException mex ) {
332                            String errMsg = "MessagingException: ";
333                            throw new RuntimeException( errMsg,mex );
334                    }
335            }
336    
337            /**
338             * é€ä¿¡å…?CC)アドレスé…å?をクリアã—ã¾ã™ã?
339             * @og.rev 4.3.6.0 (2009/04/01) æ–°è¦è¿½åŠ?
340             *
341             */
342            public void clearCc() {
343                    try {
344                            mimeMsg.setRecipients( Message.RecipientType.CC, (InternetAddress[])null );
345                    } catch( IllegalWriteException ex ) {
346                            String errMsg = "Address Exception: ";
347                            throw new RuntimeException( errMsg,ex );
348                    } catch( IllegalStateException ex ) {
349                            String errMsg = "Address Exception: ";
350                            throw new RuntimeException( errMsg,ex );
351                    } catch ( MessagingException mex ) {
352                            String errMsg = "MessagingException: ";
353                            throw new RuntimeException( errMsg,mex );
354                    }
355            }
356    
357            /**
358             * é€ä¿¡å…?BCC)アドレスé…å?をクリアã—ã¾ã™ã?
359             * @og.rev 4.3.6.0 (2009/04/01) æ–°è¦è¿½åŠ?
360             *
361             */
362            public void clearBcc() {
363                    try {
364                            mimeMsg.setRecipients( Message.RecipientType.BCC, (InternetAddress[])null );
365                    } catch( IllegalWriteException ex ) {
366                            String errMsg = "Address Exception: ";
367                            throw new RuntimeException( errMsg,ex );
368                    } catch( IllegalStateException ex ) {
369                            String errMsg = "Address Exception: ";
370                            throw new RuntimeException( errMsg,ex );
371                    } catch ( MessagingException mex ) {
372                            String errMsg = "MessagingException: ";
373                            throw new RuntimeException( errMsg,mex );
374                    }
375            }
376    
377            /**
378             * 返信å…?replyTo)アドレスé…å?ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
379             *
380             * @param   replyTo 返信å…?replyTo)アドレスé…å?
381             */
382            public void setReplyTo( final String[] replyTo ) {
383                    try {
384                            if( replyTo != null ) {
385                                    mimeMsg.setReplyTo( getAddress( replyTo ) );
386                            }
387                    } catch( AddressException ex ) {
388                            String errMsg = "Address Exception: ";
389                            throw new RuntimeException( errMsg,ex );
390                    } catch ( MessagingException mex ) {
391                            String errMsg = "MessagingException: ";
392                            throw new RuntimeException( errMsg,mex );
393                    }
394            }
395    
396            /**
397             * タイトルをセãƒ?ƒˆã—ã¾ã™ã?
398             *
399             * @param   subject タイトル
400             */
401            public void setSubject( final String subject ) {
402                    // Servlet ã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã¯ã€iso8859_1 ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•ã‚ŒãŸæ–?­—ãŒ
403                    // ã‚»ãƒ?ƒˆã•れるã?ã§ã€ãƒ¦ãƒ‹ã‚³ãƒ¼ãƒ‰ã«å¤‰æ›´ã—ã¦ãŠã‹ãªã?¨æ–?­—化ã‘ã™ã‚‹ã?
404                    // JRun 3.0 ã§ã¯ã€å•題ãªã‹ã£ãŸãŒã€tomcat3.1 ã§ã¯å•題ãŒã‚ã‚‹ã€?
405                    try {
406                            if( subject != null ) {
407                                    mimeMsg.setSubject( mcSet.encodeWord( subject ) );
408                            }
409                    } catch( AddressException ex ) {
410                            String errMsg = "Address Exception: ";
411                            throw new RuntimeException( errMsg,ex );
412                    } catch ( MessagingException mex ) {
413                            String errMsg = "MessagingException: ";
414                            throw new RuntimeException( errMsg,mex );
415                    }
416            }
417    
418            /**
419             * 添付ファイルåé?列をセãƒ?ƒˆã—ã¾ã™ã?
420             *
421             * @param   fname 添付ファイルåé?åˆ?
422             */
423            public void setFilename( final String[] fname ) {
424                    if( fname != null && fname.length > 0 ) {
425                            int size = fname.length;
426                            filename = new String[size];
427                            System.arraycopy( fname,0,filename,0,size );
428                    }
429            }
430    
431            /**
432             * メãƒ?‚»ãƒ¼ã‚¸(本æ–?ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
433             *
434             * @param   msg メãƒ?‚»ãƒ¼ã‚¸(本æ–?
435             */
436            public void setMessage( final String msg ) {
437                    // ãªãœã‹ã€ãƒ¡ãƒ?‚»ãƒ¼ã‚¸ã®æœ?¾Œã?ã€?CR><LF>ã‚’ã‚»ãƒ?ƒˆã—ã¦ãŠãã€?
438    
439                    if( msg == null ) { message = CR; }
440                    else {              message = msg + CR; }
441            }
442    
443            /**
444             * ãƒ?ƒãƒ?‚°æƒ??ã®è¡¨ç¤ºã‚’行ã†ã‹ã©ã?‹ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
445             *
446             * @param   debug 表示有無[true/false]
447             */
448            public void setDebug( final boolean debug ) {
449                session.setDebug( debug );
450            }
451    
452            /**
453             * æŒ?®šã•れãŸãƒ•ァイルをã?ルãƒãƒ‘ートã«è¿½åŠ?—ã¾ã™ã?
454             *
455             * @param   fileStr マルãƒãƒ‘ートã™ã‚‹ãƒ•ァイルå?
456             */
457            private void addMmpFile( final String fileStr ) {
458                    try {
459                            MimeBodyPart mbp = new MimeBodyPart();
460                            FileDataSource fds = new FileDataSource(fileStr);
461                            mbp.setDataHandler(new DataHandler(fds));
462                            mbp.setFileName(MimeUtility.encodeText(fds.getName(), charset, "B"));
463                            mbp.setHeader("Content-Transfer-Encoding", "base64");
464                            mmPart.addBodyPart(mbp);
465                    }
466                    catch( UnsupportedEncodingException ex ) {
467                            String errMsg = "Multipart UnsupportedEncodingException: ";
468                            throw new RuntimeException( errMsg,ex );
469                    }
470                    catch ( MessagingException mex ) {
471                            String errMsg = "MessagingException: ";
472                            throw new RuntimeException( errMsg,mex );
473                    }
474            }
475    
476            /**
477             * æŒ?®šã•ã‚ŒãŸæ–?­—å?ã‚’ã?ルãƒãƒ‘ートã«è¿½åŠ?—ã¾ã™ã?
478             *
479             * @param   textStr マルãƒãƒ‘ートã™ã‚‹æ–‡å­—å?
480             */
481            private void addMmpText( final String textStr ) {
482                    try {
483                            MimeBodyPart mbp = new MimeBodyPart();
484                            mbp.setText(textStr, charset);
485                            mbp.setHeader("Content-Transfer-Encoding", mcSet.getBit());
486                            mmPart.addBodyPart(mbp, 0);
487                    }
488                    catch ( MessagingException mex ) {
489                            String errMsg = "MessagingException: ";
490                            throw new RuntimeException( errMsg,mex );
491                    }
492            }
493    
494            /**
495             * æ–?­—エンコードをè€??ã—㟠InternetAddress を作æ?ã—ã¾ã™ã?
496             *
497             * @param   adrs オリジナルã®ã‚¢ãƒ‰ãƒ¬ã‚¹æ–?­—å?
498             *
499             * @return  æ–?­—エンコードをè€??ã—㟠InternetAddress
500             */
501            private InternetAddress getAddress( final String adrs ) {
502                    final InternetAddress rtnAdrs ;
503                    int sep = adrs.indexOf( '<' );
504                    if( sep >= 0 ) {
505                            String address  = adrs.substring( sep+1,adrs.indexOf( '>' ) ).trim();
506                            String personal = adrs.substring( 0,sep ).trim();
507    
508                            rtnAdrs = mcSet.getAddress( address,personal );
509                    }
510                    else {
511                            try {
512                                    rtnAdrs = new InternetAddress( adrs );
513                            }
514                            catch( AddressException ex ) {
515                                    String errMsg = "æŒ?®šã?アドレスをセãƒ?ƒˆã§ãã¾ã›ã‚“ã€?
516                                                                            + "adrs=" + adrs  ;
517                                    throw new RuntimeException( errMsg,ex );
518                            }
519                    }
520    
521                    return rtnAdrs ;
522            }
523    
524            /**
525             * æ–?­—エンコードをè€??ã—㟠InternetAddress を作æ?ã—ã¾ã™ã?
526             * ã“れã¯ã€ã‚¢ãƒ‰ãƒ¬ã‚¹æ–?­—é?列ã‹ã‚‰ã?InternetAddress é…å?を作æ?ã™ã‚‹ã€?
527             * コンビニエンスメソãƒ?ƒ‰ã§ã™ã?
528             * 処ç?ã®ã‚‚ã?ã¯ã€?getAddress( String ) をループã—ã¦ã?‚‹ã?‘ã§ã™ã?
529             *
530             * @param   adrs アドレスæ–?­—é?åˆ?
531             *
532             * @return  æ–?­—エンコード後ã?InternetAddressé…å?
533             * @see     #getAddress( String )
534             */
535            private InternetAddress[] getAddress( final String[] adrs ) {
536                    InternetAddress[] rtnAdrs = new InternetAddress[adrs.length];
537                    for( int i=0; i<adrs.length; i++ ) {
538                            rtnAdrs[i] = getAddress( adrs[i] );
539                    }
540    
541                    return rtnAdrs ;
542            }
543    
544            /**
545             * コマンドã‹ã‚‰å®Ÿè¡Œã§ãã‚‹ã€ãƒ†ã‚¹ãƒˆç”¨ã® main メソãƒ?ƒ‰ã§ã™ã?
546             *
547             * Usage: java org.opengion.fukurou.mail.MailTX &lt;from&gt; &lt;to&gt; &lt;host&gt; [&lt;file&gt; ....]
548             * ã§ã€è¤?•°ã®æ·»ä»˜ãƒ•ァイルをé?付ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã?
549             *
550             * @param       args    コマンド引数é…å?
551             * @throws Exception ãªã‚“らã‹ã?エラーãŒç™ºç”Ÿã—ãŸå?åˆã?
552             */
553            public static void main( final String[] args ) throws Exception {
554                    if(args.length < 3) {
555                            LogWriter.log("Usage: java org.opengion.fukurou.mail.MailTX <from> <to> <host> [<file> ....]");
556                            return ;
557                    }
558    
559                    String host  = args[2] ;
560                    String chset = "ISO-2022-JP" ;
561    
562                    MailTX sender = new MailTX( host,chset );
563    
564                    sender.setFrom( args[0] );
565                    String[] to = { args[1] };
566                    sender.setTo( to );
567    
568                    if( args.length > 3 ) {
569                            String[] filename = new String[ args.length-3 ];
570                            for( int i=0; i<args.length-3; i++ ) {
571                                    filename[i] = args[i+3];
572                            }
573                            sender.setFilename( filename );
574                    }
575    
576                    sender.setSubject( "メールé€ä¿¡ãƒ?‚¹ãƒ? );
577                    String msg = "ã“れã¯ãƒ?‚¹ãƒˆãƒ¡ãƒ¼ãƒ«ã§ã™ã?" + CR +
578                                                    "ã?¾ãå—ä¿¡ã§ãã¾ã—ãŸã?" + CR;
579                    sender.setMessage( msg );
580    
581                    sender.sendmail();
582            }
583    }