package cmm.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import cmm.Constant;
import cmm.service.CmmApiService;
import cmm.util.CmmUtil;
import cmm.util.DataMap;
import cmm.util.DateUtil;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import egovframework.rte.fdl.property.EgovPropertyService;


/**  
 * API관련 서비스 클래스를 구현한다.
 * @Class Name : CmmApiServiceImpl.java
 * @author ecplaza 
 * @since 2018-04-18
 * @version 1.0
 */
@Service("cmmApiService")
public class CmmApiServiceImpl extends EgovAbstractServiceImpl implements CmmApiService {

	/** LOGGER */
	private static final Logger LOGGER = LoggerFactory.getLogger(CmmServiceImpl.class);
	
	  /** EgovPropertyService */
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertiesService;
    
    @Override
    public JSONObject getCultureinfoApiList(DataMap paramMap){
    	String resultXml = "";
    	JSONObject xmlJSONObj = null;
    	
		try {
			HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(this.getCultureinfoUrl(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
	    	int statusCode = httpClient.executeMethod(getMethod);
			
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getCultureinfoApiList() String xml to JSON Parsing error", jsoe);
				}
			}else{
				xmlJSONObj = new JSONObject();
				JSONObject jsonObjResponse = new JSONObject();
				JSONObject jsonObjComMsgHeader = new JSONObject();
				jsonObjComMsgHeader.put("SuccessYN", "N");
				jsonObjComMsgHeader.put("ReturnCode", statusCode);
				jsonObjComMsgHeader.put("ErrMsg", "통신 오류상태입니다.");
				jsonObjResponse.put("comMsgHeader", jsonObjComMsgHeader);
				xmlJSONObj.put("response",jsonObjResponse);
			}
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("fail in getCultureinfoApiList()", e);
		} catch (HttpException e) {
			LOGGER.error("fail in getCultureinfoApiList()", e);
		} catch (IOException e) {
			LOGGER.error("fail in getCultureinfoApiList()", e);
		} catch (Exception e) {
			LOGGER.error("fail in getCultureinfoApiList()", e);
		}
    	return xmlJSONObj;
    }
    private String getCultureinfoUrl(DataMap paramMap){
    	String url = paramMap.getString("reqUrl");
    	paramMap.remove("reqUrl");
    	if(!"".equals(paramMap.getString("viewType"))){
    		if(Constant.VIEW_TYPE_D.equals(paramMap.getString("viewType"))){
    			url = url.substring(0, url.lastIndexOf("/"));
    			url += "/"+paramMap.getString("viewType").toLowerCase()+"/";
    		}
    		paramMap.remove("viewType");
    	}
    	 url += this.getQueryString(paramMap);
    	return url;
    }
    private String getQueryString(DataMap paramMap){
    	String url = "";
    	Set<String> keySet = paramMap.keySet();
		Iterator<String> keys = keySet.iterator();
		int cnt = 0;
		while (keys.hasNext()) {
			String key = keys.next();
			String value = paramMap.getString(key);
			if(cnt>0){
				url += "&";
			}else{
				url += "?";
			}
			url += key;
			url += "=";
			url += value;
			
			cnt++;
		}
    	return url;
    }
    @Override
    public JSONObject getDissForecastInfoList(DataMap paramMap){
    	String resultXml = "";
    	JSONObject xmlJSONObj = null;
		try {
			String addr = propertiesService.getString("openapi.apis.data.url");
	    	paramMap.setString("serviceKey", propertiesService.getString("openapi.apis.data.serviceKey"));
	    	paramMap.setString("pageNo", "1");
	    	paramMap.setString("numOfRows", "2000");
	    	paramMap.setString("type", "xml");
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+this.getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getDissForecastInfoList() String xml to JSON Parsing error", jsoe);
				}
			}else{
				// 통신오류
				xmlJSONObj = new JSONObject();
				JSONObject jsonObjResponse = new JSONObject();
				JSONObject jsonObjComMsgHeader = new JSONObject();
				jsonObjComMsgHeader.put("ErrMsg", "통신 오류상태입니다.");
				jsonObjComMsgHeader.put("returnReasonCode", statusCode);
				jsonObjComMsgHeader.put("returnAuthMsg", "통신 오류상태입니다.");
				jsonObjResponse.put("cmmMsgHeader", jsonObjComMsgHeader);
				xmlJSONObj.put("OpenAPI_ServiceResponse",jsonObjResponse);
			}
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("fail in getDissForecastInfoList()", e);
		} catch (HttpException e) {
			LOGGER.error("fail in getDissForecastInfoList()", e);
		} catch (IOException e) {
			LOGGER.error("fail in getDissForecastInfoList()", e);
		} catch (Exception e) {
			LOGGER.error("fail in getDissForecastInfoList()", e);
		}
    	return xmlJSONObj;
    }
    @Override
    @Cacheable(value="ctprvnMesureCache", key="{#sido, #dataTime}")
	public DataMap getCtprvnMesureSidoList(String sido, String dataTime) {
		
		String resultXml = "", resultCode = "", resultMsg = "";
		int useTimeout = 5;
    	boolean isSuccess = true;
    	DataMap paramMap = new DataMap();
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	JSONObject xmlJSONObj = null;
    	
		try {
			String addr = propertiesService.getString("openapi.airkorea.url");
	    	paramMap.setString("serviceKey", propertiesService.getString("openapi.airkorea.serviceKey"));
	    	paramMap.setString("pageNo", "1");
	    	paramMap.setString("numOfRows", "2000");
	    	paramMap.setString("searchCondition", propertiesService.getString("openapi.airkorea.searchCondition.hour"));
	    	paramMap.setString("ver", propertiesService.getString("openapi.airkorea.ver"));
			paramMap.setString("sidoName",  URLEncoder.encode(CmmUtil.getAisSidoName(sido),"UTF-8"));
			
			HttpClient httpClient = new HttpClient();
			httpClient.getParams().setParameter("http.connection.timeout", useTimeout * 1000);// 원격 호스트와 연결을 설정하는 시간
			httpClient.getParams().setParameter("http.socket.timeout",  useTimeout * 1000);//데이터를 기다리는 시간
			//httpClient.getParams().setParameter("http.connection-manager.timeout",  useTimeout * 1000);// 연결 및 소켓 시간 초과 
			//httpClient.getParams().setParameter("http.protocol.head-body-timeout",  useTimeout * 1000);
			
			HttpMethod getMethod = new GetMethod(addr+this.getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
	    	
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getCtprvnMesureSidoLIst() String xml to JSON Parsing error", jsoe);
				}
			}else{
				// 통신오류
				rsMap.setString("resultMsg","통신 오류상태입니다.");
				rsMap.setString("resultCode",String.valueOf(statusCode));
				isSuccess = false;
			}
				
		} catch (ConnectTimeoutException e) {
			LOGGER.error("fail in getCtprvnMesureSidoLIst()", e);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("fail in getCtprvnMesureSidoLIst()", e);
		} catch (HttpException e) {
			LOGGER.error("fail in getCtprvnMesureSidoLIst()", e);
		} catch (IOException e) {
			LOGGER.error("fail in getCtprvnMesureSidoLIst()", e);
		} catch (Exception e) {
			LOGGER.error("fail in getCtprvnMesureSidoLIst()", e);
		} finally{
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
	    			JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    			JSONObject jsonItems = null;
	    			
	    			resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			
	    			if(jsonBody.has("items") && jsonBody.get("items") instanceof JSONObject){
	    				jsonItems = jsonBody.getJSONObject("items");
	    				if(jsonItems.has("item")){
		    				JSONArray jsonArray = null;
	    					if(jsonItems.get("item") instanceof JSONObject){
	    						jsonArray = new JSONArray();
	    						jsonArray.put(jsonItems.getJSONObject("item"));
	    					}else{
	    						jsonArray =jsonItems.getJSONArray("item");
	    					}
	    					for(int i=0; i<jsonArray.length();i++){
	    						JSONObject obj = jsonArray.getJSONObject(i);
	    						obj.put("sido", sido);
	    						DataMap map = CmmUtil.getMapFromJsonObject(obj);
	    						if(sido.indexOf("인천") != -1){
	    							// 인천 광역시 남구  - > 2018.07.01 일자로  미추홀구로 변경
	    							if(map.getString("cityName").indexOf("남구") != -1){
	    								map.setString("sigungu", "미추홀구");
	    							}else{
	    								map.setString("sigungu", map.getString("cityName"));
	    							}
	    						}else{
	    							map.setString("sigungu", map.getString("cityName"));
	    						}
	    						
	    						map.setString("so2Value", map.getString("so2Value").replaceAll("-", "0"));
	    						map.setString("coValue", map.getString("coValue").replaceAll("-", "0"));
	    						map.setString("o3Value", map.getString("o3Value").replaceAll("-", "0"));
	    						map.setString("no2Value", map.getString("no2Value").replaceAll("-", "0"));
	    						map.setString("pm10Value", map.getString("pm10Value").replaceAll("-", "0"));
	    						map.setString("pm25Value", map.getString("pm25Value").replaceAll("-", "0"));
	    						resultList.add(map);
	    						
	    						if(dataTime.equals(map.getString("dataTime"))){
	    							break;
	    						}
	    					}
		    			}else{
		    				rsMap.setString("resultMsg","[데이터 가공오류]item 미존재");
		    				rsMap.setString("resultCode","11");
		    			}
	    			}else{
	    				rsMap.setString("resultMsg","[데이터 가공오류]item 미존재");
	    				rsMap.setString("resultCode","11");
	    			}
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getCtprvnMesureSidoLIst() JSON Parsing error", jsoe);
				}
			}
		}
    	if(isSuccess){
    		rsMap.setString("resultCode",resultCode);
			rsMap.setString("resultMsg",resultMsg);
    	}
    	rsMap.put("resultList", resultList);
    	return rsMap;
    }
    @Override
	@Cacheable(value="forecastCache", key="{#baseDate, #baseTime, #nx, #ny}")
	public DataMap getForecastTimeDataList(String baseDate, String baseTime, String nx, String ny) {
		
		String resultXml = "", resultCode = "", resultMsg = "";
		DataMap paramMap = new DataMap();
		DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	JSONObject xmlJSONObj = null;
		
		try {
			String addr = propertiesService.getString("openapi.kma.forecastTimeData.url");
	    	paramMap.setString("serviceKey", propertiesService.getString("openapi.kma.serviceKey"));
	    	paramMap.setString("base_date", baseDate);
	    	paramMap.setString("base_time", baseTime);
	    	paramMap.setString("nx", nx);
	    	paramMap.setString("ny", ny);
	    	paramMap.setString("pageNo", "1");
	    	paramMap.setString("numOfRows", "1000");
	    		
			HttpClient httpClient = new HttpClient();
			HttpMethod getMethod = new GetMethod(addr+this.getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
	    	
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getForecastTimeDataList() String xml to JSON Parsing error", jsoe);
				}
			}else{
				xmlJSONObj = new JSONObject();
				JSONObject jsonObjResponse = new JSONObject();
				JSONObject jsonObjComMsgHeader = new JSONObject();
				jsonObjComMsgHeader.put("resultMsg", "통신 오류상태입니다.");
				jsonObjComMsgHeader.put("resultCode", statusCode);
				jsonObjResponse.put("header", jsonObjComMsgHeader);
				xmlJSONObj.put("response",jsonObjResponse);
			}
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("fail in getForecastTimeDataList()", e);
		} catch (HttpException e) {
			LOGGER.error("fail in getForecastTimeDataList()", e);
		} catch (IOException e) {
			LOGGER.error("fail in getForecastTimeDataList()", e);
		} catch (Exception e) {
			LOGGER.error("fail in getForecastTimeDataList()", e);
		} finally{
			JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
			JSONObject jsonHeader = jsonResponse.getJSONObject("header");
			resultCode = jsonHeader.get("resultCode").toString();
			resultMsg = jsonHeader.get("resultMsg").toString();
			if("0000".equals(resultCode)){
				try {
					JSONObject jsonBody = jsonResponse.getJSONObject("body");
					if(jsonBody.has("items")){
						if(jsonBody.get("items") instanceof JSONObject){
							JSONObject jsonItems = jsonBody.getJSONObject("items");
							if(jsonItems.has("item")){
								JSONArray jsonArray = null;
								if(jsonItems.get("item") instanceof JSONObject){
									jsonArray = new JSONArray();
									jsonArray.put(jsonItems.getJSONObject("item"));
								}else{
									jsonArray =jsonItems.getJSONArray("item");
								}
								for(int i=0; i<jsonArray.length();i++){
									JSONObject obj = jsonArray.getJSONObject(i);
									String nowTime = DateUtil.currentDateHh() +"00";
									if(nowTime.indexOf(obj.get("fcstTime").toString()) == -1){
										continue;
									}
									resultList.add(CmmUtil.getMapFromJsonObject(obj));
								}
							}
						}
					}
				} catch (org.json.JSONException jsoe) {
					LOGGER.error("fail in getForecastTimeDataList() JSON Parsing error", jsoe);
				}
			}
		}
		rsMap.setString("resultCode",resultCode);
		rsMap.setString("resultMsg",resultMsg);
    	rsMap.put("resultList", resultList);
    	
    	return rsMap;
    }
    @Override
	public DataMap getNaverApiGeocode(DataMap paramMap) {
		
        JSONObject jsonObj = null;  
        DataMap rtnMap = new DataMap();
        BufferedReader br = null; 
        InputStreamReader isr = null;
        int total = 0;
		try {
			
			String apiURL =  propertiesService.getString("openapi.naver.map.geocode.url");
	        String clientId = propertiesService.getString("openapi.naver.map.clientId");
	        String clientSecret = propertiesService.getString("openapi.naver.map.clientSecret");
			
			String addr = URLEncoder.encode(paramMap.getString("juso"), "UTF-8");
			URL url = new URL(apiURL+"?query=" + addr);
			HttpURLConnection con = (HttpURLConnection)url.openConnection();
			con.setRequestMethod("GET");
		    con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
	        con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
			int responseCode = con.getResponseCode();
			if(responseCode==200) {
				isr = new InputStreamReader(con.getInputStream(),"UTF-8");
			    br = new BufferedReader(isr);
			} else {  
				isr = new InputStreamReader(con.getErrorStream(),"UTF-8");
			    br = new BufferedReader(isr);
			}
			
			String inputLine;
			StringBuffer response = new StringBuffer();
			while ((inputLine = br.readLine()) != null) {
			    response.append(inputLine);
			}
			if(responseCode==200) { 
				jsonObj = new JSONObject(response.toString());
				jsonObj.put("successYn","Y");
			} else {
			 	JSONObject errObj = new JSONObject(response.toString());
			 	jsonObj = new JSONObject();
			 	jsonObj.put("result", errObj);
			 	jsonObj.put("successYn","N");
			}
			if("Y".equals(jsonObj.get("successYn").toString()) ){
            	if(jsonObj.has("status") && jsonObj.has("meta")){
            		JSONObject meta = jsonObj.getJSONObject("meta");
            		if("OK".equals(jsonObj.getString("status")) && meta.getInt("count") > 0){
            			// 데이터 존재
            			if(jsonObj.has("addresses") && jsonObj.get("addresses") instanceof JSONArray){
            				// 결과값이 JSONArray
            				JSONArray addresses = jsonObj.getJSONArray("addresses");
            				if(addresses != null && addresses.length() > 0){
            					JSONObject result = addresses.getJSONObject(0);
        						if(result.has("x") && result.has("y")){
        							rtnMap.setString("mapX", result.getString("x"));
        							rtnMap.setString("mapY", result.getString("y"));
        							
        							total = 1;
            					}
            				}
            			}
            		}
            	}
            }
			rtnMap.setInt("total", total);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} catch (MalformedURLException e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} catch (ProtocolException e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} catch (IOException e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} catch (JSONException e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} catch (Exception e) {
			LOGGER.error("Error in getNaverApiGeocode()", e);
		} finally{
			try {
				if(isr != null){
					isr.close();
				}
				if(br != null){
					br.close();
				}
			} catch (IOException e) {
				LOGGER.error("Error in getNaverApiGeocode() close", e);
			}
		}
		return rtnMap;
	}
    @Override
	public DataMap getNaverApiReversegeocode(DataMap paramMap) {
        JSONObject jsonObj = null;  
        DataMap rtnMap = new DataMap();
        BufferedReader br = null; 
        InputStreamReader isr = null;
        int total = 0;
        
		try {
			String apiURL =  propertiesService.getString("openapi.naver.map.reversegeocode.url") + "?request=coordsToaddr&sourcecrs=epsg:4326&output=json";
	        String clientId = propertiesService.getString("openapi.naver.map.clientId");
	        String clientSecret = propertiesService.getString("openapi.naver.map.clientSecret");
			
		    String xy = paramMap.getString("xy");
			URL url = new URL(apiURL+"&coords=" + xy);
	        HttpURLConnection con = (HttpURLConnection)url.openConnection();
	        con.setRequestMethod("GET");
	        con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
	        int responseCode = con.getResponseCode();
	        if(responseCode==200) {
				isr = new InputStreamReader(con.getInputStream(),"UTF-8");
			    br = new BufferedReader(isr);
			} else {  
				isr = new InputStreamReader(con.getErrorStream(),"UTF-8");
			    br = new BufferedReader(isr);
			}
	        
	        String inputLine;
	        StringBuffer response = new StringBuffer();
	        while ((inputLine = br.readLine()) != null) {
	            response.append(inputLine);
	        }
	        if(responseCode==200) { 
	        	jsonObj = new JSONObject(response.toString());
	        	jsonObj.put("successYn","Y");
	        } else {
	         	JSONObject errObj = new JSONObject(response.toString());
	         	jsonObj = new JSONObject();
	         	jsonObj.put("result", errObj);
	         	jsonObj.put("successYn","N");
	        }
	        if("Y".equals(jsonObj.get("successYn").toString()) ){
            	if(jsonObj.has("status")){
            		JSONObject status = jsonObj.getJSONObject("status");
            		if(status.getInt("code") == 0){
            			// 데이터 존재
            			if(jsonObj.has("results") && jsonObj.get("results") instanceof JSONArray){
            				// 결과값이 JSONArray
            				JSONArray results = jsonObj.getJSONArray("results");
            				if(results != null && results.length() > 0){
            					JSONObject result = results.getJSONObject(0);
            					if(result != null && result.has("region")){
            						JSONObject region = result.getJSONObject("region");
            						if(region.has("area2")){
                						// 세종시일경우 안나옴.
                						if(region.getJSONObject("area2").has("name")){
                							 rtnMap.setString("sigugun", region.getJSONObject("area2").getString("name"));
                						}
                					}
            						if(region.has("area1")){
                						if(region.getJSONObject("area1").has("name")){
                							rtnMap.setString("sido", region.getJSONObject("area1").getString("name"));
                							if(rtnMap.getString("sido").indexOf("세종") > -1){
                								// 세종인경우 시군구에 담는다.
                								rtnMap.setString("sigugun", rtnMap.getString("sido"));
                							}
                							total = 1;
                						}
                					}
            					}
            				}
            			}
            		}
            	}
	        }  
	        
	        rtnMap.setInt("total", total);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} catch (MalformedURLException e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} catch (ProtocolException e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} catch (IOException e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} catch (JSONException e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} catch (Exception e) {
			LOGGER.error("Error in getNaverApiReversegeocode()", e);
		} finally{
			try {
				if(isr != null){
					isr.close();
				}
				if(br != null){
					br.close();
				}
			} catch (IOException e) {
				LOGGER.error("Error in getNaverApiGeocode() close", e);
			}
		}
		return rtnMap;
	}
    @Override
	public DataMap getNaverApiJuso(DataMap paramMap) {
		
        JSONObject jsonObj = null;  
        DataMap rtnMap = new DataMap();
        BufferedReader br = null; 
        InputStreamReader isr = null;
        int total = 0;
        
		try {
			String apiURL =  propertiesService.getString("openapi.naver.map.geocode.url");
	        String clientId = propertiesService.getString("openapi.naver.map.clientId");
	        String clientSecret = propertiesService.getString("openapi.naver.map.clientSecret");
			
			String addr = URLEncoder.encode(paramMap.getString("juso"), "UTF-8");
			URL url = new URL(apiURL+"?query=" + addr);
			HttpURLConnection con = (HttpURLConnection)url.openConnection();
			con.setRequestMethod("GET");
			con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
		    con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
			int responseCode = con.getResponseCode();
			if(responseCode==200) {
				isr = new InputStreamReader(con.getInputStream(),"UTF-8");
			    br = new BufferedReader(isr);
			} else {  
				isr = new InputStreamReader(con.getErrorStream(),"UTF-8");
			    br = new BufferedReader(isr);
			}
			
			String inputLine;
			StringBuffer response = new StringBuffer();
			while ((inputLine = br.readLine()) != null) {
			    response.append(inputLine);
			}
			
			if(responseCode==200) { 
				jsonObj = new JSONObject(response.toString());
				jsonObj.put("successYn","Y");
			} else {
			 	JSONObject errObj = new JSONObject(response.toString());
			 	jsonObj = new JSONObject();
			 	jsonObj.put("result", errObj);
			 	jsonObj.put("successYn","N");
			}
			if("Y".equals(jsonObj.get("successYn").toString()) ){
            	if(jsonObj.has("status") && jsonObj.has("meta")){
            		JSONObject meta = jsonObj.getJSONObject("meta");
            		if("OK".equals(jsonObj.getString("status")) && meta.getInt("count") > 0){
            			// 데이터 존재
            			if(jsonObj.has("addresses") && jsonObj.get("addresses") instanceof JSONArray){
            				// 결과값이 JSONArray
            				JSONArray addresses = jsonObj.getJSONArray("addresses");
            				if(addresses != null && addresses.length() > 0){
            					JSONObject result = addresses.getJSONObject(0);
        						if(result.has("x") && result.has("y")){
        							rtnMap.setString("point_x", result.getString("x"));
        							rtnMap.setString("point_y", result.getString("y"));
        							
        							total = 1;
            					}
        						if(result.has("jibunAddress")){
        							// ex)	"jibunAddress":"전라남도 완도군 완도읍"
        							//		"jibunAddress":"제주특별자치도 제주시 노형동 245"
        							//		"jibunAddress":"울산광역시 동구"
        							String [] jibunAddress = result.getString("jibunAddress").split(" ",5);
        							rtnMap.setString("sido", jibunAddress[0]);
        							if (jibunAddress.length >= 2) rtnMap.setString("sigugun", jibunAddress[1]);
        							if (jibunAddress.length >= 3) rtnMap.setString("dongmyun", jibunAddress[2]);
        							if (jibunAddress.length >= 4) rtnMap.setString("rest", jibunAddress[3]);
        						}
        						
            				}
            			}
            		}
            	}
            }
			rtnMap.setInt("total", total);
			rtnMap.setString("successYn", jsonObj.getString("successYn"));
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} catch (MalformedURLException e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} catch (ProtocolException e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} catch (IOException e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} catch (JSONException e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} catch (Exception e) {
			LOGGER.error("Error in getNaverApiJuso() paramMap="+paramMap+", jsonObj="+jsonObj, e);
		} finally{
			try {
				if(isr != null){
					isr.close();
				}
				if(br != null){
					br.close();
				}
			} catch (IOException e) {
				LOGGER.error("Error in getNaverApiJuso() close", e);
			}
		}
		return rtnMap;
	}
    @Override
	public DataMap getNaverApiSearch(DataMap paramMap) {
		JSONObject jsonObj = null;  
		DataMap rtnMap = new DataMap();
		BufferedReader br = null; 
		InputStreamReader isr = null;
		List<DataMap> resultList = new ArrayList<DataMap>();
		
		String code = paramMap.getString("code"); // 01-관광지 , 02-맛집, 03-숙박
		//String [] sort = {"sim","date"}; // 정렬 옵션: sim (유사도순-기본값), date (날짜순)
		String gubun = "";
		if("01".equals(code)){
			gubun = "관광지";
		}else if("02".equals(code)){
			gubun = "맛집";
		}else if("03".equals(code)){
			gubun = "숙박";
		}
		String apiURL =  propertiesService.getString("openapi.naver.search.url");
        String clientId = propertiesService.getString("openapi.naver.map.clientId");
        String clientSecret = propertiesService.getString("openapi.naver.map.clientSecret");
       
        // 검색 인자 지역 + "공백 필수"+  관광지, 맛집, 숙박
        try {
            String text = URLEncoder.encode(paramMap.getString("addr")+" "+gubun, "UTF-8");
            apiURL = apiURL + "?query="+ text;
            if(!StringUtils.isBlank(paramMap.getString("sort"))){
            	apiURL += "&sort="+paramMap.getString("sort"); // 기본 sim
            }
            if(!StringUtils.isBlank(paramMap.getString("start"))){
            	apiURL += "&start="+paramMap.getString("start"); // 기본 1
            }
            if(!StringUtils.isBlank(paramMap.getString("display"))){
            	apiURL += "&display="+paramMap.getString("display"); // 기본 10
            }
            
            URL url = new URL(apiURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("X-Naver-Client-Id", clientId);
            con.setRequestProperty("X-Naver-Client-Secret", clientSecret);
            int responseCode = con.getResponseCode();
            if(responseCode==200) { 
            	isr = new InputStreamReader(con.getInputStream());
                br = new BufferedReader(isr);
            } else {  
            	isr = new InputStreamReader(con.getErrorStream());
                br = new BufferedReader(isr);
            }
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }
			if(responseCode==200) { 
				jsonObj = new JSONObject(response.toString());
				jsonObj.put("successYn","Y");
			} else {
			 	JSONObject errObj = new JSONObject(response.toString());
			 	jsonObj = new JSONObject();
			 	jsonObj.put("result", errObj);
			 	jsonObj.put("successYn","N");
			}
			if("Y".equals(jsonObj.getString("successYn")) ){
				rtnMap.setString("total", (jsonObj.has("total") ? jsonObj.get("total").toString() : "0"));
				rtnMap.setString("start", (jsonObj.has("start") ? jsonObj.get("start").toString() : "0"));
				rtnMap.setString("display", (jsonObj.has("display") ? jsonObj.get("display").toString() : "0"));
				if(jsonObj.has("items")){
					JSONArray jsonArray = null;
					if(jsonObj.get("items") instanceof JSONArray){
						jsonArray =jsonObj.getJSONArray("items");
					}else{
						jsonArray = new JSONArray();
						jsonArray.put(jsonObj.getJSONObject("items"));
					}
					for(int i=0; i<jsonArray.length();i++){
						JSONObject obj = jsonArray.getJSONObject(i);
						resultList.add(CmmUtil.getMapFromJsonObject(obj));
					}
				}
			}
			rtnMap.setString("code", code);
			rtnMap.setString("successYn", jsonObj.getString("successYn"));
			rtnMap.put("resultList", resultList);
            
        } catch (UnsupportedEncodingException e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} catch (MalformedURLException e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} catch (ProtocolException e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} catch (IOException e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} catch (JSONException e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} catch (Exception e) {
			LOGGER.error("Error in getNaverApiSearch()", e);
		} finally {
			try {
				if(isr != null){
					isr.close();
				}
				if(br != null){
					br.close();
				}
			} catch (IOException e) {
				LOGGER.error("Error in getNaverApiSearch() close", e);
			}
		}
        return rtnMap;
	}
    @Override
	public List<DataMap> getToolsApiNews(DataMap paramMap) {
		
		BufferedReader br = null; 
		InputStreamReader isr = null;
		OutputStream wr = null;
		List<DataMap> mapList = new ArrayList<DataMap>();
		
		try {
			String access_key = propertiesService.getString("openapi.tools.kinds.accessKey");
            String apiURL = propertiesService.getString("openapi.tools.kinds.url");
			
			JSONObject argument = new JSONObject();
			argument.put("query", paramMap.getString("query"));
			argument.put("provider", paramMap.get("provider"));
			argument.put("category", paramMap.get("category"));
			argument.put("sort",  paramMap.get("sort"));
			argument.put("hilight", StringUtils.defaultIfEmpty(paramMap.getString("hilight"), "2000"));
			argument.put("return_from", StringUtils.defaultIfEmpty(paramMap.getString("return_from"), "0"));
			argument.put("return_size", StringUtils.defaultIfEmpty(paramMap.getString("return_size"), "15"));
			argument.put("fields", paramMap.get("fields"));
			
			JSONObject paramJSON = new JSONObject();
			paramJSON.put("access_key", access_key);
			paramJSON.put("argument", argument);	
			
			String body = paramJSON.toString();
            
            URL url = new URL(apiURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            
            con.setDoOutput(true);
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            
            wr = con.getOutputStream();
            wr.write(body.getBytes());
            wr.flush();
           
            int responseCode = con.getResponseCode();
            if(responseCode==200) { // 정상 호출
            	isr = new InputStreamReader(con.getInputStream());
            	br = new BufferedReader(isr);
                JSONObject json = new JSONObject(br.readLine());
                if(json !=null && json.has("return_object")){
                	JSONObject return_object = (JSONObject) json.get("return_object");
                	if(return_object.has("documents")){
                		JSONArray newsArr =  null;
                		if(return_object.get("documents") instanceof JSONArray){
                			newsArr = (JSONArray) return_object.get("documents");
                			
                			for(int i=0; i<newsArr.length(); i++){
    	                      	JSONObject news = (JSONObject) newsArr.get(i);
    	                      	/*DataMap datamap = new DataMap();
    	                      	datamap.setString("news_id", (String)news.get("news_id"));
    	                      	datamap.setString("title", (String)news.get("title"));
    	                      	datamap.setString("hilight", (String)news.get("hilight"));
    	                      	datamap.setString("published_at", (String)news.get("published_at"));
    	                      	datamap.setString("enveloped_at", (String)news.get("enveloped_at"));
    	                      	datamap.setString("dateline", (String)news.get("dateline"));
    	                      	datamap.setString("provider", (String)news.get("provider"));
    	                      	datamap.setString("byline", (String)news.get("byline"));
    	                      	datamap.setString("images", (String)news.get("images"));*/

    	                      	mapList.add(CmmUtil.getMapFromJsonObject(news));
                            }
                		}else{
                			newsArr = new JSONArray();
                			newsArr.put(return_object.get("documents"));
                		}
                	} else {
                		return mapList;
                	}
                } else {
                	return mapList;
                }
           } else {  // 에러 발생
        	   return mapList;
           }
       } catch (UnsupportedEncodingException e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		} catch (MalformedURLException e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		} catch (ProtocolException e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		} catch (IOException e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		} catch (JSONException e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		} catch (Exception e) {
			LOGGER.error("Error in getToolsApiNews()", e);
		}  finally{
			try {
				if(wr != null){
					wr.close();
				}
				if(br != null){
					br.close();
				}
				if(isr != null){
					isr.close();
				}
			} catch (IOException e) {
				LOGGER.error("Error in getToolsApiNews() close", e);
			}
		}
       
		return mapList;
	}
    @Override
	public DataMap getGiaList(DataMap paramMap) {
		
		String resultXml = "", resultCode = "99", resultMsg = ""; // 99 기타 요류
		boolean isSuccess = true;
    	JSONObject xmlJSONObj = null;
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	
		try {
			String addr = propertiesService.getString("api.visitkorea.gia.list.url");;
	    	paramMap.setString("serviceKey", propertiesService.getString("api.visitkorea.gia.serviceKey"));
	    	// contentTypeId 필수 : 호출하는곳에서 맵핑해서 넘겨준다.
	    	// 나머지는 픽스
	    	paramMap.setString("pageNo", "1");
	    	paramMap.setString("numOfRows", "20000");
	    	paramMap.setString("arrange", "A");
	    	paramMap.setString("listYN", "Y");
	    	paramMap.setString("MobileOS", "ETC");
	    	paramMap.setString("MobileApp", "TourAPI3.0_Guide");
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
		    		isSuccess = true;
				} catch (org.json.JSONException jsoe) {
					resultMsg = "[String xml to JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("String xml to JSON Parsing error in getGiaList()", jsoe);
				}
			}else{
				// 통신오류
				resultMsg = "통신 오류상태입니다.";
			}
		} catch (ConnectTimeoutException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaList()", e);
		} catch (UnsupportedEncodingException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaList()", e);
		} catch (HttpException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaList()", e);
		} catch (IOException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaList()", e);
		} catch (Exception e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaList()", e);
		} finally {
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
					resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			if("0000".equals(resultCode)){
	    				JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    				JSONObject jsonItems = jsonBody.getJSONObject("items");
	    				if(jsonItems.has("item")){
	    					JSONArray jsonArray = null;
	    					if(jsonItems.get("item") instanceof JSONArray){
	    						jsonArray =jsonItems.getJSONArray("item");
	    					}else{
	    						jsonArray = new JSONArray();
	    						jsonArray.put(jsonItems.getJSONObject("item"));
	    					}
	    					for(int i=0; i<jsonArray.length();i++){
	    						JSONObject obj = jsonArray.getJSONObject(i);
	    						DataMap map = CmmUtil.getMapFromJsonObject(obj);
	    						if(!StringUtils.isBlank(map.getString("title"))){
	    							map.setString("title",  StringEscapeUtils.unescapeHtml4(map.getString("title")));
	    						}
	    						resultList.add(map);
	    					}
	    				}
	    			}
				} catch (org.json.JSONException jsoe) {
					resultCode = "99";
					resultMsg = "[JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("JSON Parsing error in getGiaList()", jsoe);
				}
			}
			rsMap.setString("resultCode", resultCode);
			rsMap.setString("resultMsg", resultMsg);
			rsMap.put("resultList", resultList);
		}
		return rsMap;
	}
    @Override
    public DataMap getGiaDetailCommon(DataMap paramMap){
    	// 한국관광공사 API 상세 공통정보
		String resultXml = "", resultCode = "99", resultMsg = ""; // 99 기타 요류
		int totalCount = 0;
		boolean isSuccess = true;
    	JSONObject xmlJSONObj = null;
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	
		try {
			String addr = propertiesService.getString("api.visitkorea.gia.detail.common.url");;
	    	paramMap.setString("serviceKey", propertiesService.getString("api.visitkorea.gia.serviceKey"));
	    	//paramMap.setString("contentId", "2518765"); 
	    	//paramMap.setString("contenttypeid", "12"); // 의미가 없는것 같음.
	    	paramMap.setString("MobileOS", "ETC");
	    	paramMap.setString("MobileApp", "TourAPI3.0_Guide");
	    	paramMap.setString("defaultYN", "Y"); //기본정보조회
	    	paramMap.setString("firstImageYN", "Y"); //대표이미지조회
	    	paramMap.setString("areacodeYN", "Y"); // 지역코드조회
	    	paramMap.setString("catcodeYN", "Y"); // 서비스분류코드조회
	    	paramMap.setString("addrinfoYN", "Y"); // 주소조회
	    	paramMap.setString("mapinfoYN", "N"); // 좌표조회
	    	paramMap.setString("overviewYN", "Y"); //개요 조회
	    	paramMap.setString("transGuideYN", "Y"); //길안내조회
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
		    		isSuccess = true;
				} catch (org.json.JSONException jsoe) {
					resultMsg = "[String xml to JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("String xml to JSON Parsing error in getGiaDetailCommon()", jsoe);
				}
			}else{
				// 통신오류
				resultMsg = "통신 오류상태입니다.";
			}
		} catch (ConnectTimeoutException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailCommon()", e);
		} catch (UnsupportedEncodingException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailCommon()", e);
		} catch (HttpException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailCommon()", e);
		} catch (IOException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailCommon()", e);
		} catch (Exception e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailCommon()", e);
		} finally {
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
					resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			if("0000".equals(resultCode)){
	    				JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    				totalCount = jsonBody.getInt("totalCount");
	    				if(totalCount > 0){
		    				JSONObject jsonItems = jsonBody.getJSONObject("items");
		    				if(jsonItems.has("item")){
		    					JSONArray jsonArray = null;
		    					if(jsonItems.get("item") instanceof JSONArray){
		    						jsonArray =jsonItems.getJSONArray("item");
		    					}else{
		    						jsonArray = new JSONArray();
		    						jsonArray.put(jsonItems.getJSONObject("item"));
		    					}
		    					for(int i=0; i<jsonArray.length();i++){
		    						JSONObject obj = jsonArray.getJSONObject(i);
		    						DataMap map = CmmUtil.getMapFromJsonObject(obj);
		    						// 목록에서의 필드명이 같지만 경로 및 파일 다름 : 다른명으로 구분해서 넣어줘여함
		    						if(!StringUtils.isBlank(map.getString("firstimage"))){
		    							map.setString("detCom_firstimage" , map.getString("firstimage"));
		    							map.remove("firstimage");
		    						}
	    							if(!StringUtils.isBlank(map.getString("firstimage2"))){
	    								map.setString("detCom_firstimage2" , map.getString("firstimage2"));
	    								map.remove("firstimage2");
		    						}
	    							if(!StringUtils.isBlank(map.getString("mapx")) && !StringUtils.isBlank(map.getString("mapy"))){
	    								map.setString("xy", map.getString("mapx").trim()+","+map.getString("mapy").trim());
	    								DataMap rtnMap =  getNaverApiReversegeocode(map);
	    								map.setString("sido", rtnMap.getString("sido"));
	    								map.setString("sigugun", rtnMap.getString("sigugun"));
	    								map.remove("xy");
	    							}
		    						resultList.add(map);
		    					}
		    				}
	    				}
	    			}
				} catch (org.json.JSONException jsoe) {
					resultCode = "99";
					resultMsg = "[JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("JSON Parsing error in getGiaDetailCommon()", jsoe);
				}
			}
			
			rsMap.setInt("totalCount", totalCount);
			rsMap.setString("resultCode", resultCode);
			rsMap.setString("resultMsg", resultMsg);
			rsMap.put("resultList", resultList);
		}
		return rsMap;
    }
    @Override
    public DataMap getGiaDetailIntro(DataMap paramMap){
    	// 한국관광공사 API 상세 소개정보
		String resultXml = "", resultCode = "99", resultMsg = ""; // 99 기타 요류
		int totalCount = 0;
		boolean isSuccess = true;
    	JSONObject xmlJSONObj = null;
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	
		try {
			String addr = propertiesService.getString("api.visitkorea.gia.detail.intro.url");;
	    	paramMap.setString("serviceKey", propertiesService.getString("api.visitkorea.gia.serviceKey"));
	    	//paramMap.setString("contentId", "570762"); 
	    	//paramMap.setString("contenttypeid", "39"); // 의미가 없는것 같음.
	    	paramMap.setString("MobileOS", "ETC");
	    	paramMap.setString("MobileApp", "TourAPI3.0_Guide");
	    	paramMap.setString("introYN", "Y");
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
		    		isSuccess = true;
				} catch (org.json.JSONException jsoe) {
					resultMsg = "[String xml to JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("String xml to JSON Parsing error in getGiaDetailIntro()", jsoe);
				}
			}else{
				// 통신오류
				resultMsg = "통신 오류상태입니다.";
			}
		} catch (ConnectTimeoutException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailIntro()", e);
		} catch (UnsupportedEncodingException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailIntro()", e);
		} catch (HttpException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailIntro()", e);
		} catch (IOException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailIntro()", e);
		} catch (Exception e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailIntro()", e);
		} finally {
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
					resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			if("0000".equals(resultCode)){
	    				JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    				totalCount = jsonBody.getInt("totalCount");
	    				if(totalCount > 0){
		    				JSONObject jsonItems = jsonBody.getJSONObject("items");
		    				if(jsonItems.has("item")){
	        					JSONArray jsonArray = null;
	        					if(jsonItems.get("item") instanceof JSONArray){
	        						jsonArray =jsonItems.getJSONArray("item");
	        					}else{
	        						jsonArray = new JSONArray();
	        						jsonArray.put(jsonItems.getJSONObject("item"));
	        					}
	        					for(int i=0; i<jsonArray.length();i++){
	        						resultList.add(CmmUtil.getMapFromJsonObject(jsonArray.getJSONObject(i)));
	        					}
	        				}
	    				}
	    			}
				} catch (org.json.JSONException jsoe) {
					resultCode = "99";
					resultMsg = "[JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("JSON Parsing error in getGiaDetailIntro()", jsoe);
				}
			}
			
			rsMap.setInt("totalCount", totalCount);
			rsMap.setString("resultCode", resultCode);
			rsMap.setString("resultMsg", resultMsg);
			rsMap.put("resultList", resultList);
		}
		return rsMap;
    }
    @Override
    public DataMap getGiaDetailInfo(DataMap paramMap){
    	// 한국관광공사 API 상세 반복 및 코스 정보 or 룸 이미지
		String resultXml = "", resultCode = "99", resultMsg = ""; // 99 기타 요류
		int totalCount = 0;
		boolean isSuccess = true;
    	JSONObject xmlJSONObj = null;
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	
		try {
			String addr = propertiesService.getString("api.visitkorea.gia.detail.info.url");;
	    	paramMap.setString("serviceKey", propertiesService.getString("api.visitkorea.gia.serviceKey"));
	    	//paramMap.setString("contentTypeId", "26");  // 39 반복정보 , 25 코스정보
	    	//paramMap.setString("contentId", "2381406");  // 570762 반복정보  , 2381406 코스정보
	    	paramMap.setString("MobileOS", "ETC");
	    	paramMap.setString("MobileApp", "TourAPI3.0_Guide");
	    	paramMap.setString("listYN", "Y");
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
		    		isSuccess = true;
				} catch (org.json.JSONException jsoe) {
					resultMsg = "[String xml to JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("String xml to JSON Parsing error in getGiaDetailInfo()", jsoe);
				}
			}else{
				// 통신오류
				resultMsg = "통신 오류상태입니다.";
			}
		} catch (ConnectTimeoutException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailInfo()", e);
		} catch (UnsupportedEncodingException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailInfo()", e);
		} catch (HttpException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailInfo()", e);
		} catch (IOException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailInfo()", e);
		} catch (Exception e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailInfo()", e);
		} finally {
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
					resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			if("0000".equals(resultCode)){
	    				JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    				totalCount = jsonBody.getInt("totalCount");
	    				if(totalCount > 0){
		    				JSONObject jsonItems = jsonBody.getJSONObject("items");
		    				if(jsonItems.has("item")){
	        					JSONArray jsonArray = null;
	        					if(jsonItems.get("item") instanceof JSONArray){
	        						jsonArray =jsonItems.getJSONArray("item");
	        					}else{
	        						jsonArray = new JSONArray();
	        						jsonArray.put(jsonItems.getJSONObject("item"));
	        					}
	        					for(int i=0; i<jsonArray.length();i++){
	        						resultList.add(CmmUtil.getMapFromJsonObject(jsonArray.getJSONObject(i)));
	        					}
	        				}
	    				}
	    			}
				} catch (org.json.JSONException jsoe) {
					resultCode = "99";
					resultMsg = "[JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("JSON Parsing error in getGiaDetailInfo()", jsoe);
				}
			}
			
			rsMap.setInt("totalCount", totalCount);
			rsMap.setString("resultCode", resultCode);
			rsMap.setString("resultMsg", resultMsg);
			rsMap.put("resultList", resultList);
		}
		return rsMap;
    }
    @Override
    public DataMap getGiaDetailImage(DataMap paramMap){
    	// 한국관광공사 API 상세 추가이미지 및 메뉴이미지 정보
		String resultXml = "", resultCode = "99", resultMsg = ""; // 99 기타 요류
		int totalCount = 0;
		boolean isSuccess = true;
    	JSONObject xmlJSONObj = null;
    	DataMap rsMap = new DataMap();
    	List<DataMap> resultList = new ArrayList<DataMap>();
    	
		try {
			String addr = propertiesService.getString("api.visitkorea.gia.detail.image.url");;
	    	paramMap.setString("serviceKey", propertiesService.getString("api.visitkorea.gia.serviceKey"));
	    	//paramMap.setString("contentTypeId", "39");  // 39 반복정보 , 25 코스정보
	    	//paramMap.setString("contentId", "570762");  // 570762 반복정보  , 2381406 코스정보
	    	paramMap.setString("MobileOS", "ETC");
	    	paramMap.setString("MobileApp", "TourAPI3.0_Guide");
	    	paramMap.setString("imageYN", StringUtils.defaultString(paramMap.getString("imageYN"), "Y")); // Y : 추가이미지, N : 메뉴이미지
	    	
	    	HttpClient httpClient = new HttpClient();
	    	HttpMethod getMethod = new GetMethod(addr+getQueryString(paramMap));
	    	getMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // encoding : UTF-8
			
			int statusCode = httpClient.executeMethod(getMethod);
			byte[] responseBody = getMethod.getResponseBody();
			resultXml = new String(responseBody, "UTF-8"); // encoding : UTF-8
			if(statusCode == 200){
				try {
		    		xmlJSONObj = XML.toJSONObject(resultXml);
		    		isSuccess = true;
				} catch (org.json.JSONException jsoe) {
					resultMsg = "[String xml to JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("String xml to JSON Parsing error in getGiaDetailImage()", jsoe);
				}
			}else{
				// 통신오류
				resultMsg = "통신 오류상태입니다.";
			}
		} catch (ConnectTimeoutException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailImage()", e);
		} catch (UnsupportedEncodingException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailImage()", e);
		} catch (HttpException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailImage()", e);
		} catch (IOException e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailImage()", e);
		} catch (Exception e) {
			resultMsg = e.getMessage();
			LOGGER.error("Error in getGiaDetailImage()", e);
		} finally {
			if(isSuccess){
				try {
					JSONObject jsonResponse = xmlJSONObj.getJSONObject("response");
					JSONObject jsonHeader = jsonResponse.getJSONObject("header");
					resultCode = jsonHeader.get("resultCode").toString();
	    			resultMsg = jsonHeader.get("resultMsg").toString();
	    			if("0000".equals(resultCode)){
	    				JSONObject jsonBody = jsonResponse.getJSONObject("body");
	    				totalCount = jsonBody.getInt("totalCount");
	    				if(totalCount > 0){
		    				JSONObject jsonItems = jsonBody.getJSONObject("items");
		    				if(jsonItems.has("item")){
	        					JSONArray jsonArray = null;
	        					if(jsonItems.get("item") instanceof JSONArray){
	        						jsonArray =jsonItems.getJSONArray("item");
	        					}else{
	        						jsonArray = new JSONArray();
	        						jsonArray.put(jsonItems.getJSONObject("item"));
	        					}
	        					for(int i=0; i<jsonArray.length();i++){
	        						resultList.add(CmmUtil.getMapFromJsonObject(jsonArray.getJSONObject(i)));
	        					}
	        				}
	    				}
	    			}
				} catch (org.json.JSONException jsoe) {
					resultCode = "99";
					resultMsg = "[JSON Parsing error]"+ jsoe.getMessage();
					LOGGER.error("JSON Parsing error in getGiaDetailImage()", jsoe);
				}
			}
			
			rsMap.setInt("totalCount", totalCount);
			rsMap.setString("resultCode", resultCode);
			rsMap.setString("resultMsg", resultMsg);
			rsMap.put("resultList", resultList);
		}
		return rsMap;
    }
}
