/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JZMCtrlBbssInfoImpl
*	ソースファイル名：JZMCtrlBbssInfoImpl.java
*	作成者			：FJ）原田
*	日付			：2017年04月18日
*＜機能概要＞
*	ＢＢＳＳ社 SOAP連携（本番環境用）コマンド発行部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v32.00.00	2017/04/18  FJ)原田		【ANK-3149-00-00】新セキュリティパック
*	v32.00.01	2017/06/02  FJ)原田		【ST-2017-0000009】新セキュリティーパック案件の外部接続時におけるシステムエラー対応
*   v68.00.00   2023/12/25  FJ)広田		 ANK-4463-00-00_【eo定期】サービスサーバリプレース対応_ＳT工程まで
**********************************************************************/
package eo.common.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.fujitsu.futurity.model.common.JCMAPLConstMgr;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JWCStrConst;


/**
 *  BBSS連携独自処理部品（本番環境用）です。<p>
 * <br>
 * @author 富士通
 */
public class JKKCtrlBbssInfoImpl extends JKKCtrlBbssInfo
{
	
	// HTTP関連定数定義
	/**
	 * HTTPヘッダ Content-TYPE
	 */
	private static final String CONTENT_TYPE = "Content-Type";
	
	/**
	 * HTTPヘッダ Conten-TYPE（値）
	 */
	private static final String CONTENT_TYPE_VALUE = "application/soap+xml; charset=UTF-8";

	// ANK-4463 ADD START
	/**
	 * HTTPヘッダ2 SOAPAction
	 */
	private static final String SOAPACTION = "SOAPAction";
	
	/**
	 * HTTPヘッダ2 SOAPAction（値）
	 */
	private static final String SOAPACTION_VALUE = "action1";
	// ANK-4463 ADD END
	
	/**
	 * HTTPヘッダ リクエストメソッド定数
	 */
	private static final String HTTP_REQUEST_METHOD = "POST";
	
	/** 通信方式SSL */
	private static final String S_HTTPS = "https";
	

	//SOAP 関連定数定義
	/**
	 * SOAP1.2用Namespace
	 */
	private static final String SOAP12 = "http://schemas.xmlsoap.org/soap/envelope/";
	
	/**
	 * SOAPエンベロープのPrefix
	 */
	private static final String SOAP_PREFIX = "soapenv";
	
	// SAOP-ENV:body内部系
	/**
	 * CRLF定数定義
	 */
	private static final String CRLF = "\r\n";

	
	// XML要素情報定数定義（結果コード取得電文）
	// ST-2017-0000009 MOD START
	///**
	// * 電文結果情報(CommonAddSubscriptionResponse)
	// */
	//private static final String CONTROL_RESULT_INFO = "CommonAddSubscriptionResponse";
	/**
	 * 電文結果情報(multiRef)
	 */
	private static final String CONTROL_RESULT_INFO = "multiRef";
	// ST-2017-0000009 MOD END

	
	/**
	 * リセラＩＤ
	 */
	private static final String RESELLER_ID = "RESELLER_ID";

	/**
	 * 商品ＩＤ
	 */
	private static final String PRODUCT_ID = "PRODUCT_ID";

	/**
	 * 会員ＩＤ
	 */
	private static final String MEMBER_ID = "MEMBER_ID";

	/**
	 * 数量
	 */
	private static final String CNT = "CNT";

	/**
	 * キャンペーンＩＤ
	 */
	private static final String CMP_ID = "CMP_ID";

	/**
	 * パスワード
	 */
	private static final String PWD = "PWD";

	/**
	 * ユーザサブスクリプションPIN
	 */
	private static final String USER_SBSCPT_PIN = "userSubscriptionPin";

	/**
	 * サブスクリプションID配列
	 */
	private static final String SBSCPT_ID = "subscriptionIds";

	/**
	 * 申し込み日
	 */
	private static final String SIGN_UP_DTM = "signupDate";

