package com.eactive.eai.adapter.socket2.config;

import com.eactive.eai.adapter.AdapterPropManager;
import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.adapter.EAIException;
import com.eactive.eai.adapter.socket2.common.Env;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import com.eactive.eai.adapter.socket2.protocol.admin.AdminServer;
import com.eactive.eai.adapter.socket2.protocol.append.AppendClient;
import com.eactive.eai.adapter.socket2.protocol.append.AppendServer;
import com.eactive.eai.adapter.socket2.protocol.cert.CertClient;
import com.eactive.eai.adapter.socket2.protocol.cert.CertServer;
import com.eactive.eai.adapter.socket2.protocol.cisco.CiscoClient;
import com.eactive.eai.adapter.socket2.protocol.cisco.CiscoServer;
import com.eactive.eai.adapter.socket2.protocol.delimiter.DelimiterClient;
import com.eactive.eai.adapter.socket2.protocol.delimiter.DelimiterServer;
import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.DynamicOffsetClient;
import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.DynamicOffsetServer;
import com.eactive.eai.adapter.socket2.protocol.echo.EchoClient;
import com.eactive.eai.adapter.socket2.protocol.echo.EchoServer;
import com.eactive.eai.adapter.socket2.protocol.envelop.EnvelopClient;
import com.eactive.eai.adapter.socket2.protocol.envelop.EnvelopServer;
import com.eactive.eai.adapter.socket2.protocol.fixedheader.FixedHeaderClient;
import com.eactive.eai.adapter.socket2.protocol.fixedheader.FixedHeaderServer;
import com.eactive.eai.adapter.socket2.protocol.fixedpayload.FixedPayloadClient;
import com.eactive.eai.adapter.socket2.protocol.fixedpayload.FixedPayloadServer;
import com.eactive.eai.adapter.socket2.protocol.http.HttpServer;
import com.eactive.eai.adapter.socket2.protocol.inicis.InicisClient;
import com.eactive.eai.adapter.socket2.protocol.inicis.InicisServer;
import com.eactive.eai.adapter.socket2.protocol.inisafe.InisafeClient;
import com.eactive.eai.adapter.socket2.protocol.inisafe.InisafeServer;
import com.eactive.eai.adapter.socket2.protocol.inisafe2020.Inisafe2020Client;
import com.eactive.eai.adapter.socket2.protocol.inisafe2020.Inisafe2020Server;
import com.eactive.eai.adapter.socket2.protocol.inisafenatn.InisafeNatnPayloadClient;
import com.eactive.eai.adapter.socket2.protocol.inisafenatn.InisafeNatnPayloadServer;
import com.eactive.eai.adapter.socket2.protocol.inisafepayload.InisafePayloadClient;
import com.eactive.eai.adapter.socket2.protocol.inisafepayload.InisafePayloadServer;
import com.eactive.eai.adapter.socket2.protocol.law.LawClient;
import com.eactive.eai.adapter.socket2.protocol.law.LawServer;
import com.eactive.eai.adapter.socket2.protocol.login.BindClient;
import com.eactive.eai.adapter.socket2.protocol.login.LazyClient;
import com.eactive.eai.adapter.socket2.protocol.login.LoginClient;
import com.eactive.eai.adapter.socket2.protocol.proxy.ProxyServer;
import com.eactive.eai.adapter.socket2.protocol.tcseed.TcseedClient;
import com.eactive.eai.adapter.socket2.protocol.tcseed.TcseedServer;
import com.eactive.eai.adapter.socket2.protocol.udp.UdpClient;
import com.eactive.eai.adapter.socket2.protocol.udp.UdpServer;
import com.eactive.eai.adapter.socket2.protocol.variableheader.VariableHeaderClient;
import com.eactive.eai.adapter.socket2.protocol.variableheader.VariableHeaderServer;
import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbClient;
import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbServer;
import com.eactive.eai.adapter.socket2.protocol.xecure.XecureClient;
import com.eactive.eai.adapter.socket2.protocol.xecure.XecureServer;
import com.eactive.eai.adapter.socket2.protocol.xecure2.Xecure2Client;
import com.eactive.eai.adapter.socket2.protocol.xecure2.Xecure2Server;
import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Client;
import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Server;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.NullControl;

import java.util.Properties;

public class SocketAdapterFactory {
	private static Logger logger = SocketLoggerManager.getInstance().getLogger();
//	private static Logger errLogger = SocketLoggerManager.getInstance().getErrLogger();

	private enum SocketType {
		SERVER, CLIENT, ADMIN, UNKNOWN;

        public static SocketType getValue(String value) {
            try {
                return valueOf(value.toUpperCase());
            } catch (Exception e) {
                return UNKNOWN;
            }
        }
	}
	
	private enum Protocol {
		ADMIN,
		CERT,		
		CISCO,
		ECHO,
		EGSEED,
		ENVELOP,			
		FIXED_LENGTH_HEADER,
		FIXED_LENGTH_PAYLOAD,
		VARIABLE_LENGTH_HEADER,
		INISAFE,
		INISAFE_2020,
		INISAFE_NATN,
		INISAFE_PAYLOAD,
		HTTP,	
		PROXY,
		TCSEED,
		UDP_FIXED_LENGTH_HEADER,
		UDP_FIXED_LENGTH_PAYLOAD,
		XECURE,
		XECURE2,
		XECURE3,
		LOGIN,
		LAZY,
		BIND,		
		LAW,
		DELIMITER,
		INICIS,	
		APPEND,
		XC3EPB,
		DYNAMIC_OFFSET,
		UNKNOWN;

        public static Protocol getValue(String value) {
            try {
                return valueOf(value.toUpperCase());
            } catch (Exception e) {
                return UNKNOWN;
            }
        }
	}
	
//	private static boolean isDrMode = false;
//	static {
//		if("Y".equals(System.getProperty(Keys.DR_MODE, "N").toUpperCase())) {
//			isDrMode = true;
//		}
//	}
	
	public SocketAdapterFactory() {
		super();
	}
	
	public static ISocketAdapter createSocketAdapter(SocketAdapterContext context) throws EAIException {
		if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) {
			logger.info(context.getAdapterName() + " | create socket adapter ... ");
		}

