/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKCtrlMvnoSvcKeiInfoImpl
*   ソースファイル名：JKKCtrlMvnoSvcKeiInfoImpl.java
*   作成者          ：富士通
*   日付            ：2013年12月14日
*＜機能概要＞
*   MVNOサービス契約お客様変更 SOAP連携（本番向け）コマンド発行部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*	v8.00.00	2013/12/14	 FJ）稲岡	【ANK-1584-00-00】対応 L2-MVNO(本体)
*	v8.00.01	2014/01/29	 FJ）稲岡	【ANK-1584-00-00】対応 XML生成時<record>削除
*	v8.00.02	2014/02/26	 FJ）稲岡	【ST-2014-0000058】対応 XML生成時 SOAP-ENV→soapenv
*	v28.00.00	2016/10/31	 FJ）二村	【ANK-3033-00-00】対応 mineo連絡先メールアドレス取得
*	v28.00.01	2016/12/15	 FJ）二村	【ANK-3033-04-00】対応 soapenv:EnvelopeにURI追加
*   v29.00.00   2017/04/21	 FJ)クウン	【ANK-3132-00-00】バックヤード画面へのコンテンツ同意登録機能の追加
*   v68.00.00   2023/12/25	 FJ)広田	 ANK-4463-00-00_【eo定期】サービスサーバリプレース対応_ＳT工程まで
**********************************************************************/
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.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
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 org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
//import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
//import eo.ejb.cbs.cbsmsg.EKKA0030001CBSMsg;

import eo.common.util.JKKStringUtil;


/**
 * MVNOサービス契約お客様変更処理部品（本番）クラスです。
 * @author 富士通
 */
public class JKKCtrlMvnoSvcKeiInfoImpl extends JKKCtrlMvnoSvcKeiInfo
{
	
	/**
	 * インスタンス
	 */
	private static JKKCtrlMvnoSvcKeiInfoImpl instance = null;

	/**
	 * XML作成時のエンコーディング
	 */
	private static final String ENCODING = "UTF-8";

	/**
	 * 正常レスポンスコード
	 */
	private static final String OK_RESPONSE_RETURN_CODE = "0000";

	/**
	 * SOALFAULT（処理例外）
	 */
	private static final String SOAP_FAULT = "fault";

	/**
	 * SOALFAULT（エラーコード）
	 */
	private static final String SOAP_FAULT_CODE = "reason";

	/**
	 * SOALFAULT（エラー詳細）
	 */
	private static final String SOAP_FAULT_STRING = "detail";

//	/**
//	 * CRA0001
//	 */
//	private static final String ENDPOINT_CRA0001 = "taku_fsekikr0060";

	/**
	 * MVNO_URL
	 */
	private static final String MVNO_URL = "MVNO_URL";

	/**
	 * VIEWID
	 */
	private static final String MVNO_VIEWID = "MVNO_VIEWID";

	/**
	 * OPERATORID
	 */
	private static final String MVNO_OPERATORID = "MVNO_OPERATORID";

	/**
	 * 外部インターフェイスID
	 */
	private static final String OUT_IF_ID = "KKIFE229";

	/**
	 * コマンド実行結果
	 */
	private static final String CMD_RESULT_CD = "CMD_RESULT_CD";

	/**
	 * エラーメッセージ
	 */
	private static final String CMD_ERROR_MESSAGE = "CMD_ERROR_MESSAGE";

	/**
	 * コンストラクタです。
	 */
	private JKKCtrlMvnoSvcKeiInfoImpl()
	{
	}

	// ▼▼ ANK-3033-00-00 ADD START ▼▼
	/**
	 * 繰り返し要素
	 */
	public static final String ELEMENT = "element";

	/**
	 * レコード
	 */
	public static final String RECORD = "record";

	/**
	 * タグ名
	 */
	private static final String[] tagNames = { "Envelope", "Body", "Header",
	"initResponse" };

	/**
	 * タグ属性(=TYPE)
	 */
	private static final String[] typeValues = { "service_if",
	"service_if_list" };
	// ▲▲ ANK-3033-00-00 ADD END ▲▲