	/**
	 * 予備項目1
	 */
	private static final String RESERVE_1 = "reserve1";

	/**
	 * 予備項目2
	 */
	private static final String RESERVE_2 = "reserve2";

	/**
	 * 予備項目3
	 */
	private static final String RESERVE_3 = "reserve3";

	/**
	 * 予備項目4
	 */
	private static final String RESERVE_4 = "reserve4";

	/**
	 * 予備項目5
	 */
	private static final String RESERVE_5 = "reserve5";

	/**
	 * ステータスコード
	 */
	private static final String STATUS_CD = "statusCode";

	/**
	 * ステータスメッセージ
	 */
	private static final String STATUS_MSG = "statusMessage";

	/**
	 * BBSS連携タイムアウト値
	 */
	protected static final String BBSS_TIMEOUT_KKIFE355 = "BBSS_TIMEOUT_KKIFE355";
	
	/**
	 * 接続先URL
	 */
	protected static final String BBSS_URL_KKIFE355 = "BBSS_URL_KKIFE355";
	
	/**
	 * BBSS用プロキシホスト
	 */
	protected static final String BBSS_HTTPS_PROXY_HOST = "BBSS_HTTPS_PROXY_HOST";
	
	/**
	 * BBSS用プロキシポート
	 */
	protected static final String BBSS_HTTPS_PROXY_PORT = "BBSS_HTTPS_PROXY_PORT";
	
	/**
	 * 他事業者契約異動種別コード
	 */
	protected static final String TAJGS_KEI_IDO_SBT_CD = "tajgsKeiIdoSbtCd";

	/**
	 * BBSS会員ID
	 */
	protected static final String BBSS_MEMBER_ID = "bbssMemberId";
	
	/**
	 * XMLStreamWriterクラス
	 */
	private XMLStreamWriter writer = null;
	
	/**
	 * Writerクラス
	 */
	private Writer wt = null;
	
	// 文字化け対策
	/**
	 * StringWriterクラス
	 */
	private StringWriter sw = new StringWriter();

	/**
	 * 戻り電文がSoapメッセージ
	 */
	private boolean soapMessage = false;
	
	/**
	 * エラーコード（ERR0001)
	 */
	private static final String ERR0001 = "ERR0001";
	
	/**
	 * エラーコード（ERR0002)
	 */
	private static final String ERR0002 = "ERR0002";
	
	/**
	 * エラーコード（ERR0003)
	 */
	private static final String ERR0003 = "ERR0003";
	
	/**
	 * エラーコード（ERR0004)
	 */
	private static final String ERR0004 = "ERR0004";
	
	/**
	 * エラーコード（ERR0005)
	 */
	private static final String ERR0005 = "ERR0005";
	
	/**
	 * エラーコード（ERR0006)
	 */
	private static final String ERR0006 = "ERR0006";
	
	/**
	 * エラーコード（ERR0007)
	 */
	private static final String ERR0007 = "ERR0007";
	
	/**
	 * エラーコード（ERR0008)
	 */
	private static final String ERR0008 = "ERR0008";
	
	/**
	 * エラーコード（ERR0009)
	 */
	private static final String ERR0009 = "ERR0009";
	
	/**
	 * レスポンス電文
	 */
	private static String responseXml = "";
	
	/**
	 * データ定義、XML要素変換テーブル
	 */
	private static HashMap<String, String> elementToMap = new HashMap<String, String>() 
	{
		{
			//リセラID
			put(RESELLER_ID, "resellerId");
			//商品ID
			put(PRODUCT_ID, "productId");
			//会員ID
			put(MEMBER_ID, "memberId");
			//数量
			put(CNT, "quantity");
			//キャンペーンID
			put(CMP_ID, "campaignId");
			//パスワード
			put(PWD, "password");
		}
	};

