    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 */
    016package org.opengion.hayabusa.report;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.fukurou.util.StringUtil;
    020
    021import org.opengion.fukurou.mail.MailReceiveListener ;
    022import org.opengion.fukurou.mail.MailTX ;
    023import org.opengion.fukurou.mail.MailMessage ;
    024import org.opengion.fukurou.mail.MailAttachFiles ;
    025
    026import java.util.Date;
    027
    028/**
    029 * MailReceiveListener の実装クラスです。
    030 * MailRX クラスにセットすることで、メール１件ごとに receive( MailMessage ) メソッドが
    031 * 呼び出されます。
    032 * メール１件に、添付ファイルが複数登録されている場合の処理を行っています。
    033 * 添付ファイルごとに要求番号を採番して、要求番号.xls としてセーブし、帳票要求テーブルに
    034 * 書き込みます。
    035 *
    036 * @og.rev 3.8.0.0 (2005/06/07) 新規追加
    037 * @og.group 帳票システム
    038 *
    039 * @version  4.0
    040 * @author   Kazuhiko Hasegawa
    041 * @since    JDK5.0,
    042 */
    043public class ExcelInsertReceiveListener implements MailReceiveListener {
    044
    045        // EXCEL取込時に使用するテンポラリフォルダ名。ファイル名は、要求番号.xls
    046        private final String EXCELIN_URL =
    047                HybsSystem.url2dir( StringUtil.nval(
    048                                                                HybsSystem.sys( "EXCEL_IN_FILE_URL" ) ,
    049                                                                HybsSystem.sys( "FILE_URL"   ) + "EXCELIN/" ) ) ;
    050
    051        private GE50Access ge50 = null;
    052
    053        /**
    054         * メール受信処理で、１メール受信ごとに呼び出されます。
    055         * 処理結果を、boolean で返します。
    056         *
    057         * @param message MailMessageオブジェクト
    058         *
    059         * @return      処理結果(正常:true / 異常:false)
    060         */
    061        public boolean receive( final MailMessage message ) {
    062                System.out.println();
    063                System.out.println( "Receive " + new Date() );
    064
    065                String errMsg ;
    066                boolean okFlag = false;
    067
    068                // 毎回 オブジェクトを構築します。登録日付が初期化されます。
    069                ge50 = new GE50Access( "CXXXXX","M_RECEIVE","ExcelInsert" );
    070
    071                try {
    072                        String from             = message.getHeader( "From" );
    073                        String subject  = message.getSubject();
    074                        String content  = message.getContent();
    075                        String msgid    = message.getMessageID();
    076                        String comments = from + " " + subject + " " + msgid ;
    077
    078                        String systemId = getContentParam( content,"SYSTEM_ID" );
    079                        if( systemId == null ) {
    080                                errMsg = "メール本文に SYSTEM_ID=[xx] のキーワードが存在しません。" ;
    081                                errorReport( message,errMsg ) ;
    082                                return okFlag;
    083                        }
    084
    085                        System.out.println( " From:" + from );
    086                        String joken = getContentParam( content,"JOKEN" );
    087                        if( joken == null ) { joken = "EXCELIN"; }
    088
    089                        ge50.setSystemId( systemId );
    090                        ge50.setJoken   ( joken );
    091                        ge50.setComments( comments );
    092
    093                        MailAttachFiles attFiles = new MailAttachFiles( message.getMessage() );
    094                        String[] files = attFiles.getNames();
    095                        if( files == null || files.length == 0 ) {
    096                                errMsg = "メールに EXCEL 添付ファイルが存在しません。" ;
    097                                errorReport( message,errMsg ) ;
    098                                return okFlag;
    099                        }
    100
    101                        // 添付ファイルの数だけ処理します。
    102                        for( int i=0; i<files.length; i++ ) {
    103                                String ykno    = ge50.makeYkno();               // 新たな要求番号が内部にもセットされる。
    104                                String file    = ykno + ".xls" ;
    105                                String attFile = files[i];
    106
    107                                // LISTID を取得します。 EXCELファイル名に(帳票ID)を入れます。
    108                                int st = attFile.indexOf( '(' );
    109                                int ed = attFile.indexOf( ')',st );
    110                                if( st < 0 || ed < 0 ) {
    111                                        errMsg = "EXCEL 添付ファイルに(帳票ID)が存在しません。[" + attFile + "]" ;
    112                                        errorReport( message,errMsg ) ;
    113                                        return okFlag;
    114                                }
    115
    116                                String listId  = attFile.substring( st+1,ed );
    117                                if( listId.length() == 0 ) {
    118                                        errMsg = "EXCEL 添付ファイルの(帳票ID)を切り出せません。[" + attFile + "]" ;
    119                                        errorReport( message,errMsg ) ;
    120                                        return okFlag;
    121                                }
    122
    123                                String fileDir = EXCELIN_URL + systemId + "/" + listId + "/" ;
    124
    125                                attFiles.saveFileName( fileDir,file,i );
    126
    127                                ge50.setListId( listId );
    128                                ge50.setOutDir( fileDir );
    129                                ge50.setOutFile( files[i] );
    130
    131                                ge50.insertGE50( GE50Access.FG_SET );
    132
    133                                System.out.println( attFile + " -> " + file );
    134                        }
    135                        System.out.println( " End." );
    136                        okFlag = true;
    137                }
    138                catch( Throwable ex ) {
    139                        errMsg = StringUtil.stringStackTrace( ex );
    140                        errorReport( message,errMsg ) ;
    141                        okFlag = false;
    142                }
    143                return okFlag;
    144        }
    145
    146        /**
    147         * メール処理中にエラーが発生した場合の処理を行います。
    148         * 処理は、３種類あります。
    149         * １．エラーメールを、EXCELIN_URL/ERROR_MAIL フォルダに、メッセージID.txt で保存します。
    150         * ２．COMMON_MAIL_SERVER と ERROR_MAIL_TO_USERS が設定されている場合に、
    151         *     そのあて先に、返信メールを送信します。
    152         * ３．GE50(帳票要求テーブル)と、GE51(帳票エラーテーブル)にエラー状況を書き込みます。
    153         *
    154         * @param message MailMessageオブジェクト
    155         * @param errorMessage エラーメッセージ
    156         */
    157        private void errorReport( final MailMessage message,final String errorMessage ) {
    158                // エラーメールを 所定のディレクトリに出力します。
    159                message.saveSimpleMessage( EXCELIN_URL + "/ERROR_MAIL/" );
    160
    161                String subject          = "EXCEL取込メール受信中にエラーが発生しました。";
    162                String org_from         = message.getHeader( "From" ) ;
    163                String ord_subject      = message.getSubject();
    164                String content          = message.getContent();
    165                String errMsg = subject + HybsSystem.CR
    166                                        + " Subject=" + ord_subject + " From=" + org_from + HybsSystem.CR
    167                                        + " MessageID=" + message.getMessageID() + HybsSystem.CR
    168                                        + " Save ErrorMail=" + EXCELIN_URL + "/ERROR_MAIL/" + HybsSystem.CR
    169                                        + errorMessage + HybsSystem.CR
    170                                        + "==========================================================="
    171                                        + HybsSystem.CR
    172                                        + content ;
    173
    174                if( ge50 != null ) {
    175                        String systemId = ge50.getSystemId() ;
    176                        if( systemId == null ) { ge50.setSystemId( "ERR" ); }
    177
    178                        // エラー時の要求番号は、新たに採番しなおします。
    179                        ge50.makeYkno();
    180
    181                        ge50.insertGE50( GE50Access.FG_ERR2 );
    182                        ge50.insertErrorGE56( errMsg );
    183                }
    184
    185                // host と user のメール送信先が記述されている場合は、メールでも転送する。
    186                String   host = message.getHost();
    187                String   from = message.getUser();
    188
    189                if( host != null && from != null ) {
    190                        String[] to             = new String[] { org_from };
    191                        String[] cc = StringUtil.csv2Array( HybsSystem.sys( "ERROR_MAIL_TO_USERS" ) );
    192
    193                        MailTX tx = new MailTX( host );
    194                        tx.setFrom( from );
    195                        tx.setTo( to );
    196                        if( cc.length > 0 ) { tx.setCc( cc ); }
    197                        tx.setSubject( subject );
    198                        tx.setMessage( errMsg );
    199                        tx.sendmail();
    200                }
    201        }
    202
    203        /**
    204         * メッセージ本文より、指定のキーに関連付けられている情報を切り出します。
    205         * これは、指定の文字列=[設定値] というキーワードから、設定値を取り出します。
    206         * 指定の文字列と=のと間に、スペースを入れないでください。
    207         * 設定値の切り出しは、"指定の文字列=[" と "]" の間の文字列を切り出します。
    208         * 内部にスペースが入っていても、問題ありません。ただし、] が入っている場合は、
    209         * 正常に切り出すことは出来ませんし、エスケープ文字も用意していません。
    210         *
    211         * @param       content コンテンツの文字列
    212         * @param       key     情報を切り出す時のキー
    213         *
    214         * @return      設定値 (設定値が見つからない場合:null
    215         */
    216        private String getContentParam( final String content,final String key ) {
    217                if( content == null || key == null ) { return null; }
    218
    219                String newKey = key + "=[" ;
    220
    221                // キーの存在チェックと場所を求める。
    222                int keyAd = content.indexOf( newKey );
    223                if( keyAd >= 0 ) {
    224                        // [設定値] の終了場所を求める。(見つけた位置＋文字列数)
    225                        int st = keyAd + newKey.length() ;
    226                        int ed = content.indexOf( ']' , st );
    227                        if( ed >= 0 ) {
    228                                return content.substring( st,ed );
    229                        }
    230                }
    231                return null;
    232        }
    233}