	// ▼▼ ANK-3033-04-00 ADD START ▼▼
	/**
	 * サービスインターフェイスID(mineo連絡先メールアドレス取得SIFのID)
	 */
	private static final String SVC_IF_ID_EKKA0030002 = "EKKA0030002";
	// ▲▲ ANK-3033-04-00 ADD END ▲▲
	
	//---------v29.00.00 ANK-3132-00-00 ADD START---------//
	/**
	 * サービスインターフェイスID(mineo譲渡可否情報照会SIFのID)
	 */
	private static final String SVC_IF_ID_EKKA0060001 = "EKKA0060001";
	//---------v29.00.00 ANK-3132-00-00 ADD END-----------//
	/**
	 * インスタンス取得用のメソッド
	 * 
	 * @return JKKCtrlMvnoSvcKeiInfoImpl
	 */
	public static synchronized JKKCtrlMvnoSvcKeiInfoImpl getInstance()
	{
		if(instance == null) 
		{
			instance = new JKKCtrlMvnoSvcKeiInfoImpl();
		}
		return instance;
	}

	private AgentDispatchContext inContext;
	public void setInContext(AgentDispatchContext inContext) {
		this.inContext = inContext;
	}

	private Connection connection = null;
	public void setConnection(Connection con) {
		this.connection = con;
		
	}
	
	// ANK-4463 ADD START
	// HTTP関連定数定義
	/**
	 * HTTPヘッダ Content-TYPE
	 */
	private static final String CONTENT_TYPE = "Content-Type";

	/**
	 * HTTPヘッダ Conten-TYPE（値）
	 */
	private static final String CONTENT_TYPE_VALUE = "text/xml; charset=UTF-8";
	// ANK-4463 ADD END