	/**
	 * データ定義、XML要素変換テーブル（戻り電文）
	 */
	private static HashMap<String, String> mapToElement = new HashMap<String, String>() 
	{
		{
			//ユーザサブスクリプションPIN
			put("userSubscriptionPin", USER_SBSCPT_PIN);
			//サブスクリプションID配列
			put("subscriptionIds", SBSCPT_ID);
			//申し込み日
			put("signupDate", SIGN_UP_DTM);
			//予備項目1
			put("reserve1", RESERVE_1);
			//予備項目2
			put("reserve2", RESERVE_2);
			//予備項目3
			put("reserve3", RESERVE_3);
			//予備項目4
			put("reserve4", RESERVE_4);
			//予備項目5
			put("reserve5", RESERVE_5);
			//ステータスコード
			put("statusCode", STATUS_CD);
			//ステータスメッセージ
			put("statusMessage", STATUS_MSG);
		}
	};


	/**
	 *  BBSS申込依頼処理を行います。
	 *  <br>
	 * @param serviceMap BBSS申込依頼用サービスマップ
	 * @return 処理結果コード値　0：正常　1:異常
	 */
	public Map<String, Object> call_KKIFE355(Map<String, Object> serviceMap) throws Exception
	{
		// 電文送信処理の実行
		HashMap<String, Object> result = execute(serviceMap);
		
		return result;
	}
	
	/**
	 * SOAP電文送信処理を実行する。
	 * 
	 * @param serviceMap BBSS申込依頼用サービスマップ
	 * @return 処理結果コード値　0：正常　1:異常
	 * @throws IOException 
	 */
	private HashMap<String, Object>  execute(Map<String, Object>serviceMap) throws Exception 
	{
		HashMap<String, Object> result = new HashMap<String, Object>();
		HttpURLConnection connection = null;
		InputStream is = null;
		InetAddress inetaddress = null;
		String responseContentType = null;
		OutputStream os = null;
		URL url = null;
		
		try
		{
			responseXml = new String();
			String urlString = JCMAPLConstMgr.getString(BBSS_URL_KKIFE355);
			String strPrxyHost = JCMAPLConstMgr.getString(BBSS_HTTPS_PROXY_HOST);
			String strPrxyPort = JCMAPLConstMgr.getString(BBSS_HTTPS_PROXY_PORT);
			
			url = new URL(urlString);
			
			// 通信方式判定
			boolean bSslFlg = false;
			if(urlString.startsWith(S_HTTPS))
			{
				bSslFlg = true;
			}
			
			// プロキシの設定
			int intProxyPort = 0;
			if(strPrxyHost != null)
			{
				intProxyPort = Integer.parseInt(strPrxyPort);
			}
			
			// 電文を送信
			// SSLの場合、HttpsURLConnectionへキャスト
			if(bSslFlg)
			{
				// Proxy設定値がある場合はProxyをセットしてコネクションをオープン
				if(strPrxyHost != null && strPrxyPort != null)
				{
					Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(strPrxyHost, intProxyPort));
					connection = (HttpsURLConnection) url.openConnection(proxy);
				}
				else
				{
					connection = (HttpsURLConnection) url.openConnection();
				}
				
			}
			else
			{
				// Proxy設定値がある場合はProxyをセットしてコネクションをオープン
				if(strPrxyHost != null && strPrxyPort != null)
				{
					Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(strPrxyHost, intProxyPort));
					connection = (HttpURLConnection) url.openConnection(proxy);
				}
				else
				{
					connection = (HttpURLConnection) url.openConnection();
				}
			}
			
			connection.setDoInput(true);
			connection.setDoOutput(true);
			
			// BBSS社とのSOAP通信におけるタイムアウト値
			Integer bbssTimeout =(Integer.parseInt(JCMAPLConstMgr.getString(BBSS_TIMEOUT_KKIFE355)));
			connection.setReadTimeout(bbssTimeout);
			connection.setConnectTimeout(bbssTimeout);
			
