/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCCSendFaxUtil
*   ソースファイル名：JCCSendFaxUtil.java
*   作成者          ：富士通
*   日付            ：2011年09月17日
*＜機能概要＞
*   FTP転送部品を用いてdotFAXイメージをFAXサーバに転送します
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/09/17   EK909308    新規作成
*
**********************************************************************/
package eo.common.util;

import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPFaultException;

import jp.co.nttdata_kansai.dotfax.ArrayOfFaxHeaderInfo;
import jp.co.nttdata_kansai.dotfax.ArrayOfSendInfo;
import jp.co.nttdata_kansai.dotfax.FAXService;
import jp.co.nttdata_kansai.dotfax.GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029;
import jp.co.nttdata_kansai.dotfax.GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029Response;
import jp.co.nttdata_kansai.dotfax.SearchOption;
import jp.co.nttdata_kansai.dotfax.SendInfo;
import jp.co.nttdata_kansai.dotfax.SendOptionInfo;
import jp.co.nttdata_kansai.dotfax.SendResultInfo;

/**
 * クラス名：FAX送信部品
 *
 * 処理概要： FTP転送部品を用いてFAXイメージをFAXサーバに転送します
 *            また、FAX送信履歴をFAXサーバから取得します
 *
 * 前提条件：なし
 * 
 * @author 富士通
 */
public class JCCSendFaxUtil
{
	/** FAX転送時にFTP転送で使用する内部IFのID */
	private final static String IFID = "CCIFI001";
	
	/** FTP転送パラメータ(binary転送固定) */
	private final static String TRAN_MODE = "B";
	
	/** FAX送信履歴取得情報で全指定を行う場合の文字列 */
	private final static String SET_ALL = "(all)";
	
	/** 日時指定の省略指定文字列 */
	private final static String DTM_DEFAULT = "19700101000000000";
	
	/**
	 * FTP転送部品を用いてdotFAXイメージをFAXサーバに転送します
	 *  
	 * @param mapArgs 帳票生成情報格納したHashMap。
	 * @return resultCode FTP転送結果コード(0:正常,0以外:FTP転送部品でセットしたエラーコード)
	 * @throws Exception
	 */
	public static String sendFaxImageFTP(HashMap<String, Object> mapArgs) throws Exception
	{
		String resultCode = null;
		
		try
		{
			// マッピングされた帳票生成情報をローカル変数にコピー
			String faxServerNm		= (String)mapArgs.get("FAX_SERVER_NM");				// FAXサーバー名
			String faxPortNum		= (String)mapArgs.get("FAX_PORT_NUM");				// FAXサーバーポート番号
			String faxUserNm		= (String)mapArgs.get("FAX_USER_NM");				// FAXサーバーユーザ名
			String faxPassword		= (String)mapArgs.get("FAX_PASSWORD");				// FAXサーバーパスワード
			String faxSendDir		= (String)mapArgs.get("FAX_SEND_DIR");				// FAX自動送信データの転送先フォルダのパス
			String faxRetryInterva	= (String)mapArgs.get("FAX_FTP_RETRY_INTERVAL");	// FAXイメージFTP転送リトライ間隔
			String faxRetryCntUni	= (String)mapArgs.get("FAX_FTP_RETRY_COUNT_UNI");	// FAXイメージFTP転送リトライ回数(個別)
			String faxRetryCntGene	= (String)mapArgs.get("FAX_FTP_RETRY_COUNT_GEN");	// FAXイメージFTP転送リトライ回数(全体)
			String[] faxImagePass	= (String[])mapArgs.get("FAX_IMAGE_PATH");			// FAXイメージのフルパス
			
			// FTP転送結果コードの取得領域
			HashMap<String, Object> resultMap = new HashMap<String, Object>();
			
			// FAXイメージFTP転送(パラメータ検査は全てFTP部品にて行う)
			JCCFtpClientUtil ftpUtil = new JCCFtpClientUtil();
			ftpUtil.putFtp
			(
					faxServerNm + "\r\n", 
					faxPortNum, 
					faxUserNm, 
					faxPassword, 
					Integer.parseInt(faxRetryInterva), 
					Integer.parseInt(faxRetryCntUni), 
					Integer.parseInt(faxRetryCntGene), 
					TRAN_MODE, 
					faxSendDir, 
					faxImagePass, 
					IFID, 
					true,
					resultMap
			);
			
			// FTP転送結果判定
			Integer errKubun = (Integer)resultMap.get("ERR_KBN");
			if(errKubun == 0)
			{
				// エラーなし
				resultCode = "0";
			}
			else if(errKubun == 1)
			{
				// 接続エラー
				HashMap<String, Object> conErrMap = new HashMap<String, Object>();
				conErrMap = (HashMap<String, Object>)resultMap.get("CONNECT_ERR");
				resultCode = (String)conErrMap.get("ERR_CD");
			}
			else
			{
				// ファイルエラー
				ArrayList<HashMap<String, Object>> fileErrList = (ArrayList<HashMap<String, Object>>)resultMap.get("FILE_ERR");
				HashMap<String, Object> fileErrMap = new HashMap<String, Object>(fileErrList.get(0));
				resultCode = (String)fileErrMap.get("ERR_CD");
			}
		}
		catch(Exception e)
		{
			throw new JCCFrameworkException(e);
		}
		return resultCode;
	}
	