	/**
	 * コマンド発行部品
	 * 
	 * @param serviceMap サービスマップハッシュテーブル
	 * @return サービスマップ戻り値
	 * @throws Exception
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Map ctrlMvnoInfo_KKA0003(Map serviceMap)
	{
		Hashtable<String, Object> ret = new Hashtable<String, Object>();
		HttpURLConnection conURL = null;
		InputStream is = null;
		InetAddress inetaddress = null;
		Transformer transformer = null;
		OutputStream os = null;
		// ▼▼ ANK-3033-00-00 ADD START ▼▼
		String request = null;
		String response = null;
		// ▲▲ ANK-3033-00-00 ADD END ▲▲
		
		try
		{
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "リクエストXML作成 START");
			// リクエストXML作成
			Document soapRequest = createXml(serviceMap);
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "リクエストXML作成 END");
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "URL取得 START");
			// URLをプロパティファイルから取得
			// ▼▼ ANK-3033-00-00 DEL START ▼▼
			//String url = (String)JCCModelCommon.getApplicationConst(MVNO_URL);
			// ▲▲ ANK-3033-00-00 DEL END ▲▲
			// ▼▼ ANK-3033-00-00 ADD START ▼▼
			String url = "";
			// "EKKA0030001"のサービスインターフェイスは、serviceMapにTEMPLATEIDを保持していないため、NullBrankで判別
			if (JKKStringUtil.isNullBlank((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.TEMPLATEID)))
			{
				url = (String) JCCModelCommon.getApplicationConst(MVNO_URL);
			}
			else 
			{
				url = (String) JCCModelCommon.getApplicationConst(MVNO_URL+ "_"+ (String) serviceMap.get(JKKCtrlMvnoSvcKeiInfo.OUT_IF_ID_ELSE));
			}
			// ▲▲ ANK-3033-00-00 ADD END ▲▲
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "URL取得 "+url);
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "URL取得 END");
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "MVNOサーバ接続 START");
			// MVNOサーバへ接続
			URL takunaiServer = new URL(url);
			conURL = (HttpURLConnection)takunaiServer.openConnection();
			conURL.setRequestMethod("POST");
			// ANK-4463 ADD START
			conURL.setRequestProperty(JKKCtrlMvnoSvcKeiInfoImpl.CONTENT_TYPE, JKKCtrlMvnoSvcKeiInfoImpl.CONTENT_TYPE_VALUE);
			// ANK-4463 ADD END
			conURL.setDoOutput(true);
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "MVNOサーバ接続 END");
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPリクエスト送信 START");
			// MVNOサーバへSOAPリクエストを送信
			os = conURL.getOutputStream();
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.ENCODING, ENCODING);//エンコーディング
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");//XML形式
			transformer.transform(new DOMSource(soapRequest), new StreamResult(os));
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPリクエスト送信 END");
			
			// 上り電文のログ出力
			StringWriter sw = new StringWriter();
			transformer.transform(new DOMSource(soapRequest), new StreamResult(sw));
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), sw.toString());
			// ▼▼ ANK-3033-00-00 ADD START ▼▼
			request = sw.toString();
			// ▲▲ ANK-3033-00-00 ADD END ▲▲
			inetaddress = InetAddress.getLocalHost();
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 START");
			// MVNOサーバからSOAPレスポンスを受信（同期処理なのでMVNOからの応答を待つ）
			is = conURL.getInputStream();
			DOMResult dr = new DOMResult();
			transformer.transform(new StreamSource(is), dr);
			Node node = dr.getNode();
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 END");
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 START");
			// SOAPレスポンス読込処理
			// ▼▼ ANK-3033-00-00 DEL START ▼▼
			//ret = read(node);
			// ▲▲ ANK-3033-00-00 DEL END ▲▲
			// ▼▼ ANK-3033-00-00 ADD START ▼▼
			// "EKKA0030001"のサービスインターフェイスは、serviceMapにTEMPLATEIDを保持していないため、NullBrankで判別
			if (JKKStringUtil.isNullBlank((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.TEMPLATEID)))
			{
				ret = read(node);
			} 
			else 
			{
				ret = read2((Document) node);
			}
			// ▲▲ ANK-3033-00-00 ADD END ▲▲
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 END");
			
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス文字列変換処理 START");
			// SOAPレスポンス文字列変換処理
			sw = new StringWriter();
			transformer.transform(new DOMSource(node), new StreamResult(sw));
			// ▼▼ ANK-3033-00-00 ADD START ▼▼
			response = sw.toString();
			// ▲▲ ANK-3033-00-00 ADD END ▲▲
			ret.put(JKKCtrlMvnoSvcKeiInfo.SOAP_RESPONSE, sw.toString());
			JSYejbLog.outlog(inContext, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス文字列変換処理 END");
			
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), ret);
			
			return ret;
		}
		catch(MalformedURLException e) 
		{
			e.printStackTrace();
			ret.put(CMD_RESULT_CD, "1");
			ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(ProtocolException e) 
		{
			e.printStackTrace();
			ret.put(CMD_RESULT_CD, "1");
			ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(UnknownHostException e) 
		{
			e.printStackTrace();
			ret.put(CMD_RESULT_CD, "1");
			ret.put(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);
						Node node = dr.getNode();
						// ▼▼ ANK-3033-00-00 DEL START ▼▼
						//ret = read(node);
						// ▲▲ ANK-3033-00-00 DEL END ▲▲
						// ▼▼ ANK-3033-00-00 ADD START ▼▼
						Document soapResponse = (Document) node;
						if (JKKStringUtil.isNullBlank((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.TEMPLATEID)))
						{
							ret = read(node);
						}
						else
						{
							ret = read2((Document) node);
						}
						// ▲▲ ANK-3033-00-00 ADD END ▲▲
					}
					else 
					{
						ret.put(CMD_RESULT_CD, "1");
						ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					}
				}
				catch(Exception ex) 
				{
					ex.printStackTrace();
					ret.put(CMD_RESULT_CD, "1");
					ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + ex.getMessage());
					return ret;
				}
			}
			else
			{
				ret.put(CMD_RESULT_CD, "1");
				ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			}
			return ret;
		}
		catch(TransformerException e) 
		{
			e.printStackTrace();
			ret.put(CMD_RESULT_CD, "1");
			ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
		}
		catch(Exception e) 
		{
			e.printStackTrace();
			ret.put(CMD_RESULT_CD, "1");
			ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
			return ret;
			
		}
		finally
		{
			if (os != null)
			{
				try
				{
					os.close();
				}
				catch(Exception e) 
				{
					e.printStackTrace();
					ret.put(CMD_RESULT_CD, "1");
					ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					return ret;
				}
			}
			if (is != null)
			{
				try
				{
					is.close();
				}
				catch(Exception e) 
				{
					e.printStackTrace();
					ret.put(CMD_RESULT_CD, "1");
					ret.put(CMD_ERROR_MESSAGE, "XML電文処理でエラーが発生しました。" + e.getMessage());
					return ret;
				}
			}
			// ▼▼ ANK-3033-00-00 ADD START ▼▼
			// エラーが発生した場合
			if ("1".equals(ret.get(CMD_RESULT_CD))|| !"000".equals((String) ret.get(ERROR_LEVEL))|| !"0000".equals((String) ret.get(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);
			}
			// ▲▲ ANK-3033-00-00 ADD END ▲▲
		}
	}

	/**
	 * リクエストXMLDocumentの作成
	 * 
	 * @param serviceMap サービスマップハッシュテーブル
	 * @return リクエストで送信するXMLドキュメント
	 * @throws Exception
	 */
	private Document createXml(Map serviceMap) throws Exception
	{
//		<?xml version="1.0" encoding="UTF-8"?>
//		<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
//		    <soapenv:Header>
//		        <requestID>a9jaieija98320110101160010000</requestID>
//		        <serviceID>KKSV0775</serviceID>	
//		        <channel>3</channel>
//		        <viewID>XXXX</viewID>
//		        <operatorID>XXXX</operatorID>
//		        <ipAddress></ipAddress>
//		        <operateDatetime></operateDatetime>
//		    </soapenv:Header>	

		// root要素が"<soapenv:Envelope>"のドキュメント
		DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dbfactory.newDocumentBuilder();
// ++++++++ v8.00.02 修正開始 ++++++++
//		Document doc = builder.getDOMImplementation().createDocument("http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENV:Envelope", null);
		Document doc = builder.getDOMImplementation().createDocument("http://schemas.xmlsoap.org/soap/envelope/", "soapenv:Envelope", null);
// ++++++++ v8.00.02 修正終了 ++++++++
		Element soap = doc.getDocumentElement();
		// ▼▼ ANK-3033-04-00 ADD START ▼▼
		if (SVC_IF_ID_EKKA0030002.equals((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfo.TEMPLATEID)))
		{
			soap.setAttribute("xmlns:kks", "http://eo.mvno.kopt.co.jp/KKSV084901SC/");
		}
		// ▲▲ ANK-3033-04-00 ADD END ▲▲
		
		//---------v29.00.00 ANK-3132-00-00 ADD START---------//
		if (SVC_IF_ID_EKKA0060001.equals((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfo.TEMPLATEID)))
		{
			soap.setAttribute("xmlns:kks", "http://eo.mvno.kopt.co.jp/KKSV086201SC/");
		}
		//---------v29.00.00 ANK-3132-00-00 ADD END-----------//
		// ▲▲ ANK-3033-04-00 ADD END ▲▲
		// Header部
		// <soapenv:Header>
		Element header = doc.createElement("soapenv:Header");
		soap.appendChild(header);
		// <requestID>
		Element requestId = doc.createElement("requestID");
        // ▼▼ ANK-3033-00-00 DEL START ▼▼
		//requestId.setTextContent(OUT_IF_ID + "_reqId" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
		//header.appendChild(requestId);
        // ▲▲ ANK-3033-00-00 DEL END ▲▲
		// <serviceID>
		Element serviceId = doc.createElement("serviceID");
		// ▼▼ ANK-3033-00-00 ADD START ▼▼
		// requestIDとserviceIDの分岐
		// "EKKA0030001"のサービスインターフェイスは、serviceMapにTEMPLATEIDを保持していないため、NullBrankで判別
		if (JKKStringUtil.isNullBlank((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.TEMPLATEID)))
		{
			requestId.setTextContent(OUT_IF_ID+"_reqId"+ new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
			serviceId.setTextContent("KKSV0775");
		} 
		else
		{
			requestId.setTextContent((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfo.OUT_IF_ID_ELSE)+ "_reqId"+ new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
			serviceId.setTextContent((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfo.SERVICEID));
		}
        header.appendChild(requestId);
		// ▲▲ ANK-3033-00-00 ADD END ▲▲
		// ▼▼ ANK-3033-00-00 DEL START ▼▼
		//serviceId.setTextContent("KKSV0775");
		// ▲▲ ANK-3033-00-00 DEL END ▲▲
		header.appendChild(serviceId);
		// <channel>
		Element channel = doc.createElement("channel");
		channel.setTextContent("3");
		header.appendChild(channel);
		// <viewID>
		Element viewId = doc.createElement("viewID");
		if(null != JCCModelCommon.getApplicationConst(MVNO_VIEWID))
		{
			viewId.setTextContent((String)JCCModelCommon.getApplicationConst(MVNO_VIEWID));
		}
		header.appendChild(viewId);
		// <operatorID>
		Element operatorId = doc.createElement("operatorID");
		if(null != JCCModelCommon.getApplicationConst(MVNO_OPERATORID))
		{
			operatorId.setTextContent((String)JCCModelCommon.getApplicationConst(MVNO_OPERATORID));
		}
		header.appendChild(operatorId);
		// <ipAddress>
		Element ipAddress = doc.createElement("ipAddress");
		ipAddress.setTextContent("");
		header.appendChild(ipAddress);
		// <operateDatetime>
		Element operateDatetime = doc.createElement("operateDatetime");
		operateDatetime.setTextContent(serviceMap.get(JKKCtrlMvnoSvcKeiInfo.OPERATEDATETIME).toString());
		header.appendChild(operateDatetime);
		
//	    <soapenv:Body>
//	      <init>
//	        <KKSV077501SC type="service_if">
//	            <service_if>
//	                <func_code>1</func_code>
//	                <svc_kei_no>CZ12563685</svc_kei_no>
//	                <sysid>1234567890</sysid>
//	            </service_if>
//	        </KKSV077501SC >
//	      </init>
//	    </soapenv:Body>
//	</soapenv:Envelope>

		// Body部
		// ▼▼ ANK-3033-00-00 ADD START ▼▼
		// Body部分岐1 【EKKA0030001】
		// "EKKA0030001"のサービスインターフェイスは、serviceMapにTEMPLATEIDを保持していないため、NullBrankで判別
		if (JKKStringUtil.isNullBlank((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.TEMPLATEID)))
		{
		// ▲▲ ANK-3033-00-00 ADD END ▲▲
		// <soapenv:Body>
		Element body = doc.createElement("soapenv:Body");
		soap.appendChild(body);
		// <init>
		Element init = doc.createElement("init");
		body.appendChild(init);
		// <KKSV077501SC>
		Element serviceIfID = doc.createElement("KKSV077501SC");
		init.appendChild(serviceIfID);
		// <KKSV077501SC type="service_if">
		serviceIfID.setAttribute("type", "service_if");
		// <service_if>
		Element serviceIf = doc.createElement("service_if");
		serviceIfID.appendChild(serviceIf);
		// <func_code>
		Element funcCode = doc.createElement("func_code");
		funcCode.setTextContent("1");
		serviceIf.appendChild(funcCode);
		// <svc_kei_no>
		Element svcKeiNo = doc.createElement("svc_kei_no");
		svcKeiNo.setTextContent((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.SVC_KEI_NO));
		serviceIf.appendChild(svcKeiNo);
		// <sysid>
		Element sysid = doc.createElement("sysid");
		sysid.setTextContent((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfoImpl.SYSID));
		serviceIf.appendChild(sysid);
		// ▼▼ ANK-3033-00-00 ADD START ▼▼
		// Body部分岐2
		}
		else
		{
			// <soapenv:Body>
			Element body = doc.createElement("soapenv:Body");
			soap.appendChild(body);
			// <init>
			// ▼▼ ANK-3033-04-00 MOD START ▼▼
			//Element init = doc.createElement("init");
			Element init;
			if (SVC_IF_ID_EKKA0030002.equals((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfo.TEMPLATEID))
					//---------v29.00.00 ANK-3132-00-00 ADD START---------//
					|| 	SVC_IF_ID_EKKA0060001.equals((String)serviceMap.get(JKKCtrlMvnoSvcKeiInfo.TEMPLATEID)))
					//---------v29.00.00 ANK-3132-00-00 ADD END-----------//
			{
				 init = doc.createElement("kks:init");
			}
			else
			{
				 init = doc.createElement("init");
			}
			// ▲▲ ANK-3033-04-00 MOD END ▲▲
			
			body.appendChild(init);

			// <xxxxxxxxxxSC type="service_if">
			Element serviceIfID = doc.createElement((String) serviceMap.get(JKKCtrlMvnoSvcKeiInfo.SERVICEIFID));
			init.appendChild(serviceIfID);

			List<Hashtable<String, Object>> serviceifList = (List<Hashtable<String, Object>>) serviceMap.get(JKKCtrlMvnoSvcKeiInfo.SERVICEIF);

			if (serviceifList.size() == 1) 
			{
				// <xxxxxxxxxxSC type="service_if">
				serviceIfID.setAttribute("type",JKKCtrlMvnoSvcKeiInfo.SERVICEIF);
			} 
			else 
			{
				// <xxxxxxxxxxSC type="service_if_list">
				serviceIfID.setAttribute("type",JKKCtrlMvnoSvcKeiInfo.SERVICEIF + "_list");
			}

			for (Hashtable<String, Object> map : serviceifList) 
			{
				Element serviceIf = doc.createElement(JKKCtrlMvnoSvcKeiInfo.SERVICEIF);
				serviceIfID.appendChild(serviceIf);

				for (Entry<String, Object> entry : map.entrySet())
				{
					Element item = doc.createElement(entry.getKey());
					item.setTextContent((String) entry.getValue());
					serviceIf.appendChild(item);
				}
			}
		}
		// ▲▲ ANK-3033-00-00 ADD END ▲▲
		// スタンドアロンの設定
		doc.setXmlStandalone(true);
		
		return doc;
	}

	/**
	 * 電文読み込み処理
	 * 
	 * @param node
	 * @return XML電文解析結果
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	private Hashtable<String, Object> read(Node node) 
	throws IOException,ParserConfigurationException,SAXException
	{
		Hashtable<String, Object> ret = new Hashtable<String, Object>();
		
			if(node instanceof Document)
			{
				Document soapResponse = (Document)node;
				
				// レスポンス解析
				Element root =  soapResponse.getDocumentElement();//ルート要素(<SOAP-ENV:Envelope>)
				
				// SOAP例外の場合
				if(root.getElementsByTagName(SOAP_FAULT).item(0) != null)
				{
					String faultinfo = analyzeFaultXml(node);
					ret.put(CMD_RESULT_CD, "1");
					ret.put(CMD_ERROR_MESSAGE, faultinfo);	
					return ret;
				}
				else
				{
					//リターン値取得
					String elValue = getTextContext(root, "errorLevel", 0);
					ret.put(JKKCtrlMvnoSvcKeiInfo.ERROR_LEVEL, elValue);
					String rcValue = getTextContext(root, "returnCode", 0);
					ret.put(JKKCtrlMvnoSvcKeiInfo.RETURN_CD, rcValue);
					String rmValue = getTextContext(root, "returnMessage", 0);
					ret.put(JKKCtrlMvnoSvcKeiInfo.RETURN_MESSAGE, rmValue);
					
					ret.put(CMD_RESULT_CD, "0");
					
//					// エラーチェック
//					if(OK_RESPONSE_RETURN_CODE.equals(rcValue) == false)
//					{
//						// 異常ケース
//						ret = handleResponseXMLError(ret, root);
//					}
//					else
//					{
//						// 正常ケース
//						ret = handleResponseXML(ret, root);
//					}
				}
			}
			
		return ret;
	}

	// ▼▼ ANK-3033-00-00 ADD START ▼▼
	/**
	 * 電文読み込み処理
	 * 
	 * @param soapResponse
	 * @return XML電文解析結果
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	protected Hashtable<String, Object> read2(Document soapResponse)
	throws IOException, ParserConfigurationException, SAXException
	{
		Element root = soapResponse.getDocumentElement();// ルート要素(<SOAP-ENV:Envelope>)
		Hashtable<String, Object> result = analyzeXml(root, true);

		return result;
	}

	/**
	 * コマンド送信戻り電文を解析してMap形式で返します。 <br>
	 * @param elem コマンド解析電文rootXML要素
	 * @param rootflag ルートフラグ
	 * @return XML解析結果
	 */
	public Hashtable<String, Object> analyzeXml(Node elem, boolean rootflag)
	{
		Node node = elem.getFirstChild();
		Hashtable<String, Object> resultMap = null;
		List<Map<String, Object>> bodynodelist = new ArrayList<Map<String, Object>>();
		Map<String, List<Map<String, Object>>> bodynodelistMap = new Hashtable<String, List<Map<String, Object>>>();

		// 電文の要素をすべて解析する。
		while (node != null) 
		{
			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), node.getLocalName()+ "：" + node.getTextContent());

			if (node.getNodeType() == Node.ELEMENT_NODE) 
			{
				String nodename = node.getLocalName();
				String typeValue = null;
				if (node.getAttributes().getNamedItem("type") != null)
				{
					typeValue = node.getAttributes().getNamedItem("type").getNodeValue();
				}

				String childname = "";
				NodeList nodelist = node.getChildNodes();
				
				if (nodelist != null)
				{
					for (int i = 0; i < nodelist.getLength(); i++)
					{
						Node child = nodelist.item(i);
						if (child.getNodeType() == Node.ELEMENT_NODE)
						{
							childname = child.getLocalName();
							break;
						}
					}
				}

				// SOAP例外の場合
				if (JKKCtrlMvnoSvcKeiInfoImpl.SOAP_FAULT.equals(nodename.toLowerCase())|| JKKCtrlMvnoSvcKeiInfoImpl.SOAP_FAULT.equals(childname.toLowerCase()))
				{
					resultMap = new Hashtable<String, Object>();
					String faultinfo = analyzeFaultXml(node);
					resultMap.put(CMD_RESULT_CD, "1");
					resultMap.put(CMD_ERROR_MESSAGE, faultinfo);
					return resultMap;
				}
				else
				{
					if (resultMap == null) 
					{
						resultMap = new Hashtable<String, Object>();
					}
					Hashtable<String, Object> resultinfo = analyzeXml(node,false);
					// 繰り返し要素の親タグ、または繰り返し要素の場合
					if (RECORD.equals(nodename)|| JKKCtrlMvnoSvcKeiInfo.SERVICEIF.equals(nodename)|| ELEMENT.equals(nodename)
							|| nodename.startsWith(ELEMENT + "_")|| Arrays.asList(typeValues).contains(typeValue)) 
					{
						// bodynodelistは、繰り返し要素ごとに使い分ける
						if (null == bodynodelistMap.get(nodename)) 
						{
							bodynodelist = new ArrayList<Map<String, Object>>();
							bodynodelistMap.put(nodename, bodynodelist);
						}
						if (resultinfo != null && !resultinfo.isEmpty())
						{
							bodynodelist.add(resultinfo);
						}
						resultMap.put(nodename, bodynodelist);
					}
					// 子要素のみを取り出すタグの場合
					else if (Arrays.asList(tagNames).contains(nodename)) 
					{
						resultMap.putAll(analyzeXml(node, false));
					}
					else
					{
						resultMap.put(nodename, node.getTextContent());
						// err属性が存在する場合
						if (node.getAttributes().getNamedItem("err") != null)
						{
							String errCd = node.getAttributes().getNamedItem("err").getTextContent();
							resultMap.put(nodename + "_err", errCd);
						}
					}
				}
			}
			// 次のノードを取得
			node = node.getNextSibling();
		}

		if (rootflag) 
		{
			if (resultMap == null)
			{
				resultMap = new Hashtable<String, Object>();
			}
			resultMap.put(CMD_RESULT_CD, "0");
			return resultMap;
		}
		return resultMap;
	}
	// ▲▲ ANK-3033-00-00 ADD END ▲▲
//	/**
//	 * レスポンスXMLDocumentの解析（正常）
//	 * 
//	 * @param root ルート要素
//	 * @param ret
//	 * @return レスポンスXMLドキュメントの解析結果
//	 */
//	private Hashtable<String, Object> handleResponseXML(Hashtable<String, Object> ret, Element root)
//	{
//		//soapの子要素recordを取得
//		NodeList recordList = root.getElementsByTagName("record");
//		//recordの要素数分まわす
//		for(int i = 0; i < recordList.getLength(); i++)
//		{
//			Hashtable<String, Object> data = new Hashtable<String, Object>();
//			Element record = (Element)recordList.item(i);
//			
//			// サービス契約番号
//			String text = getTextContext(record, "svc_kei_no", 0);
//			if(null != text && text.length() > 0)
//			{
//				ret.put(JKKCtrlMvnoSvcKeiInfoImpl.SVC_KEI_NO, text);
//			}
//			// SYSID
//			text = getTextContext(record, "sysid", 0);
//			if(null != text && text.length() > 0)
//			{
//				ret.put(JKKCtrlMvnoSvcKeiInfoImpl.SYSID, text);
//			}
//			
//			JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION , this.getClass(), "record" + ":" + data);
//		}
//		
//		return ret;
//	}
	
//	/**
//	 * レスポンスXMLDocumentの解析（エラー）
//	 * 
//	 * @param root ルート要素
//	 * @param ret
//	 * @return レスポンスXMLドキュメントの解析結果
//	 */
//	private Hashtable<String, Object> handleResponseXMLError(Hashtable<String, Object> ret, Element root)
//	{
//		//soapの子要素recordを取得
//		NodeList recordList = root.getElementsByTagName("record");
//		//recordの要素数分まわす
//		for(int i = 0; i < recordList.getLength(); i++)
//		{
//			Hashtable<String, Object> data = new Hashtable<String, Object>();
//			Element record = (Element)recordList.item(i);
//			
//			// サービス契約番号エラー
//			String errCd = getErrCd(record, "svc_kei_no", 0);
//			if( null != errCd && errCd.length() > 0)
//			{
//				ret.put(EKKA0030001CBSMsg.SVC_KEI_NO_ERR, errCd);
//			}
//			// SYSIDエラー
//			errCd = getErrCd(record, "sysid", 0);
//			if( null != errCd && errCd.length() > 0)
//			{
//				ret.put(EKKA0030001CBSMsg.SYSID_ERR, errCd);
//			}
//			
//			JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION , this.getClass(), "record" + ":" + data);
//		}
//		
//		return ret;
//	}
	
