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