		try {
//			String adapterGroupName = context.getAdapterGroupName();
//			String adapterName = context.getAdapterName();
	
			ISocketAdapter adapter = null;
			
			switch(SocketType.getValue(context.getSocketType())) {
			case ADMIN:
				if(Protocol.getValue(context.getProtocol()) == Protocol.ADMIN) {
					context.setSocketType("SERVER");
				}
				else {
					throw new EAIException("unknown ADMIN protocol : " + context.getProtocol());
				}
				break;
			case SERVER:
				switch(Protocol.getValue(context.getProtocol())) {
				case ADMIN:
					adapter = new AdminServer(context);
					break;
				case CERT:
					adapter = new CertServer(context);
					break;
				case CISCO:
					if (Env.isWindows()) {     // for test
						adapter = new CiscoServer(context);
						break;
					} else {
						throw new EAIException(context.getAdapterName() + " | 'CISCO' Protocol does not support 'SERVER' socket type.");
					}
				case ECHO:
					adapter = new EchoServer(context);
					break;
				case ENVELOP:  // 20100423 JGY
					adapter = new EnvelopServer(context);
					break;					
				case FIXED_LENGTH_HEADER:
					adapter = new FixedHeaderServer(context);
					break;
				case FIXED_LENGTH_PAYLOAD:
					adapter = new FixedPayloadServer(context);
					break;
				case VARIABLE_LENGTH_HEADER:  //20121030 KWON SE HWAN
					adapter = new VariableHeaderServer(context);
					break;
				case INISAFE: // 한국은행 신한은망
					adapter = new InisafeServer(context);
					break;
				case INISAFE_2020: // 한국은행 신한은망 NEW Version
					adapter = new Inisafe2020Server(context);
					break;
				case INISAFE_NATN: // 한국은행 국고망
					adapter = new InisafeNatnPayloadServer(context);
					break;
				case INISAFE_PAYLOAD:  // 20100510 JGY // 정책금융공사
					adapter = new InisafePayloadServer(context);
					break;
				case HTTP:
					adapter = new HttpServer(context);
					break;
				case PROXY:
					adapter = new ProxyServer(context);
					break;
				case TCSEED:   // 20101213 JGY
					adapter = new TcseedServer(context);
					break;
				case UDP_FIXED_LENGTH_HEADER:
				case UDP_FIXED_LENGTH_PAYLOAD:
					adapter = new UdpServer(context);
					break;
				case XECURE:
					adapter = new XecureServer(context);
					break;
				case XECURE2:
					adapter = new Xecure2Server(context);
					break;
				case XECURE3:  // 20100901 JGY
					adapter = new Xecure3Server(context);
					break;
				case LAW:
					adapter = new LawServer(context);
					break;					
				case DELIMITER:
					adapter = new DelimiterServer(context);
					break;	
				case INICIS:
					adapter = new InicisServer(context);
					break;	
				case APPEND:
					adapter = new AppendServer(context);
					break;					
				case XC3EPB:
					adapter = new Xc3EpbServer(context);
					break;					
				case DYNAMIC_OFFSET:
					adapter = new DynamicOffsetServer(context);
					break;					
				case UNKNOWN:
				default:
					throw new EAIException("unknown protocol : " + context.getProtocol());			
				}
				break;
			case CLIENT:
				switch(Protocol.getValue(context.getProtocol())) {
				case ADMIN:
				case CERT:
					if (Env.isWindows()) {   // for test
						adapter = new CertClient(context);
						break;
					} else {
						throw new EAIException(context.getAdapterName() + " | 'CERT' Protocol does not support 'CLIENT' socket type.");
					}	
				case CISCO:
					adapter = new CiscoClient(context);
					break;
				case ECHO:
					adapter = new EchoClient(context);
					break;
				case ENVELOP:
					adapter = new EnvelopClient(context);
					break;						
				case FIXED_LENGTH_HEADER:
					adapter = new FixedHeaderClient(context);
					break;
				case FIXED_LENGTH_PAYLOAD:
					adapter = new FixedPayloadClient(context);
					break;
				case VARIABLE_LENGTH_HEADER: 
					adapter = new VariableHeaderClient(context);
					break;
				case INISAFE: // 한국은행 신한은망
					adapter = new InisafeClient(context);
					break;
				case INISAFE_2020: // 한국은행 신한은망 New Version
					adapter = new Inisafe2020Client(context);
					break;
				case INISAFE_NATN:  // 한국은행 국고망
					adapter = new InisafeNatnPayloadClient(context);
					break;					
				case INISAFE_PAYLOAD:  // 정책금융공사
					adapter = new InisafePayloadClient(context);
					break;					
				case HTTP:
				case PROXY:
					throw new EAIException(context.getAdapterName() + " | '" + context.getProtocol() + "' Protocol does not support 'CLIENT' socket type.");
				case TCSEED:  
					adapter = new TcseedClient(context);
					break;	
				case UDP_FIXED_LENGTH_HEADER:
				case UDP_FIXED_LENGTH_PAYLOAD:
					adapter = new UdpClient(context);
					break;
				case XECURE:
					adapter = new XecureClient(context);
					break;
				case XECURE2:
					adapter = new Xecure2Client(context);
					break;
				case XECURE3:
					adapter = new Xecure3Client(context);
					break;
				case LOGIN:
					adapter = new LoginClient(context);
					break;
				case LAZY:
					adapter = new LazyClient(context);
					break;
				case BIND:
					adapter = new BindClient(context);
					break;					
				case LAW:
					adapter = new LawClient(context);
					break;
				case DELIMITER:
					adapter = new DelimiterClient(context);
					break;	
				case INICIS:
					adapter = new InicisClient(context);
					break;	
				case APPEND:
					adapter = new AppendClient(context);
					break;	
				case XC3EPB:
					adapter = new Xc3EpbClient(context);
					break;	
				case DYNAMIC_OFFSET:
					adapter = new DynamicOffsetClient(context);
					break;							
				case UNKNOWN:
				default:
					throw new EAIException("unknown protocol : " + context.getProtocol());			
				}
				break;
			case UNKNOWN:
			default:
				throw new EAIException("unknown socket type : " + context.getSocketType());	
			}			
			
			SocketAdapterManager.getInstance().addAdapter(adapter);

			return adapter;
		} catch (EAIException e) {
			throw e;
		} catch (Exception e) {
			throw new EAIException(e);
		}
	}
		
	// START A SOCKET ADAPTER CONFIGURATION
	public static ISocketAdapter createSocketAdapter(AdapterVO config) throws Exception {
		return createSocketAdapter(createContext(config));
	}
	
	public static SocketAdapterContext createContext(AdapterVO config) throws Exception {
		SocketAdapterContext context = new SocketAdapterContext();
		context.setAdapterGroupName(config.getAdapterGroupName());
		context.setAdapterName(config.getName());

		//PropManager manager = PropManager.getInstance();
		AdapterPropManager manager = AdapterPropManager.getInstance();
		Properties prop = manager.getProperties(config.getPropGroupName());
//		String errMsg = null;
		
		/**
		 * protocol
		 */
		if (!"".equals(prop.getProperty(Constants.PROTOCOL, "").trim())) {
			context.setProtocol(prop.getProperty(Constants.PROTOCOL, context.getProtocol()).trim());
			if (!context.getProtocol().matches("(FIXED_LENGTH_HEADER|FIXED_LENGTH_PAYLOAD|VARIABLE_LENGTH_HEADER|CISCO|CERT|INISAFE|INISAFE_2020|INISAFE_NATN|INISAFE_PAYLOAD|EGSEED|TCSEED|ADMIN|HTTP|OBJECT|UDP_FIXED_LENGTH_HEADER|UDP_FIXED_LENGTH_PAYLOAD|XECURE|XECURE2|XECURE3|ENVELOP|LOGIN|LAZY|BIND|APPEND|DELIMITER|INICIS|XC3EPB|DYNAMIC_OFFSET|)")) {
				throw new Exception(context.getAdapterName() + " | protocol must be one of (FIXED_LENGTH_HEADER|FIXED_LENGTH_PAYLOAD|VARIABLE_LENGTH_HEADER|CISCO|CERT|INISAFE|INISAFE_2020|INISAFE_NATN|INISAFE_PAYLOAD|EGSEED|TCSEED|ADMIN|HTTP|OBJECT|UDP_FIXED_LENGTH_HEADER|UDP_FIXED_LENGTH_PAYLOAD|XECURE|XECURE2|XECURE3|ENVELOP|LOGIN|LAZY|BIND|APPEND|DELIMITER|INICIS|XC3EPB|DYNAMIC_OFFSET|), but - '" + context.getProtocol() + "'");
			}
		} else {
			// for backward compatibility
			if ("CISCO".equals(prop.getProperty(Constants.LL_FIELD_TYPE))) {
				context.setProtocol("CISCO");
			}
			logger.warn(context.getAdapterName() + " | 'protocol' is not specified. use default : " + context.getProtocol());
		}

		/**
		 * adapter.group.name
		 */
		if (prop.getProperty(Constants.ADAPTER_GROUP_NAME) == null) {
			throw new Exception(context.getAdapterName() + " | adapter group name is null");
		}
		
		/**
		 * bound.usage
		 */
		if (!"".equals(prop.getProperty(Constants.BOUND_USAGE, "").trim())) {
			context.setBoundUsage(prop.getProperty(Constants.BOUND_USAGE, context.getBoundUsage()).trim());
			if ("INBOUND,OUTBOUND,IOBOUND".indexOf(context.getBoundUsage()) < 0) {
				throw new Exception(context.getAdapterName() + " | " + Constants.BOUND_USAGE + " must be one of [INBOUND|OUTBOUND|IOBOUND], but - '" + context.getBoundUsage() + "'");
			}
		}

		/**
		 * socket.type
		 */
		if (!"".equals(prop.getProperty(Constants.SOCKET_TYPE, "").trim())) {
			if ("ADMIN".equals(context.getSocketType()))
				context.setSocketType("SERVER");

			context.setSocketType(prop.getProperty(Constants.SOCKET_TYPE, context.getSocketType()).trim());
			if ("SERVER,CLIENT".indexOf(context.getSocketType()) < 0) {
				throw new Exception(context.getAdapterName() + " | " + Constants.SOCKET_TYPE + " must be one of [SERVER|CLIENT], but - '" + context.getSocketType() + "'");
			}
		}

		/**
		 * permanent
		 */
		if (!"".equals(prop.getProperty(Constants.PERMANENT, "").trim())) {
			context.setPermanent(prop.getProperty(Constants.PERMANENT, context.getPermanent()).trim());
			if (context.getPermanent() == null || !context.getPermanent().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.PERMANENT + " must be one of [Y|N], but - '" + context.getPermanent() + "'");
			}
		}
		
		/**
		 * blocking
		 */
		if (!"".equals(prop.getProperty(Constants.BLOCKING, "").trim())) {
			context.setBlocking(prop.getProperty(Constants.BLOCKING, context.getBlocking()).trim());
			if (context.getBlocking() == null || !context.getBlocking().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.BLOCKING + " must be one of [Y|N], but - '" + context.getBlocking() + "'");
			}
		}
		
		/**
		 * host.name | port.number
		 */
		context.setHostName(prop.getProperty(Constants.HOST_NAME, context.getHostName()).trim());

		context.setPortNumber(Integer.parseInt(prop.getProperty(Constants.PORT_NUMBER, Integer
				.toString(context.getPortNumber())).trim()));

		/**
		 * local.host.name | local.port.number (CLIENT type || PROXY protocol)
		 */
		if (context.getSocketType().equals(SocketAdapterContext.CLIENT_SOCKET)) {
			if (!"".equals(prop.getProperty(Constants.LOCAL_PORT_NUMBER, "").trim())) {
				try {
					context.setLocalPortNumber(Integer.parseInt(prop.getProperty(Constants.LOCAL_PORT_NUMBER, Integer.toString(context.getLocalPortNumber())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LOCAL_PORT_NUMBER + " | " + e.getMessage());
				}
			}
			
			if (!"".equals(prop.getProperty(Constants.LOCAL_HOST_NAME, "").trim())) {
				context.setLocalHostName(prop.getProperty(Constants.LOCAL_HOST_NAME, context.getLocalHostName()).trim());
			}
		}
		
		/**
		 * max.connection
		 */
		if (!"".equals(prop.getProperty(Constants.MAX_CONNECTION, "").trim())) {
			try {
				context.setMaxConnection(Integer.parseInt(prop.getProperty(Constants.MAX_CONNECTION, Integer.toString(context.getMaxConnection())).trim()));
				if (context.getSocketType().equals(SocketAdapterContext.CLIENT_SOCKET) && context.getMaxConnection() < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.MAX_CONNECTION + "(" + context.getMaxConnection() + ") < 0");
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.MAX_CONNECTION + " | " + e.getMessage());
			}		
		} else {
			if (context.isServer()) {
				context.setMaxConnection(0);
			}
		}
		
		/**
		 * connection.limit.per.ip
		 */
		if (!"".equals(prop.getProperty(Constants.CONN_LIMIT_PER_IP, "").trim())) {
			try {
				context.setConnLimitPerIp(Integer.parseInt(prop.getProperty(Constants.CONN_LIMIT_PER_IP, Integer.toString(context.getConnLimitPerIp())).trim()));
				if (context.getConnLimitPerIp() < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.CONN_LIMIT_PER_IP + " must be > 0, but - '" + context.getConnLimitPerIp() + "'");
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.CONN_LIMIT_PER_IP + " | " + e.getMessage());
			}
		}
		
		/**
		 * max.thread
		 */
		if (!"".equals(prop.getProperty(Constants.MAX_THREAD, "").trim())) {
			try {
				context.setMaxThread(Integer.parseInt(prop.getProperty(Constants.MAX_THREAD, Integer.toString(context.getMaxThread())).trim()));
				if (context.getMaxThread() < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " must be > 0, but - '" + context.getMaxThread() + "'");
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " | " + e.getMessage());
			}
		// for backward compatibility - old socket
		} else if (!"".equals(prop.getProperty("max.session", "").trim())) {
			logger.warn(context.getAdapterName() + " | old socket property | change property name 'max.session' -> '" + Constants.MAX_THREAD + "'");
			try {
				context.setMaxThread(Integer.parseInt(prop.getProperty("max.session", Integer.toString(context.getMaxThread())).trim()));
				if (context.getMaxThread() < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " must be > 0, but - '" + context.getMaxThread() + "'");
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " | " + e.getMessage());
			}
		}
		
		/**
		 * timeout
		 */
		if (!"".equals(prop.getProperty(Constants.TIMEOUT, "").trim())) {
			try {
				context.setTimeout(Integer.parseInt(prop.getProperty(Constants.TIMEOUT, Integer.toString(context.getTimeout())).trim()));
				if (context.getTimeout() < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.TIMEOUT + " must be > 0, but - '" + context.getTimeout() + "'");
				}
				
				if (context.getTimeout() > 600) {
					logger.warn(context.getAdapterName() + " | timeout is to big '" + context.getTimeout() + "' -> timeout is reset to 600 (sec)");
					context.setTimeout(600);
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.TIMEOUT + " | " + e.getMessage());
			}
		}

		
		/**
		 * idle timeout
		 */
		if (!"".equals(prop.getProperty(Constants.IDLE_TIMEOUT, "").trim())) {
			try {
				context.setIdleTimeout(Integer.parseInt(prop.getProperty(Constants.IDLE_TIMEOUT, Integer.toString(context.getIdleTimeout())).trim()));
				// idle.timeout 을 설정하지 않을 경우, 0으로 처리되므로 동일하게 체크하도록 수정함
				// 다만, L4에 의해 비정상 종료되는 경우가 발생할 수 있으므로 유의해서 사용해야 함
				if (context.getIdleTimeout() == 0) {
					logger.warn(context.getAdapterName() + " | idle.timeout =" + context.getIdleTimeout() + ", session will not close");
				}
				else {
					if (context.getIdleTimeout() < 0) {
						throw new Exception(context.getAdapterName() + " | " + Constants.IDLE_TIMEOUT + " must be > 0, but - '" + context.getIdleTimeout() + "'");
					}
					
					if (context.getIdleTimeout() <= context.getTimeout()) {
						throw new Exception(context.getAdapterName() + " | idle.timeout (" + context.getIdleTimeout() + " sec) must be greater than timeout(" + context.getTimeout() + " sec)");
					}
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.IDLE_TIMEOUT + " | " + e.getMessage());
			}
		} 
		
		/**
		 * response.type
		 */
		if (!"".equals(prop.getProperty(Constants.RESPONSE_TYPE, "").trim())) {
			context.setResponseType(prop.getProperty(Constants.RESPONSE_TYPE, context.getResponseType()).trim());
			if ("SYNC,ASYN".indexOf(context.getResponseType()) < 0) {
				throw new Exception(context.getAdapterName() + " | " + Constants.RESPONSE_TYPE + " must be one of (SYNC|ASYN), but - '" + context.getResponseType() + "'");
			}
		}

		/**
		 * socket.reuse
		 */
		if (!"".equals(prop.getProperty(Constants.SOCKET_REUSE, "").trim())) {
			context.setSocketReuse(prop.getProperty(Constants.SOCKET_REUSE, context.getSocketReuse()).trim());
			if ("Y,N".indexOf(context.getSocketReuse()) < 0) {
				throw new Exception(context.getAdapterName() + " | " + Constants.SOCKET_REUSE + " must be one of [Y|N], but - '" + context.getSocketReuse() + "'");
			}
		}
		
		/**
		 * ack.support
		 */
		if (!"".equals(prop.getProperty(Constants.ACK_SUPPORT, "").trim())) {
			context.setAckSupport(prop.getProperty(Constants.ACK_SUPPORT, context.getAckSupport()).trim());
			if ("Y,N".indexOf(context.getAckSupport()) < 0) {
				throw new Exception(context.getAdapterName() + " | " + Constants.ACK_SUPPORT + " must be one of [Y|N], but - '" + context.getAckSupport() + "'");
			}
		}
		
		/**
		 * acl
		 */
		if (!"".equals(prop.getProperty(Constants.ACL_LIST, "").trim())) {
			context.setAclList(prop.getProperty(Constants.ACL_LIST , context.getAclList()).trim());
		}
		
		/**
		 * validation.rule
		 */
		if (!"".equals(prop.getProperty(Constants.VALIDATION_RULE, "").trim())) {
			context.setValidationRule(prop.getProperty(Constants.VALIDATION_RULE, context.getValidationRule()).trim());
		}		
		
		/**
		 * datacontrol.rule
		 */
		if (!"".equals(prop.getProperty(Constants.DATACONTROL_RULE, ""))) {
			context.setDataControlRule(prop.getProperty(Constants.DATACONTROL_RULE, context.getDataControlRule()));
		}	
		
		/**
		 * business.work.class.code
		 */
		context.setBwkClsCd(prop.getProperty(Constants.WORK_CLASS_CODE, context.getBwkClsCd()).trim());

		/**
		 * trace.level
		 */
		if (!"".equals(prop.getProperty(Constants.TRACE_LEVEL, "").trim())) {
			try {
				context.setTraceLevel(Integer.parseInt(prop.getProperty(Constants.TRACE_LEVEL, Integer
						.toString(context.getTraceLevel())).trim()));
				if ("0,1,2,3".indexOf(Integer.toString(context.getTraceLevel())) < 0) {
					throw new Exception(context.getAdapterName() + " | " + Constants.TRACE_LEVEL + " must be one of [0|1|2|3], but - '" + context.getTraceLevel() + "'");
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.TRACE_LEVEL + " | " + e.getMessage());
			}
		}			

		/**
		 * description
		 */
		context.setDescription(prop.getProperty(Constants.DESCRIPTION, context.getDescription()).trim());

		
		/**
		 * polling 
		 *     - polling.use               : Y|N
		 *     - polling.role              : SEDNER|RECEIVER
		 *     - polling.oneway            : Y|N
		 *     - polling.timeout           : SENDER   (default:client)
		 *     - polling.request           : SENDER   (default:client)
		 *     - polling.response.pattern  : SENDER   (default:client)
		 *     - polling.request.pattern   : RECEIVER (default:server)
		 *     - polling.replacement       : RECEIVER (default:server)
		 */
		
		/**
		 * polling.use
		 */
		if (!"".equals(prop.getProperty(Constants.POLLING_USE, "").trim())) {
			context.setPollingUse(prop.getProperty(Constants.POLLING_USE, context.getPollingUse()).trim());
			if (!context.getPollingUse().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_USE + " must be one of [Y|N], but - '" + context.getPollingUse() + "'");
			}
		}

		if (context.isPollingUse()) {
			/**
			 * polling.role
			 */
			// JGY 20100510
			String pollingRole = prop.getProperty(Constants.POLLING_ROLE, "").trim();
			if ("".equals(pollingRole)) {
				if (context.isClient()) {
					context.setPollingRole("SENDER");
				} else {
					context.setPollingRole("RECEIVER");
				}
			} else {
//				if (!context.getPollingRole().matches("(SENDER|RECEIVER)")) {
			    if (!pollingRole.matches("(SENDER|RECEIVER)")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_ROLE + " must be one of (SENDER|RECEIVER), but -> '" + pollingRole + "'");
				}
				context.setPollingRole(prop.getProperty(Constants.POLLING_ROLE, context.getPollingRole()).trim());
			}
			
			/**
			 * polling.oneway
			 */
			if (!"".equals(prop.getProperty(Constants.POLLING_ONEWAY, "").trim())) {
				context.setPollingOneway(prop.getProperty(Constants.POLLING_ONEWAY, context.getPollingOneway()).trim());
			}

			/**
			 * polling.timeout
			 */
			if (!"".equals(prop.getProperty(Constants.POLLING_TIMEOUT, "").trim())) {
				try {
					context.setPollingTimeout(Integer.parseInt(prop.getProperty(Constants.POLLING_TIMEOUT, Integer.toString(context.getPollingTimeout())).trim()));
					if (context.getPollingTimeout() <= 0) {
						throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " must be > 0, but - '" + context.getPollingTimeout() + "'");
					}
					if (context.getPollingTimeout() <= context.getTimeout()) {
						throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " must be > timeout(" + context.getTimeout() + ")");
					}
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " | " + e.getMessage(), e);
				}
			}
		
			/**
			 * polling.request
			 */
			if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST, ""))) ) {
				context.setPollingRequest( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST, context.getPollingRequest())) );
			}
			
			/**
			 * polling.request.pattern
			 */
			if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST_PATTERN, ""))) ) {
				context.setPollingRequestPattern( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST_PATTERN, context.getPollingRequestPattern())) );
			}

			/**
			 * polling.replacement
			 */
			if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REPLACEMENT, ""))) ) {
				context.setPollingReplacement ( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REPLACEMENT, context.getPollingReplacement())) );
			}

			/**
			 * polling.response.pattern
			 */
			if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_RESPONSE_PATTERN, ""))) ) {
				context.setPollingResponsePattern( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_RESPONSE_PATTERN, context.getPollingResponsePattern())) );
			}
		}
		
		
		/**KSH
		 * init.msg.use
		 */
		if (!"".equals(prop.getProperty(Constants.INIT_MSG_USE, "").trim())) {
			context.setInitMsgUse(prop.getProperty(Constants.INIT_MSG_USE, context.getInitMsgUse()).trim());
			if (!context.getInitMsgUse().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.INIT_MSG_USE + " must be one of [Y|N], but - '" + context.getInitMsgUse() + "'");
			}
		}

		if (context.isInitMsgUse()) {
			/**
			 * init.msg.role
			 */
			// KSH
			String initMsgRole = prop.getProperty(Constants.INIT_MSG_ROLE, "").trim();
			if ("".equals(initMsgRole)) {
				if (context.isClient()) {
					context.setInitMsgRole("SENDER");
				} else {
					context.setInitMsgRole("RECEIVER");
				}
			} else {
			    if (!initMsgRole.matches("(SENDER|RECEIVER)")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.INIT_MSG_ROLE + " must be one of (SENDER|RECEIVER), but -> '" + initMsgRole + "'");
				}
				context.setInitMsgRole(prop.getProperty(Constants.INIT_MSG_ROLE, context.getInitMsgRole()).trim());
			}
			
			/**
			 * init.msg.request
			 */
			if (!"".equals(prop.getProperty(Constants.INIT_MSG_REQUEST, "").trim())) {
				context.setInitMsgRequest(prop.getProperty(Constants.INIT_MSG_REQUEST, context.getInitMsgRequest()).trim());
			}
			
			/**
			 * init.msg.request.pattern
			 */
			if (!"".equals(prop.getProperty(Constants.INIT_MSG_REQUEST_PATTERN, "").trim())) {
				context.setInitMsgRequestPattern(prop.getProperty(Constants.INIT_MSG_REQUEST_PATTERN, context.getInitMsgRequestPattern()).trim());
			}

			/**
			 * init.msg.replacement
			 */
			if (!"".equals(prop.getProperty(Constants.INIT_MSG_REPLACEMENT, "").trim())) {
				context.setInitMsgReplacement(prop.getProperty(Constants.INIT_MSG_REPLACEMENT, context.getInitMsgReplacement()).trim());
			}

			/**
			 * init.msg.response.pattern
			 */
			if (!"".equals(prop.getProperty(Constants.INIT_MSG_RESPONSE_PATTERN, "").trim())) {
				context.setInitMsgResponsePattern(prop.getProperty(Constants.INIT_MSG_RESPONSE_PATTERN, context.getInitMsgResponsePattern()).trim());
			}
		}
		
		
		/**
		 * FIXED_LENGTH_HEADER, UDP_FIXED_LENGTH_HEADER, XECURE, XECURE2, XECURE3, EGSEED, ENVELOP protocol only
		 * VARIABLE_LENGTH_HEADER add 2012.10.30 Kwon Se Hwan
		 *     - ll.field.type
		 *     - ll.field.offset
		 *     - ll.field.length
		 *     - ll.field.include
		 *     - ll.include
		 */
    	if ("FIXED_LENGTH_HEADER".equals(context.getProtocol()) 
     	 || "VARIABLE_LENGTH_HEADER".equals(context.getProtocol()) 
    	 || "UDP_FIXED_LENGTH_HEADER".equals(context.getProtocol()) 
		 || "EGSEED".equals(context.getProtocol())
		 || "TCSEED".equals(context.getProtocol()) 
		 || "ENVELOP".equals(context.getProtocol())
		 || "XECURE".equals(context.getProtocol())
		 || "XECURE2".equals(context.getProtocol())
    	 || "XECURE3".equals(context.getProtocol())
    	 || "LOGIN".equals(context.getProtocol())
    	 || "LAZY".equals(context.getProtocol())
    	 || "BIND".equals(context.getProtocol())
    	 || "APPEND".equals(context.getProtocol())
    	 || "INICIS".equals(context.getProtocol())
    	 || "XC3EPB".equals(context.getProtocol())
    	 || "DYNAMIC_OFFSET".equals(context.getProtocol())
    	 ) {

    		if (!"".equals(prop.getProperty(Constants.LL_FIELD_TYPE, "").trim())) {
				context.setLlFieldType(prop.getProperty(Constants.LL_FIELD_TYPE, context.getLlFieldType()).trim());
				if (!context.getLlFieldType().matches("(BIN|CHAR|NONE)")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_TYPE + " must be one of (BIN|CHAR|NONE), but - '" + context.getLlFieldType() + "'");
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlFieldType("CHAR");
    		}
	
			/**
			 * ll.field.offset
			 */
			if (!"".equals(prop.getProperty(Constants.LL_FIELD_OFFSET, "").trim())) {
				try {
					context.setLlFieldOffset(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_OFFSET, 
							Integer.toString(context.getLlFieldOffset())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_OFFSET + " | " + e.getMessage());
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlFieldOffset(0);
 			}
			
			/**
			 * ll.field.length
			 */
    		if (!"".equals(prop.getProperty(Constants.LL_LENGTH_ADJUST, "").trim())) {
				try {
					context.setLlLenAdjust(Integer.parseInt(prop.getProperty(Constants.LL_LENGTH_ADJUST,
							Integer.toString(context.getLlFieldLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_LENGTH_ADJUST + " | " + e.getMessage());
				}
    		}
			
			/**
			 * ll.field.length
			 */
    		if (!"".equals(prop.getProperty(Constants.LL_FIELD_LENGTH, "").trim())) {
				try {
					context.setLlFieldLength(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH,
							Integer.toString(context.getLlFieldLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_LENGTH + " | " + e.getMessage());
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlFieldLength(7);
    		}
			
			/**
			 * ll.field.include
			 */
			if (!"".equals(prop.getProperty(Constants.LL_FIELD_INCLUDE, "").trim())) {
				context.setLlFieldInclude(prop.getProperty(Constants.LL_FIELD_INCLUDE, 
						context.getLlFieldInclude()).trim());
				if (!context.getLlFieldInclude().matches("[Y|N]")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_INCLUDE + " must be one of [Y|N], but - '" + context.getLlFieldInclude() + "'");
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlFieldInclude("N");
			}
			
			/**
			 * ll.offset.exclude
			 */
			if (!"".equals(prop.getProperty(Constants.LL_OFFSET_EXCLUDE, "").trim())) {
				context.setLlOffsetExclude(prop.getProperty(Constants.LL_OFFSET_EXCLUDE, 
						context.getLlOffsetExclude()).trim());
				if (!context.getLlOffsetExclude().matches("[Y|N]")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_OFFSET_EXCLUDE + " must be one of [Y|N], but - '" + context.getLlOffsetExclude() + "'");
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlOffsetExclude("N");
			}
			
			/**
			 * ll.include
			 */
			if (!"".equals(prop.getProperty(Constants.LL_INCLUDE, "").trim())) {
				context.setLlInclude(prop.getProperty(Constants.LL_INCLUDE, 
						context.getLlInclude()).trim());
				if (!context.getLlFieldInclude().matches("[Y|N]")) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_INCLUDE + " must be one of [Y|N], but - '" + context.getLlInclude() + "'");
				}
    		} else if ("XECURE".equals(context.getProtocol())) {
    			context.setLlInclude("Y");
			}
			
	 			
	 		/** 
			 * recv.header.length   2012.10.30 Kwon Se Hwan
 			 */
			if (!"".equals(prop.getProperty(Constants.RECV_HEADER_LENGTH, "").trim())) {
				try {
					context.setRecvHeaderLength(Integer.parseInt(prop.getProperty(Constants.RECV_HEADER_LENGTH,
							Integer.toString(context.getRecvHeaderLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.RECV_HEADER_LENGTH + " | " + e.getMessage());
				}
    		} 
			
			/**
			 * send.header.length    2012.10.30 Kwon Se Hwan
			 */
			if (!"".equals(prop.getProperty(Constants.SEND_HEADER_LENGTH, "").trim())) {
				try {
					context.setSendHeaderLength(Integer.parseInt(prop.getProperty(Constants.SEND_HEADER_LENGTH,
							Integer.toString(context.getSendHeaderLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.SEND_HEADER_LENGTH + " | " + e.getMessage());
				}
    		} 
	
    	}
    	
    	
		/**
		 * FIXED_LENGTH_PAYLOAD, UDP_FIXED_LENGTH_PAYLOAD, INISAFE_PAYLOAD protocol only
		 *     - send.payload.length
		 *     - recv.payload.length
		 */
    	if ("FIXED_LENGTH_PAYLOAD".equals(context.getProtocol())
    	 || "INISAFE_PAYLOAD".equals(context.getProtocol())		// 20100510 JGY
    	 || "UDP_FIXED_LENGTH_PAYLOAD".equals(context.getProtocol())) {
			/**
			 * send.payload.length
			 */
    		if (!"".equals(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, "").trim())) {
				try {
					context.setSendPayloadLength(Integer.parseInt(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH,
							Integer.toString(context.getSendPayloadLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.SEND_PAYLOAD_LENGTH + " | " + e.getMessage());
				}
    		}
			/**
			 * recv.payload.length
			 */
    		if (!"".equals(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, "").trim())) {
				try {
					context.setRecvPayloadLength(Integer.parseInt(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH,
							Integer.toString(context.getRecvPayloadLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.RECV_PAYLOAD_LENGTH + " | " + e.getMessage());
				}
    		}
    	}

    	
		/**
		 * SSL
		 *     - ssl.use
		 *     - ssl.cert.store
		 *     - ssl.cert.password
		 */
		if (!"".equals(prop.getProperty(Constants.SSL_USE, "").trim())) {
			context.setSslUse(prop.getProperty(Constants.SSL_USE, context.getSslUse()).trim());
			/*
			if (!context.getSslUse().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.SSL_USE + " must be one of [Y|N], but - '" + context.getSslUse() + "'");
			}
			*/
	
			context.setSslCertStore(prop.getProperty(Constants.SSL_CERT_STORE, context.getSslCertStore()).trim());
	
			context.setSslCertPassword(prop.getProperty(Constants.SSL_CERT_PASSWORD, context.getSslCertPassword()).trim());
		}

		/**
		 * INISAFE, INISAFE_NATN protocol only
		 */    	
    	if ( "INISAFE".equals(context.getProtocol()) || "INISAFE_2020".equals(context.getProtocol())) {			
			context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, 
					context.getInisafeConfigPath()).trim());

			context.setInisafeRelatedAdapterGroups(prop.getProperty(Constants.INISAFE_RELATED_ADAPTER_GROUPS, 
					context.getInisafeRelatedAdapterGroups()).trim());

			if (!"".equals(prop.getProperty(Constants.INISAFE_START_MESSAGE, "").trim())) {
				context.setInisafeStartMessage(prop.getProperty(Constants.INISAFE_START_MESSAGE, 
						context.getInisafeStartMessage()).trim());
			}

			if (!"".equals(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, "").trim())) {
				context.setInisafeStopMessage(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, 
						context.getInisafeStopMessage()).trim());
			}
    	}
    	else if ( "INISAFE_NATN".equals(context.getProtocol()) ) {			
			context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, 
					context.getInisafeConfigPath()).trim());

			context.setInisafeRelatedAdapterGroups(prop.getProperty(Constants.INISAFE_RELATED_ADAPTER_GROUPS, 
					context.getInisafeRelatedAdapterGroups()).trim());

			if (!"".equals(prop.getProperty(Constants.INISAFE_START_MESSAGE, "").trim())) {
				context.setInisafeStartMessage(prop.getProperty(Constants.INISAFE_START_MESSAGE, 
						context.getInisafeStartMessage()).trim());
			}

			if (!"".equals(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, "").trim())) {
				context.setInisafeStopMessage(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, 
						context.getInisafeStopMessage()).trim());
			}
			
			/**
			 * send.payload.length
			 */
    		if (!"".equals(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, "").trim())) {
				try {
					context.setSendPayloadLength(Integer.parseInt(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH,
							Integer.toString(context.getSendPayloadLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.SEND_PAYLOAD_LENGTH + " | " + e.getMessage());
				}
    		}
    		else {
    			context.setSendPayloadLength(460);
    		}
			/**
			 * recv.payload.length
			 */
    		if (!"".equals(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, "").trim())) {
				try {
					context.setRecvPayloadLength(Integer.parseInt(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH,
							Integer.toString(context.getRecvPayloadLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.RECV_PAYLOAD_LENGTH + " | " + e.getMessage());
				}
    		}
    		else {
    			context.setRecvPayloadLength(460);
    		}
    		
    		/**
			 * ll.field.length
			 */
    		if (!"".equals(prop.getProperty(Constants.LL_FIELD_LENGTH, "").trim())) {
				try {
					context.setLlFieldLength(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH,
							Integer.toString(context.getLlFieldLength())).trim()));
				} catch (NumberFormatException e) {
					throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_LENGTH + " | " + e.getMessage());
				}
    		} else {
    			context.setLlFieldLength(0);
    		}
    	}
    	
		/**
		 * INISAFE_PAYLOAD protocol only - 20100510 JGY
		 */    	
    	if ("INISAFE_PAYLOAD".equals(context.getProtocol())) {			
			context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, 
					context.getInisafeConfigPath()).trim());
			
			context.setInisafeIdPassword(prop.getProperty(Constants.INISAFE_ID_PASSWORD, 
					context.getInisafeIdPassword()).trim());
    	}
    	
    	/**
		 * sms.running.time
		 */
		if (!"".equals(prop.getProperty(Constants.SMS_RUNNING_TIME, "").trim())) {
			context.setSmsRunningTime(prop.getProperty(Constants.SMS_RUNNING_TIME , context.getSmsRunningTime()).trim());
		}
		
		/**
		 * XECURE protocol only
		 *     - xecure.type
		 *     - xecure.config.path
		 *     - xecure.remote.cert
		 */
    	
    	if ("XECURE".equals(context.getProtocol())) {
			context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType()));
			if (!context.getXecureType().matches("(BASIC|FIXED|WELCOME|ENVELOPE|FIXEDHEADER)")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.XECURE_TYPE + " must be one of (BASIC|FIXED|WELCOME|ENVELOPE|FIXEDHEADER), but - '" + context.getXecureType() + "'");
			}

			context.setXecureConfigPath(prop.getProperty(Constants.XECURE_CONFIG_PATH, 
					context.getXecureConfigPath()).trim());
			
			context.setXecureRemoteCert(prop.getProperty(Constants.XECURE_REMOTE_CERT, 
					context.getXecureRemoteCert()).trim());
    	}
    	
		/**
		 * XECURE2 protocole only
		 * - xecure2.config.path
		 * - xecure2.sm.ip
		 * - xecure2.sm.port 
		 */
		if ("XECURE2".equals(context.getProtocol())) {
			if (!"".equals(prop.getProperty(Constants.XECURE2_CONFIG_PATH, "").trim())) {
				context.setXecure2ConfigPath(prop.getProperty(Constants.XECURE2_CONFIG_PATH, 
						context.getXecure2ConfigPath()).trim());
			}
			
			if (!"".equals(prop.getProperty(Constants.XECURE2_SM_IP, "").trim())) {
				context.setXecure2SmIp(prop.getProperty(Constants.XECURE2_SM_IP, 
						context.getXecure2SmIp()).trim());
			}
			
			try {
				if (!"".equals(prop.getProperty(Constants.XECURE2_SM_PORT, "").trim())) {
					context.setXecure2SmPort(Integer.parseInt(prop.getProperty(Constants.XECURE2_SM_PORT, 
							Integer.toString(context.getXecure2SmPort())).trim()));
				}
			} catch (NumberFormatException e) {
				throw new Exception(context.getAdapterName() + " | " + Constants.XECURE2_SM_PORT + " | " + e.getMessage());
			}
			
			// use CISCO interface only
			if (!"".equals(prop.getProperty(Constants.XECURE_TYPE, "").trim())) {
				context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType()));
			}
		}
		
		/**
		 * XECURE3 protocol only
		 *     - xecure3.type
		 *     - xecure3.config.path
		 *     - xecure3.remote.cert
		 */
    	
    	if ("XECURE3".equals(context.getProtocol())) {
			context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType()));
			if (!context.getXecureType().matches("(ENVELOPE)")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.XECURE_TYPE + " must be one of (ENVELOPE), but - '" + context.getXecureType() + "'");
			}
			
			if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_STORE, "").trim())) {
				context.setXecure3CertStore(prop.getProperty(Constants.XECURE3_CERT_STORE, 
						context.getXecure3CertStore()).trim());
			}

			if (!"".equals(prop.getProperty(Constants.XECURE3_SERVER_CERT, "").trim())) {
				context.setXecure3ServerCert(prop.getProperty(Constants.XECURE3_SERVER_CERT, 
						context.getXecure3ServerCert()).trim());
			}
			
			if (!"".equals(prop.getProperty(Constants.XECURE3_CLIENT_CERT, "").trim())) {
				context.setXecure3ClientCert(prop.getProperty(Constants.XECURE3_CLIENT_CERT, 
						context.getXecure3ClientCert()).trim());
			}
			
			if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_KEY, "").trim())) {
				context.setXecure3CertKey(prop.getProperty(Constants.XECURE3_CERT_KEY, 
						context.getXecure3CertKey()).trim());
			}
			
			if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_PASSWORD, "").trim())) {
				context.setXecure3CertPassword(prop.getProperty(Constants.XECURE3_CERT_PASSWORD, 
						context.getXecure3CertPassword()).trim());
			}
    	}
    	/**
    	 * XC3EPB protocol only
    	 *     - xc3epb.password
    	 *     - xc3epb.config.path
    	 */
    	
    	if ("XC3EPB".equals(context.getProtocol())) {
    		
    		if (!"".equals(prop.getProperty(Constants.XC3EPB_PASSWORD, "").trim())) {
    			context.setXc3epbPassword(prop.getProperty(Constants.XC3EPB_PASSWORD, 
    					context.getXc3epbPassword()).trim());
    		}
    		if (!"".equals(prop.getProperty(Constants.XC3EPB_CONFIG_PATH, "").trim())) {
    			context.setXc3epbConfigPath(prop.getProperty(Constants.XC3EPB_CONFIG_PATH, 
    					context.getXc3epbConfigPath()).trim());
    		}
    	}
    	
		// 20100423 JGY
		if ("ENVELOP".equals(context.getProtocol())) {
			if (!"".equals(prop.getProperty(Constants.ENVELOP_SIGNCERT_PATH, "").trim())) {
				context.setEnvelopSigncertPath(prop.getProperty(Constants.ENVELOP_SIGNCERT_PATH, 
						context.getEnvelopSigncertPath()).trim());
			}

			if (!"".equals(prop.getProperty(Constants.ENVELOP_SIGNKEY_PATH, "").trim())) {
				context.setEnvelopSignkeyPath(prop.getProperty(Constants.ENVELOP_SIGNKEY_PATH, 
						context.getEnvelopSignkeyPath()).trim());
			}

			if (!"".equals(prop.getProperty(Constants.ENVELOP_PASSWORD, "").trim())) {
				context.setEnvelopPassword(prop.getProperty(Constants.ENVELOP_PASSWORD, 
						context.getEnvelopPassword()).trim());
			}
		}
		
		/**
		 * TCSEED protocol only - 20101213 JGY
		 */    	
    	if ("TCSEED".equals(context.getProtocol())) {			
			context.setTcseedKeyStore(prop.getProperty(Constants.TCSEED_KEY_STORE, 
					context.getTcseedKeyStore()).trim());

    	}
    	/**
    	 * INICIS protocol only
    	 */
	
    	if ("INICIS".equals(context.getProtocol())) {
    		context.setInicisKeyPath(prop.getProperty(Constants.INICIS_KEY_PATH, 
					context.getInicisKeyPath()));
    		context.setInicisKeyPass(prop.getProperty(Constants.INICIS_KEY_PASS, 
					context.getInicisKeyPass()));
    	}    	
    	/**
    	 * DELIMITER protocol only
    	 */
	
    	if ("DELIMITER".equals(context.getProtocol())) {
    		context.setDelimiter(prop.getProperty(Constants.DELIMITER,
					context.getDelimiter()));
    	}   
    	
		if ((  "LOGIN".equals(context.getProtocol()) 
				||"BIND".equals(context.getProtocol())
				||"LAZY".equals(context.getProtocol()) )
			&& context.isClient()) {
    		context.setLoginSend(prop.getProperty(Constants.LOGIN_SEND, 
					context.getLoginSend()));
    		context.setLoginRecv(prop.getProperty(Constants.LOGIN_RECV, 
					context.getLoginRecv()));
			context.setLlFieldLengthAlpha(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH_ALPHA,
					Integer.toString(context.getLlFieldLengthAlpha()))));
		}	
		if ("BIND".equals(context.getProtocol()) && context.isClient()) {
    		context.setBindType(prop.getProperty(Constants.BIND_TYPE, 
    				context.getBindType()));
		}		
		if ("APPEND".equals(context.getProtocol())){
    		context.setAppendHead(prop.getProperty(Constants.APPEND_HEAD, 
    				context.getAppendHead()));
    		context.setAppendTail(prop.getProperty(Constants.APPEND_TAIL, 
    				context.getAppendTail()));
		}	
    	
		/**
		 * block.ip.list
		 */
		if (!"".equals(prop.getProperty(Constants.BLOCK_IP_LIST,"")) && context.isServer()) {
			context.setBlockIpList(prop.getProperty(Constants.BLOCK_IP_LIST,""));
		}		
		/**
		 * l4.skip.ip.list
		 */
		if (!"".equals(prop.getProperty(Constants.L4_SKIP_IP_LIST,"")) && context.isServer()) {
			context.setL4SkipIpList(prop.getProperty(Constants.L4_SKIP_IP_LIST,""));
		}	
		
    	/**
		 * SingleSession
		 */
		if (!"".equals(prop.getProperty(Constants.IS_SINGLE_SESSION, ""))) {
			context.setSingleSession(prop.getProperty(Constants.IS_SINGLE_SESSION, context.getSingleSession()));
			if (context.getSingleSession() == null || !context.getSingleSession().matches("[Y|N]")) {
				throw new Exception(context.getAdapterName() + " | " + Constants.IS_SINGLE_SESSION + " must be one of [Y|N], but - '" + context.getSingleSession() + "'");
			}
		}		
		
		/**
		 * SingleSession Primary
		 */
		if(!"".equals(prop.getProperty(Constants.SINGLE_PRIMARY_INST, ""))) {
			context.setPrimaryInstId( prop.getProperty(Constants.SINGLE_PRIMARY_INST, context.getPrimaryInstId()));
		}
		if ("DYNAMIC_OFFSET".equals(context.getProtocol())){
			if(!"".equals(prop.getProperty(Constants.DYNAMIC_OFFSET_PATTERN, ""))) {
				context.setDynamicOffsetPattern( prop.getProperty(Constants.DYNAMIC_OFFSET_PATTERN, context.getDynamicOffsetPattern()));
			}
			if(!"".equals(prop.getProperty(Constants.DATA_ADD_RULE, ""))) {
				context.setDataAddRule( prop.getProperty(Constants.DATA_ADD_RULE, context.getDataAddRule()));
			}
			if(!"".equals(prop.getProperty(Constants.DATA_REMOVE_RULE, ""))) {
				context.setDataRemoveRule( prop.getProperty(Constants.DATA_REMOVE_RULE, context.getDataRemoveRule()));
			}
			context.setLlInclude("Y");
		}
		
		/**
		 * keep.alive
		 */
		if (!"".equals(prop.getProperty(Constants.KEEP_ALIVE,"N"))) {
			context.setKeepAlive(prop.getProperty(Constants.KEEP_ALIVE,"N"));
		}
		
		return context;
	}
}