	/**
	 * dotFAXサーバからFAX送信履歴を取得します
	 *  
	 * @param FAX送信履歴を取得するためのパラメータ
	 * @return FAX送信履歴情報を格納したArrayList
	 * @throws Exception
	 */
	public static ArrayList<HashMap<String, Object>> getSendHistory(HashMap<String, Object> paramMap) throws Exception
	{
		// 入力パラメータ検査
		String fromDtm = (String)paramMap.get("FAX_HISTROY_FROM_DTM");
		String groupNm = (String)paramMap.get("FAX_GROUP_NM");
		String wsdlPath = (String)paramMap.get("FAX_WSDL_PATH");
		String qNmUri = (String)paramMap.get("FAX_Q_NM_URI");
		String qNmLocal = (String)paramMap.get("FAX_Q_NM_LOCAL");
		
		// 取得開始日時
		if(chkNull(fromDtm))
		{
			throw new Exception("FAX送信履歴の取得開始日時が指定されていません。");
		}
		// FAX送信グループ名
		if(chkNull(groupNm))
		{
			throw new Exception("仮想FAX送信グループ名称が指定されていません。");
		}
		// WSDLパス
		if(chkNull(wsdlPath))
		{
			throw new Exception("WSDLファイルの配置先パスが指定されていません。");
		}
		// 名前空間URI
		if(chkNull(qNmUri))
		{
			throw new Exception("dotFAXサービスで使用する名前空間URIが指定されていません。");
		}
		// 名前空間ローカル部
		if(chkNull(qNmLocal))
		{
			throw new Exception("dotFAXサービスで使用する名前空間ローカル部が指定されていません。");
		}
		
		// FAX送信履歴情報格納領域
		HashMap<String, Object> resultMap = null;
		HashMap<String, Object> sendOptIfMap = null;
		HashMap<String, Object> sendResultInfoMap = null;
		
		ArrayList<HashMap<String, Object>> resultList = new ArrayList<HashMap<String, Object>>();
		try
		{
			// FAXサービスのインスタンス化
			URL baseUrl = FAXService.class.getResource(".");
			URL url = new URL(baseUrl, wsdlPath);
			QName nm = new QName(qNmUri, qNmLocal);
			FAXService faxService = new FAXService(url, nm);
			
			// 送信履歴格納領域のインスタンス化
			List<SendInfo> lst = new ArrayList<SendInfo>();
			
			// FAX送信情報格納クラスのインスタンス化
			GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029 si = new GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029();
			
			// FAX送信情報検索条件の設定
			SearchOption so = new SearchOption();
			so.setDateTimeFrom(convertXMLGregorianCalendar(fromDtm));
			so.setDateTimeTo(convertXMLGregorianCalendar(DTM_DEFAULT));
			so.setTelephoneNumber(SET_ALL);
			si.setImageFileName(SET_ALL);
			si.setRequestHostName(SET_ALL);
			si.setSendNumber(SET_ALL);
			si.setNote(SET_ALL);
			si.setTargetName(groupNm);
			
			// FAX送信待ち情報取得
			//so.setStatus(0);
			//si.setSearchOption(so);
			//lst.addAll(getOptionalSendInfo(faxService, si));
			
			// FAX送信中情報取得
			//so.setStatus(1);
			//si.setSearchOption(so);
			//lst.addAll(getOptionalSendInfo(faxService, si));
			
			// FAX送信完了
			so.setStatus(2);
			si.setSearchOption(so);
			lst.addAll(getOptionalSendInfo(faxService, si));
			
			// FAX送信エラー
			so.setStatus(3);
			si.setSearchOption(so);
			lst.addAll(getOptionalSendInfo(faxService, si));
			
			// FAX送信中止情報取得
			so.setStatus(4);
			si.setSearchOption(so);
			lst.addAll(getOptionalSendInfo(faxService, si));
			
			// 検索結果が0件の場合はnull復帰
			if(lst.size() == 0)
			{
				return null;
			}
			
			// 送信履歴Listを格納する変数群
			SendInfo sendIf = null;	
			String sendNum = null;
			String reqHostNm = null;
			String reqDateTime = null;
			String targetNm = null;
			String telNum = null;
			String fileNm = null;
			String userData = null;
			
			// 送信履歴Listから情報を1件ずつ取得
			for(int i = 0; i < lst.size(); i++)
			{
				// HashMap領域のインスタンス化
				resultMap = new HashMap<String, Object>();
				
				// i件目の履歴情報を取得
				sendIf = lst.get(i);
				
				// マップ形式でない履歴情報の取得
				sendNum = sendIf.getSendNumber();
				reqHostNm = sendIf.getRequestHostName();
				reqDateTime = convertDtm(sendIf.getRequestDateTime());
				targetNm = sendIf.getTargetName();
				telNum = sendIf.getTelephoneNumber();
				fileNm = sendIf.getFileName();
				userData = sendIf.getUserData();
				
				// 送信オプション情報の取得
				sendOptIfMap = getSendOptIfMap(sendIf);
				
				// 送信状況情報の取得
				sendResultInfoMap = getSendResultMap(sendIf);
				
				// FAX送信履歴情報のマッピング
				resultMap.put("FAX_SEND_NUM", sendNum);							// 送信番号
				resultMap.put("FAX_REQ_HOST_NM", reqHostNm);					// 送信依頼元IPアドレス
				resultMap.put("FAX_REQ_DTM", reqDateTime);						// 送信依頼受付日時
				resultMap.put("FAX_TARGET_NM", targetNm);						// ターゲット名
				resultMap.put("FAX_TEL_NUM", telNum);							// 電話番号
				resultMap.put("FAX_FILE_NM", fileNm);							// イメージファイル名
				resultMap.put("FAX_USER_DATA", userData);						// ユーザーデータ
				resultMap.put("FAX_SEND_OPT_IF", sendOptIfMap);					// 送信オプション情報
				resultMap.put("FAX_SEND_RESULT_IF", sendResultInfoMap);			// 送信状況情報
				
				// 結果リストに追加
				resultList.add(resultMap);
			}
		}
		// 例外発生はそのままスロー
		catch(Throwable t)
		{
			throw new Exception(t);
		}
		return resultList;
	}
	
