View Javadoc
1   /*
2    * Copyright 2012-2020 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.app.web.go;
17  
18  import java.io.IOException;
19  import java.io.UnsupportedEncodingException;
20  import java.net.URLEncoder;
21  import java.util.Map;
22  
23  import javax.annotation.Resource;
24  
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.Logger;
27  import org.codelibs.core.lang.StringUtil;
28  import org.codelibs.core.net.URLUtil;
29  import org.codelibs.fess.Constants;
30  import org.codelibs.fess.app.web.base.FessSearchAction;
31  import org.codelibs.fess.app.web.error.ErrorAction;
32  import org.codelibs.fess.crawler.util.CharUtil;
33  import org.codelibs.fess.es.log.exentity.ClickLog;
34  import org.codelibs.fess.helper.PathMappingHelper;
35  import org.codelibs.fess.helper.SearchLogHelper;
36  import org.codelibs.fess.helper.ViewHelper;
37  import org.codelibs.fess.util.ComponentUtil;
38  import org.codelibs.fess.util.DocumentUtil;
39  import org.dbflute.util.DfTypeUtil;
40  import org.lastaflute.web.Execute;
41  import org.lastaflute.web.response.ActionResponse;
42  import org.lastaflute.web.response.HtmlResponse;
43  import org.lastaflute.web.response.StreamResponse;
44  
45  public class GoAction extends FessSearchAction {
46  
47      // ===================================================================================
48      //                                                                            Constant
49      //
50      private static final Logger logger = LogManager.getLogger(GoAction.class);
51  
52      @Resource
53      protected PathMappingHelper pathMappingHelper;
54  
55      // ===================================================================================
56      //                                                                           Attribute
57      //
58  
59      // ===================================================================================
60      //                                                                               Hook
61      //                                                                              ======
62  
63      // ===================================================================================
64      //                                                                      Search Execute
65      //                                                                      ==============
66      @Execute
67      public ActionResponse index(final GoForm form) throws IOException {
68          validate(form, messages -> {}, () -> asHtml(virtualHost(path_Error_ErrorJsp)));
69          if (isLoginRequired()) {
70              return redirectToLogin();
71          }
72  
73          Map<String, Object> doc = null;
74          try {
75              doc =
76                      searchHelper.getDocumentByDocId(form.docId,
77                              new String[] { fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldConfigId() }, getUserBean()).orElse(null);
78          } catch (final Exception e) {
79              logger.warn("Failed to request: " + form.docId, e);
80          }
81          if (doc == null) {
82              saveError(messages -> messages.addErrorsDocidNotFound(GLOBAL, form.docId));
83              return redirect(ErrorAction.class);
84          }
85          final String url = DocumentUtil.getValue(doc, fessConfig.getIndexFieldUrl(), String.class);
86          if (url == null) {
87              saveError(messages -> messages.addErrorsDocumentNotFound(GLOBAL, form.docId));
88              return redirect(ErrorAction.class);
89          }
90  
91          if (fessConfig.isSearchLog()) {
92              final String userSessionId = userInfoHelper.getUserCode();
93              if (userSessionId != null) {
94                  final SearchLogHelper searchLogHelper = ComponentUtil.getSearchLogHelper();
95                  final ClickLogxentity/ClickLog.html#ClickLog">ClickLog clickLog = new ClickLog();
96                  clickLog.setUrlId((String) doc.get(fessConfig.getIndexFieldId()));
97                  clickLog.setUrl(url);
98                  clickLog.setRequestedAt(systemHelper.getCurrentTimeAsLocalDateTime());
99                  clickLog.setQueryRequestedAt(DfTypeUtil.toLocalDateTime(Long.parseLong(form.rt)));
100                 clickLog.setUserSessionId(userSessionId);
101                 clickLog.setDocId(form.docId);
102                 clickLog.setQueryId(form.queryId);
103                 if (form.order != null) {
104                     clickLog.setOrder(form.order);
105                 }
106                 searchLogHelper.addClickLog(clickLog);
107             }
108         }
109 
110         String hash;
111         if (StringUtil.isNotBlank(form.hash)) {
112             final String value = URLUtil.decode(form.hash, Constants.UTF_8);
113             final StringBuilder buf = new StringBuilder(value.length() + 100);
114             for (final char c : value.toCharArray()) {
115                 if (CharUtil.isUrlChar(c) || c == ' ') {
116                     buf.append(c);
117                 } else {
118                     try {
119                         buf.append(URLEncoder.encode(String.valueOf(c), Constants.UTF_8));
120                     } catch (final UnsupportedEncodingException e) {
121                         // NOP
122                     }
123                 }
124             }
125             hash = buf.toString();
126         } else {
127             hash = StringUtil.EMPTY;
128         }
129 
130         final String targetUrl = pathMappingHelper.replaceUrl(url);
131         if (isFileSystemPath(targetUrl)) {
132             if (fessConfig.isSearchFileProxyEnabled()) {
133                 final ViewHelper viewHelper = ComponentUtil.getViewHelper();
134                 try {
135                     final StreamResponse response = viewHelper.asContentResponse(doc);
136                     if (response.getHttpStatus().orElse(200) == 404) {
137                         logger.debug("Not found: {}", targetUrl);
138                         saveError(messages -> messages.addErrorsNotFoundOnFileSystem(GLOBAL, targetUrl));
139                         return redirect(ErrorAction.class);
140                     }
141                     return response;
142                 } catch (final Exception e) {
143                     logger.warn("Failed to load: " + doc, e);
144                     saveError(messages -> messages.addErrorsNotLoadFromServer(GLOBAL, targetUrl));
145                     return redirect(ErrorAction.class);
146                 }
147             } else {
148                 return HtmlResponse.fromRedirectPathAsIs(targetUrl + hash);
149             }
150         } else {
151             return HtmlResponse.fromRedirectPathAsIs(DocumentUtil.encodeUrl(targetUrl + hash));
152         }
153     }
154 
155     protected boolean isFileSystemPath(final String url) {
156         return url.startsWith("file:") || url.startsWith("smb:") || url.startsWith("smb1:") || url.startsWith("ftp:")
157                 || url.startsWith("storage:");
158     }
159 }