/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCKCtrlCisInfoImpl
*   ソースファイル名：JCKCtrlCisInfoImpl.java
*   作成者          ：富士通
*   日付            ：2015年05月25日
*＜機能概要＞
*   CISシステム SOAP連携（本番向け）コマンド発行部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v16.00.00   2015/05/25	FJ)酒井		【ANK-2480-00-00】対応 新電力
*   v41.00.00   2019/03/05	FJ)中原		【OM-2019-0000247】eo電気契約一意照(KKIFE260)で異常なタイムアウト
*   
**********************************************************************/
package eo.ejb.common;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Hashtable;
import java.util.Map;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;

import com.fujitsu.futurity.model.ejb.common.JSYejbLog;

/**
 * CISシステム SOAP連携（本番向け）コマンド発行部品クラスです。
 * @author 富士通
 */
public class JCKCtrlCisInfoImpl extends JCKCtrlCisInfo
{
	/**
	 * インスタンス
	 */
	private static JCKCtrlCisInfo instance = null;

	/**
	 * コンストラクタです。
	 */
	private JCKCtrlCisInfoImpl()
	{
	}

	/**
	 * インスタンス取得用のメソッド
	 * 
	 * @return JCKCtrlCisInfoImpl
	 */
	public static synchronized JCKCtrlCisInfo getInstance()
	{
		if(instance == null) 
		{
			instance = new JCKCtrlCisInfoImpl();
		}
		return instance;
	}

	/**
	 * KKIFE253_eo電気契約お客様変更
	 * 
	 * @param serviceMap サービスマップハッシュテーブル
	 * @return サービスマップ戻り値
	 * @throws Exception
	 */
	public Map<String, Object> call_KKIFE253(Map<String, Object> serviceMap)
	{
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "call_KKIFE253:START");
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "serviceMap:" + serviceMap.toString());
		
		Map<String, Object> resultMap = call_CIS(serviceMap, (String)JCCModelCommon.getApplicationConst(CIS_URL_KKIFE253));
		
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "resultMap:" + resultMap.toString());
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "call_KKIFE253:END");
		
		return resultMap;
	}

	/**
	 * KKIFE264_eo電気契約一覧照会
	 * 
	 * @param serviceMap サービスマップハッシュテーブル
	 * @return サービスマップ戻り値
	 * @throws Exception
	 */
	public Map<String, Object> call_KKIFE264(Map<String, Object> serviceMap)
	{
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "call_KKIFE264:START");
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "serviceMap:" + serviceMap.toString());
		
		Map<String, Object> resultMap = call_CIS(serviceMap, (String)JCCModelCommon.getApplicationConst(CIS_URL_KKIFE264));
		
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "resultMap:" + resultMap.toString());
		JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "call_KKIFE264:END");

		return resultMap;
	}

	/**
	 * コマンド発行部品
	 * 
	 * @param serviceMap サービスマップハッシュテーブル
	 * @param url CISサーバ接続のURL
	 * @return サービスマップ戻り値
	 * @throws TransformerFactoryConfigurationError
	 */
	private Map<String, Object> call_CIS(Map<String, Object> serviceMap, String url) throws TransformerFactoryConfigurationError {

		Hashtable<String, Object> ret = new Hashtable<String, Object>();
		HttpURLConnection conURL = null;
		InputStream is = null;
		InetAddress inetaddress = null;
		Transformer transformer = null;
		OutputStream os = null;
		StringWriter sw = null;
		Document requestXml = null;
		Document responseXml = null;
		String request = null;
		String response = null;
		
		try
		{
			/** 
			 * リクエストXML作成
			 */
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "リクエストXML作成 START");
			requestXml = createXml(serviceMap);
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "リクエストXML作成 END");
			
			/**
			 * CISサーバへ接続
			 */
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "CISサーバ接続 START");
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "URL "+url);
			URL cisServer = new URL(url);
			conURL = (HttpURLConnection)cisServer.openConnection();
			conURL.setRequestMethod(HTTP_REQUEST_METHOD);
			conURL.setDoOutput(true);
			// OM-2019-0000247 ADD START
			int timeoutMilliSec = Integer.parseInt(JCCModelCommon.getApplicationConst(CIS_SOAP_TIMEOUT));
			conURL.setConnectTimeout(timeoutMilliSec);
			// OM-2019-0000247 ADD END
			// OM-2019-0000247 MOD START
