/*
* Copyright 2008-2009 MOPAS(Ministry of Public Administration and Security).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package egovframework.rte.itl.webservice.service.impl;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebParam.Mode;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import egovframework.rte.itl.integration.EgovIntegrationMessage;
import egovframework.rte.itl.integration.EgovIntegrationMessageHeader;
import egovframework.rte.itl.integration.EgovIntegrationMessageHeader.ResultCode;
import egovframework.rte.itl.webservice.EgovWebServiceMessage;
import egovframework.rte.itl.webservice.EgovWebServiceMessageHeader;
import egovframework.rte.itl.webservice.service.EgovWebServiceClassLoader;
import egovframework.rte.itl.webservice.service.EgovWebServiceClient;
import egovframework.rte.itl.webservice.service.MessageConverter;
import egovframework.rte.itl.webservice.service.ServiceEndpointInterfaceInfo;
import egovframework.rte.itl.webservice.service.ServiceParamInfo;
/**
* 웹서비스 Client로 실제 웹서비스를 호출하는 구현 클래스
* <p>
* <b>NOTE:</b> 웹서비스 Client로 실제 웹서비스를 호출하는 class이다.
* @author 실행환경 개발팀 심상호
* @since 2009.06.01
* @version 1.0
* @see <pre>
* == 개정이력(Modification Information) ==
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.06.01 심상호 최초 생성
*
* </pre>
*/
public class EgovWebServiceClientImpl implements EgovWebServiceClient {
private Log LOG = LogFactory.getLog(this.getClass());
/** ServiceEndpointInterfaceInfo */
protected ServiceEndpointInterfaceInfo serviceEndpointInterfaceInfo;
/** MessageConverter */
protected MessageConverter messageConverter;
/** serviceEndpointInterfaceClass */
protected Class<?> serviceEndpointInterfaceClass;
/** wsdl URL */
protected URL wsdlURL;
/** service name */
protected QName serviceName;
/** port name */
protected QName portName;
/** service */
protected Service service;
/** method */
protected Method method;
/** client */
protected Object client;
/** 초기화 flag */
protected boolean initialized = false;
/** 초기화 flag lock */
protected Object initializedLock = new Object();
/**
* Constructor
* @param classLoader
* EgovWebServiceClassLoader
* @param serviceEndpointInterfaceInfo
* ServiceEndpointInterfaceInfo
* @param messageConverter
* MessageConverter
* @throws IllegalArgumentException
* <code>classLoader</code>,
* <code>serviceEndpointInterfaceInfo</code>
* , <code>messageConverter</code> 값이
* <code>null</code>인 경우
* @throws ClassNotFoundException
* Class를 생성할 수 없는 경우
* @throws SecurityException
* @throws NoSuchMethodException
* @throws MalformedURLException
*/
public EgovWebServiceClientImpl(EgovWebServiceClassLoader classLoader,
ServiceEndpointInterfaceInfo serviceEndpointInterfaceInfo,
MessageConverter messageConverter) throws ClassNotFoundException,
SecurityException, NoSuchMethodException, MalformedURLException {
super();
LOG.debug("Create EgovWebServiceClient");
if (classLoader == null) {
LOG.error("Argument 'classLoader' is null");
throw new IllegalArgumentException();
} else if (serviceEndpointInterfaceInfo == null) {
LOG.error("Argument 'serviceEndpointInterfaeInfo' is null");
throw new IllegalArgumentException();
} else if (messageConverter == null) {
LOG.error("Argument 'messageConverter' is null");
throw new IllegalArgumentException();
}
this.serviceEndpointInterfaceInfo = serviceEndpointInterfaceInfo;
this.messageConverter = messageConverter;
// ServiceEndpointInterface Class를 load한다.
serviceEndpointInterfaceClass =
classLoader.loadClass(serviceEndpointInterfaceInfo);
LOG.debug("serviceEndpointInterfaceClass = "
+ serviceEndpointInterfaceClass);
// service를 생성한다.
wsdlURL = new URL(serviceEndpointInterfaceInfo.getWsdlAddress());
LOG.debug("wsdlURL = " + wsdlURL);
serviceName =
new QName(serviceEndpointInterfaceInfo.getNamespace(),
serviceEndpointInterfaceInfo.getServiceName());
LOG.debug("serviceName = " + serviceName);
portName =
new QName(serviceEndpointInterfaceInfo.getNamespace(),
serviceEndpointInterfaceInfo.getPortName());
LOG.debug("portName = " + portName);
// Method 추출
List<Class<?>> paramClasses = new ArrayList<Class<?>>();
for (ServiceParamInfo paramInfo : serviceEndpointInterfaceInfo
.getParamInfos()) {
if (paramInfo.getMode().equals(Mode.OUT)
|| paramInfo.getMode().equals(Mode.INOUT)) {
paramClasses.add(Holder.class);
} else {
paramClasses.add(classLoader.loadClass(paramInfo.getType()));
}
}
this.method =
serviceEndpointInterfaceClass.getMethod(
serviceEndpointInterfaceInfo.getOperationName(), paramClasses
.toArray(new Class<?>[] {}));
LOG.debug("method = " + method);
LOG.debug("Finish to creating EgovWebServiceClient");
}
@SuppressWarnings("unchecked")
public EgovIntegrationMessage service(EgovIntegrationMessage requestMessage) {
LOG.debug("EgovWebServiceClient service (requestMesage = "
+ requestMessage + ")");
synchronized (initializedLock) {
if (initialized == false) {
LOG.debug("Initialize Client");
// ServiceEndpointInterface Impl 객체 생성
try {
service = Service.create(wsdlURL, serviceName);
client =
service
.getPort(portName, serviceEndpointInterfaceClass);
initialized = true;
} catch (Throwable e) {
LOG.error("Cannot create web service port", e);
initialized = false;
// 초기화 실패
return new EgovWebServiceMessage(
new EgovWebServiceMessageHeader(requestMessage
.getHeader()) {
{
setResultCode(ResultCode.FAIL_IN_INITIALIZING);
}
});
}
}
}
LOG.debug("Create Request Message");
// get request params
List<Object> params = new ArrayList<Object>();
// requestMessage의 Body를 value object로 변환한다.
boolean succeed = false;
try {
Map<String, Object> requestBody = requestMessage.getBody();
for (ServiceParamInfo paramInfo : serviceEndpointInterfaceInfo
.getParamInfos()) {
if (paramInfo.getMode().equals(Mode.IN)
|| paramInfo.getMode().equals(Mode.INOUT)) {
Object valueObject = null;
if (paramInfo.getType() == EgovWebServiceMessageHeader.TYPE) {
LOG.debug("Insert Message Header");
LOG.debug("value = " + requestMessage.getHeader());
valueObject = requestMessage.getHeader();
} else {
LOG.debug("Insert Param \"" + paramInfo.getName()
+ "\"");
Object typedObject =
requestBody.get(paramInfo.getName());
valueObject =
messageConverter.convertToValueObject(typedObject,
paramInfo.getType());
LOG.debug("value = " + valueObject);
}
if (paramInfo.getMode().equals(Mode.INOUT)) {
LOG.debug("Wrapping Holder");
valueObject = new Holder(valueObject);
}
params.add(valueObject);
} else {
params.add(new Holder());
}
}
succeed = true;
} catch (Throwable e) {
LOG.error("Cannot Create Request Message", e);
}
if (succeed == false) {
// 요청 메시시 생성 실패
return new EgovWebServiceMessage(new EgovWebServiceMessageHeader(
requestMessage.getHeader()) {
{
setResultCode(ResultCode.FAIL_IN_CREATING_REQUEST_MESSAGE);
}
});
}
// call method
LOG.debug("Invoke method");
Object[] paramArray = params.toArray();
succeed = false;
try {
method.invoke(client, paramArray);
succeed = true;
} catch (Throwable e) {
LOG.error("Fail to invoke method", e);
}
if (succeed == false) {
// 메소드 호출 실패
return new EgovWebServiceMessage(new EgovWebServiceMessageHeader(
requestMessage.getHeader()) {
{
setResultCode(ResultCode.FAIL_IN_SENDING_REQUEST);
}
});
}
// responseValueObject를 typed object로 변환한다.
LOG.debug("Parse Response Message");
EgovIntegrationMessageHeader responseHeader = null;
succeed = true;
// response parsing은 최대한 가능한 만큼 수행한다.
Map<String, Object> responseBody = new HashMap<String, Object>();
int i = 0;
for (ServiceParamInfo paramInfo : serviceEndpointInterfaceInfo
.getParamInfos()) {
if (paramInfo.getMode().equals(Mode.OUT)
|| paramInfo.getMode().equals(Mode.INOUT)) {
Object valueObject = ((Holder) paramArray[i]).value;
if (paramInfo.getType() == EgovWebServiceMessageHeader.TYPE) {
responseHeader = (EgovWebServiceMessageHeader) valueObject;
} else {
try {
Object typedObject =
messageConverter.convertToTypedObject(valueObject,
paramInfo.getType());
responseBody.put(paramInfo.getName(), typedObject);
} catch (Throwable e) {
LOG.error("Cannot parse response message", e);
succeed = false;
}
}
}
i++;
}
if (succeed) {
// 응답 메시지 헤더가 없는 경우, requestHeader를 이용하여 생성
if (responseHeader == null) {
responseHeader =
new EgovWebServiceMessageHeader(requestMessage.getHeader());
}
return new EgovWebServiceMessage(responseHeader, responseBody);
} else {
// 응답 메시지 parsing 실패
if (responseHeader == null) {
responseHeader =
new EgovWebServiceMessageHeader(requestMessage.getHeader());
}
responseHeader
.setResultCode(ResultCode.FAIL_IN_PARSING_RESPONSE_MESSAGE);
return new EgovWebServiceMessage(responseHeader, responseBody);
}
}
}