	/**
	 * XMLドキュメントの要素の値を取得
	 * 
	 * @param element ルート要素
	 * @param value 要素名
	 * @param i 要素番号
	 * @return 取得した要素の値
	 */
	private String getTextContext(Element element, String value, int i)
	{
		Node node = element.getElementsByTagName(value).item(i);
		String textCon = node.getTextContent();
		return textCon;
	}
	
	/**
	 * XMLFAULT電文解析処理
	 * 
	 * @param elem XMLFAULT電文
	 * @return ArrayListエラー情報
	 */
	private String analyzeFaultXml(Node elem) 
	{
		Node node = elem.getFirstChild();
		String errmsg = "";
		
		while(node != null)
		{
			if(node.getNodeType() == Node.ELEMENT_NODE) 
			{
				String nodename = node.getLocalName();
				
				if(JKKCtrlMvnoSvcKeiInfoImpl.SOAP_FAULT_CODE.equals(nodename.toLowerCase()))
				{
					Node child = node.getFirstChild();
					if(child != null)
					{
						errmsg = errmsg + "エラーコード：" + child.getTextContent();
					}
				}
				if(JKKCtrlMvnoSvcKeiInfoImpl.SOAP_FAULT_STRING.equals(nodename.toLowerCase()))
				{
					errmsg = errmsg + "エラー詳細：" + node.getTextContent();
				}
			}
			
			node = node.getNextSibling();
		}
		
		return errmsg;
	}
	
//	/**
//	 * エラーコード取得
//	 * 
//	 * @param element ルート要素
//	 * @param value 要素名
//	 * @param i 要素番号
//	 * @return エラーコード
//	 */
//	private String getErrCd(Element element, String value, int i)
//	{
//		String errCd = null;
//		Node node = element.getElementsByTagName(value).item(i);
//		
//		if(node.getAttributes().getNamedItem("err") != null)
//		{
//			String StrErr = node.getAttributes().getNamedItem("err").getTextContent();
//			int intErr = Integer.parseInt(StrErr.substring(1));
//			if(intErr == 1)
//			{
//				errCd = "E1";
//			}
//			else if(intErr <= 52)
//			{
//				errCd = "E2";
//			}
//			else if(intErr <= 99)
//			{
//				errCd = "E3";
//			}
//			else
//			{
//				errCd = "EA";
//			}
//			JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), value + " err=" + StrErr);
//		}
//		
//		return errCd;
//	}
	
}