	/**
	 * 送信履歴情報を取得する
	 * 
	 * @param faxService 送信履歴情報
	 * @param si 送信履歴情報取得オプション
	 * @return 送信履歴情報
	 * @throws Exception
	 */
	private static List<SendInfo> getOptionalSendInfo(FAXService faxService, GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029 si) throws Exception
	{
		ArrayOfSendInfo asi = new ArrayOfSendInfo();
		List<SendInfo> lst = new ArrayList<SendInfo>();
		GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029Response sor = new GetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029Response();
		try
		{
			sor = faxService.getFAXServiceSoap().getSendInformation(si);
			asi = sor.getGetSendInformationX0028StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020StringX002CX0020SearchOptionX0029Result();
			lst = asi.getSendInfo();
		}
		// 指定範囲内の履歴件数0件の場合はサイズ0のListをそのまま復帰
		catch(SOAPFaultException sfe)
		{
			String msg = sfe.getMessage();
			if(msg.indexOf("送信情報") > 0 && msg.indexOf("は存在しません") > 0)
			{
				return lst;
			}
			else
			{
				throw sfe;
			}
		}
		// その他の異常はそのままスロー
		catch(Throwable t)
		{
			throw new Exception(t);
		}
		
		return lst;
	}
	
	/**
	 * 送信履歴情報から送信オプション情報を取得してHashMap形式に変換する
	 * 
	 * @param sendIf 送信履歴情報
	 * @return 送信オプション情報
	 * @throws Exception
	 */
	private static HashMap<String, Object> getSendOptIfMap(SendInfo sendIf) throws Exception
	{
		HashMap<String, Object> sendOptIfMap = new HashMap<String, Object>();
		
		// 送信オプション情報の取得
		SendOptionInfo sendOptionInfo = sendIf.getSendOptionInfo();
		
		// キューイング
		int queueing = sendOptionInfo.getQueueing();
		if(chkNull(queueing) == false)
		{
			sendOptIfMap.put("Queueing", String.valueOf(queueing));
		}
		// 優先度
		int priority = sendOptionInfo.getPriority();
		if(chkNull(priority) == false)
		{
			sendOptIfMap.put("Priority", String.valueOf(priority));
		}
		
		// 送信開始ページ番号
		int startPage = sendOptionInfo.getStartPage();
		if(chkNull(startPage) == false)
		{
			sendOptIfMap.put("StartPage", String.valueOf(startPage));
		}
		
		// 送信終了ページ番号
		int endPage = sendOptionInfo.getEndPage();
		if(chkNull(endPage) == false)
		{
			sendOptIfMap.put("EndPage", String.valueOf(endPage));
		}
		
		// 送信リトライ回数
		int retryCnt = sendOptionInfo.getMaxRetryCount();
		if(chkNull(retryCnt) == false)
		{
			sendOptIfMap.put("MaxRetryCount", String.valueOf(retryCnt));
		}
		
		// 送信リトライ間隔
		int retryInterval = sendOptionInfo.getRetryIntervalSecond();
		if(chkNull(retryInterval) == false)
		{
			sendOptIfMap.put("RetryIntervalSecond", String.valueOf(retryInterval));
		}
		
		// イメージファイルサイズ
		int fileSize = sendOptionInfo.getFileSize();
		if(chkNull(fileSize) == false)
		{
			sendOptIfMap.put("FileSize", String.valueOf(fileSize));
		}
		// TSI情報
		String tsi = sendOptionInfo.getTSI();
		if(chkNull(tsi) == false)
		{
			sendOptIfMap.put("TSI", tsi);
		}
		
		// CSIチェック文字列
		String csiCheck = sendOptionInfo.getCSICheck();
		if(chkNull(csiCheck) == false)
		{
			sendOptIfMap.put("CSICheck", csiCheck);
		}
		
		// 呼出応答待ち時間
		int waitAns = sendOptionInfo.getWaitAnswerSecond();
		if(chkNull(waitAns) == false)
		{
			sendOptIfMap.put("WaitAnswerSecond", String.valueOf(waitAns));
		}
		
		// 送信速度上限
		int maxSpeed = sendOptionInfo.getMaxSpeedLevel();
		if(chkNull(maxSpeed) == false)
		{
			sendOptIfMap.put("MaxSpeedLevel", String.valueOf(maxSpeed));
		}
		
		// 送信速度下限
		int minSpeed = sendOptionInfo.getMinSpeedLevel();
		if(chkNull(minSpeed) == false)
		{
			sendOptIfMap.put("MinSpeedLevel", String.valueOf(minSpeed));
		}
		
		// 符号化上限
		int maxEnc = sendOptionInfo.getMaxEncoding();
		if(chkNull(maxEnc) == false)
		{
			sendOptIfMap.put("MaxEncoding", String.valueOf(maxEnc));
		}
		
		// 符号化下限
		int minEnc = sendOptionInfo.getMinEncoding();
		if(chkNull(minEnc) == false)
		{
			sendOptIfMap.put("MinEncoding", String.valueOf(minEnc));
		}
		
		// 解像度下限
		int minReso = sendOptionInfo.getMinResolution();
		if(chkNull(minReso) == false)
		{
			sendOptIfMap.put("MinResolution", String.valueOf(minReso));
		}
		
		// 用紙サイズ下限
		int minPageSize = sendOptionInfo.getMinPageSize();
		if(chkNull(minPageSize) == false)
		{
			sendOptIfMap.put("MinPageSize", String.valueOf(minPageSize));
		}
		
		// FAXヘッダー情報
		ArrayOfFaxHeaderInfo faxHeaderInfoArray = sendOptionInfo.getFaxHeaderInfo();
		if(null != faxHeaderInfoArray)
		{
			// 現状はFaxHeaderInfoはnullのため、コメント化
//			List<FaxHeaderInfo> lst = new ArrayList<FaxHeaderInfo>();
//			lst = faxHeaderInfoArray.getFaxHeaderInfo();
//			if(null != lst)
//			{
//				ArrayList<HashMap<String, Object>> faxHeadArray = new ArrayList<HashMap<String, Object>>();
//				for(int i = 0; i < lst.size(); i++)
//				{
//					// i番目のFAXヘッダ情報を取得
//					FaxHeaderInfo faxHeaderInfo = lst.get(i);
//					
//					// ArrayListに格納
//					faxHeadArray.add(getFaxHeaderInfoMap(faxHeaderInfo));
//				}
//				// FAXヘッダ情報をHashMapにセット
//				sendOptIfMap.put("FaxHeaderInfo", faxHeadArray);
//			}
		}
		
		// 送信オプション情報を復帰
		return sendOptIfMap;
	}
	
//	/**
//	 * FAXヘッダ情報リストをHashMapに変換する
//	 * 
//	 * @param sendIf 送信履歴情報
//	 * @return 送信オプション情報
//	 * @throws Exception
//	 */
//	private static HashMap<String, Object> getFaxHeaderInfoMap(FaxHeaderInfo faxHeaderInfo) throws Exception
//	{
//		HashMap<String, Object> faxHeadMap = new HashMap<String, Object>();
//		
//		// 描画位置
//		Integer position = faxHeaderInfo.getPosition();
//		if(chkNull(position) == false)
//		{
//			faxHeadMap.put("Position", String.valueOf(position));
//		}
//		
//		// 描画文字列
//		String text = faxHeaderInfo.getText();
//		if(chkNull(text) == false)
//		{
//			faxHeadMap.put("Text", text);
//		}
//		
//		// フォント名
//		String fontName = faxHeaderInfo.getFontName();
//		if(chkNull(fontName) == false)
//		{
//			faxHeadMap.put("FontName", fontName);
//		}
//		
//		// フォントスタイル
//		Integer fontStyle = faxHeaderInfo.getFontStyle();
//		if(chkNull(fontStyle) == false)
//		{
//			faxHeadMap.put("FontStyle", String.valueOf(fontStyle));
//		}
//		
//		// フォントサイズ
//		Integer fontSize = faxHeaderInfo.getFontSize();
//		if(chkNull(fontSize) == false)
//		{
//			faxHeadMap.put("FontSize", String.valueOf(fontSize));
//		}
//		
//		// 水平位置
//		Integer levelPosition = faxHeaderInfo.getLevelPosition();
//		if(chkNull(levelPosition) == false)
//		{
//			faxHeadMap.put("LevelPosition", String.valueOf(levelPosition));
//		}
//		
//		// 垂直位置
//		Integer verticalPosition = faxHeaderInfo.getVerticalPosition();
//		if(chkNull(verticalPosition) == false)
//		{
//			faxHeadMap.put("VerticalPosition", String.valueOf(verticalPosition));
//		}
//		
//		// FAXヘッダ情報を復帰
//		return faxHeadMap;
//	}
	