//			conURL.setReadTimeout(Integer.parseInt(JCCModelCommon.getApplicationConst(CIS_SOAP_TIMEOUT)));
			conURL.setReadTimeout(timeoutMilliSec);
			// OM-2019-0000247 MOD END
			conURL.setRequestProperty(CONTENT_TYPE, CONTENT_TYPE_VALUE);
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "CISサーバ接続 END");
			
			/**
			 * CISサーバへSOAPリクエストを送信
			 */
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPリクエスト送信 START");
			conURL.connect();
			os = conURL.getOutputStream();
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			transformer = transformerFactory.newTransformer();
			//エンコーディング
			transformer.setOutputProperty(OutputKeys.ENCODING, ENCODING);
			//XML形式
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
			transformer.transform(new DOMSource(requestXml), new StreamResult(os));
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPリクエスト送信 END");
			
			
			/**
			 * 上り電文のログ出力
			 */
			sw = new StringWriter();
			transformer.transform(new DOMSource(requestXml), new StreamResult(sw));
			request = sw.toString();
			inetaddress = InetAddress.getLocalHost();
			
			/**
			 * CISサーバからSOAPレスポンスを受信（同期処理なのでCISからの応答を待つ）
			 */
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 START");
			is = conURL.getInputStream();
			DOMResult dr = new DOMResult();
			transformer.transform(new StreamSource(is), dr);
			responseXml = (Document)dr.getNode();
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 END");
			
			/**
			 * 下り電文のログ出力
			 */
			sw = new StringWriter();
			transformer.transform(new DOMSource(responseXml), new StreamResult(sw));
			response = sw.toString();

			/**
			 * SOAPレスポンス読込処理
			 */
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 START");
			ret = read(responseXml);
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), ret);
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 END");
			
			return ret;
		}
		catch(MalformedURLException e) 
		{
			e.printStackTrace();
			ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
			ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(ProtocolException e) 
		{
			e.printStackTrace();
			ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
			ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(UnknownHostException e) 
		{
			e.printStackTrace();
			ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
			ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch (IOException e) 
		{
			e.printStackTrace();
			
			if(conURL != null && inetaddress != null)
			{
				is = conURL.getErrorStream();
				try 
				{
					if(is != null)
					{
						DOMResult dr = new DOMResult();
						transformer.transform(new StreamSource(is), dr);
						responseXml = (Document)dr.getNode();
						ret = read(responseXml);
					}
					else 
					{
						ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
						ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					}
				}
				catch(Exception ex) 
				{
					ex.printStackTrace();
					ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
					ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + ex.getMessage());
					return ret;
				}
			}
			else
			{
				ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
				ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			}
			return ret;
		}
		catch(TransformerException e) 
		{
			e.printStackTrace();
			ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
			ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(Exception e) 
		{
			e.printStackTrace();
			ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
			ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
			
		}
		finally
		{
			if (os != null)
			{
				try
				{
					os.close();
				}
				catch(Exception e) 
				{
					e.printStackTrace();
					ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
					ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					return ret;
				}
			}
			if (is != null)
			{
				try
				{
					is.close();
				}
				catch(Exception e) 
				{
					e.printStackTrace();
					ret.put(JCKCtrlCisInfo.CMD_RESULT_CD, "1");
					ret.put(JCKCtrlCisInfo.CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					return ret;
				}
			}
			
			if("1".equals((String)ret.get(JCKCtrlCisInfo.CMD_RESULT_CD))
					|| !"000".equals((String)ret.get(JCKCtrlCisInfo.ERROR_LEVEL))
					|| !"0000".equals((String)ret.get(JCKCtrlCisInfo.RETURN_CD))){
				
				JSYejbLog.outlog(null, JSYejbLog.ERROR, this.getClass(), "リクエストXML：" + request);
				JSYejbLog.outlog(null, JSYejbLog.ERROR, this.getClass(), "レスポンスXML：" + response);
				
			}else{
				
				JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "リクエストXML：" + request);
				JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "レスポンスXML：" + response);
			}
		}
	}	
}
