package nlib.sch.web; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.activation.MimetypesFileTypeMap; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import nlib.cmm.Constant; import nlib.sch.service.CmmVO; import nlib.sch.util.DataMap; import egovframework.rte.fdl.cmmn.exception.EgovBizException; import nlib.cmm.NlibCommonController; import nlib.cmm.service.CodeService; import nlib.cmm.service.NlibProperty; import nlib.cmm.service.PagingVO; import nlib.col.service.CartService; import nlib.col.service.CollectionService; import nlib.col.service.CollectionVO; import nlib.col.service.InterestService; import nlib.col.service.RisService; import nlib.sch.service.NlibSearchService; import nlib.sch.service.NlibSearchVO; import nlib.sch.util.NlibCmmUtil; import nlib.user.service.NlibLoginVO; import nlib.util.StringUtil; @Controller public class NlibSearchController extends NlibCommonController { private static final Logger log = LoggerFactory.getLogger(NlibSearchController.class); @Value("#{properties['list.paging.page.size']}") private String DEFUALT_PAGE_SIZE; @Resource(name = "cartService") private CartService cartService; @Resource(name = "codeService") private CodeService codeService; @Resource(name="risService") private RisService risService; @Resource(name = "interestService") private InterestService interestService; @Resource(name = "nlibProperty") protected NlibProperty nlibProperty; @Resource(name = "collectionService") private CollectionService collectionService; @Resource(name = "nlibSearchService") private NlibSearchService nlibSearchService; /** * 소장자료 화면을 호출한다. * * @param req * @return */ @RequestMapping(value = {"/search/searchList.do", "/search/searchListCondition.do"} ) public String searchList( HttpServletRequest req , Authentication authentication , ModelMap model , @ModelAttribute("searchVO") NlibSearchVO searchVO , HttpServletRequest request , HttpServletResponse res , String csrfToken) throws Exception { HttpSession session = request.getSession(); String councilCd = (String)session.getAttribute("councilCd"); boolean fromMenu = request.getServletPath().contains("/search/searchList.do"); if(fromMenu) { String sfield = searchVO.getSfield(); String query = searchVO.getQuery(); searchVO = new NlibSearchVO(); searchVO.setSfield(sfield); searchVO.setQuery(query); } if(!fromMenu && !isValidCsrfToken(request, csrfToken)) { model.addAttribute("msg", "잘못된 접근입니다."); model.addAttribute("url","/"); return "nlib/cmm/alert"; } //검색엔진파라미터로 문화원코드 searchVO.setMngOrgCd(councilCd); List operList = new ArrayList(); // 페이징 사이즈 코드 목록 조회 (DB방식으로 변경 2021.08.06 KNKIM) List> pageSizeCodes = codeService.listCodes("PAGE_SIZE_OPTION"); if(searchVO.getPageIndex() < 1) searchVO.setPageIndex(1); if(searchVO.getPageSize() < 1) searchVO.setPageSize(DEFUALT_PAGE_SIZE); searchVO.setQuery(StringUtil.getString(searchVO.getQuery(), "")); searchVO.setReQuery(StringUtil.getString(searchVO.getReQuery(), "")); //결과내재검색만 입력했을경우 if(searchVO.getQuery().length() == 0 && searchVO.getReQuery().length() > 0) { searchVO.setQuery(searchVO.getReQuery()); searchVO.setReQuery(""); searchVO.setReQueryChk("query"); } //검색엔진 try{ searchVO = nlibSearchService.getSearch(searchVO); //페이지 셋팅 PagingVO pageVO = new PagingVO(); pageVO.setPagingVO(Integer.parseInt(searchVO.getTotalCount()), searchVO.getPageIndex(), searchVO.getPageSize()); String mbInfoId = getMbInfoId(request); if(StringUtil.isEmpty(mbInfoId)) { // 검색엔진에서 받아온 masterId로 상세정보 조회 operList = collectionService.setDetailInfoForList(searchVO.getResultList(), null); } else { // 검색엔진에서 받아온 masterId로 상세정보 조회 operList = collectionService.setDetailInfoForList(searchVO.getResultList(), getMbInfoId(request)); } //결과 데이터 담기 searchVO.setResultList(operList); // 경로 NlibCmmUtil.setNfsPathModelMap(request,model); model.addAttribute("pageVO", pageVO); model.addAttribute("searchVO", searchVO); }catch(NumberFormatException e){ log.error("searchList.do paging > NumberFormatException 발생 : " + e.toString()); }catch(Exception e){ log.error("searchList.do getSearch > Exception 발생 : " + e.toString()); } //주제분야 목록 조회 List> clsf = codeService.listCtClsfs(); //자료유형 List> firstClassList = codeService.listCodes(Constant.CODE_ID_MASTER_TYPE_DIV_CD); List> secondClassList = codeService.listCodes(Constant.CODE_ID_DTLS_TYPE_DIV_CD); //검색엔진 주제분야 카운트 List> subject= searchVO.getSubjectCountList(); List> type= searchVO.getTypeCountList(); int count = 0; // 검색엔진 건수 자료 조합 for(int i=0; i paramMap , ModelMap model , @ModelAttribute("searchVO") NlibSearchVO searchVO , HttpServletRequest request , HttpServletResponse res ) throws Exception { HttpSession session = request.getSession(); String masterId = request.getParameter("masterId"); String mbInfoId = getMbInfoId(request); String councilCd = (String)session.getAttribute("councilCd"); CollectionVO colVO = new CollectionVO(); colVO.setMasterId(masterId); colVO.setMbInfoId(StringUtil.getString(mbInfoId,"")); colVO.setMngOrgCd(councilCd); collectionService.insertDataInquiryLog(colVO); } /** * 소장자료 상세조회 * * @param req * @return */ @RequestMapping(value = "/search/searchItemDetail.do") public String searchItemDetail( Authentication authentication , @RequestParam Map paramMap , ModelMap model , @ModelAttribute("searchVO") NlibSearchVO searchVO , HttpServletRequest request , HttpServletResponse res ) throws Exception { HttpSession session = request.getSession(); String masterId = request.getParameter("masterId"); List mngOrgList = new ArrayList<>(); List keywordList = new ArrayList<>(); CollectionVO vo = new CollectionVO(); vo.setMasterId(masterId); vo.setMbInfoId(getMbInfoId(request)); vo = collectionService.getItemInfo(vo); if(vo == null) { model.addAttribute("msg", "해당 자료를 조회할 수 없습니다.\\n관리자에게 문의하여 주시기 바랍니다."); model.addAttribute("url","/search/searchList.do"); return "nlib/cmm/alert"; } String councilCd = (String)session.getAttribute("councilCd"); vo.setMngOrgCd(councilCd); //함께 볼만한 자료 List seeTogetherListVO = collectionService.selectSeeTogetherList(vo); //유사한 자료 List similarListVO = collectionService.selectSimilarList(vo); //관리부서명 중복 제외하고 리스트생성 for(int i=0; similarListVO.size() > i; i++) { if(!mngOrgList.contains(similarListVO.get(i).getDeptNm())) { mngOrgList.add(similarListVO.get(i).getDeptNm()); } } model.addAttribute("seeTogetherListVO", seeTogetherListVO); model.addAttribute("similarListVO", similarListVO); model.addAttribute("mngOrgList",mngOrgList); //반납예정일 편집 if(!(vo == null) && !StringUtil.getString(vo.getRtnExpctDd(),"").equals("")) { String strDate = vo.getRtnExpctDd(); SimpleDateFormat dtFormat = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat newDtFormat = new SimpleDateFormat("yyyy-MM-dd"); Date formatDate = dtFormat.parse(strDate); String strNewDtFormat = newDtFormat.format(formatDate); vo.setRtnExpctDd(strNewDtFormat); } //키워드 편집 if(!(vo == null) && !StringUtil.getString(vo.getKeyword(),"").equals("")) { String keyword_arr[] = vo.getKeyword().replace(',',';').split(";"); for(int i = 0; keyword_arr.length > i; i++) { keywordList.add(keyword_arr[i]); } } //목차 편집 if(!(vo == null) && !StringUtil.getString(vo.getBookIndex(),"").equals("")) { String bookIndex = vo.getBookIndex(); bookIndex = bookIndex.replace("---","-"); if(bookIndex.indexOf("***") != -1) bookIndex = bookIndex.substring(0, bookIndex.indexOf("***")); vo.setBookIndex(bookIndex); } MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap(); String imageType = mimetypesFileTypeMap.getContentType(vo.getRprsThumbUrl()); String imagePath = ""; String councilDnsHost = StringUtil.getHostName(request.getRequestURL().toString()); //이미지 확장자를 판별할 수 없을때 if(!imageType.startsWith("image")) { imageType = "jpeg"; imagePath = "https://" + councilDnsHost + ".nculture.org/images/meta_og_image.jpg"; }else { imagePath = StringUtil.getString(vo.getRprsThumbUrl(),""); } // CSRF 토큰 생성 (2021.12.02 KKN 추가) String token = generateCsrfToken(request); model.addAttribute("csrfToken", token); model.addAttribute("imageType",imageType); model.addAttribute("imagePath",imagePath); model.addAttribute("keywordList",keywordList); model.addAttribute("result", vo); model.addAttribute("searchVO", searchVO); return "nlib/collection/searchItemDetail"; } /** * YOURLS의 API를 통해서 단축URL 가져오기 * @param cmmVO * @param model * @param commandMap * @param req * @param res * @return * @throws EgovBizException */ @RequestMapping(value="/search/shorturl-data.do") @ResponseBody public String shorturl ( @ModelAttribute("cmmVO") CmmVO cmmVO , ModelMap model , HttpServletRequest req , HttpServletResponse res ) throws EgovBizException { String returnUrl = ""; DataMap paramMap = DataMap.getParamMap(req); BufferedReader br = null; try { String originUrl = URLEncoder.encode(paramMap.getString("url"), "UTF-8"); URL url = new URL( NlibProperty.getProperty("shorturl.api") + "&action=shorturl&format=xml&title=nculture&url=" + originUrl); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); //con.setRequestProperty("Authorization", header); int responseCode = con.getResponseCode(); if(responseCode==200) { // 정상 호출 br = new BufferedReader(new InputStreamReader(con.getInputStream())); } else { // 에러 발생 br = new BufferedReader(new InputStreamReader(con.getErrorStream())); } String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = br.readLine()) != null) { response.append(inputLine); } String str = response.toString(); Pattern pattern = Pattern.compile("(.+?)"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { returnUrl = matcher.group(1); if(matcher.group(1) == null){ break; } } } catch (IOException e) { log.error("shorturl-data.do 단축url > IOException 발생 : " + e.toString()); } finally { try { if(br != null)br.close(); } catch (IOException e) { log.error("shorturl-data.do 단축url > IOException 발생 : " + e.toString()); } } return returnUrl; } /** * 상세검색 팝업. * * (2021.10.19 YJS 추가) * * @param request * @param model * @return * @throws Exception */ @RequestMapping(value="/search/getDetailedSearchFormPopup.do") public String getDetailedSearchFormPopup(HttpServletRequest request, ModelMap model) throws Exception { //주제분야 목록 조회 List> clsf = codeService.listCtClsfs(); model.addAttribute("firstCategoryList", clsf); model.addAttribute("secondCategoryList", clsf); //자료유형 model.addAttribute("firstClassList", codeService.listCodes(Constant.CODE_ID_MASTER_TYPE_DIV_CD)); model.addAttribute("secondClassList", codeService.listCodes(Constant.CODE_ID_DTLS_TYPE_DIV_CD)); // CSRF 토큰 생성 (2021.12.02 KKN 추가) String token = generateCsrfToken(request); model.addAttribute("csrfToken", token); return "nlib/search/getDetailedSearchFormPopup"; } }