	/**
	 * 送信履歴情報から送信状況情報を取得してHashMap形式に変換する
	 * 
	 * @param sendIf 送信履歴情報
	 * @return 送信状況情報
	 * @throws Exception
	 */
	private static HashMap<String, Object> getSendResultMap(SendInfo sendIf) throws Exception
	{
		HashMap<String, Object> sendResultInfoMap = new HashMap<String, Object>();
		
		// 送信状況情報の取得
		SendResultInfo sendResultInfo = sendIf.getSendResultInfo();
		
		// ホスト名
		String hostName = sendResultInfo.getHostName();
		if(chkNull(hostName) == false)
		{
			sendResultInfoMap.put("HostName", hostName);
		}
		
		// 仮想FAXグループ名
		String faxGroupName = sendResultInfo.getFAXGroupName();
		if(chkNull(faxGroupName) == false)
		{
			sendResultInfoMap.put("FAXGroupName", faxGroupName);
		}
		
		// 仮想FAX名
		String faxName = sendResultInfo.getFAXName();
		if(chkNull(faxName) == false)
		{
			sendResultInfoMap.put("FAXName", faxName);
		}
		
		// 論理チャネル番号
		int channelNumber = sendResultInfo.getChannelNumber();
		if(chkNull(channelNumber) == false)
		{
			sendResultInfoMap.put("ChannelNumber", String.valueOf(channelNumber));
		}
		
		// ステータス
		int status = sendResultInfo.getStatus();
		if(chkNull(status) == false)
		{
			sendResultInfoMap.put("Status", String.valueOf(status));
		}
		
		// エラー理由
		int errorReason = sendResultInfo.getErrorReason();
		if(chkNull(errorReason) == false)
		{
			sendResultInfoMap.put("ErrorReason", String.valueOf(errorReason));
		}
		
		// 回線切断理由
		int disconnectReason = sendResultInfo.getDisconnectReason();
		if(chkNull(disconnectReason) == false)
		{
			sendResultInfoMap.put("DisconnectReason", String.valueOf(disconnectReason));
		}
		
		// 送信エラー概要
		int faxErrorGeneralCode = sendResultInfo.getFaxErrorGeneralCode();
		if(chkNull(faxErrorGeneralCode) == false)
		{
			sendResultInfoMap.put("FaxErrorGeneralCode", String.valueOf(faxErrorGeneralCode));
		}
		
		// 送信エラー発生フェーズ
		int faxErrorPhase = sendResultInfo.getFaxErrorPhase();
		if(chkNull(faxErrorPhase) == false)
		{
			sendResultInfoMap.put("FaxErrorPhase", String.valueOf(faxErrorPhase));
		}
		// 送信エラーコード
		int faxErrorCode = sendResultInfo.getFaxErrorCode();
		if(chkNull(faxErrorCode) == false)
		{
			sendResultInfoMap.put("FaxErrorCode", String.valueOf(faxErrorCode));
		}
		
		// 送信エラーサブコード
		int faxErrorSubCode = sendResultInfo.getFaxErrorSubCode();
		if(chkNull(faxErrorSubCode) == false)
		{
			sendResultInfoMap.put("FaxErrorSubCode", String.valueOf(faxErrorSubCode));
		}
		
		// 送信結果コード
		String resultCode = sendResultInfo.getResultCode();
		if(chkNull(resultCode) == false)
		{
			sendResultInfoMap.put("ResultCode", resultCode);
		}
		
		// ダイヤル開始日時
		XMLGregorianCalendar dialStartDateTime = sendResultInfo.getDialStartDateTime();
		if(null != dialStartDateTime)
		{
			sendResultInfoMap.put("DialStartDateTime", convertDtm(dialStartDateTime));
		}
		
		// ダイヤル応答日時
		XMLGregorianCalendar dialAnswerDateTime = sendResultInfo.getDialAnswerDateTime();
		if(null != dialAnswerDateTime)
		{
			sendResultInfoMap.put("DialAnswerDateTime", convertDtm(dialAnswerDateTime));
		}
		
		// ネゴシエーション開始日時
		XMLGregorianCalendar negotiationStartDateTime = sendResultInfo.getNegotiationStartDateTime();
		if(null != negotiationStartDateTime)
		{
			sendResultInfoMap.put("NegotiationStartDateTime", convertDtm(negotiationStartDateTime));
		}
		
		// ネゴシエーション完了日時
		XMLGregorianCalendar negotiationEndDateTime = sendResultInfo.getNegotiationEndDateTime();
		if(null != negotiationEndDateTime)
		{
			sendResultInfoMap.put("NegotiationEndDateTime", convertDtm(negotiationEndDateTime));
		}
		
		// 送信終日時
		XMLGregorianCalendar sendEndDateTime = sendResultInfo.getSendEndDateTime();
		if(null != sendEndDateTime)
		{
			sendResultInfoMap.put("SendEndDateTime", convertDtm(sendEndDateTime));
		}
		
		// 回線切断日時
		XMLGregorianCalendar disconnectDateTime = sendResultInfo.getDisconnectDateTime();
		if(null != disconnectDateTime)
		{
			sendResultInfoMap.put("DisconnectDateTime", convertDtm(disconnectDateTime));
		}
		
		// 送信先FAX機メーカーコード
		String destinationFAXMakerCode = sendResultInfo.getDestinationFAXMakerCode();
		if(chkNull(destinationFAXMakerCode) == false)
		{
			sendResultInfoMap.put("DestinationFAXMakerCode", destinationFAXMakerCode);
		}
		
		// 送信先CSI情報
		String destinationCSI = sendResultInfo.getDestinationCSI();
		if(chkNull(destinationCSI) == false)
		{
			sendResultInfoMap.put("DestinationCSI", destinationCSI);
		}
		
		// 送信中ページ番号
		int currentPage = sendResultInfo.getCurrentPage();
		if(chkNull(currentPage) == false)
		{
			sendResultInfoMap.put("CurrentPage", String.valueOf(currentPage));
		}
		
		// 送信済みページ番号
		int pageCount = sendResultInfo.getPageCount();
		if(chkNull(pageCount) == false)
		{
			sendResultInfoMap.put("PageCount", String.valueOf(pageCount));
		}
		
		// ダイヤル試行回数
		int dialTryCount = sendResultInfo.getDialTryCount();
		if(chkNull(dialTryCount) == false)
		{
			sendResultInfoMap.put("DialTryCount", String.valueOf(dialTryCount));
		}
		
		// 通信速度
		int sendSpeed = sendResultInfo.getSendSpeed();
		if(chkNull(sendSpeed) == false)
		{
			sendResultInfoMap.put("SendSpeed", String.valueOf(sendSpeed));
		}
		
		// 符号化
		int sendEncoding = sendResultInfo.getSendEncoding();
		if(chkNull(sendEncoding) == false)
		{
			sendResultInfoMap.put("SendEncoding", String.valueOf(sendEncoding));
		}
		
		// 解像度
		int sendResolution = sendResultInfo.getSendResolution();
		if(chkNull(sendResolution) == false)
		{
			sendResultInfoMap.put("SendResolution", String.valueOf(sendResolution));
		}
		
		// 用紙サイズ
		int sendPageSize = sendResultInfo.getSendPageSize();
		if(chkNull(sendPageSize) == false)
		{
			sendResultInfoMap.put("SendPageSize", String.valueOf(sendPageSize));
		}
		
		// 送信中止依頼状況
		int cancelOption = sendResultInfo.getCancelOption();
		if(chkNull(cancelOption) == false)
		{
			sendResultInfoMap.put("CancelOption", String.valueOf(cancelOption));
		}
		
		// 送信中止開始秒数
		int cancelDelaySecond = sendResultInfo.getCancelDelaySecond();
		if(chkNull(cancelDelaySecond) == false)
		{
			sendResultInfoMap.put("CancelDelaySecond", String.valueOf(cancelDelaySecond));
		}
		
		// 送信中止依頼日時
		XMLGregorianCalendar cancelRequestDateTime = sendResultInfo.getCancelRequestDateTime();
		if(null != cancelRequestDateTime)
		{
			sendResultInfoMap.put("CancelRequestDateTime", convertDtm(cancelRequestDateTime));
		}
		
		// 送信中止完了日時
		XMLGregorianCalendar canceledDateTime = sendResultInfo.getCanceledDateTime();
		if(null != canceledDateTime)
		{
			sendResultInfoMap.put("CanceledDateTime", convertDtm(canceledDateTime));
		}
		
		return sendResultInfoMap;
	}
	