			connection.setRequestMethod(JKKCtrlBbssInfoImpl.HTTP_REQUEST_METHOD);
			connection.setRequestProperty(JKKCtrlBbssInfoImpl.CONTENT_TYPE, JKKCtrlBbssInfoImpl.CONTENT_TYPE_VALUE);
			// ANK-4463 ADD START
			connection.setRequestProperty(JKKCtrlBbssInfoImpl.SOAPACTION, JKKCtrlBbssInfoImpl.SOAPACTION_VALUE);
			// ANK-4463 ADD END
			os = connection.getOutputStream();
			
			// 送信用の電文を作成
			this.write(serviceMap, os);
			
			connection.connect();
			
			inetaddress =  InetAddress.getLocalHost();

			// 電文の戻りを取得
			is = connection.getInputStream();
			
			responseContentType = connection.getHeaderField("Content-Type");
			
			result = this.read(inetaddress.getHostName(), inetaddress.getHostAddress(), responseContentType, is);
			
			return result;
		}
		catch(NullPointerException e)
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0001);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（NullPointerException）が発生しました。" + e.getMessage());	
			return result;
		}
		catch(XMLStreamException e) 
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0002);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（XMLStreamException）が発生しました。" + e.getMessage());	
			return result;
		}
		catch(MalformedURLException e) 
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0003);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（MalformedURLException）が発生しました。" + e.getMessage());	
			return result;
		}
		catch (IOException e) 
		{
			
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			if(connection != null && inetaddress != null)
			{
				is = connection.getErrorStream();
				responseContentType = connection.getHeaderField("Content-Type");
				try 
				{
					if(is != null)
					{
						String msg = connection.getResponseMessage();
						result = this.read(inetaddress.getHostName(), inetaddress.getHostAddress(), responseContentType, is);
					}
					else 
					{
						result.put(JWCStrConst.CMD_RESULT_CD,"1");
						result.put(JWCStrConst.CMD_ERROR_CD, ERR0004);
						result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（IOException）が発生しました。" + e.getMessage());
					}
				}
				catch(Exception ex) 
				{
					result.put(JWCStrConst.CMD_RESULT_CD,"1");
					result.put(JWCStrConst.CMD_ERROR_CD, ERR0005);
					result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（IOException）が発生しました。" + ex.getMessage());	
					return result;
				}
			}
			if(result != null && result.get(JWCStrConst.CMD_ERROR_MESSAGE) != null )
			{
				result.put(JWCStrConst.CMD_RESULT_CD,"1");
			}
			else 
			{
				result.put(JWCStrConst.CMD_RESULT_CD,"1");
				result.put(JWCStrConst.CMD_ERROR_CD, ERR0006);
				result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（IOException）が発生しました。" + e.getMessage());	
			}
			return result;
		}
		catch (ParserConfigurationException e) 
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0007);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（ParserConfigurationException）が発生しました。" + e.getMessage());	
			return result;
		}
		catch (SAXException e) 
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0008);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（SAXException）が発生しました。" + e.getMessage());	
			return result;
		}
		catch(Exception e) 
		{
			result.put(JWCStrConst.CMD_RESULT_CD,"1");
			result.put(JWCStrConst.CMD_ERROR_CD, ERR0009);
			result.put(JWCStrConst.CMD_ERROR_MESSAGE,"XML電文処理でエラー（Exception）が発生しました。" + e.getMessage());	
			return result;
			
		}
		finally
		{
			result.put("LOG_RESULT", "sendHttpRequestResponse"
										+ JKKCtrlBbssInfoImpl.CRLF
										+ "RequestText:"
										+ (os != null ? os : "RequestText == null")
										+ JKKCtrlBbssInfoImpl.CRLF
										+ "ResponseText:"
										+ (!("".equals(responseXml)) ? responseXml : "ResponseText == null")
										);
			if(os != null)
			{
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(is != null)
			{
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	
	}
	
	/**
	 * 電文送信初期処理
	 * @param wt Writerオブジェクト
	 */
	private void init(Writer wt) 
	throws FactoryConfigurationError,XMLStreamException
	{
		this.wt = wt;
		
		XMLOutputFactory outfactory = XMLOutputFactory.newInstance();
		this.writer = outfactory.createXMLStreamWriter(this.sw);
		this.writer.setPrefix(SOAP_PREFIX, SOAP12);
			
	}
	/**
	 * クローズ処理
	 */
	private void close()
	throws XMLStreamException,IOException
	{
		
		writer.flush();
		writer.close();
		
		// 最後に全部出す。
		this.wt.write(sw.toString());
	}
	
	/**
	 * XML名前空間書き込み処理
	 * 
	 * @param prefix Prefix
	 * @param uri 名前空間URL
	 * @throws XMLStreamException
	 */
	private void writeNamespace(String prefix, String uri) 
	throws XMLStreamException
	{
		this.writer.writeNamespace(prefix, uri);
	}
	
	/**
	 * XMLドキュメント開始タグ出力処理
	 * 
	 * @param encoding
	 * @throws XMLStreamException
	 */
	private void writeStartDocument(String encoding) 
	throws XMLStreamException
	{
		this.writer.writeStartDocument(encoding, "1.0");
	}
	
	/**
	 * XMLドキュメント終了タグ出力処理
	 * @throws XMLStreamException
	 * 
	 */
	private void writeEndDocument() 
	throws XMLStreamException
	{
		this.writer.writeEndDocument();
	}
	
	/**
	 * XML要素開始タグ出力処理
	 * 
	 * @param name
	 * @throws XMLStreamException
	 */
	private void writeStartElement(String name) 
	throws XMLStreamException
	{
		this.writer.writeStartElement(name);
	}
	
	/**
	 * XMLSoap要素開始タグ出力処理
	 * 
	 * @param name
	 * @throws XMLStreamException
	 */
	private void writeStartSOAPElement(String name) 
	throws XMLStreamException
	{
		this.writer.writeStartElement(SOAP_PREFIX, name, SOAP12);
	}
	
	/**
	 * XML要素終了タグ出力処理
	 * 
	 * @param name
	 * @throws XMLStreamException
	 */
	private void writeEndElement(String name) 
	throws XMLStreamException
	{
		this.writer.writeEndElement();
	}
	
	/**
	 * XML要素終了タグ出力処理
	 * 
	 * @param name
	 * @throws XMLStreamException
	 */
	private void writeEndSOAPElement(String name) 
	throws XMLStreamException
	{
		this.writer.writeEndElement();
	}
	
	/**
	 * XMLデータ出力処理
	 * 
	 * @param str
	 * @throws XMLStreamException
	 */
	private void writeCharacters(String str) 
	throws XMLStreamException
	{
		if(str == null)
		{
			this.writer.writeCharacters("");
		}
		else
		{
			this.writer.writeCharacters(str);
		}
	}
	
	/**
	 * XML出力処理
	 * 
	 * @param userData
	 * @param osw
	 * @throws XMLStreamException
	 */
	private int writeXML(Map<String, Object> userData,OutputStreamWriter osw) 
	throws XMLStreamException,IOException
	{
		
		int result = 0;
		this.init(osw);
		
		this.writeStartDocument("UTF-8");
		this.writeStartSOAPElement("Envelope");
		this.writeNamespace(SOAP_PREFIX, SOAP12);
		// ST-2017-0000009 ADD START
		this.writeStartSOAPElement("Body");
		// ST-2017-0000009 ADD END
		
		// 電文のBody部を作成
		result = this.writeUserData(userData);
		
		// ST-2017-0000009 ADD START
		this.writeEndSOAPElement("Body");
		// ST-2017-0000009 ADD END
		this.writeEndSOAPElement("Envelope");
		this.writeEndDocument();
		
		this.close();
		
		return result;
	}
	
	/**
	 * 書き込み
	 * 
	 * @param userData 送信対象データ
	 * @param os os
	 * @return result
	 * @throws IOException IOException
	 * @throws XMLStreamException XMLStreamException
	 */
	public int write(Map<String, Object> userData,OutputStream os) 
	throws IOException,XMLStreamException
	{
		OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
		try 
		{
				
			// 本文
			int result = this.writeXML(userData,osw);
			osw.write(JKKCtrlBbssInfoImpl.CRLF);
			
			return result;
		}
		finally 
		{
			if(osw != null) {
				osw.flush();
				osw.close();
			}
			if(os != null) {
				os.flush();
				os.close();
			}
		}
	}
	
	/**
	 * ユーザデータ部分のメッセージ生成
	 * @param writer
	 * @param userData
	 * @throws XMLStreamException
	 */
	private int writeUserData(Map<String, Object> userData) 
	throws XMLStreamException
	{
		int result = 0;
		
		// ST-2017-0000009 ADD START
		this.writeStartElement("commonAddSubscription");
		// ST-2017-0000009 ADD END
		this.writeStartElement("CommonAddSubscriptionRequest");
		
		result = this.trace(userData);
		
		this.writeEndElement("CommonAddSubscriptionRequest");
		// ST-2017-0000009 ADD START
		this.writeEndElement("commonAddSubscription");
		// ST-2017-0000009 ADD END
		
		return result;
		
	}
	
	/**
	 * UserData内をトレースする。
	 * @param writer
	 * @param map
	 * @param serviceIfFlag
	 * @throws XMLStreamException
	 */
	private int trace(Map<String, Object> serviceMap)
	throws XMLStreamException
	{
		//リセラID
		this.writeStartElement(getElementName(RESELLER_ID));
		this.writeCharacters(convString("kopticom"));
		this.writeEndElement(getElementName(RESELLER_ID));
	
		//商品ID
		if(serviceMap.containsKey(TAJGS_KEI_IDO_SBT_CD))
		{
			// 他事業者契約異動種別コードが"0201"（インターネットサギウォールライセンス申込依頼）の場合
			if(serviceMap.get(TAJGS_KEI_IDO_SBT_CD).equals(JKKStrConst.TAJGS_KEI_IDO_SBT_CD_INETSGWL_RS_MSKM_REQ))
			{
				this.writeStartElement(getElementName(PRODUCT_ID));
				this.writeCharacters(convString("BSDCDK0016"));
				this.writeEndElement(getElementName(PRODUCT_ID));
			}
			// 他事業者契約異動種別コードが"0211"（ノートンファミリープレミアライセンス申込依頼）の場合
			else if (serviceMap.get(TAJGS_KEI_IDO_SBT_CD).equals(JKKStrConst.TAJGS_KEI_IDO_SBT_CD_NTFMLPRM_RS_MSKM_REQ))
			{
				this.writeStartElement(getElementName(PRODUCT_ID));
				this.writeCharacters(convString("dammy"));
				this.writeEndElement(getElementName(PRODUCT_ID));
			}
		}
		else
		{
			// エラーログ出力
			return -1;
		}
	
		//会員ID
		if(serviceMap.containsKey(BBSS_MEMBER_ID))
		{
			this.writeStartElement(getElementName(MEMBER_ID));
			this.writeCharacters(convString(serviceMap.get(BBSS_MEMBER_ID)));
			this.writeEndElement(getElementName(MEMBER_ID));
		}
		else
		{
			// エラーログ出力
			return -1;
		}
	
		//数量（"1"固定）
		this.writeStartElement(getElementName(CNT));
		this.writeCharacters(convString("1"));
		this.writeEndElement(getElementName(CNT));
	
		//キャンペーンID("null"固定)
		this.writeStartElement(getElementName(CMP_ID));
		this.writeCharacters(null);
		this.writeEndElement(getElementName(CMP_ID));
	
		//パスワード("null"固定)
		this.writeStartElement(getElementName(PWD));
		this.writeCharacters(null);
		this.writeEndElement(getElementName(PWD));
		
		return 0;
	}
	
	/**
	 *  オブジェクトを文字列に変換します。
	 *  
	 * @param obj 変換するオブジェクト
	 * @return 変換された文字列
	 */
	private String convString(Object obj)
	{
		if (obj == null) 
		{
			return "";
		}
		else if (obj instanceof Integer) 
		{
			return String.valueOf((Integer)obj);
		}
		else if (obj instanceof Long) 
		{
			return String.valueOf((Long)obj);
		}
		else if (obj instanceof Short) 
		{
			return String.valueOf((Short)obj);
		}
		else if (obj instanceof Double) 
		{
			return String.valueOf((Double)obj);
		}
		else if (obj instanceof Float) 
		{
			return String.valueOf((Float)obj);
		}
		else if (obj instanceof Byte) 
		{
			return String.valueOf((Byte)obj);
		}
		else if (obj instanceof Boolean) 
		{
			return String.valueOf((Boolean)obj);
		}
		else if (obj instanceof String) 
		{
			return (String)obj;
		}
		return obj.toString();
	}

	/**
	 * 項目名からSoapElement名を取得します。
	 * 
	 * @param obj 項目名
	 * @return XMLElement名
	 */
	private String getElementName(String obj) 
	{
		return elementToMap.get(obj);
	}
	
	/**
	 * Soap項目名から項目名を取得します。
	 * 
	 * @param obj Soap項目名
	 * @return 項目名
	 */
	private String getMapName(String obj) 
	{
		return mapToElement.get(obj);
	}
	
	/**
	 * 電文読み込み処理
	 * 
	 * @param host
	 * @param ip
	 * @param contentType
	 * @param is
	 * @return XML電文解析結果
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	private HashMap<String, Object> read(String host, String ip, String contentType, InputStream is) 
	throws IOException,ParserConfigurationException,SAXException
	{
		String charset = this.getEncoding(contentType);
		StringReader sr = readSingleResource(charset, is);
		
		HashMap<String, Object>result = null;
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setNamespaceAware(true);
		DocumentBuilder db = dbf.newDocumentBuilder();
		
		Document doc = db.parse(new InputSource(sr));
		
		Element elem = doc.getDocumentElement();
		
		// XMLの実行結果を取得する。
		result = analyzeXml(elem,true);
		
		return result;
	}

	/**
	 * 電文読み取り処理（添付ファイルなし）
	 * 
	 * @param charSet
	 * @param is
	 * @return
	 * @throws IOException
	 */
	private StringReader readSingleResource(String charSet, InputStream is) 
	throws IOException
	{
		this.soapMessage = true;
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		byte[] buf = new byte[1024*8];
		
		int length = readLine(is, buf, 0, buf.length);
		
		while(length != -1){
			// ボディ部
			baos.write(buf, 0, length);
			length = readLine(is, buf, 0, buf.length);
		}
		
		responseXml = baos.toString("UTF-8");
		
		byte[] contents = baos.toByteArray();
		
		
		// コンテントタイプから、encoding指定を得る。
		StringReader reader = new StringReader(new String(contents, charSet));
		
		return reader;
	}
	
	/**
	 * 行データ取得処理
	 * 
	 * @param is InputStream 
	 * @param abyte0 abyte0[]
	 * @param i i
	 * @param j j
	 * @return int 実行結果
	 * @throws IOException
	 */
	private int readLine(InputStream is, byte abyte0[], int i, int j) 
	throws IOException 
	{
		if (j <= 0) 
		{
			return 0;
		}
		int k = 0;
		int l;
		do 
		{
			if((l = is.read()) == -1) 
			{
				break;
			}
			abyte0[i++] = (byte)l;
			k++;
		}
		while(l != 10 && k != j);
		
		return k <= 0 ? -1 : k;
	}
	
	/**
	 * エンコーディングデータ取得処理
	 * 
	 * @param contentType HTTPContentType文字列
	 * @return エンコーディング
	 */
	private String getEncoding(String contentType)
	{
		if(contentType != null)
		{
			
			// 半角空白で切って、
			String[] contentTypes = contentType.split(" ");
			
			// 開始がcharsetで始まるものを探して、
			for(String ct : contentTypes){
				if(ct.startsWith("charset=")){
					ct = ct.trim();
					return ct.substring("charset=".length());
				}
			}
		}
		
		// 見つけられなかった場合
		return "UTF-8";
	}
	
	/**
	 * コマンド送信戻り電文解析処理
	 * 
	 * @param elem コマンド解析電文rootXML要素
	 * @return XML解析結果
	 */
	private HashMap<String, Object> analyzeXml(Node elem,boolean rootflag) 
	{
		Node node = elem.getFirstChild();
		HashMap<String, Object> resultMap = null;
		
		ArrayList<Map<String, Object>>nodelist = new ArrayList<Map<String, Object>>();
		
		//電文の要素をすべて解析する。
		while(node != null)
		{
			if(node.getNodeType() == Node.ELEMENT_NODE) 
			{
				String nodename = node.getLocalName();
				
				if(JKKCtrlBbssInfoImpl.CONTROL_RESULT_INFO.equals(nodename)) 
				{
					if(resultMap == null) {
						resultMap = new HashMap<String, Object>();
					}
					Map<String, Object>resultinfo = analyzeResultXml(node);
					nodelist.add(resultinfo);
					resultMap.put(JWCStrConst.CMD_RESULT_CD,"0");
					resultMap.put(JWCStrConst.CMD_RESULT_DETAIL,nodelist);
					
				}
				// 子供のノードがある場合、さらに子供の要素をチェックする。
				if(node.hasChildNodes()) 
				{
					HashMap<String, Object> child = analyzeXml(node,false);
					if(child != null) {
						return child;
					}
				}
			}
				node = node.getNextSibling();
		}
		
		if(rootflag && resultMap == null)
		{
			resultMap = new HashMap<String, Object>();
			resultMap.put(JWCStrConst.CMD_RESULT_CD,"0");
			return resultMap;
		}
		
		return resultMap;
	}
	
	/**
	 * コマンド結果発行戻り電文解析処理
	 * 
	 * @param elem XMLコマンド発行電文戻りNode
	 * @return コマンド結果発行戻値
	 */
	private Map<String, Object>analyzeResultXml(Node elem) 
	{
		
		Node node = elem.getFirstChild();
		HashMap<String, Object>result = new HashMap<String, Object>();
		
		while(node != null) {
			
			if(node.getNodeType() == Node.ELEMENT_NODE) 
			{
				String nodename = node.getLocalName();
				String elementString = this.getMapName(nodename);
				
				if(elementString != null) {
					// ST-2017-0000009 MOD START
//					result.put(elementString,node.getTextContent());
					if("subscriptionIds".equals(nodename))
					{
						Node node2 = node.getFirstChild();
						while(node2 != null) 
						{
							if(node2.getNodeType() == Node.ELEMENT_NODE && "subscriptionIds".equals(node2.getLocalName())) 
							{
								String subscriptionIds = node2.getTextContent();
								result.put(elementString, subscriptionIds);
								break;
							}
							node2 = node2.getNextSibling();
						}
					}
					else
					{
						result.put(elementString,node.getTextContent());
					}
					// ST-2017-0000009 MOD END
				}
			}
			
			node = node.getNextSibling();
		}
		return result;
	}
	
}