	/**
	 * 指定の年月日時分秒(YYYYMMDDHHMMSSsss)の文字列をXMLGregorianCalendar形式に変換する
	 * 
	 * @param dtm 年月日時分秒
	 * @return XMLGregorianCalendar
	 * @throws Exception
	 */
	private static XMLGregorianCalendar convertXMLGregorianCalendar(String dtm) throws Exception
	{
		// 文字列を数値に変換
		int year = Integer.parseInt(dtm.substring(0, 4));
		int month = Integer.parseInt(dtm.substring(4, 6));
		int date = Integer.parseInt(dtm.substring(6, 8));
		int hour = Integer.parseInt(dtm.substring(8, 10));
		int minute = Integer.parseInt(dtm.substring(10, 12));
		int second = Integer.parseInt(dtm.substring(12, 14));
		int millisecond = Integer.parseInt(dtm.substring(14,17));
		
		// カレンダーのインスタンス化
		GregorianCalendar gc = new GregorianCalendar();
				
		gc.set(Calendar.YEAR, year);
		gc.set(Calendar.MONTH, month - 1);
		gc.set(Calendar.DATE, date);
		gc.set(Calendar.HOUR_OF_DAY, hour);
		gc.set(Calendar.MINUTE, minute);
		gc.set(Calendar.SECOND, second);
		gc.set(Calendar.MILLISECOND, millisecond);
		
		// XMLGregorianCalendar形式にして復帰
		DatatypeFactory factory = DatatypeFactory.newInstance();
		return factory.newXMLGregorianCalendar(gc);
	}
	
	/**
	 * XMLGregorianCalendarを年月日時分秒(YYYYMMDDHHMMSSsss)の形式に変換する
	 * 
	 * @param dtm 年月日時分秒
	 * @return XMLGregorianCalendar
	 * @throws Exception
	 */
	private static String convertDtm(XMLGregorianCalendar xmlGc) throws Exception
	{
		// 文字列形式に変換
		StringBuffer dtmBuf = new StringBuffer();
		
		dtmBuf.append(String.format("%04d",xmlGc.getYear()));
		dtmBuf.append(String.format("%02d",xmlGc.getMonth()));
		dtmBuf.append(String.format("%02d",xmlGc.getDay()));
		dtmBuf.append(String.format("%02d",xmlGc.getHour()));
		dtmBuf.append(String.format("%02d",xmlGc.getMinute()));
		dtmBuf.append(String.format("%02d",xmlGc.getSecond()));
		if(xmlGc.getMillisecond() != DatatypeConstants.FIELD_UNDEFINED)
		{
			dtmBuf.append(String.format("%03d",xmlGc.getMillisecond()));
		}
		else
		{
			dtmBuf.append("000");
		}
		
		return dtmBuf.toString();
	}
	
	/**
	 * オブジェクトが設定されているか判定する
	 * <br>
	 * @param arg0 判定する文字列
	 * @return オブジェクトに値が設定されていない場合はtrue
	 */
	private static boolean chkNull(Object arg0) 
	{
		if (null == arg0) 
		{
			return true;
		}
		if(arg0 instanceof String)
		{
			if(arg0.toString().length() == 0)
			{
				return true;
			}
		}
		else if(arg0 instanceof String[])
		{
			String[] arg1 = (String[])arg0;
			if(arg1.length == 0)
			{
				return true;
			}
		}
		else if(arg0 instanceof Integer)
		{
			Integer arg1 = (Integer)arg0;
			if(arg1 == -1)
			{
				return true;
			}
		}
		return false;
	}	
}