From 7f3ee40e37958836238cecbbdfd98a23ff2da539 Mon Sep 17 00:00:00 2001
From: Shinsuke Sugaya <shinsuke@yahoo.co.jp>
Date: Thu, 22 Oct 2015 14:50:00 +0900
Subject: [PATCH] modify json api
---
.../org/codelibs/fess/api/BaseApiManager.java | 6 +-
.../codelibs/fess/api/es/EsApiManager.java | 19 +-
.../fess/api/json/JsonApiManager.java | 404 ++++++++------
.../codelibs/fess/api/xml/XmlApiManager.java | 407 --------------
.../fess/app/service/FavoriteLogService.java | 62 +++
.../fess/app/service/SearchService.java | 324 +++++++++++
.../dataconfig/AdminDataconfigAction.java | 3 -
.../app/web/admin/dict/AdminDictAction.java | 2 +-
.../kuromoji/AdminDictKuromojiAction.java | 4 +-
.../dict/synonym/AdminDictSynonymAction.java | 8 +-
.../fileconfig/AdminFileconfigAction.java | 3 -
.../web/admin/general/AdminGeneralAction.java | 6 +-
.../admin/keymatch/AdminKeymatchAction.java | 8 +-
.../admin/labeltype/AdminLabeltypeAction.java | 3 -
.../AdminRequestheaderAction.java | 3 -
.../admin/webconfig/AdminWebconfigAction.java | 5 +-
.../org/codelibs/fess/app/web/go/GoForm.java | 2 -
.../fess/app/web/search/SearchAction.java | 516 ++++++------------
.../fess/app/web/search/SearchForm.java | 92 +++-
.../codelibs/fess/dict/DictionaryCreator.java | 10 +-
.../codelibs/fess/dict/DictionaryFile.java | 4 +-
.../codelibs/fess/dict/DictionaryManager.java | 28 +-
.../fess/dict/kuromoji/KuromojiCreator.java | 4 +-
.../fess/dict/kuromoji/KuromojiFile.java | 6 +-
.../fess/dict/synonym/SynonymCreator.java | 4 +-
.../fess/dict/synonym/SynonymFile.java | 6 +-
.../fess/entity/SearchRenderData.java | 170 ++++++
.../fess/entity/SearchRequestParams.java | 27 +
.../codelibs/fess/es/client/FessEsClient.java | 26 +-
.../fess/helper/HotSearchWordHelper.java | 18 +
.../org/codelibs/fess/helper/QueryHelper.java | 72 ++-
.../fess/mylasta/action/FessHtmlPath.java | 3 -
.../fess/mylasta/action/FessUserBean.java | 10 +-
.../org/codelibs/fess/util/ComponentUtil.java | 16 +-
.../org/codelibs/fess/util/DocumentUtil.java | 2 +-
.../codelibs/fess/util/QueryResponseList.java | 8 +-
.../org/codelibs/fess/util/ResourceUtil.java | 6 +-
src/main/resources/fess_api.xml | 5 -
.../webapp/WEB-INF/view/searchResults.jsp | 2 +-
39 files changed, 1258 insertions(+), 1046 deletions(-)
delete mode 100644 src/main/java/org/codelibs/fess/api/xml/XmlApiManager.java
create mode 100644 src/main/java/org/codelibs/fess/app/service/FavoriteLogService.java
create mode 100644 src/main/java/org/codelibs/fess/app/service/SearchService.java
create mode 100644 src/main/java/org/codelibs/fess/entity/SearchRenderData.java
create mode 100644 src/main/java/org/codelibs/fess/entity/SearchRequestParams.java
diff --git a/src/main/java/org/codelibs/fess/api/BaseApiManager.java b/src/main/java/org/codelibs/fess/api/BaseApiManager.java
index 75a216acc..965caf935 100644
--- a/src/main/java/org/codelibs/fess/api/BaseApiManager.java
+++ b/src/main/java/org/codelibs/fess/api/BaseApiManager.java
@@ -33,14 +33,12 @@ public abstract class BaseApiManager implements WebApiManager {
protected static final String HOT_SEARCH_WORD_API = "/hotSearchWordApi";
- protected static final String SUGGEST_API = "/suggestApi";
-
protected static final String SEARCH_API = "/searchApi";
protected String pathPrefix;
protected static enum FormatType {
- SEARCH, LABEL, SUGGEST, HOTSEARCHWORD, FAVORITE, FAVORITES, OTHER, PING;
+ SEARCH, LABEL, HOTSEARCHWORD, FAVORITE, FAVORITES, OTHER, PING;
}
public String getPathPrefix() {
@@ -60,8 +58,6 @@ public abstract class BaseApiManager implements WebApiManager {
return FormatType.SEARCH;
} else if (FormatType.LABEL.name().equals(type)) {
return FormatType.LABEL;
- } else if (FormatType.SUGGEST.name().equals(type)) {
- return FormatType.SUGGEST;
} else if (FormatType.HOTSEARCHWORD.name().equals(type)) {
return FormatType.HOTSEARCHWORD;
} else if (FormatType.FAVORITE.name().equals(type)) {
diff --git a/src/main/java/org/codelibs/fess/api/es/EsApiManager.java b/src/main/java/org/codelibs/fess/api/es/EsApiManager.java
index 8edfacf1e..ab974851c 100644
--- a/src/main/java/org/codelibs/fess/api/es/EsApiManager.java
+++ b/src/main/java/org/codelibs/fess/api/es/EsApiManager.java
@@ -39,23 +39,24 @@ public class EsApiManager extends BaseApiManager {
}
@Override
- public boolean matches(HttpServletRequest request) {
+ public boolean matches(final HttpServletRequest request) {
final String servletPath = request.getServletPath();
if (servletPath.startsWith(pathPrefix)) {
- FessLoginAssist loginAssist = ComponentUtil.getLoginAssist();
+ final FessLoginAssist loginAssist = ComponentUtil.getLoginAssist();
return loginAssist.getSessionUserBean().map(user -> user.hasRoles(acceptedRoles)).orElseGet(() -> Boolean.FALSE).booleanValue();
}
return false;
}
@Override
- public void process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ public void process(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException,
+ ServletException {
String path = request.getServletPath().substring(pathPrefix.length());
if (!path.startsWith("/")) {
path = "/" + path;
}
- Method httpMethod = Method.valueOf(request.getMethod().toUpperCase(Locale.ROOT));
- CurlRequest curlRequest = new CurlRequest(httpMethod, getUrl() + path);
+ final Method httpMethod = Method.valueOf(request.getMethod().toUpperCase(Locale.ROOT));
+ final CurlRequest curlRequest = new CurlRequest(httpMethod, getUrl() + path);
request.getParameterMap().entrySet().stream().forEach(entry -> {
if (entry.getValue().length > 1) {
curlRequest.param(entry.getKey(), String.join(",", entry.getValue()));
@@ -68,7 +69,7 @@ public class EsApiManager extends BaseApiManager {
if (httpMethod != Method.GET) {
try (ServletInputStream in = request.getInputStream(); OutputStream out = con.getOutputStream()) {
CopyUtil.copy(in, out);
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new IORuntimeException(e);
}
}
@@ -76,17 +77,17 @@ public class EsApiManager extends BaseApiManager {
try (InputStream in = con.getInputStream(); ServletOutputStream out = response.getOutputStream()) {
response.setStatus(con.getResponseCode());
CopyUtil.copy(in, out);
- } catch (IOException e) {
+ } catch (final IOException e) {
try (InputStream err = con.getErrorStream()) {
logger.error(new String(InputStreamUtil.getBytes(err), Constants.CHARSET_UTF_8));
- } catch (IOException e1) {}
+ } catch (final IOException e1) {}
throw new IORuntimeException(e);
}
});
// TODO exception
}
- public void setAcceptedRoles(String[] acceptedRoles) {
+ public void setAcceptedRoles(final String[] acceptedRoles) {
this.acceptedRoles = acceptedRoles;
}
diff --git a/src/main/java/org/codelibs/fess/api/json/JsonApiManager.java b/src/main/java/org/codelibs/fess/api/json/JsonApiManager.java
index 8c13bec66..c365333ce 100644
--- a/src/main/java/org/codelibs/fess/api/json/JsonApiManager.java
+++ b/src/main/java/org/codelibs/fess/api/json/JsonApiManager.java
@@ -18,11 +18,15 @@ package org.codelibs.fess.api.json;
import java.io.IOException;
import java.io.StringWriter;
+import java.net.URLDecoder;
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 javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -31,18 +35,28 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringEscapeUtils;
import org.codelibs.core.CoreLibConstants;
import org.codelibs.core.lang.StringUtil;
+import org.codelibs.core.misc.DynamicProperties;
import org.codelibs.fess.Constants;
import org.codelibs.fess.api.BaseApiManager;
-import org.codelibs.fess.api.WebApiRequest;
-import org.codelibs.fess.api.WebApiResponse;
+import org.codelibs.fess.app.service.FavoriteLogService;
+import org.codelibs.fess.app.service.SearchService;
+import org.codelibs.fess.entity.FacetInfo;
+import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.PingResponse;
+import org.codelibs.fess.entity.SearchRenderData;
+import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.es.client.FessEsClient;
import org.codelibs.fess.exception.WebApiException;
+import org.codelibs.fess.helper.FieldHelper;
+import org.codelibs.fess.helper.HotSearchWordHelper;
+import org.codelibs.fess.helper.HotSearchWordHelper.Range;
+import org.codelibs.fess.helper.LabelTypeHelper;
+import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.helper.UserInfoHelper;
import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.DocumentUtil;
import org.codelibs.fess.util.FacetResponse;
import org.codelibs.fess.util.FacetResponse.Field;
-import org.codelibs.fess.util.MoreLikeThisResponse;
-import org.codelibs.fess.util.WebApiUtil;
import org.lastaflute.web.util.LaRequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,6 +65,9 @@ public class JsonApiManager extends BaseApiManager {
private static final Logger logger = LoggerFactory.getLogger(JsonApiManager.class);
+ @Resource
+ protected DynamicProperties crawlerProperties;
+
public JsonApiManager() {
setPathPrefix("/json");
}
@@ -76,9 +93,6 @@ public class JsonApiManager extends BaseApiManager {
case LABEL:
processLabelRequest(request, response, chain);
break;
- case SUGGEST:
- processSuggestRequest(request, response, chain);
- break;
case HOTSEARCHWORD:
processHotSearchWordRequest(request, response, chain);
break;
@@ -119,26 +133,26 @@ public class JsonApiManager extends BaseApiManager {
}
protected void processSearchRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
+ final SearchService searchService = ComponentUtil.getComponent(SearchService.class);
+
int status = 0;
String errMsg = StringUtil.EMPTY;
String query = null;
final StringBuilder buf = new StringBuilder(1000);
request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE, Constants.SEARCH_LOG_ACCESS_TYPE_JSON);
- final String queryId = request.getParameter("queryId");
try {
- chain.doFilter(new WebApiRequest(request, SEARCH_API), new WebApiResponse(response));
- WebApiUtil.validate();
- query = WebApiUtil.getObject("searchQuery");
- final String execTime = WebApiUtil.getObject("execTime");
- final String queryTime = WebApiUtil.getObject("queryTime");
- final String searchTime = WebApiUtil.getObject("searchTime");
- final String pageSize = WebApiUtil.getObject("pageSize");
- final String currentPageNumber = WebApiUtil.getObject("currentPageNumber");
- final String allRecordCount = WebApiUtil.getObject("allRecordCount");
- final String allPageCount = WebApiUtil.getObject("allPageCount");
- final List<Map<String, Object>> documentItems = WebApiUtil.getObject("documentItems");
- final FacetResponse facetResponse = WebApiUtil.getObject("facetResponse");
- final MoreLikeThisResponse moreLikeThisResponse = WebApiUtil.getObject("moreLikeThisResponse");
+ final SearchRenderData data = new SearchRenderData();
+ final SearchApiRequestParams params = new SearchApiRequestParams(request);
+ searchService.search(request, params, data);
+ query = params.getQuery();
+ final String execTime = data.getExecTime();
+ final String queryTime = Long.toString(data.getQueryTime());
+ final String pageSize = Integer.toString(data.getPageSize());
+ final String currentPageNumber = Integer.toString(data.getCurrentPageNumber());
+ final String allRecordCount = Long.toString(data.getAllRecordCount());
+ final String allPageCount = Integer.toString(data.getAllPageCount());
+ final List<Map<String, Object>> documentItems = data.getDocumentItems();
+ final FacetResponse facetResponse = data.getFacetResponse();
buf.append("\"query\":");
buf.append(escapeJson(query));
@@ -146,14 +160,7 @@ public class JsonApiManager extends BaseApiManager {
buf.append(execTime);
buf.append(",\"queryTime\":");
buf.append(queryTime);
- buf.append(",\"searchTime\":");
- buf.append(searchTime);
buf.append(',');
- if (StringUtil.isNotBlank(queryId)) {
- buf.append("\"queryId\":");
- buf.append(escapeJson(queryId));
- buf.append(',');
- }
buf.append("\"pageSize\":");
buf.append(pageSize);
buf.append(',');
@@ -248,46 +255,6 @@ public class JsonApiManager extends BaseApiManager {
buf.append(']');
}
}
- if (moreLikeThisResponse != null && !moreLikeThisResponse.isEmpty()) {
- buf.append(',');
- buf.append("\"moreLikeThis\":[");
- boolean first = true;
- for (final Map.Entry<String, List<Map<String, Object>>> mltEntry : moreLikeThisResponse.entrySet()) {
- if (!first) {
- buf.append(',');
- } else {
- first = false;
- }
- buf.append("{\"id\":");
- buf.append(escapeJson(mltEntry.getKey()));
- buf.append(",\"result\":[");
- boolean first1 = true;
- for (final Map<String, Object> document : mltEntry.getValue()) {
- if (!first1) {
- buf.append(',');
- } else {
- first1 = false;
- }
- buf.append('{');
- boolean first2 = true;
- for (final Map.Entry<String, Object> entry : document.entrySet()) {
- if (StringUtil.isNotBlank(entry.getKey()) && entry.getValue() != null) {
- if (!first2) {
- buf.append(',');
- } else {
- first2 = false;
- }
- buf.append(escapeJson(entry.getKey()));
- buf.append(':');
- buf.append(escapeJson(entry.getValue()));
- }
- }
- buf.append('}');
- }
- buf.append("]}");
- }
- buf.append(']');
- }
} catch (final Exception e) {
status = 1;
errMsg = e.getMessage();
@@ -304,11 +271,13 @@ public class JsonApiManager extends BaseApiManager {
}
protected void processLabelRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
+ final LabelTypeHelper labelTypeHelper = ComponentUtil.getLabelTypeHelper();
+
int status = 0;
String errMsg = StringUtil.EMPTY;
final StringBuilder buf = new StringBuilder(255);
try {
- final List<Map<String, String>> labelTypeItems = ComponentUtil.getLabelTypeHelper().getLabelTypeItemList();
+ final List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList();
buf.append("\"recordCount\":");
buf.append(labelTypeItems.size());
if (!labelTypeItems.isEmpty()) {
@@ -341,91 +310,20 @@ public class JsonApiManager extends BaseApiManager {
}
- protected void processSuggestRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- // TODO
- // int status = 0;
- // String errMsg = StringUtil.EMPTY;
- // final StringBuilder buf = new StringBuilder(255);
- // try {
- // chain.doFilter(new WebApiRequest(request, SUGGEST_API), new WebApiResponse(response));
- // WebApiUtil.validate();
- // final Integer suggestRecordCount = WebApiUtil.getObject("suggestRecordCount");
- // final List<SuggestResponse> suggestResultList = WebApiUtil.getObject("suggestResultList");
- // final List<String> suggestFieldName = WebApiUtil.getObject("suggestFieldName");
- //
- // buf.append("\"recordCount\":");
- // buf.append(suggestRecordCount);
- //
- // if (suggestResultList.size() > 0) {
- // buf.append(',');
- // buf.append("\"result\":[");
- // boolean first1 = true;
- // for (int i = 0; i < suggestResultList.size(); i++) {
- //
- // final SuggestResponse suggestResponse = suggestResultList.get(i);
- //
- // for (final Map.Entry<String, List<String>> entry : suggestResponse.entrySet()) {
- // final String fn = suggestFieldName.get(i);
- // if (!first1) {
- // buf.append(',');
- // } else {
- // first1 = false;
- // }
- //
- // final SuggestResponseList srList = (SuggestResponseList) entry.getValue();
- //
- // buf.append("{\"token\":");
- // buf.append(escapeJson(entry.getKey()));
- // buf.append(", \"fn\":");
- // buf.append(escapeJson(fn));
- // buf.append(", \"startOffset\":");
- // buf.append(Integer.toString(srList.getStartOffset()));
- // buf.append(", \"endOffset\":");
- // buf.append(Integer.toString(srList.getEndOffset()));
- // buf.append(", \"numFound\":");
- // buf.append(Integer.toString(srList.getNumFound()));
- // buf.append(", ");
- // buf.append("\"result\":[");
- // boolean first2 = true;
- // for (final String value : srList) {
- // if (!first2) {
- // buf.append(',');
- // } else {
- // first2 = false;
- // }
- // buf.append(escapeJson(value));
- // }
- // buf.append("]}");
- // }
- //
- // }
- // buf.append(']');
- // }
- // } catch (final Exception e) {
- // if (e instanceof WebApiException) {
- // status = ((WebApiException) e).getStatusCode();
- // } else {
- // status = 1;
- // }
- // errMsg = e.getMessage();
- // if (logger.isDebugEnabled()) {
- // logger.debug("Failed to process a suggest request.", e);
- // }
- // }
- //
- // writeJsonResponse(status, buf.toString(), errMsg);
-
- }
-
protected void processHotSearchWordRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
+ if (Constants.FALSE.equals(crawlerProperties.getProperty(Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY, Constants.TRUE))) {
+ writeJsonResponse(9, null, "Unsupported operation.");
+ return;
+ }
+
+ final HotSearchWordHelper hotSearchWordHelper = ComponentUtil.getHotSearchWordHelper();
int status = 0;
String errMsg = StringUtil.EMPTY;
final StringBuilder buf = new StringBuilder(255);
try {
- chain.doFilter(new WebApiRequest(request, HOT_SEARCH_WORD_API), new WebApiResponse(response));
- WebApiUtil.validate();
- final List<String> hotSearchWordList = WebApiUtil.getObject("hotSearchWordList");
+ final List<String> hotSearchWordList =
+ hotSearchWordHelper.getHotSearchWordList(Range.parseRange(request.getParameter("range")));
buf.append("\"result\":[");
boolean first1 = true;
@@ -455,39 +353,128 @@ public class JsonApiManager extends BaseApiManager {
}
protected void processFavoriteRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- int status = 0;
- String body = null;
- String errMsg = null;
+ if (Constants.FALSE.equals(crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE))) {
+ writeJsonResponse(9, null, "Unsupported operation.");
+ return;
+ }
+
+ final UserInfoHelper userInfoHelper = ComponentUtil.getUserInfoHelper();
+ final FieldHelper fieldHelper = ComponentUtil.getFieldHelper();
+ final SearchService searchService = ComponentUtil.getComponent(SearchService.class);
+ final FavoriteLogService favoriteLogService = ComponentUtil.getComponent(FavoriteLogService.class);
+
try {
- chain.doFilter(new WebApiRequest(request, FAVORITE_API), new WebApiResponse(response));
- WebApiUtil.validate();
+ final String docId = request.getParameter("docId");
+ final String queryId = request.getParameter("queryId");
+
+ final String[] docIds = userInfoHelper.getResultDocIds(URLDecoder.decode(queryId, Constants.UTF_8));
+ if (docIds == null) {
+ throw new WebApiException(6, "No searched urls.");
+ }
+
+ searchService
+ .getDocumentByDocId(docId, new String[] { fieldHelper.idField, fieldHelper.urlField, fieldHelper.favoriteCountField })
+ .ifPresent(doc -> {
+ final String favoriteUrl = doc == null ? null : DocumentUtil.getValue(doc, fieldHelper.urlField, String.class);
+ final String userCode = userInfoHelper.getUserCode();
- body = "\"result\":\"ok\"";
+ if (StringUtil.isBlank(userCode)) {
+ throw new WebApiException(2, "No user session.");
+ } else if (StringUtil.isBlank(favoriteUrl)) {
+ throw new WebApiException(2, "URL is null.");
+ }
+
+ boolean found = false;
+ for (final String id : docIds) {
+ if (docId.equals(id)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new WebApiException(5, "Not found: " + favoriteUrl);
+ }
+
+ if (!favoriteLogService.addUrl(userCode, favoriteUrl)) {
+ throw new WebApiException(4, "Failed to add url: " + favoriteUrl);
+ }
+
+ final String id = DocumentUtil.getValue(doc, fieldHelper.idField, String.class);
+ final Long count = DocumentUtil.getValue(doc, fieldHelper.favoriteCountField, Long.class);
+ if (count != null) {
+ searchService.update(id, fieldHelper.favoriteCountField, count.longValue() + 1);
+ } else {
+ throw new WebApiException(7, "Failed to update count: " + favoriteUrl);
+ }
+
+ writeJsonResponse(0, "\"result\":\"ok\"", null);
+
+ }).orElse(() -> {
+ throw new WebApiException(6, "Not found: " + docId);
+ });
} catch (final Exception e) {
+ int status;
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
- errMsg = e.getMessage();
+ writeJsonResponse(status, null, e.getMessage());
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a favorite request.", e);
}
}
- writeJsonResponse(status, body, errMsg);
}
protected void processFavoritesRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
+ if (Constants.FALSE.equals(crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE))) {
+ writeJsonResponse(9, null, "Unsupported operation.");
+ return;
+ }
+
+ final UserInfoHelper userInfoHelper = ComponentUtil.getUserInfoHelper();
+ final FieldHelper fieldHelper = ComponentUtil.getFieldHelper();
+ final SearchService searchService = ComponentUtil.getComponent(SearchService.class);
+ final FavoriteLogService favoriteLogService = ComponentUtil.getComponent(FavoriteLogService.class);
+
int status = 0;
String body = null;
String errMsg = null;
try {
- chain.doFilter(new WebApiRequest(request, FAVORITES_API), new WebApiResponse(response));
- WebApiUtil.validate();
- final List<String> docIdList = WebApiUtil.getObject("docIdList");
+ final String queryId = request.getParameter("queryId");
+ final String userCode = userInfoHelper.getUserCode();
+
+ if (StringUtil.isBlank(userCode)) {
+ throw new WebApiException(2, "No user session.");
+ } else if (StringUtil.isBlank(queryId)) {
+ throw new WebApiException(3, "Query ID is null.");
+ }
+
+ final String[] docIds = userInfoHelper.getResultDocIds(queryId);
+ final List<Map<String, Object>> docList =
+ searchService.getDocumentListByDocIds(docIds, new String[] { fieldHelper.urlField, fieldHelper.docIdField,
+ fieldHelper.favoriteCountField });
+ List<String> urlList = new ArrayList<>(docList.size());
+ for (final Map<String, Object> doc : docList) {
+ final String urlObj = DocumentUtil.getValue(doc, fieldHelper.urlField, String.class);
+ if (urlObj != null) {
+ urlList.add(urlObj.toString());
+ }
+ }
+ urlList = favoriteLogService.getUrlList(userCode, urlList);
+ final List<String> docIdList = new ArrayList<>(urlList.size());
+ for (final Map<String, Object> doc : docList) {
+ final String urlObj = DocumentUtil.getValue(doc, fieldHelper.urlField, String.class);
+ if (urlObj != null && urlList.contains(urlObj)) {
+ final String docIdObj = DocumentUtil.getValue(doc, fieldHelper.docIdField, String.class);
+ if (docIdObj != null) {
+ docIdList.add(docIdObj);
+ }
+ }
+ }
final StringBuilder buf = new StringBuilder();
buf.append("\"num\":").append(docIdList.size());
@@ -671,4 +658,103 @@ public class JsonApiManager extends BaseApiManager {
return Integer.toHexString(ch).toUpperCase();
}
+ protected static class SearchApiRequestParams implements SearchRequestParams {
+
+ private final HttpServletRequest request;
+
+ private int startPosition = -1;
+
+ private int pageSize = -1;
+
+ protected SearchApiRequestParams(final HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getQuery() {
+ return request.getParameter("query");
+ }
+
+ @Override
+ public String getOperator() {
+ return request.getParameter("op");
+ }
+
+ @Override
+ public String[] getAdditional() {
+ return request.getParameterValues("additional");
+ }
+
+ @Override
+ public Map<String, String[]> getFields() {
+ // TODO Auto-generated method stub
+ return new HashMap<>();
+ }
+
+ @Override
+ public String[] getLanguages() {
+ return request.getParameterValues("lang");
+ }
+
+ @Override
+ public GeoInfo getGeoInfo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public FacetInfo getFacetInfo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getSort() {
+ return request.getParameter("sort");
+ }
+
+ @Override
+ public int getStartPosition() {
+ if (startPosition != -1) {
+ return startPosition;
+ }
+
+ final String start = request.getParameter("start");
+ final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+ if (StringUtil.isBlank(start)) {
+ startPosition = queryHelper.getDefaultStart();
+ } else {
+ try {
+ startPosition = Integer.parseInt(start);
+ } catch (final NumberFormatException e) {
+ startPosition = queryHelper.getDefaultStart();
+ }
+ }
+ return startPosition;
+ }
+
+ @Override
+ public int getPageSize() {
+ if (pageSize != -1) {
+ return pageSize;
+ }
+
+ final String num = request.getParameter("num");
+ final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+ if (StringUtil.isBlank(num)) {
+ pageSize = queryHelper.getDefaultPageSize();
+ } else {
+ try {
+ pageSize = Integer.parseInt(num);
+ if (pageSize > queryHelper.getMaxPageSize() || pageSize <= 0) {
+ pageSize = queryHelper.getMaxPageSize();
+ }
+ } catch (final NumberFormatException e) {
+ pageSize = queryHelper.getDefaultPageSize();
+ }
+ }
+ return pageSize;
+ }
+
+ }
}
diff --git a/src/main/java/org/codelibs/fess/api/xml/XmlApiManager.java b/src/main/java/org/codelibs/fess/api/xml/XmlApiManager.java
deleted file mode 100644
index 3a3518dc8..000000000
--- a/src/main/java/org/codelibs/fess/api/xml/XmlApiManager.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright 2009-2015 the CodeLibs Project and the Others.
- *
- * 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 org.codelibs.fess.api.xml;
-
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.codelibs.core.CoreLibConstants;
-import org.codelibs.core.lang.StringUtil;
-import org.codelibs.fess.Constants;
-import org.codelibs.fess.api.BaseApiManager;
-import org.codelibs.fess.api.WebApiRequest;
-import org.codelibs.fess.api.WebApiResponse;
-import org.codelibs.fess.entity.PingResponse;
-import org.codelibs.fess.es.client.FessEsClient;
-import org.codelibs.fess.util.ComponentUtil;
-import org.codelibs.fess.util.FacetResponse;
-import org.codelibs.fess.util.FacetResponse.Field;
-import org.codelibs.fess.util.MoreLikeThisResponse;
-import org.codelibs.fess.util.WebApiUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class XmlApiManager extends BaseApiManager {
- private static final Logger logger = LoggerFactory.getLogger(XmlApiManager.class);
-
- public XmlApiManager() {
- setPathPrefix("/xml");
- }
-
- @Override
- public boolean matches(final HttpServletRequest request) {
- if (Constants.FALSE.equals(ComponentUtil.getCrawlerProperties().getProperty(Constants.WEB_API_XML_PROPERTY, Constants.TRUE))) {
- return false;
- }
-
- final String servletPath = request.getServletPath();
- return servletPath.startsWith(pathPrefix);
- }
-
- @Override
- public void process(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException,
- ServletException {
- final String formatType = request.getParameter("type");
- switch (getFormatType(formatType)) {
- case SEARCH:
- processSearchRequest(request, response, chain);
- break;
- case LABEL:
- processLabelRequest(request, response, chain);
- break;
- case SUGGEST:
- processSuggestRequest(request, response, chain);
- break;
- case PING:
- processPingRequest(request, response, chain);
- break;
- default:
- writeXmlResponse(-1, StringUtil.EMPTY, "Not found.");
- break;
- }
-
- }
-
- protected void processPingRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- final FessEsClient fessEsClient = ComponentUtil.getElasticsearchClient();
- int status;
- String errMsg = null;
- try {
- final PingResponse pingResponse = fessEsClient.ping();
- status = pingResponse.getStatus();
- } catch (final Exception e) {
- status = 9;
- errMsg = e.getMessage();
- if (errMsg == null) {
- errMsg = e.getClass().getName();
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Failed to process a ping request.", e);
- }
- }
-
- writeXmlResponse(status, null, errMsg);
- }
-
- protected void processSearchRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- int status = 0;
- String errMsg = StringUtil.EMPTY;
- final StringBuilder buf = new StringBuilder(1000);
- String query = null;
- request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE, Constants.SEARCH_LOG_ACCESS_TYPE_XML);
- final String queryId = request.getParameter("queryId");
- try {
- chain.doFilter(new WebApiRequest(request, SEARCH_API), new WebApiResponse(response));
- WebApiUtil.validate();
- query = WebApiUtil.getObject("searchQuery");
- final String execTime = WebApiUtil.getObject("execTime");
- final String queryTime = WebApiUtil.getObject("queryTime");
- final String searchTime = WebApiUtil.getObject("searchTime");
- final String pageSize = WebApiUtil.getObject("pageSize");
- final String currentPageNumber = WebApiUtil.getObject("currentPageNumber");
- final String allRecordCount = WebApiUtil.getObject("allRecordCount");
- final String allPageCount = WebApiUtil.getObject("allPageCount");
- final List<Map<String, Object>> documentItems = WebApiUtil.getObject("documentItems");
- final FacetResponse facetResponse = WebApiUtil.getObject("facetResponse");
- final MoreLikeThisResponse moreLikeThisResponse = WebApiUtil.getObject("moreLikeThisResponse");
-
- buf.append("<query>");
- buf.append(escapeXml(query));
- buf.append("</query>");
- buf.append("<exec-time>");
- buf.append(execTime);
- buf.append("</exec-time>");
- buf.append("<query-time>");
- buf.append(queryTime);
- buf.append("</query-time>");
- buf.append("<search-time>");
- buf.append(searchTime);
- buf.append("</search-time>");
- if (StringUtil.isNotBlank(queryId)) {
- buf.append("<query-id>");
- buf.append(escapeXml(queryId));
- buf.append("</query-id>");
- }
- buf.append("<page-size>");
- buf.append(pageSize);
- buf.append("</page-size>");
- buf.append("<page-number>");
- buf.append(currentPageNumber);
- buf.append("</page-number>");
- buf.append("<record-count>");
- buf.append(allRecordCount);
- buf.append("</record-count>");
- buf.append("<page-count>");
- buf.append(allPageCount);
- buf.append("</page-count>");
- buf.append("<result>");
- for (final Map<String, Object> document : documentItems) {
- buf.append("<doc>");
- for (final Map.Entry<String, Object> entry : document.entrySet()) {
- final String name = entry.getKey();
- if (StringUtil.isNotBlank(name) && entry.getValue() != null && ComponentUtil.getQueryHelper().isApiResponseField(name)) {
- final String tagName = convertTagName(name);
- buf.append('<');
- buf.append(tagName);
- buf.append('>');
- buf.append(escapeXml(entry.getValue()));
- buf.append("</");
- buf.append(tagName);
- buf.append('>');
- }
- }
- buf.append("</doc>");
- }
- buf.append("</result>");
- if (facetResponse != null && facetResponse.hasFacetResponse()) {
- buf.append("<facet>");
- // facet field
- if (facetResponse.getFieldList() != null) {
- for (final Field field : facetResponse.getFieldList()) {
- buf.append("<field name=\"");
- buf.append(escapeXml(field.getName()));
- buf.append("\">");
- for (final Map.Entry<String, Long> entry : field.getValueCountMap().entrySet()) {
- buf.append("<value count=\"");
- buf.append(escapeXml(entry.getValue()));
- buf.append("\">");
- buf.append(escapeXml(entry.getKey()));
- buf.append("</value>");
- }
- buf.append("</field>");
- }
- }
- // facet query
- if (facetResponse.getQueryCountMap() != null) {
- buf.append("<query>");
- for (final Map.Entry<String, Long> entry : facetResponse.getQueryCountMap().entrySet()) {
- buf.append("<value count=\"");
- buf.append(escapeXml(entry.getValue()));
- buf.append("\">");
- buf.append(escapeXml(entry.getKey()));
- buf.append("</value>");
- }
- buf.append("</query>");
- }
- buf.append("</facet>");
- }
- if (moreLikeThisResponse != null && !moreLikeThisResponse.isEmpty()) {
- buf.append("<more-like-this>");
- for (final Map.Entry<String, List<Map<String, Object>>> mltEntry : moreLikeThisResponse.entrySet()) {
- buf.append("<result id=\"");
- buf.append(escapeXml(mltEntry.getKey()));
- buf.append("\">");
- for (final Map<String, Object> document : mltEntry.getValue()) {
- buf.append("<doc>");
- for (final Map.Entry<String, Object> entry : document.entrySet()) {
- if (StringUtil.isNotBlank(entry.getKey()) && entry.getValue() != null) {
- final String tagName = convertTagName(entry.getKey());
- buf.append('<');
- buf.append(tagName);
- buf.append('>');
- buf.append(escapeXml(entry.getValue().toString()));
- buf.append("</");
- buf.append(tagName);
- buf.append('>');
- }
- }
- buf.append("</doc>");
- }
- buf.append("</result>");
- }
- buf.append("</more-like-this>");
- }
- } catch (final Exception e) {
- status = 1;
- errMsg = e.getMessage();
- if (errMsg == null) {
- errMsg = e.getClass().getName();
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Failed to process a search request.", e);
- }
- }
-
- writeXmlResponse(status, buf.toString(), errMsg);
- }
-
- private String convertTagName(final String name) {
- final String tagName = StringUtil.decamelize(name).replaceAll("_", "-").toLowerCase();
- return tagName;
- }
-
- protected void processLabelRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- int status = 0;
- String errMsg = StringUtil.EMPTY;
- final StringBuilder buf = new StringBuilder(255);
- try {
- final List<Map<String, String>> labelTypeItems = ComponentUtil.getLabelTypeHelper().getLabelTypeItemList();
- buf.append("<record-count>");
- buf.append(labelTypeItems.size());
- buf.append("</record-count>");
- buf.append("<result>");
- for (final Map<String, String> labelMap : labelTypeItems) {
- buf.append("<label>");
- buf.append("<name>");
- buf.append(escapeXml(labelMap.get(Constants.ITEM_LABEL)));
- buf.append("</name>");
- buf.append("<value>");
- buf.append(escapeXml(labelMap.get(Constants.ITEM_VALUE)));
- buf.append("</value>");
- buf.append("</label>");
- }
- buf.append("</result>");
- } catch (final Exception e) {
- status = 1;
- errMsg = e.getMessage();
- if (logger.isDebugEnabled()) {
- logger.debug("Failed to process a label request.", e);
- }
-
- }
-
- writeXmlResponse(status, buf.toString(), errMsg);
- }
-
- protected void processSuggestRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
- // TODO
- // int status = 0;
- // String errMsg = StringUtil.EMPTY;
- // final StringBuilder buf = new StringBuilder(255);
- // try {
- // chain.doFilter(new WebApiRequest(request, SUGGEST_API), new WebApiResponse(response));
- // WebApiUtil.validate();
- // final Integer suggestRecordCount = WebApiUtil.getObject("suggestRecordCount");
- // final List<SuggestResponse> suggestResultList = WebApiUtil.getObject("suggestResultList");
- // final List<String> suggestFieldName = WebApiUtil.getObject("suggestFieldName");
- //
- // buf.append("<record-count>");
- // buf.append(suggestRecordCount);
- // buf.append("</record-count>");
- // if (suggestResultList.size() > 0) {
- // buf.append("<result>");
- //
- // for (int i = 0; i < suggestResultList.size(); i++) {
- //
- // final SuggestResponse suggestResponse = suggestResultList.get(i);
- //
- // for (final Map.Entry<String, List<String>> entry : suggestResponse.entrySet()) {
- // final SuggestResponseList srList = (SuggestResponseList) entry.getValue();
- // final String fn = suggestFieldName.get(i);
- // buf.append("<suggest>");
- // buf.append("<token>");
- // buf.append(escapeXml(entry.getKey()));
- // buf.append("</token>");
- // buf.append("<fn>");
- // buf.append(escapeXml(fn));
- // buf.append("</fn>");
- // buf.append("<start-offset>");
- // buf.append(escapeXml(Integer.toString(srList.getStartOffset())));
- // buf.append("</start-offset>");
- // buf.append("<end-offset>");
- // buf.append(escapeXml(Integer.toString(srList.getEndOffset())));
- // buf.append("</end-offset>");
- // buf.append("<num-found>");
- // buf.append(escapeXml(Integer.toString(srList.getNumFound())));
- // buf.append("</num-found>");
- // buf.append("<result>");
- // for (final String value : srList) {
- // buf.append("<value>");
- // buf.append(escapeXml(value));
- // buf.append("</value>");
- // }
- // buf.append("</result>");
- // buf.append("</suggest>");
- //
- // }
- // }
- // buf.append("</result>");
- // }
- // } catch (final Exception e) {
- // if (e instanceof WebApiException) {
- // status = ((WebApiException) e).getStatusCode();
- // } else {
- // status = 1;
- // }
- // errMsg = e.getMessage();
- // if (logger.isDebugEnabled()) {
- // logger.debug("Failed to process a suggest request.", e);
- // }
- // }
- //
- // writeXmlResponse(status, buf.toString(), errMsg);
- }
-
- protected void writeXmlResponse(final int status, final String body, final String errMsg) {
- final StringBuilder buf = new StringBuilder(1000);
- buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- buf.append("<response>");
- buf.append("<version>");
- buf.append(Constants.WEB_API_VERSION);
- buf.append("</version>");
- buf.append("<status>");
- buf.append(status);
- buf.append("</status>");
- if (status == 0) {
- if (StringUtil.isNotBlank(body)) {
- buf.append(body);
- }
- } else {
- buf.append("<message>");
- buf.append(escapeXml(errMsg));
- buf.append("</message>");
- }
- buf.append("</response>");
- write(buf.toString(), "text/xml", Constants.UTF_8);
-
- }
-
- protected String escapeXml(final Object obj) {
- final StringBuilder buf = new StringBuilder(255);
- if (obj instanceof List<?>) {
- buf.append("<list>");
- for (final Object child : (List<?>) obj) {
- buf.append("<item>").append(escapeXml(child)).append("</item>");
- }
- buf.append("</list>");
- } else if (obj instanceof Map<?, ?>) {
- buf.append("<data>");
- for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
-
- buf.append("<name>").append(escapeXml(entry.getKey())).append("</name><value>").append(escapeXml(entry.getValue()))
- .append("</value>");
- }
- buf.append("</data>");
- } else if (obj instanceof Date) {
- final SimpleDateFormat sdf = new SimpleDateFormat(CoreLibConstants.DATE_FORMAT_ISO_8601_EXTEND);
- buf.append(StringEscapeUtils.escapeXml(sdf.format(obj)));
- } else if (obj != null) {
- buf.append(StringEscapeUtils.escapeXml(obj.toString()));
- }
- return buf.toString();
- }
-
-}
diff --git a/src/main/java/org/codelibs/fess/app/service/FavoriteLogService.java b/src/main/java/org/codelibs/fess/app/service/FavoriteLogService.java
new file mode 100644
index 000000000..e88597ae2
--- /dev/null
+++ b/src/main/java/org/codelibs/fess/app/service/FavoriteLogService.java
@@ -0,0 +1,62 @@
+package org.codelibs.fess.app.service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.codelibs.fess.es.exbhv.FavoriteLogBhv;
+import org.codelibs.fess.es.exbhv.UserInfoBhv;
+import org.codelibs.fess.es.exentity.FavoriteLog;
+import org.codelibs.fess.helper.SystemHelper;
+import org.dbflute.cbean.result.ListResultBean;
+
+public class FavoriteLogService {
+ @Resource
+ protected SystemHelper systemHelper;
+
+ @Resource
+ protected UserInfoBhv userInfoBhv;
+
+ @Resource
+ protected FavoriteLogBhv favoriteLogBhv;
+
+ public boolean addUrl(final String userCode, final String url) {
+ return userInfoBhv.selectEntity(cb -> {
+ cb.query().setCode_Equal(userCode);
+ }).map(userInfo -> {
+ final FavoriteLog favoriteLog = new FavoriteLog();
+ favoriteLog.setUserInfoId(userInfo.getId());
+ favoriteLog.setUrl(url);
+ favoriteLog.setCreatedTime(systemHelper.getCurrentTimeAsLong());
+ favoriteLogBhv.insert(favoriteLog);
+ return true;
+ }).orElse(false);
+ }
+
+ public List<String> getUrlList(final String userCode, final List<String> urlList) {
+ if (urlList.isEmpty()) {
+ return urlList;
+ }
+
+ return userInfoBhv.selectEntity(cb -> {
+ cb.query().setCode_Equal(userCode);
+ }).map(userInfo -> {
+ final ListResultBean<FavoriteLog> list = favoriteLogBhv.selectList(cb2 -> {
+ cb2.query().setUserInfoId_Equal(userInfo.getId());
+ cb2.query().setUrl_InScope(urlList);
+ });
+ if (!list.isEmpty()) {
+ final List<String> newUrlList = new ArrayList<>(list.size());
+ for (final FavoriteLog favoriteLog : list) {
+ newUrlList.add(favoriteLog.getUrl());
+ }
+ return newUrlList;
+ }
+ return Collections.<String> emptyList();
+ }).orElse(Collections.<String> emptyList());
+
+ }
+
+}
diff --git a/src/main/java/org/codelibs/fess/app/service/SearchService.java b/src/main/java/org/codelibs/fess/app/service/SearchService.java
new file mode 100644
index 000000000..c8a409c95
--- /dev/null
+++ b/src/main/java/org/codelibs/fess/app/service/SearchService.java
@@ -0,0 +1,324 @@
+package org.codelibs.fess.app.service;
+
+import java.text.NumberFormat;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.codelibs.core.lang.StringUtil;
+import org.codelibs.core.misc.DynamicProperties;
+import org.codelibs.fess.Constants;
+import org.codelibs.fess.entity.SearchRenderData;
+import org.codelibs.fess.entity.SearchRequestParams;
+import org.codelibs.fess.es.client.FessEsClient;
+import org.codelibs.fess.es.client.FessEsClient.SearchConditionBuilder;
+import org.codelibs.fess.es.exentity.SearchLog;
+import org.codelibs.fess.es.exentity.UserInfo;
+import org.codelibs.fess.helper.FieldHelper;
+import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.helper.SearchLogHelper;
+import org.codelibs.fess.helper.SystemHelper;
+import org.codelibs.fess.helper.UserInfoHelper;
+import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.QueryResponseList;
+import org.dbflute.optional.OptionalEntity;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SearchService {
+
+ // ===================================================================================
+ // Constant
+ //
+ private static final Logger logger = LoggerFactory.getLogger(SearchService.class);
+
+ protected static final Pattern FIELD_EXTRACTION_PATTERN = Pattern.compile("^([a-zA-Z0-9_]+):.*");
+
+ // ===================================================================================
+ // Attribute
+ //
+ @Resource
+ protected DynamicProperties crawlerProperties;
+
+ @Resource
+ protected FessEsClient fessEsClient;
+
+ @Resource
+ protected SystemHelper systemHelper;
+
+ @Resource
+ protected FieldHelper fieldHelper;
+
+ @Resource
+ protected QueryHelper queryHelper;
+
+ @Resource
+ protected UserInfoHelper userInfoHelper;
+
+ // ===================================================================================
+ // Method
+ // ==============
+
+ public void search(final HttpServletRequest request, final SearchRequestParams params, final SearchRenderData data) {
+ final long startTime = System.currentTimeMillis();
+ final boolean searchLogSupport =
+ Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE));
+
+ if (StringUtil.isNotBlank(params.getOperator())) {
+ request.setAttribute(Constants.DEFAULT_OPERATOR, params.getOperator());
+ }
+
+ final StringBuilder queryBuf = new StringBuilder(255);
+ if (StringUtil.isNotBlank(params.getQuery())) {
+ if (params.getQuery().indexOf(" OR ") >= 0) {
+ queryBuf.append('(').append(params.getQuery()).append(')');
+ } else {
+ queryBuf.append(params.getQuery());
+ }
+ }
+ if (params.getAdditional() != null) {
+ appendAdditionalQuery(params.getAdditional(), additional -> {
+ queryBuf.append(' ').append(additional);
+ });
+ }
+ params.getFields().entrySet().stream().forEach(entry -> {
+ appendQueries(queryBuf, entry.getKey(), entry.getValue());
+ });
+ if (StringUtil.isNotBlank(params.getSort())) {
+ queryBuf.append(" sort:").append(params.getSort());
+ }
+ if (params.getLanguages() != null) {
+ appendQueries(queryBuf, fieldHelper.langField, params.getLanguages());
+ }
+
+ final String query = queryBuf.toString().trim();
+
+ final int pageStart = params.getStartPosition();
+ final int pageSize = params.getPageSize();
+ final List<Map<String, Object>> documentItems =
+ fessEsClient.search(
+ fieldHelper.docIndex,
+ fieldHelper.docType,
+ searchRequestBuilder -> {
+ return SearchConditionBuilder.builder(searchRequestBuilder).query(query).offset(pageStart).size(pageSize)
+ .facetInfo(params.getFacetInfo()).geoInfo(params.getGeoInfo())
+ .responseFields(queryHelper.getResponseFields()).build();
+ }, (searchRequestBuilder, execTime, searchResponse) -> {
+ final QueryResponseList queryResponseList = ComponentUtil.getQueryResponseList();
+ queryResponseList.init(searchResponse, pageStart, pageSize);
+ return queryResponseList;
+ });
+ data.setDocumentItems(documentItems);
+
+ // search
+ final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
+ data.setFacetResponse(queryResponseList.getFacetResponse());
+
+ final String[] highlightQueries = (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
+ if (highlightQueries != null) {
+ final StringBuilder buf = new StringBuilder(100);
+ for (final String q : highlightQueries) {
+ buf.append("&hq=").append(q);
+ }
+ data.setAppendHighlightParams(buf.toString());
+ }
+
+ // search log
+ if (searchLogSupport) {
+ storeSearchLog(request, query, pageStart, pageSize, queryResponseList);
+ }
+
+ queryResponseList.setExecTime(System.currentTimeMillis() - startTime);
+ final NumberFormat nf = NumberFormat.getInstance(request.getLocale());
+ nf.setMaximumIntegerDigits(2);
+ nf.setMaximumFractionDigits(2);
+ String execTime;
+ try {
+ execTime = nf.format((double) queryResponseList.getExecTime() / 1000);
+ } catch (final Exception e) {
+ execTime = StringUtil.EMPTY;
+ }
+ data.setExecTime(execTime);
+
+ data.setPageSize(queryResponseList.getPageSize());
+ data.setCurrentPageNumber(queryResponseList.getCurrentPageNumber());
+ data.setAllRecordCount(queryResponseList.getAllRecordCount());
+ data.setAllPageCount(queryResponseList.getAllPageCount());
+ data.setExistNextPage(queryResponseList.isExistNextPage());
+ data.setExistPrevPage(queryResponseList.isExistPrevPage());
+ data.setCurrentStartRecordNumber(queryResponseList.getCurrentStartRecordNumber());
+ data.setCurrentEndRecordNumber(queryResponseList.getCurrentEndRecordNumber());
+ data.setPageNumberList(queryResponseList.getPageNumberList());
+ data.setPartialResults(queryResponseList.isPartialResults());
+ data.setQueryTime(queryResponseList.getQueryTime());
+ data.setSearchQuery(query);
+ }
+
+ protected void storeSearchLog(final HttpServletRequest request, final String query, final int pageStart, final int pageSize,
+ final QueryResponseList queryResponseList) {
+ final long now = systemHelper.getCurrentTimeAsLong();
+
+ final SearchLogHelper searchLogHelper = ComponentUtil.getSearchLogHelper();
+ final SearchLog searchLog = new SearchLog();
+
+ String userCode = null;
+ if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.USER_INFO_PROPERTY, Constants.TRUE))) {
+ userCode = userInfoHelper.getUserCode();
+ if (StringUtil.isNotBlank(userCode)) {
+ final UserInfo userInfo = new UserInfo();
+ userInfo.setCode(userCode);
+ userInfo.setCreatedTime(now);
+ userInfo.setUpdatedTime(now);
+ searchLog.setUserInfo(OptionalEntity.of(userInfo));
+ }
+ }
+
+ searchLog.setHitCount(queryResponseList.getAllRecordCount());
+ searchLog.setResponseTime(Integer.valueOf((int) queryResponseList.getExecTime()));
+ searchLog.setSearchWord(StringUtils.abbreviate(query, 1000));
+ searchLog.setSearchQuery(StringUtils.abbreviate(queryResponseList.getSearchQuery(), 1000));
+ searchLog.setRequestedTime(now);
+ searchLog.setQueryOffset(pageStart);
+ searchLog.setQueryPageSize(pageSize);
+
+ searchLog.setClientIp(StringUtils.abbreviate(request.getRemoteAddr(), 50));
+ searchLog.setReferer(StringUtils.abbreviate(request.getHeader("referer"), 1000));
+ searchLog.setUserAgent(StringUtils.abbreviate(request.getHeader("user-agent"), 255));
+ if (userCode != null) {
+ searchLog.setUserSessionId(userCode);
+ }
+ final Object accessType = request.getAttribute(Constants.SEARCH_LOG_ACCESS_TYPE);
+ if (Constants.SEARCH_LOG_ACCESS_TYPE_JSON.equals(accessType)) {
+ searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_JSON);
+ } else if (Constants.SEARCH_LOG_ACCESS_TYPE_XML.equals(accessType)) {
+ searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_XML);
+ } else if (Constants.SEARCH_LOG_ACCESS_TYPE_OTHER.equals(accessType)) {
+ searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_OTHER);
+ } else {
+ searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_WEB);
+ }
+
+ @SuppressWarnings("unchecked")
+ final Map<String, List<String>> fieldLogMap = (Map<String, List<String>>) request.getAttribute(Constants.FIELD_LOGS);
+ if (fieldLogMap != null) {
+ for (final Map.Entry<String, List<String>> logEntry : fieldLogMap.entrySet()) {
+ for (final String value : logEntry.getValue()) {
+ searchLog.addSearchFieldLogValue(logEntry.getKey(), StringUtils.abbreviate(value, 1000));
+ }
+ }
+ }
+
+ searchLogHelper.addSearchLog(searchLog);
+ }
+
+ public String[] getLanguages(final HttpServletRequest request, final SearchRequestParams params) {
+ if (params.getLanguages() != null) {
+ final Set<String> langSet = new HashSet<>();
+ for (final String lang : params.getLanguages()) {
+ if (StringUtil.isNotBlank(lang) && lang.length() < 1000) {
+ if (Constants.ALL_LANGUAGES.equalsIgnoreCase(lang)) {
+ langSet.add(Constants.ALL_LANGUAGES);
+ } else {
+ final String normalizeLang = systemHelper.normalizeLang(lang);
+ if (normalizeLang != null) {
+ langSet.add(normalizeLang);
+ }
+ }
+ }
+ }
+ if (langSet.size() > 1 && langSet.contains(Constants.ALL_LANGUAGES)) {
+ return new String[] { Constants.ALL_LANGUAGES };
+ } else {
+ langSet.remove(Constants.ALL_LANGUAGES);
+ }
+ return langSet.toArray(new String[langSet.size()]);
+ } else if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY, Constants.FALSE))) {
+ final Set<String> langSet = new HashSet<>();
+ final Enumeration<Locale> locales = request.getLocales();
+ if (locales != null) {
+ while (locales.hasMoreElements()) {
+ final Locale locale = locales.nextElement();
+ final String normalizeLang = systemHelper.normalizeLang(locale.toString());
+ if (normalizeLang != null) {
+ langSet.add(normalizeLang);
+ }
+ }
+ if (!langSet.isEmpty()) {
+ return langSet.toArray(new String[langSet.size()]);
+ }
+ }
+ }
+ return StringUtil.EMPTY_STRINGS;
+ }
+
+ protected void appendQueries(final StringBuilder queryBuf, final String key, final String[] values) {
+ if (values.length == 1) {
+ queryBuf.append(' ').append(key).append(":\"").append(values[0]).append('\"');
+ } else if (values.length > 1) {
+ boolean first = true;
+ queryBuf.append(" (");
+ for (final String value : values) {
+ if (first) {
+ first = false;
+ } else {
+ queryBuf.append(" OR ");
+ }
+ queryBuf.append(key).append(":\"").append(value).append('\"');
+ }
+ queryBuf.append(')');
+ }
+ }
+
+ public void appendAdditionalQuery(final String[] additionalQueries, final Consumer<String> consumer) {
+ final Set<String> fieldSet = new HashSet<>();
+ for (final String additional : additionalQueries) {
+ if (StringUtil.isNotBlank(additional) && additional.length() < 1000 && !hasFieldInQuery(fieldSet, additional)) {
+ consumer.accept(additional);
+ }
+ }
+ }
+
+ protected boolean hasFieldInQuery(final Set<String> fieldSet, final String query) {
+ final Matcher matcher = FIELD_EXTRACTION_PATTERN.matcher(query);
+ if (matcher.matches()) {
+ final String field = matcher.replaceFirst("$1");
+ if (fieldSet.contains(field)) {
+ return true;
+ }
+ fieldSet.add(field);
+ }
+ return false;
+ }
+
+ public OptionalEntity<Map<String, Object>> getDocumentByDocId(final String docId, final String[] fields) {
+ return fessEsClient.getDocument(fieldHelper.docIndex, fieldHelper.docType, builder -> {
+ builder.setQuery(QueryBuilders.termQuery(fieldHelper.docIdField, docId));
+ builder.addFields(fields);
+ return true;
+ });
+ }
+
+ public List<Map<String, Object>> getDocumentListByDocIds(final String[] docIds, final String[] fields) {
+ return fessEsClient.getDocumentList(fieldHelper.docIndex, fieldHelper.docType, builder -> {
+ builder.setQuery(QueryBuilders.termsQuery(fieldHelper.docIdField, docIds));
+ builder.setSize(queryHelper.getMaxPageSize());
+ builder.addFields(fields);
+ return true;
+ });
+ }
+
+ public boolean update(final String id, final String field, final Object value) {
+ return fessEsClient.update(fieldHelper.docIndex, fieldHelper.docType, id, field, value);
+ }
+}
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/dataconfig/AdminDataconfigAction.java b/src/main/java/org/codelibs/fess/app/web/admin/dataconfig/AdminDataconfigAction.java
index 2ae39edc3..b6409985e 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/dataconfig/AdminDataconfigAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/dataconfig/AdminDataconfigAction.java
@@ -30,9 +30,6 @@ import org.codelibs.fess.app.service.DataConfigService;
import org.codelibs.fess.app.service.LabelTypeService;
import org.codelibs.fess.app.service.RoleTypeService;
import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.dataconfig.CreateForm;
-import org.codelibs.fess.app.web.admin.dataconfig.EditForm;
-import org.codelibs.fess.app.web.admin.dataconfig.SearchForm;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.ds.DataStoreFactory;
import org.codelibs.fess.es.exentity.DataConfig;
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/dict/AdminDictAction.java b/src/main/java/org/codelibs/fess/app/web/admin/dict/AdminDictAction.java
index 0292fb539..a06a9fe52 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/dict/AdminDictAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/dict/AdminDictAction.java
@@ -55,7 +55,7 @@ public class AdminDictAction extends FessAdminAction {
@Execute
public HtmlResponse index(final ListForm form) {
return asHtml(path_AdminDict_IndexJsp).renderWith(data -> {
- DictionaryFile<? extends DictionaryItem>[] dictFiles = dictionaryManager.getDictionaryFiles();
+ final DictionaryFile<? extends DictionaryItem>[] dictFiles = dictionaryManager.getDictionaryFiles();
data.register("dictFiles", dictFiles);
});
}
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/dict/kuromoji/AdminDictKuromojiAction.java b/src/main/java/org/codelibs/fess/app/web/admin/dict/kuromoji/AdminDictKuromojiAction.java
index 24c42d811..85c968138 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/dict/kuromoji/AdminDictKuromojiAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/dict/kuromoji/AdminDictKuromojiAction.java
@@ -311,7 +311,7 @@ public class AdminDictKuromojiAction extends FessAdminAction {
return kuromojiService.getKuromojiFile(form.dictId).map(file -> {
try (InputStream inputStream = form.kuromojiFile.getInputStream()) {
file.update(inputStream);
- } catch (IOException e) {
+ } catch (final IOException e) {
throwValidationError(messages -> messages.addErrorsFailedToUploadKuromojiFile(GLOBAL), () -> {
return redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId));
});
@@ -381,7 +381,7 @@ public class AdminDictKuromojiAction extends FessAdminAction {
// Assist Logic
// ============
- protected OptionalEntity<KuromojiItem> createKuromojiItem(CreateForm form) {
+ protected OptionalEntity<KuromojiItem> createKuromojiItem(final CreateForm form) {
switch (form.crudMode) {
case CrudMode.CREATE:
if (form instanceof CreateForm) {
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/dict/synonym/AdminDictSynonymAction.java b/src/main/java/org/codelibs/fess/app/web/admin/dict/synonym/AdminDictSynonymAction.java
index 9a2ebf4b8..c61559d9f 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/dict/synonym/AdminDictSynonymAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/dict/synonym/AdminDictSynonymAction.java
@@ -323,7 +323,7 @@ public class AdminDictSynonymAction extends FessAdminAction {
return synonymService.getSynonymFile(form.dictId).map(file -> {
try (InputStream inputStream = form.synonymFile.getInputStream()) {
file.update(inputStream);
- } catch (IOException e) {
+ } catch (final IOException e) {
throwValidationError(messages -> messages.addErrorsFailedToUploadSynonymFile(GLOBAL), () -> {
return redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId));
});
@@ -397,7 +397,7 @@ public class AdminDictSynonymAction extends FessAdminAction {
// Assist Logic
// ============
- protected OptionalEntity<SynonymItem> createSynonymItem(CreateForm form) {
+ protected OptionalEntity<SynonymItem> createSynonymItem(final CreateForm form) {
switch (form.crudMode) {
case CrudMode.CREATE:
if (form instanceof CreateForm) {
@@ -439,11 +439,11 @@ public class AdminDictSynonymAction extends FessAdminAction {
};
}
- private void validateSynonymString(String[] values, VaErrorHook hook) {
+ private void validateSynonymString(final String[] values, final VaErrorHook hook) {
if (values.length == 0) {
return;
}
- for (String value : values) {
+ for (final String value : values) {
if (value.indexOf(',') >= 0) {
throwValidationError(messages -> {
messages.addErrorsInvalidStrIsIncluded(GLOBAL, value, ",");
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/fileconfig/AdminFileconfigAction.java b/src/main/java/org/codelibs/fess/app/web/admin/fileconfig/AdminFileconfigAction.java
index 8b83f685a..f1785a7e9 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/fileconfig/AdminFileconfigAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/fileconfig/AdminFileconfigAction.java
@@ -25,9 +25,6 @@ import org.codelibs.fess.app.service.FileConfigService;
import org.codelibs.fess.app.service.LabelTypeService;
import org.codelibs.fess.app.service.RoleTypeService;
import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.fileconfig.CreateForm;
-import org.codelibs.fess.app.web.admin.fileconfig.EditForm;
-import org.codelibs.fess.app.web.admin.fileconfig.SearchForm;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.es.exentity.FileConfig;
import org.codelibs.fess.helper.SystemHelper;
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java b/src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java
index 77019277c..ce026587c 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java
@@ -148,12 +148,12 @@ public class AdminGeneralAction extends FessAdminAction {
form.esHttpUrl = crawlerProperties.getProperty(Constants.ELASTICSEARCH_WEB_URL_PROPERTY, Constants.ELASTICSEARCH_WEB_URL);
}
- private Integer getPropertyAsInteger(String key, int defaultValue) {
- String value = crawlerProperties.getProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY);
+ private Integer getPropertyAsInteger(final String key, final int defaultValue) {
+ final String value = crawlerProperties.getProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY);
if (value != null) {
try {
return Integer.valueOf(value);
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
// ignore
}
}
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/keymatch/AdminKeymatchAction.java b/src/main/java/org/codelibs/fess/app/web/admin/keymatch/AdminKeymatchAction.java
index 1f5bcf466..a866e40fe 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/keymatch/AdminKeymatchAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/keymatch/AdminKeymatchAction.java
@@ -163,7 +163,7 @@ public class AdminKeymatchAction extends FessAdminAction {
public HtmlResponse editfromconfirm(final EditForm form) {
validate(form, messages -> {}, toEditHtml());
form.crudMode = CrudMode.EDIT;
- String id = form.id;
+ final String id = form.id;
keyMatchService.getKeyMatch(id).ifPresent(entity -> {
copyBeanToBean(entity, form, op -> {});
}).orElse(() -> {
@@ -195,7 +195,7 @@ public class AdminKeymatchAction extends FessAdminAction {
public HtmlResponse deletefromconfirm(final EditForm form) {
form.crudMode = CrudMode.DELETE;
validate(form, messages -> {}, toEditHtml());
- String id = form.id;
+ final String id = form.id;
keyMatchService.getKeyMatch(id).ifPresent(entity -> {
copyBeanToBean(entity, form, op -> {});
}).orElse(() -> {
@@ -279,7 +279,7 @@ public class AdminKeymatchAction extends FessAdminAction {
public HtmlResponse delete(final EditForm form) {
verifyCrudMode(form.crudMode, CrudMode.DELETE);
validate(form, messages -> {}, toEditHtml());
- String id = form.id;
+ final String id = form.id;
keyMatchService.getKeyMatch(id).ifPresent(entity -> {
keyMatchService.delete(entity);
saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
@@ -300,7 +300,7 @@ public class AdminKeymatchAction extends FessAdminAction {
switch (form.crudMode) {
case CrudMode.CREATE:
if (form instanceof CreateForm) {
- KeyMatch entity = new KeyMatch();
+ final KeyMatch entity = new KeyMatch();
entity.setCreatedBy(username);
entity.setCreatedTime(currentTime);
entity.setUpdatedBy(username);
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/labeltype/AdminLabeltypeAction.java b/src/main/java/org/codelibs/fess/app/web/admin/labeltype/AdminLabeltypeAction.java
index 7b8642dbd..f76cb1643 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/labeltype/AdminLabeltypeAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/labeltype/AdminLabeltypeAction.java
@@ -24,9 +24,6 @@ import org.codelibs.fess.app.pager.LabelTypePager;
import org.codelibs.fess.app.service.LabelTypeService;
import org.codelibs.fess.app.service.RoleTypeService;
import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.labeltype.CreateForm;
-import org.codelibs.fess.app.web.admin.labeltype.EditForm;
-import org.codelibs.fess.app.web.admin.labeltype.SearchForm;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.es.exentity.LabelType;
import org.codelibs.fess.helper.SystemHelper;
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/requestheader/AdminRequestheaderAction.java b/src/main/java/org/codelibs/fess/app/web/admin/requestheader/AdminRequestheaderAction.java
index b20cb2f80..e4c28a275 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/requestheader/AdminRequestheaderAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/requestheader/AdminRequestheaderAction.java
@@ -30,9 +30,6 @@ import org.codelibs.fess.app.pager.RequestHeaderPager;
import org.codelibs.fess.app.service.RequestHeaderService;
import org.codelibs.fess.app.service.WebConfigService;
import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.requestheader.CreateForm;
-import org.codelibs.fess.app.web.admin.requestheader.EditForm;
-import org.codelibs.fess.app.web.admin.requestheader.SearchForm;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.es.exentity.RequestHeader;
import org.codelibs.fess.es.exentity.WebConfig;
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/webconfig/AdminWebconfigAction.java b/src/main/java/org/codelibs/fess/app/web/admin/webconfig/AdminWebconfigAction.java
index c575d0b08..74c00ce21 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/webconfig/AdminWebconfigAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/webconfig/AdminWebconfigAction.java
@@ -21,13 +21,10 @@ import javax.annotation.Resource;
import org.codelibs.fess.Constants;
import org.codelibs.fess.annotation.Token;
import org.codelibs.fess.app.pager.WebConfigPager;
-import org.codelibs.fess.app.service.WebConfigService;
import org.codelibs.fess.app.service.LabelTypeService;
import org.codelibs.fess.app.service.RoleTypeService;
+import org.codelibs.fess.app.service.WebConfigService;
import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.webconfig.CreateForm;
-import org.codelibs.fess.app.web.admin.webconfig.EditForm;
-import org.codelibs.fess.app.web.admin.webconfig.SearchForm;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.es.exentity.WebConfig;
import org.codelibs.fess.helper.SystemHelper;
diff --git a/src/main/java/org/codelibs/fess/app/web/go/GoForm.java b/src/main/java/org/codelibs/fess/app/web/go/GoForm.java
index a1925d237..da1426e42 100644
--- a/src/main/java/org/codelibs/fess/app/web/go/GoForm.java
+++ b/src/main/java/org/codelibs/fess/app/web/go/GoForm.java
@@ -1,8 +1,6 @@
package org.codelibs.fess.app.web.go;
public class GoForm {
- private static final long serialVersionUID = 1L;
-
//@Required(target = "go,cache")
//@Maxbytelength(maxbytelength = 100)
public String docId;
diff --git a/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java b/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
index 054da6035..d6c967578 100644
--- a/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
@@ -16,34 +16,24 @@
package org.codelibs.fess.app.web.search;
-import java.text.NumberFormat;
-import java.time.Clock;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
-import org.apache.commons.lang3.StringUtils;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.Constants;
+import org.codelibs.fess.app.service.SearchService;
import org.codelibs.fess.app.web.RootAction;
import org.codelibs.fess.app.web.base.FessSearchAction;
-import org.codelibs.fess.es.client.FessEsClient.SearchConditionBuilder;
-import org.codelibs.fess.es.exentity.SearchLog;
-import org.codelibs.fess.es.exentity.UserInfo;
+import org.codelibs.fess.entity.SearchRenderData;
import org.codelibs.fess.exception.InvalidQueryException;
import org.codelibs.fess.exception.ResultOffsetExceededException;
-import org.codelibs.fess.helper.SearchLogHelper;
-import org.codelibs.fess.util.ComponentUtil;
-import org.codelibs.fess.util.QueryResponseList;
-import org.dbflute.optional.OptionalEntity;
+import org.codelibs.fess.util.FacetResponse;
import org.lastaflute.taglib.function.LaFunctions;
import org.lastaflute.web.Execute;
import org.lastaflute.web.response.HtmlResponse;
@@ -59,17 +49,11 @@ public class SearchAction extends FessSearchAction {
//
private static final Logger logger = LoggerFactory.getLogger(SearchAction.class);
- protected static final long DEFAULT_START_COUNT = 0;
-
- protected static final int MAX_PAGE_SIZE = 100;
-
- private static final int DEFAULT_PAGE_SIZE = 20;
-
- protected static final Pattern FIELD_EXTRACTION_PATTERN = Pattern.compile("^([a-zA-Z0-9_]+):.*");
-
// ===================================================================================
// Attribute
//
+ @Resource
+ protected SearchService searchService;
// ===================================================================================
// Hook
@@ -85,15 +69,16 @@ public class SearchAction extends FessSearchAction {
@Execute
public HtmlResponse search(final SearchForm form) {
- if (viewHelper.isUseSession() && StringUtil.isNotBlank(form.num)) {
- normalizePageNum(form);
- final HttpSession session = request.getSession();
- if (session != null) {
- session.setAttribute(Constants.RESULTS_PER_PAGE, form.num);
- }
+ final HtmlResponse response = doSearch(form);
+ if (viewHelper.isUseSession()) {
+ LaRequestUtil.getOptionalRequest().ifPresent(request -> {
+ final HttpSession session = request.getSession(false);
+ if (session != null) {
+ session.setAttribute(Constants.RESULTS_PER_PAGE, form.num);
+ }
+ });
}
-
- return doSearch(form);
+ return response;
}
@Execute
@@ -145,297 +130,58 @@ public class SearchAction extends FessSearchAction {
return asHtml(path_SearchJsp).renderWith(data -> {
updateSearchParams(form);
buildLabelParams(form.fields);
- doSearchInternal(data, form);
- data.register("displayQuery", getDisplayQuery(form, labelTypeHelper.getLabelTypeItemList()));
- data.register("pagingQuery", getPagingQuery(form));
- });
- }
-
- protected HtmlResponse doMove(final SearchForm form, final int move) {
- int pageNum = getDefaultPageSize();
- if (StringUtil.isBlank(form.num)) {
- form.num = String.valueOf(getDefaultPageSize());
- } else {
+ form.lang = searchService.getLanguages(request, form);
try {
- pageNum = Integer.parseInt(form.num);
- } catch (final NumberFormatException e) {
- form.num = String.valueOf(getDefaultPageSize());
- }
- }
-
- if (StringUtil.isBlank(form.pn)) {
- form.start = String.valueOf(DEFAULT_START_COUNT);
- } else {
- Integer pageNumber = Integer.parseInt(form.pn);
- if (pageNumber != null && pageNumber > 0) {
- pageNumber = pageNumber + move;
- if (pageNumber < 1) {
- pageNumber = 1;
- }
- form.start = String.valueOf((pageNumber - 1) * pageNum);
- } else {
- form.start = String.valueOf(DEFAULT_START_COUNT);
- }
- }
-
- return doSearch(form);
- }
-
- protected String doSearchInternal(final RenderData data, final SearchForm form) {
- final StringBuilder queryBuf = new StringBuilder(255);
- if (StringUtil.isNotBlank(form.query)) {
- queryBuf.append(form.query);
- }
- if (StringUtil.isNotBlank(form.op)) {
- request.setAttribute(Constants.DEFAULT_OPERATOR, form.op);
- }
- if (queryBuf.indexOf(" OR ") >= 0) {
- queryBuf.insert(0, '(').append(')');
- }
- if (form.additional != null) {
- final Set<String> fieldSet = new HashSet<String>();
- for (final String additional : form.additional) {
- if (StringUtil.isNotBlank(additional) && additional.length() < 1000 && !hasFieldInQuery(fieldSet, additional)) {
- queryBuf.append(' ').append(additional);
- }
- }
- }
- if (!form.fields.isEmpty()) {
- for (final Map.Entry<String, String[]> entry : form.fields.entrySet()) {
- final List<String> valueList = new ArrayList<String>();
- final String[] values = entry.getValue();
- if (values != null) {
- for (final String v : values) {
- valueList.add(v);
+ final WebRenderData renderData = new WebRenderData(data);
+ searchService.search(request, form, renderData);
+ // favorite or screenshot
+ if (favoriteSupport || screenShotManager != null) {
+ final String searchQuery = renderData.getSearchQuery();
+ final List<Map<String, Object>> documentItems = renderData.getDocumentItems();
+ form.queryId = userInfoHelper.generateQueryId(searchQuery, documentItems);
+ if (screenShotManager != null) {
+ screenShotManager.storeRequest(form.queryId, documentItems);
+ data.register("screenShotSupport", true);
}
}
- if (valueList.size() == 1) {
- queryBuf.append(' ').append(entry.getKey()).append(":\"").append(valueList.get(0)).append('\"');
- } else if (valueList.size() > 1) {
- queryBuf.append(" (");
- for (int i = 0; i < valueList.size(); i++) {
- if (i != 0) {
- queryBuf.append(" OR");
- }
- queryBuf.append(' ').append(entry.getKey()).append(":\"").append(valueList.get(i)).append('\"');
- }
- queryBuf.append(')');
- }
-
- }
- }
- if (StringUtil.isNotBlank(form.sort)) {
- queryBuf.append(" sort:").append(form.sort);
- }
- if (form.lang != null) {
- final Set<String> langSet = new HashSet<>();
- for (final String lang : form.lang) {
- if (StringUtil.isNotBlank(lang) && lang.length() < 1000) {
- if (Constants.ALL_LANGUAGES.equalsIgnoreCase(lang)) {
- langSet.add(Constants.ALL_LANGUAGES);
- } else {
- final String normalizeLang = systemHelper.normalizeLang(lang);
- if (normalizeLang != null) {
- langSet.add(normalizeLang);
- }
- }
- }
- }
- if (langSet.size() > 1 && langSet.contains(Constants.ALL_LANGUAGES)) {
- langSet.clear();
- form.lang = new String[] { Constants.ALL_LANGUAGES };
- } else {
- langSet.remove(Constants.ALL_LANGUAGES);
- }
- appendLangQuery(queryBuf, langSet);
- } else if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY, Constants.FALSE))) {
- final Set<String> langSet = new HashSet<>();
- final Enumeration<Locale> locales = request.getLocales();
- if (locales != null) {
- while (locales.hasMoreElements()) {
- final Locale locale = locales.nextElement();
- final String normalizeLang = systemHelper.normalizeLang(locale.toString());
- if (normalizeLang != null) {
- langSet.add(normalizeLang);
- }
+ } catch (final InvalidQueryException e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(e.getMessage(), e);
}
- if (!langSet.isEmpty()) {
- appendLangQuery(queryBuf, langSet);
+ throwValidationError(e.getMessageCode(), () -> asHtml(path_ErrorJsp));
+ } catch (final ResultOffsetExceededException e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(e.getMessage(), e);
}
+ throwValidationError(messages -> {
+ messages.addErrorsResultSizeExceeded(GLOBAL);
+ }, () -> asHtml(path_ErrorJsp));
}
- }
-
- final String query = queryBuf.toString().trim();
+ form.rt = Long.toString(systemHelper.getCurrentTimeAsLong());
+ data.register("displayQuery", getDisplayQuery(form, labelTypeHelper.getLabelTypeItemList()));
+ data.register("pagingQuery", getPagingQuery(form));
+ });
+ }
- // init pager
- if (StringUtil.isBlank(form.start)) {
- form.start = String.valueOf(DEFAULT_START_COUNT);
- } else {
+ protected HtmlResponse doMove(final SearchForm form, final int move) {
+ int start = queryHelper.getDefaultStart();
+ if (StringUtil.isNotBlank(form.pn)) {
try {
- Integer.parseInt(form.start);
- } catch (final NumberFormatException e) {
- form.start = String.valueOf(DEFAULT_START_COUNT);
- }
- }
- if (StringUtil.isBlank(form.num)) {
- form.num = String.valueOf(getDefaultPageSize());
- }
- normalizePageNum(form);
-
- final int pageStart = Integer.parseInt(form.start);
- final int pageNum = Integer.parseInt(form.num);
- List<Map<String, Object>> documentItems = null;
- try {
- documentItems =
- fessEsClient.search(fieldHelper.docIndex, fieldHelper.docType,
- searchRequestBuilder -> {
- return SearchConditionBuilder.builder(searchRequestBuilder).query(query).offset(pageStart).size(pageNum)
- .facetInfo(form.facet).geoInfo(form.geo).responseFields(queryHelper.getResponseFields()).build();
- }, (searchRequestBuilder, execTime, searchResponse) -> {
- final QueryResponseList queryResponseList = ComponentUtil.getQueryResponseList();
- queryResponseList.init(searchResponse, pageStart, pageNum);
- return queryResponseList;
- });
- } catch (final InvalidQueryException e) {
- if (logger.isDebugEnabled()) {
- logger.debug(e.getMessage(), e);
- }
- throwValidationError(e.getMessageCode(), () -> asHtml(path_ErrorJsp));
- } catch (final ResultOffsetExceededException e) {
- if (logger.isDebugEnabled()) {
- logger.debug(e.getMessage(), e);
- }
- throwValidationError(messages -> {
- messages.addErrorsResultSizeExceeded(GLOBAL);
- }, () -> asHtml(path_ErrorJsp));
- }
- data.register("documentItems", documentItems);
-
- // search
- final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
- data.register("facetResponse", queryResponseList.getFacetResponse());
- final NumberFormat nf = NumberFormat.getInstance(LaRequestUtil.getRequest().getLocale());
- nf.setMaximumIntegerDigits(2);
- nf.setMaximumFractionDigits(2);
- String execTime;
- try {
- execTime = nf.format((double) queryResponseList.getExecTime() / 1000);
- } catch (final Exception e) {
- execTime = StringUtil.EMPTY;
- }
- data.register("execTime", execTime);
-
- final Clock clock = Clock.systemDefaultZone();
- form.rt = Long.toString(clock.millis());
-
- // favorite
- if (favoriteSupport || screenShotManager != null) {
- form.queryId = userInfoHelper.generateQueryId(query, documentItems);
- if (screenShotManager != null) {
- screenShotManager.storeRequest(form.queryId, documentItems);
- data.register("screenShotSupport", true);
- }
- }
-
- // search log
- if (searchLogSupport) {
- final long now = systemHelper.getCurrentTimeAsLong();
-
- final SearchLogHelper searchLogHelper = ComponentUtil.getSearchLogHelper();
- final SearchLog searchLog = new SearchLog();
-
- String userCode = null;
- if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.USER_INFO_PROPERTY, Constants.TRUE))) {
- userCode = userInfoHelper.getUserCode();
- if (StringUtil.isNotBlank(userCode)) {
- final UserInfo userInfo = new UserInfo();
- userInfo.setCode(userCode);
- userInfo.setCreatedTime(now);
- userInfo.setUpdatedTime(now);
- searchLog.setUserInfo(OptionalEntity.of(userInfo));
- }
- }
-
- searchLog.setHitCount(queryResponseList.getAllRecordCount());
- searchLog.setResponseTime(Integer.valueOf((int) queryResponseList.getExecTime()));
- searchLog.setSearchWord(StringUtils.abbreviate(query, 1000));
- searchLog.setSearchQuery(StringUtils.abbreviate(queryResponseList.getSearchQuery(), 1000));
- searchLog.setRequestedTime(now);
- searchLog.setQueryOffset(pageStart);
- searchLog.setQueryPageSize(pageNum);
-
- searchLog.setClientIp(StringUtils.abbreviate(request.getRemoteAddr(), 50));
- searchLog.setReferer(StringUtils.abbreviate(request.getHeader("referer"), 1000));
- searchLog.setUserAgent(StringUtils.abbreviate(request.getHeader("user-agent"), 255));
- if (userCode != null) {
- searchLog.setUserSessionId(userCode);
- }
- final Object accessType = request.getAttribute(Constants.SEARCH_LOG_ACCESS_TYPE);
- if (Constants.SEARCH_LOG_ACCESS_TYPE_JSON.equals(accessType)) {
- searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_JSON);
- } else if (Constants.SEARCH_LOG_ACCESS_TYPE_XML.equals(accessType)) {
- searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_XML);
- } else if (Constants.SEARCH_LOG_ACCESS_TYPE_OTHER.equals(accessType)) {
- searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_OTHER);
- } else {
- searchLog.setAccessType(Constants.SEARCH_LOG_ACCESS_TYPE_WEB);
- }
-
- @SuppressWarnings("unchecked")
- final Map<String, List<String>> fieldLogMap = (Map<String, List<String>>) request.getAttribute(Constants.FIELD_LOGS);
- if (fieldLogMap != null) {
- for (final Map.Entry<String, List<String>> logEntry : fieldLogMap.entrySet()) {
- for (final String value : logEntry.getValue()) {
- searchLog.addSearchFieldLogValue(logEntry.getKey(), StringUtils.abbreviate(value, 1000));
+ int pageNumber = Integer.parseInt(form.pn);
+ if (pageNumber > 0) {
+ pageNumber = pageNumber + move;
+ if (pageNumber < 1) {
+ pageNumber = 1;
}
+ start = (pageNumber - 1) * form.getPageSize();
}
+ } catch (final NumberFormatException e) {
+ // ignore
}
-
- searchLogHelper.addSearchLog(searchLog);
- }
-
- final String[] highlightQueries = (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
- if (highlightQueries != null) {
- final StringBuilder buf = new StringBuilder(100);
- for (final String q : highlightQueries) {
- buf.append("&hq=").append(q);
- }
- data.register("appendHighlightQueries", buf.toString());
}
+ form.start = String.valueOf(start);
- data.register("pageSize", queryResponseList.getPageSize());
- data.register("currentPageNumber", queryResponseList.getCurrentPageNumber());
- data.register("allRecordCount", queryResponseList.getAllRecordCount());
- data.register("allPageCount", queryResponseList.getAllPageCount());
- data.register("existNextPage", queryResponseList.isExistNextPage());
- data.register("existPrevPage", queryResponseList.isExistPrevPage());
- data.register("currentStartRecordNumber", queryResponseList.getCurrentStartRecordNumber());
- data.register("currentEndRecordNumber", queryResponseList.getCurrentEndRecordNumber());
- data.register("pageNumberList", queryResponseList.getPageNumberList());
- data.register("partialResults", queryResponseList.isPartialResults());
- // TODO
- // data.register("queryTime", queryResponseList.get);
- // data.register("searchTime", queryResponseList.get);
-
- return query;
- }
-
- protected void appendLangQuery(final StringBuilder queryBuf, final Set<String> langSet) {
- if (langSet.size() == 1) {
- queryBuf.append(' ').append(fieldHelper.langField).append(':').append(langSet.iterator().next());
- } else if (langSet.size() > 1) {
- boolean first = true;
- for (final String lang : langSet) {
- if (first) {
- queryBuf.append(" (");
- first = false;
- } else {
- queryBuf.append(" OR ");
- }
- queryBuf.append(fieldHelper.langField).append(':').append(lang);
- }
- queryBuf.append(')');
- }
+ return doSearch(form);
}
protected void updateSearchParams(final SearchForm form) {
@@ -472,57 +218,12 @@ public class SearchAction extends FessSearchAction {
return buf.toString();
}
- protected void normalizePageNum(final SearchForm form) {
- try {
- final int num = Integer.parseInt(form.num);
- if (num > getMaxPageSize()) {
- // max page size
- form.num = String.valueOf(getMaxPageSize());
- } else if (num <= 0) {
- form.num = String.valueOf(getDefaultPageSize());
- }
- } catch (final NumberFormatException e) {
- form.num = String.valueOf(getDefaultPageSize());
- }
- }
-
- protected int getDefaultPageSize() {
- return DEFAULT_PAGE_SIZE;
- }
-
- protected int getMaxPageSize() {
- final Object maxPageSize = crawlerProperties.get(Constants.SEARCH_RESULT_MAX_PAGE_SIZE);
- if (maxPageSize == null) {
- return MAX_PAGE_SIZE;
- }
- try {
- return Integer.parseInt(maxPageSize.toString());
- } catch (final NumberFormatException e) {
- return MAX_PAGE_SIZE;
- }
- }
-
- protected boolean hasFieldInQuery(final Set<String> fieldSet, final String query) {
- final Matcher matcher = FIELD_EXTRACTION_PATTERN.matcher(query);
- if (matcher.matches()) {
- final String field = matcher.replaceFirst("$1");
- if (fieldSet.contains(field)) {
- return true;
- }
- fieldSet.add(field);
- }
- return false;
- }
-
protected String getPagingQuery(final SearchForm form) {
final StringBuilder buf = new StringBuilder(200);
if (form.additional != null) {
- final Set<String> fieldSet = new HashSet<String>();
- for (final String additional : form.additional) {
- if (StringUtil.isNotBlank(additional) && additional.length() < 1000 && !hasFieldInQuery(fieldSet, additional)) {
- buf.append("&additional=").append(LaFunctions.u(additional));
- }
- }
+ searchService.appendAdditionalQuery(form.additional, additional -> {
+ buf.append("&additional=").append(LaFunctions.u(additional));
+ });
}
if (StringUtil.isNotBlank(form.sort)) {
buf.append("&sort=").append(LaFunctions.u(form.sort));
@@ -566,4 +267,107 @@ public class SearchAction extends FessSearchAction {
return buf.toString();
}
+ protected static class WebRenderData extends SearchRenderData {
+ private final RenderData data;
+
+ WebRenderData(final RenderData data) {
+ this.data = data;
+ }
+
+ @Override
+ public void setDocumentItems(final List<Map<String, Object>> documentItems) {
+ data.register("documentItems", documentItems);
+ super.setDocumentItems(documentItems);
+ }
+
+ @Override
+ public void setFacetResponse(final FacetResponse facetResponse) {
+ data.register("facetResponse", facetResponse);
+ super.setFacetResponse(facetResponse);
+ }
+
+ @Override
+ public void setAppendHighlightParams(final String appendHighlightParams) {
+ data.register("appendHighlightParams", appendHighlightParams);
+ super.setAppendHighlightParams(appendHighlightParams);
+ }
+
+ @Override
+ public void setExecTime(final String execTime) {
+ data.register("execTime", execTime);
+ super.setExecTime(execTime);
+ }
+
+ @Override
+ public void setPageSize(final int pageSize) {
+ data.register("pageSize", pageSize);
+ super.setPageSize(pageSize);
+ }
+
+ @Override
+ public void setCurrentPageNumber(final int currentPageNumber) {
+ data.register("currentPageNumber", currentPageNumber);
+ super.setCurrentPageNumber(currentPageNumber);
+ }
+
+ @Override
+ public void setAllRecordCount(final long allRecordCount) {
+ data.register("allRecordCount", allRecordCount);
+ super.setAllRecordCount(allRecordCount);
+ }
+
+ @Override
+ public void setAllPageCount(final int allPageCount) {
+ data.register("allPageCount", allPageCount);
+ super.setAllPageCount(allPageCount);
+ }
+
+ @Override
+ public void setExistNextPage(final boolean existNextPage) {
+ data.register("existNextPage", existNextPage);
+ super.setExistNextPage(existNextPage);
+ }
+
+ @Override
+ public void setExistPrevPage(final boolean existPrevPage) {
+ data.register("existPrevPage", existPrevPage);
+ super.setExistPrevPage(existPrevPage);
+ }
+
+ @Override
+ public void setCurrentStartRecordNumber(final long currentStartRecordNumber) {
+ data.register("currentStartRecordNumber", currentStartRecordNumber);
+ super.setCurrentStartRecordNumber(currentStartRecordNumber);
+ }
+
+ @Override
+ public void setCurrentEndRecordNumber(final long currentEndRecordNumber) {
+ data.register("currentEndRecordNumber", currentEndRecordNumber);
+ super.setCurrentEndRecordNumber(currentEndRecordNumber);
+ }
+
+ @Override
+ public void setPageNumberList(final List<String> pageNumberList) {
+ data.register("pageNumberList", pageNumberList);
+ super.setPageNumberList(pageNumberList);
+ }
+
+ @Override
+ public void setPartialResults(final boolean partialResults) {
+ data.register("partialResults", partialResults);
+ super.setPartialResults(partialResults);
+ }
+
+ @Override
+ public void setQueryTime(final long queryTime) {
+ data.register("queryTime", queryTime);
+ super.setQueryTime(queryTime);
+ }
+
+ @Override
+ public void setSearchQuery(final String searchQuery) {
+ data.register("searchQuery", searchQuery);
+ super.setSearchQuery(searchQuery);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/codelibs/fess/app/web/search/SearchForm.java b/src/main/java/org/codelibs/fess/app/web/search/SearchForm.java
index 13825d254..c058a9624 100644
--- a/src/main/java/org/codelibs/fess/app/web/search/SearchForm.java
+++ b/src/main/java/org/codelibs/fess/app/web/search/SearchForm.java
@@ -20,10 +20,14 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
+import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.SearchRequestParams;
+import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.util.ComponentUtil;
-public class SearchForm implements Serializable {
+public class SearchForm implements SearchRequestParams, Serializable {
private static final long serialVersionUID = 1L;
@@ -94,4 +98,90 @@ public class SearchForm implements Serializable {
public Map<String, String[]> options = new HashMap<>();
+ private int startPosition = -1;
+
+ private int pageSize = -1;
+
+ @Override
+ public int getStartPosition() {
+ if (startPosition != -1) {
+ return startPosition;
+ }
+
+ final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+ if (StringUtil.isBlank(start)) {
+ startPosition = queryHelper.getDefaultStart();
+ } else {
+ try {
+ startPosition = Integer.parseInt(start);
+ } catch (final NumberFormatException e) {
+ startPosition = queryHelper.getDefaultStart();
+ }
+ }
+ start = String.valueOf(startPosition);
+ return startPosition;
+ }
+
+ @Override
+ public int getPageSize() {
+ if (pageSize != -1) {
+ return pageSize;
+ }
+
+ final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+ if (StringUtil.isBlank(num)) {
+ pageSize = queryHelper.getDefaultPageSize();
+ } else {
+ try {
+ pageSize = Integer.parseInt(num);
+ if (pageSize > queryHelper.getMaxPageSize() || pageSize <= 0) {
+ pageSize = queryHelper.getMaxPageSize();
+ }
+ } catch (final NumberFormatException e) {
+ pageSize = queryHelper.getDefaultPageSize();
+ }
+ }
+ num = String.valueOf(pageSize);
+ return pageSize;
+ }
+
+ @Override
+ public String getQuery() {
+ return query;
+ }
+
+ @Override
+ public String getOperator() {
+ return op;
+ }
+
+ @Override
+ public String[] getAdditional() {
+ return additional;
+ }
+
+ @Override
+ public Map<String, String[]> getFields() {
+ return fields;
+ }
+
+ @Override
+ public String[] getLanguages() {
+ return lang;
+ }
+
+ @Override
+ public GeoInfo getGeoInfo() {
+ return geo;
+ }
+
+ @Override
+ public FacetInfo getFacetInfo() {
+ return facet;
+ }
+
+ @Override
+ public String getSort() {
+ return sort;
+ }
}
diff --git a/src/main/java/org/codelibs/fess/dict/DictionaryCreator.java b/src/main/java/org/codelibs/fess/dict/DictionaryCreator.java
index b1b9d2d42..2761958fe 100644
--- a/src/main/java/org/codelibs/fess/dict/DictionaryCreator.java
+++ b/src/main/java/org/codelibs/fess/dict/DictionaryCreator.java
@@ -11,11 +11,11 @@ public abstract class DictionaryCreator {
protected DictionaryManager dictionaryManager;
- public DictionaryCreator(String pattern) {
+ public DictionaryCreator(final String pattern) {
this.pattern = Pattern.compile(pattern);
}
- public DictionaryFile<? extends DictionaryItem> create(String path, Date timestamp) {
+ public DictionaryFile<? extends DictionaryItem> create(final String path, final Date timestamp) {
if (!isTarget(path)) {
return null;
}
@@ -23,17 +23,17 @@ public abstract class DictionaryCreator {
return newDictionaryFile(encodePath(path), path, timestamp);
}
- protected String encodePath(String path) {
+ protected String encodePath(final String path) {
return Base64.getEncoder().encodeToString(path.getBytes(Constants.CHARSET_UTF_8));
}
- protected boolean isTarget(String path) {
+ protected boolean isTarget(final String path) {
return pattern.matcher(path).find();
}
protected abstract DictionaryFile<? extends DictionaryItem> newDictionaryFile(String id, String path, Date timestamp);
- public void setDictionaryManager(DictionaryManager dictionaryManager) {
+ public void setDictionaryManager(final DictionaryManager dictionaryManager) {
this.dictionaryManager = dictionaryManager;
}
}
diff --git a/src/main/java/org/codelibs/fess/dict/DictionaryFile.java b/src/main/java/org/codelibs/fess/dict/DictionaryFile.java
index 5ae99f946..13f989483 100644
--- a/src/main/java/org/codelibs/fess/dict/DictionaryFile.java
+++ b/src/main/java/org/codelibs/fess/dict/DictionaryFile.java
@@ -34,7 +34,7 @@ public abstract class DictionaryFile<T extends DictionaryItem> {
protected Date timestamp;
- public DictionaryFile(String id, String path, Date timestamp) {
+ public DictionaryFile(final String id, final String path, final Date timestamp) {
this.id = id;
this.path = path;
this.timestamp = timestamp;
@@ -52,7 +52,7 @@ public abstract class DictionaryFile<T extends DictionaryItem> {
return timestamp;
}
- public DictionaryFile<T> manager(DictionaryManager dictionaryManager) {
+ public DictionaryFile<T> manager(final DictionaryManager dictionaryManager) {
this.dictionaryManager = dictionaryManager;
return this;
}
diff --git a/src/main/java/org/codelibs/fess/dict/DictionaryManager.java b/src/main/java/org/codelibs/fess/dict/DictionaryManager.java
index 644e3907e..1940dcc6a 100644
--- a/src/main/java/org/codelibs/fess/dict/DictionaryManager.java
+++ b/src/main/java/org/codelibs/fess/dict/DictionaryManager.java
@@ -54,35 +54,35 @@ public class DictionaryManager {
public DictionaryFile<? extends DictionaryItem>[] getDictionaryFiles() {
try (CurlResponse response = Curl.get(getUrl() + "/_configsync/file").param("fields", "path,@timestamp").execute()) {
- Map<String, Object> contentMap = response.getContentAsMap();
+ final Map<String, Object> contentMap = response.getContentAsMap();
@SuppressWarnings("unchecked")
- List<Map<String, Object>> fileList = (List<Map<String, Object>>) contentMap.get("file");
+ final List<Map<String, Object>> fileList = (List<Map<String, Object>>) contentMap.get("file");
return fileList
.stream()
.map(fileMap -> {
try {
- String path = fileMap.get("path").toString();
- Date timestamp =
+ final String path = fileMap.get("path").toString();
+ final Date timestamp =
new SimpleDateFormat(Constants.DATE_FORMAT_ISO_8601_EXTEND_UTC).parse(fileMap.get("@timestamp")
.toString());
for (final DictionaryCreator creator : creatorList) {
- DictionaryFile<? extends DictionaryItem> file = creator.create(path, timestamp);
+ final DictionaryFile<? extends DictionaryItem> file = creator.create(path, timestamp);
if (file != null) {
return file;
}
}
- } catch (Exception e) {
+ } catch (final Exception e) {
logger.warn("Failed to load " + fileMap, e);
}
return null;
}).filter(file -> file != null).toArray(n -> new DictionaryFile<?>[n]);
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new DictionaryException("Failed to access dictionaries", e);
}
}
public OptionalEntity<DictionaryFile<? extends DictionaryItem>> getDictionaryFile(final String id) {
- for (DictionaryFile<? extends DictionaryItem> dictFile : getDictionaryFiles()) {
+ for (final DictionaryFile<? extends DictionaryItem> dictFile : getDictionaryFiles()) {
if (dictFile.getId().equals(id)) {
return OptionalEntity.of(dictFile);
}
@@ -90,7 +90,7 @@ public class DictionaryManager {
return OptionalEntity.empty();
}
- public void store(DictionaryFile<? extends DictionaryItem> dictFile, File file) {
+ public void store(final DictionaryFile<? extends DictionaryItem> dictFile, final File file) {
getDictionaryFile(dictFile.getId())
.ifPresent(currentFile -> {
if (currentFile.getTimestamp().getTime() > dictFile.getTimestamp().getTime()) {
@@ -101,11 +101,11 @@ public class DictionaryManager {
try (CurlResponse response =
Curl.post(getUrl() + "/_configsync/file").param("path", dictFile.getPath()).body(FileUtil.readUTF8(file))
.execute()) {
- Map<String, Object> contentMap = response.getContentAsMap();
+ final Map<String, Object> contentMap = response.getContentAsMap();
if (!Constants.TRUE.equalsIgnoreCase(contentMap.get("acknowledged").toString())) {
throw new DictionaryException("Failed to update " + dictFile.getPath());
}
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new DictionaryException("Failed to update " + dictFile.getPath(), e);
}
@@ -114,15 +114,15 @@ public class DictionaryManager {
});
}
- public InputStream getContentInputStream(DictionaryFile<? extends DictionaryItem> dictFile) {
+ public InputStream getContentInputStream(final DictionaryFile<? extends DictionaryItem> dictFile) {
try {
return Curl.get(getUrl() + "/_configsync/file").param("path", dictFile.getPath()).execute().getContentAsStream();
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new DictionaryException("Failed to access " + dictFile.getPath(), e);
}
}
- public void addCreator(DictionaryCreator creator) {
+ public void addCreator(final DictionaryCreator creator) {
creatorList.add(creator);
}
diff --git a/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiCreator.java b/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiCreator.java
index f10d162b2..a784ccf6b 100644
--- a/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiCreator.java
+++ b/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiCreator.java
@@ -12,12 +12,12 @@ public class KuromojiCreator extends DictionaryCreator {
super("kuromoji.*\\.txt");
}
- public KuromojiCreator(String pattern) {
+ public KuromojiCreator(final String pattern) {
super(pattern);
}
@Override
- protected DictionaryFile<? extends DictionaryItem> newDictionaryFile(String id, String path, Date timestamp) {
+ protected DictionaryFile<? extends DictionaryItem> newDictionaryFile(final String id, final String path, final Date timestamp) {
return new KuromojiFile(id, path, timestamp).manager(dictionaryManager);
}
diff --git a/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiFile.java b/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiFile.java
index 81ea1717f..62373f371 100644
--- a/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiFile.java
+++ b/src/main/java/org/codelibs/fess/dict/kuromoji/KuromojiFile.java
@@ -45,7 +45,7 @@ public class KuromojiFile extends DictionaryFile<KuromojiItem> {
List<KuromojiItem> kuromojiItemList;
- public KuromojiFile(String id, String path, Date timestamp) {
+ public KuromojiFile(final String id, final String path, final Date timestamp) {
super(id, path, timestamp);
}
@@ -114,7 +114,7 @@ public class KuromojiFile extends DictionaryFile<KuromojiItem> {
}
}
- protected void reload(final KuromojiUpdater updater, InputStream in) {
+ protected void reload(final KuromojiUpdater updater, final InputStream in) {
final List<KuromojiItem> itemList = new ArrayList<KuromojiItem>();
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(in != null ? in : dictionaryManager.getContentInputStream(this), Constants.UTF_8))) {
@@ -164,7 +164,7 @@ public class KuromojiFile extends DictionaryFile<KuromojiItem> {
}
}
if (updater != null) {
- KuromojiItem item = updater.commit();
+ final KuromojiItem item = updater.commit();
if (item != null) {
itemList.add(item);
}
diff --git a/src/main/java/org/codelibs/fess/dict/synonym/SynonymCreator.java b/src/main/java/org/codelibs/fess/dict/synonym/SynonymCreator.java
index daec4cf5e..771f4b43e 100644
--- a/src/main/java/org/codelibs/fess/dict/synonym/SynonymCreator.java
+++ b/src/main/java/org/codelibs/fess/dict/synonym/SynonymCreator.java
@@ -12,12 +12,12 @@ public class SynonymCreator extends DictionaryCreator {
super("synonym.*\\.txt");
}
- public SynonymCreator(String pattern) {
+ public SynonymCreator(final String pattern) {
super(pattern);
}
@Override
- protected DictionaryFile<? extends DictionaryItem> newDictionaryFile(String id, String path, Date timestamp) {
+ protected DictionaryFile<? extends DictionaryItem> newDictionaryFile(final String id, final String path, final Date timestamp) {
return new SynonymFile(id, path, timestamp).manager(dictionaryManager);
}
diff --git a/src/main/java/org/codelibs/fess/dict/synonym/SynonymFile.java b/src/main/java/org/codelibs/fess/dict/synonym/SynonymFile.java
index a76c667d4..58895c07f 100644
--- a/src/main/java/org/codelibs/fess/dict/synonym/SynonymFile.java
+++ b/src/main/java/org/codelibs/fess/dict/synonym/SynonymFile.java
@@ -44,7 +44,7 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
List<SynonymItem> synonymItemList;
- public SynonymFile(String id, String path, Date timestamp) {
+ public SynonymFile(final String id, final String path, final Date timestamp) {
super(id, path, timestamp);
}
@@ -114,7 +114,7 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
}
}
- protected void reload(final SynonymUpdater updater, InputStream in) {
+ protected void reload(final SynonymUpdater updater, final InputStream in) {
final List<SynonymItem> itemList = new ArrayList<SynonymItem>();
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(in != null ? in : dictionaryManager.getContentInputStream(this), Constants.UTF_8))) {
@@ -186,7 +186,7 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
}
}
if (updater != null) {
- SynonymItem item = updater.commit();
+ final SynonymItem item = updater.commit();
if (item != null) {
itemList.add(item);
}
diff --git a/src/main/java/org/codelibs/fess/entity/SearchRenderData.java b/src/main/java/org/codelibs/fess/entity/SearchRenderData.java
new file mode 100644
index 000000000..addb3b8c4
--- /dev/null
+++ b/src/main/java/org/codelibs/fess/entity/SearchRenderData.java
@@ -0,0 +1,170 @@
+package org.codelibs.fess.entity;
+
+import java.util.List;
+import java.util.Map;
+
+import org.codelibs.fess.util.FacetResponse;
+
+public class SearchRenderData {
+
+ private List<Map<String, Object>> documentItems;
+
+ private FacetResponse facetResponse;
+
+ private String appendHighlightParams;
+
+ private String execTime;
+
+ private int pageSize;
+
+ private int currentPageNumber;
+
+ private long allRecordCount;
+
+ private int allPageCount;
+
+ private boolean existNextPage;
+
+ private boolean existPrevPage;
+
+ private long currentStartRecordNumber;
+
+ private long currentEndRecordNumber;
+
+ private List<String> pageNumberList;
+
+ private boolean partialResults;
+
+ private String searchQuery;
+
+ private long queryTime;
+
+ public void setDocumentItems(final List<Map<String, Object>> documentItems) {
+ this.documentItems = documentItems;
+ }
+
+ public void setFacetResponse(final FacetResponse facetResponse) {
+ this.facetResponse = facetResponse;
+ }
+
+ public void setAppendHighlightParams(final String appendHighlightParams) {
+ this.appendHighlightParams = appendHighlightParams;
+ }
+
+ public void setExecTime(final String execTime) {
+ this.execTime = execTime;
+ }
+
+ public void setPageSize(final int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public void setCurrentPageNumber(final int currentPageNumber) {
+ this.currentPageNumber = currentPageNumber;
+ }
+
+ public void setAllRecordCount(final long allRecordCount) {
+ this.allRecordCount = allRecordCount;
+ }
+
+ public void setAllPageCount(final int allPageCount) {
+ this.allPageCount = allPageCount;
+ }
+
+ public void setExistNextPage(final boolean existNextPage) {
+ this.existNextPage = existNextPage;
+ }
+
+ public void setExistPrevPage(final boolean existPrevPage) {
+ this.existPrevPage = existPrevPage;
+ }
+
+ public void setCurrentStartRecordNumber(final long currentStartRecordNumber) {
+ this.currentStartRecordNumber = currentStartRecordNumber;
+ }
+
+ public void setCurrentEndRecordNumber(final long currentEndRecordNumber) {
+ this.currentEndRecordNumber = currentEndRecordNumber;
+ }
+
+ public void setPageNumberList(final List<String> pageNumberList) {
+ this.pageNumberList = pageNumberList;
+ }
+
+ public void setPartialResults(final boolean partialResults) {
+ this.partialResults = partialResults;
+ }
+
+ public void setQueryTime(final long queryTime) {
+ this.queryTime = queryTime;
+ }
+
+ public void setSearchQuery(final String searchQuery) {
+ this.searchQuery = searchQuery;
+ }
+
+ public List<Map<String, Object>> getDocumentItems() {
+ return documentItems;
+ }
+
+ public FacetResponse getFacetResponse() {
+ return facetResponse;
+ }
+
+ public String getAppendHighlightParams() {
+ return appendHighlightParams;
+ }
+
+ public String getExecTime() {
+ return execTime;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public int getCurrentPageNumber() {
+ return currentPageNumber;
+ }
+
+ public long getAllRecordCount() {
+ return allRecordCount;
+ }
+
+ public int getAllPageCount() {
+ return allPageCount;
+ }
+
+ public boolean isExistNextPage() {
+ return existNextPage;
+ }
+
+ public boolean isExistPrevPage() {
+ return existPrevPage;
+ }
+
+ public long getCurrentStartRecordNumber() {
+ return currentStartRecordNumber;
+ }
+
+ public long getCurrentEndRecordNumber() {
+ return currentEndRecordNumber;
+ }
+
+ public List<String> getPageNumberList() {
+ return pageNumberList;
+ }
+
+ public boolean isPartialResults() {
+ return partialResults;
+ }
+
+ public String getSearchQuery() {
+ return searchQuery;
+ }
+
+ public long getQueryTime() {
+ return queryTime;
+ }
+
+}
diff --git a/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java b/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java
new file mode 100644
index 000000000..9f4616dd5
--- /dev/null
+++ b/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java
@@ -0,0 +1,27 @@
+package org.codelibs.fess.entity;
+
+import java.util.Map;
+
+public interface SearchRequestParams {
+
+ String getQuery();
+
+ String getOperator();
+
+ String[] getAdditional();
+
+ Map<String, String[]> getFields();
+
+ String[] getLanguages();
+
+ GeoInfo getGeoInfo();
+
+ FacetInfo getFacetInfo();
+
+ String getSort();
+
+ int getStartPosition();
+
+ int getPageSize();
+
+}
diff --git a/src/main/java/org/codelibs/fess/es/client/FessEsClient.java b/src/main/java/org/codelibs/fess/es/client/FessEsClient.java
index d7f8a9004..73feeec2f 100644
--- a/src/main/java/org/codelibs/fess/es/client/FessEsClient.java
+++ b/src/main/java/org/codelibs/fess/es/client/FessEsClient.java
@@ -10,7 +10,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -36,6 +35,7 @@ import org.codelibs.fess.exception.ResultOffsetExceededException;
import org.codelibs.fess.helper.QueryHelper;
import org.codelibs.fess.indexer.FessSearchQueryException;
import org.codelibs.fess.util.ComponentUtil;
+import org.dbflute.optional.OptionalEntity;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.Action;
import org.elasticsearch.action.ActionFuture;
@@ -471,7 +471,7 @@ public class FessEsClient implements Client {
}
final long execTime = System.currentTimeMillis() - startTime;
- return searchResult.build(requestBuilder, execTime, Optional.ofNullable(response));
+ return searchResult.build(requestBuilder, execTime, OptionalEntity.ofNullable(response, () -> {/* TODO */}));
}
public <T> T search(final String index, final String type, final SearchCondition<SearchRequestBuilder> condition,
@@ -504,10 +504,10 @@ public class FessEsClient implements Client {
}
final long execTime = System.currentTimeMillis() - startTime;
- return searchResult.build(searchRequestBuilder, execTime, Optional.ofNullable(searchResponse));
+ return searchResult.build(searchRequestBuilder, execTime, OptionalEntity.ofNullable(searchResponse, () -> {/* TODO */}));
}
- public Optional<Map<String, Object>> getDocument(final String index, final String type,
+ public OptionalEntity<Map<String, Object>> getDocument(final String index, final String type,
final SearchCondition<SearchRequestBuilder> condition) {
return getDocument(index, type, condition, (response, hit) -> {
final Map<String, Object> source = hit.getSource();
@@ -522,7 +522,7 @@ public class FessEsClient implements Client {
});
}
- public <T> Optional<T> getDocument(final String index, final String type, final SearchCondition<SearchRequestBuilder> condition,
+ public <T> OptionalEntity<T> getDocument(final String index, final String type, final SearchCondition<SearchRequestBuilder> condition,
final EntityCreator<T, SearchResponse, SearchHit> creator) {
return search(index, type, condition, (queryBuilder, execTime, searchResponse) -> {
return searchResponse.map(response -> {
@@ -535,7 +535,7 @@ public class FessEsClient implements Client {
});
}
- public Optional<Map<String, Object>> getDocument(final String index, final String type, final String id,
+ public OptionalEntity<Map<String, Object>> getDocument(final String index, final String type, final String id,
final SearchCondition<GetRequestBuilder> condition) {
return getDocument(index, type, id, condition, (response, result) -> {
final Map<String, Object> source = response.getSource();
@@ -550,7 +550,7 @@ public class FessEsClient implements Client {
});
}
- public <T> Optional<T> getDocument(final String index, final String type, final String id,
+ public <T> OptionalEntity<T> getDocument(final String index, final String type, final String id,
final SearchCondition<GetRequestBuilder> condition, final EntityCreator<T, GetResponse, GetResponse> creator) {
return get(index, type, id, condition, (queryBuilder, execTime, getResponse) -> {
return getResponse.map(response -> {
@@ -562,7 +562,15 @@ public class FessEsClient implements Client {
public List<Map<String, Object>> getDocumentList(final String index, final String type,
final SearchCondition<SearchRequestBuilder> condition) {
return getDocumentList(index, type, condition, (response, hit) -> {
- return hit.getSource();
+ final Map<String, Object> source = hit.getSource();
+ if (source != null) {
+ return source;
+ }
+ final Map<String, SearchHitField> fields = hit.getFields();
+ if (fields != null) {
+ return fields.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> (Object) e.getValue().getValues()));
+ }
+ return null;
});
}
@@ -875,7 +883,7 @@ public class FessEsClient implements Client {
}
public interface SearchResult<T, B, R> {
- T build(B requestBuilder, long execTime, Optional<R> response);
+ T build(B requestBuilder, long execTime, OptionalEntity<R> response);
}
public interface EntityCreator<T, R, H> {
diff --git a/src/main/java/org/codelibs/fess/helper/HotSearchWordHelper.java b/src/main/java/org/codelibs/fess/helper/HotSearchWordHelper.java
index 3eba43da0..647a32a32 100644
--- a/src/main/java/org/codelibs/fess/helper/HotSearchWordHelper.java
+++ b/src/main/java/org/codelibs/fess/helper/HotSearchWordHelper.java
@@ -77,5 +77,23 @@ public class HotSearchWordHelper {
public long getTime() {
return time;
}
+
+ public static Range parseRange(final String value) {
+ Range range;
+ if (value == null) {
+ range = Range.ENTIRE;
+ } else if ("day".equals(value) || "1".equals(value)) {
+ range = Range.ONE_DAY;
+ } else if ("week".equals(value) || "7".equals(value)) {
+ range = Range.ONE_DAY;
+ } else if ("month".equals(value) || "30".equals(value)) {
+ range = Range.ONE_DAY;
+ } else if ("year".equals(value) || "365".equals(value)) {
+ range = Range.ONE_DAY;
+ } else {
+ range = Range.ENTIRE;
+ }
+ return range;
+ }
}
}
diff --git a/src/main/java/org/codelibs/fess/helper/QueryHelper.java b/src/main/java/org/codelibs/fess/helper/QueryHelper.java
index c846591b3..15717521e 100644
--- a/src/main/java/org/codelibs/fess/helper/QueryHelper.java
+++ b/src/main/java/org/codelibs/fess/helper/QueryHelper.java
@@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.codelibs.core.lang.StringUtil;
+import org.codelibs.core.misc.DynamicProperties;
import org.codelibs.fess.Constants;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
@@ -45,27 +46,36 @@ import org.lastaflute.web.util.LaRequestUtil;
public class QueryHelper implements Serializable {
- private static final String SCORE_FIELD = "score";
+ protected static final long serialVersionUID = 1L;
- private static final String INURL_FIELD = "inurl";
+ protected static final String SCORE_FIELD = "score";
- private static final String NOT_ = "NOT ";
+ protected static final String INURL_FIELD = "inurl";
- private static final String AND = "AND";
+ protected static final String NOT_ = "NOT ";
- private static final String OR = "OR";
+ protected static final String AND = "AND";
- private static final String NOT = "NOT";
+ protected static final String OR = "OR";
- private static final String _TO_ = " TO ";
+ protected static final String NOT = "NOT";
- private static final String _OR_ = " OR ";
+ protected static final String _TO_ = " TO ";
- private static final String _AND_ = " AND ";
+ protected static final String _OR_ = " OR ";
- private static final String DEFAULT_OPERATOR = _AND_;
+ protected static final String _AND_ = " AND ";
- private static final long serialVersionUID = 1L;
+ protected static final String DEFAULT_OPERATOR = _AND_;
+
+ protected static final int DEFAULT_START_POSITION = 0;
+
+ protected static final int DEFAULT_PAGE_SIZE = 20;
+
+ protected static final int MAX_PAGE_SIZE = 100;
+
+ @Resource
+ protected DynamicProperties crawlerProperties;
@Resource
protected RoleQueryHelper roleQueryHelper;
@@ -113,9 +123,9 @@ public class QueryHelper implements Serializable {
protected long timeAllowed = -1;
- protected Map<String, String[]> requestParameterMap = new HashMap<String, String[]>();
+ protected Map<String, String[]> requestParameterMap = new HashMap<>();
- protected Map<String, String> fieldLanguageMap = new HashMap<String, String>();
+ protected Map<String, String> fieldLanguageMap = new HashMap<>();
protected int maxSearchResultOffset = 100000;
@@ -133,9 +143,13 @@ public class QueryHelper implements Serializable {
protected String defaultQueryLanguage;
- protected Map<String, String[]> additionalQueryParamMap = new HashMap<String, String[]>();
+ protected Map<String, String[]> additionalQueryParamMap = new HashMap<>();
+
+ protected Map<String, String> fieldBoostMap = new HashMap<>();
- protected Map<String, String> fieldBoostMap = new HashMap<String, String>();
+ protected int defaultPageSize = DEFAULT_PAGE_SIZE;
+
+ protected int defaultStartPosition = DEFAULT_START_POSITION;
@PostConstruct
public void init() {
@@ -1378,6 +1392,34 @@ public class QueryHelper implements Serializable {
this.defaultQueryLanguage = defaultQueryLanguage;
}
+ public int getMaxPageSize() {
+ final Object maxPageSize = crawlerProperties.get(Constants.SEARCH_RESULT_MAX_PAGE_SIZE);
+ if (maxPageSize == null) {
+ return MAX_PAGE_SIZE;
+ }
+ try {
+ return Integer.parseInt(maxPageSize.toString());
+ } catch (final NumberFormatException e) {
+ return MAX_PAGE_SIZE;
+ }
+ }
+
+ public int getDefaultPageSize() {
+ return defaultPageSize;
+ }
+
+ public void setDefaultPageSize(final int defaultPageSize) {
+ this.defaultPageSize = defaultPageSize;
+ }
+
+ public int getDefaultStart() {
+ return defaultStartPosition;
+ }
+
+ public void setDefaultStart(final int defaultStartPosition) {
+ this.defaultStartPosition = defaultStartPosition;
+ }
+
public Map<String, String[]> getQueryParamMap() {
if (additionalQueryParamMap.isEmpty()) {
return additionalQueryParamMap;
diff --git a/src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java b/src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java
index 3bcb073ac..9d51704e3 100644
--- a/src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java
+++ b/src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java
@@ -347,9 +347,6 @@ public interface FessHtmlPath {
/** The path of the HTML: /error/badRequest.jsp */
HtmlNext path_Error_BadRequestJsp = new HtmlNext("/error/badRequest.jsp");
- /** The path of the HTML: /error/error_message.jsp */
- HtmlNext path_Error_ErrorMessageJsp = new HtmlNext("/error/error_message.jsp");
-
/** The path of the HTML: /error/footer.jsp */
HtmlNext path_Error_FooterJsp = new HtmlNext("/error/footer.jsp");
diff --git a/src/main/java/org/codelibs/fess/mylasta/action/FessUserBean.java b/src/main/java/org/codelibs/fess/mylasta/action/FessUserBean.java
index 3613691b5..df8072f68 100644
--- a/src/main/java/org/codelibs/fess/mylasta/action/FessUserBean.java
+++ b/src/main/java/org/codelibs/fess/mylasta/action/FessUserBean.java
@@ -30,7 +30,7 @@ public class FessUserBean extends TypicalUserBean<String> { // #change_it also L
// ==========
/** The serial version UID for object serialization. (Default) */
private static final long serialVersionUID = 1L;
- private User user;
+ private final User user;
// ===================================================================================
// Attribute
@@ -62,19 +62,19 @@ public class FessUserBean extends TypicalUserBean<String> { // #change_it also L
return user.getGroups();
}
- public boolean hasRole(String role) {
+ public boolean hasRole(final String role) {
return Stream.of(user.getRoleNames()).anyMatch(s -> s.equals(role));
}
- public boolean hasRoles(String[] acceptedRoles) {
+ public boolean hasRoles(final String[] acceptedRoles) {
return Stream.of(user.getRoleNames()).anyMatch(s1 -> Stream.of(acceptedRoles).anyMatch(s2 -> s2.equals(s1)));
}
- public boolean hasGroup(String group) {
+ public boolean hasGroup(final String group) {
return Stream.of(user.getGroupNames()).anyMatch(s -> s.equals(group));
}
- public boolean hasGroups(String[] acceptedGroups) {
+ public boolean hasGroups(final String[] acceptedGroups) {
return Stream.of(user.getGroupNames()).anyMatch(s1 -> Stream.of(acceptedGroups).anyMatch(s2 -> s2.equals(s1)));
}
}
diff --git a/src/main/java/org/codelibs/fess/util/ComponentUtil.java b/src/main/java/org/codelibs/fess/util/ComponentUtil.java
index 3e3404d17..fe2a8b481 100644
--- a/src/main/java/org/codelibs/fess/util/ComponentUtil.java
+++ b/src/main/java/org/codelibs/fess/util/ComponentUtil.java
@@ -45,6 +45,7 @@ import org.codelibs.fess.helper.SambaHelper;
import org.codelibs.fess.helper.SearchLogHelper;
import org.codelibs.fess.helper.SystemHelper;
import org.codelibs.fess.helper.UserAgentHelper;
+import org.codelibs.fess.helper.UserInfoHelper;
import org.codelibs.fess.helper.ViewHelper;
import org.codelibs.fess.indexer.IndexUpdater;
import org.codelibs.fess.job.JobExecutor;
@@ -54,6 +55,8 @@ import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
import org.lastaflute.web.servlet.session.SessionManager;
public final class ComponentUtil {
+ private static final String FESS_ES_CLIENT = "fessEsClient";
+
private static final String DICTIONARY_MANAGER = "dictionaryManager";
private static final String DATA_SERVICE = "dataService";
@@ -76,6 +79,8 @@ public final class ComponentUtil {
private static final String USER_AGENT_HELPER = "userAgentHelper";
+ private static final String USER_INFO_HELPER = "userInfoHelper";
+
private static final String WEB_API_MANAGER_FACTORY = "webApiManagerFactory";
private static final String JOB_HELPER = "jobHelper";
@@ -118,7 +123,7 @@ public final class ComponentUtil {
private static final String FIELD_HELPER = "fieldHelper";
- private static final String ELASTICSEARCH_CLIENT = "fessEsClient";
+ private static final String ELASTICSEARCH_CLIENT = FESS_ES_CLIENT;
private ComponentUtil() {
}
@@ -243,6 +248,10 @@ public final class ComponentUtil {
return SingletonLaContainer.getComponent(FIELD_HELPER);
}
+ public static UserInfoHelper getUserInfoHelper() {
+ return SingletonLaContainer.getComponent(USER_INFO_HELPER);
+ }
+
public static FessEsClient getElasticsearchClient() {
return SingletonLaContainer.getComponent(ELASTICSEARCH_CLIENT);
}
@@ -253,13 +262,16 @@ public final class ComponentUtil {
public static DictionaryManager getDictionaryManager() {
return SingletonLaContainer.getComponent(DICTIONARY_MANAGER);
-
}
public static DataService<EsAccessResult> getDataService() {
return SingletonLaContainer.getComponent(DATA_SERVICE);
}
+ public static FessEsClient getFessEsClient() {
+ return SingletonLaContainer.getComponent(FESS_ES_CLIENT);
+ }
+
public static FessLoginAssist getLoginAssist() {
return getComponent(FessLoginAssist.class);
}
diff --git a/src/main/java/org/codelibs/fess/util/DocumentUtil.java b/src/main/java/org/codelibs/fess/util/DocumentUtil.java
index 0dd94840b..c3689327b 100644
--- a/src/main/java/org/codelibs/fess/util/DocumentUtil.java
+++ b/src/main/java/org/codelibs/fess/util/DocumentUtil.java
@@ -38,7 +38,7 @@ public final class DocumentUtil {
}
@SuppressWarnings("unchecked")
- private static <T> T convertObj(Object value, final Class<T> clazz) {
+ private static <T> T convertObj(final Object value, final Class<T> clazz) {
if (value == null) {
return null;
}
diff --git a/src/main/java/org/codelibs/fess/util/QueryResponseList.java b/src/main/java/org/codelibs/fess/util/QueryResponseList.java
index dd30a6227..24f04988d 100644
--- a/src/main/java/org/codelibs/fess/util/QueryResponseList.java
+++ b/src/main/java/org/codelibs/fess/util/QueryResponseList.java
@@ -23,11 +23,11 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.codelibs.fess.helper.QueryHelper;
import org.codelibs.fess.helper.ViewHelper;
+import org.dbflute.optional.OptionalEntity;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
@@ -82,7 +82,7 @@ public class QueryResponseList implements List<Map<String, Object>> {
this.parent = parent;
}
- public void init(final Optional<SearchResponse> searchResponseOpt, final int start, final int pageSize) {
+ public void init(final OptionalEntity<SearchResponse> searchResponseOpt, final int start, final int pageSize) {
searchResponseOpt.ifPresent(searchResponse -> {
final SearchHits searchHits = searchResponse.getHits();
allRecordCount = searchHits.getTotalHits();
@@ -362,4 +362,8 @@ public class QueryResponseList implements List<Map<String, Object>> {
return partialResults;
}
+ public long getQueryTime() {
+ return queryTime;
+ }
+
}
diff --git a/src/main/java/org/codelibs/fess/util/ResourceUtil.java b/src/main/java/org/codelibs/fess/util/ResourceUtil.java
index 959655914..3f247752e 100644
--- a/src/main/java/org/codelibs/fess/util/ResourceUtil.java
+++ b/src/main/java/org/codelibs/fess/util/ResourceUtil.java
@@ -59,13 +59,13 @@ public class ResourceUtil {
return getPath("dict", names);
}
- protected static Path getPath(final String base, String... names) {
+ protected static Path getPath(final String base, final String... names) {
try {
final ServletContext servletContext = SingletonLaContainer.getComponent(ServletContext.class);
- String webinfoPath = servletContext.getRealPath("/WEB-INF/" + base);
+ final String webinfoPath = servletContext.getRealPath("/WEB-INF/" + base);
if (webinfoPath != null) {
- Path path = Paths.get(webinfoPath, names);
+ final Path path = Paths.get(webinfoPath, names);
if (Files.exists(path)) {
return path;
}
diff --git a/src/main/resources/fess_api.xml b/src/main/resources/fess_api.xml
index 6f46798dd..a2bf55dfe 100644
--- a/src/main/resources/fess_api.xml
+++ b/src/main/resources/fess_api.xml
@@ -5,9 +5,6 @@
<include path="fess_config.xml"/>
<component name="webApiManagerFactory" class="org.codelibs.fess.api.WebApiManagerFactory">
- <postConstruct name="add">
- <arg>xmlApiManager</arg>
- </postConstruct>
<postConstruct name="add">
<arg>jsonApiManager</arg>
</postConstruct>
@@ -19,8 +16,6 @@
</postConstruct>
</component>
- <component name="xmlApiManager" class="org.codelibs.fess.api.xml.XmlApiManager">
- </component>
<component name="jsonApiManager" class="org.codelibs.fess.api.json.JsonApiManager">
</component>
<component name="esApiManager" class="org.codelibs.fess.api.es.EsApiManager">
diff --git a/src/main/webapp/WEB-INF/view/searchResults.jsp b/src/main/webapp/WEB-INF/view/searchResults.jsp
index ec251ad1e..a87d161b4 100644
--- a/src/main/webapp/WEB-INF/view/searchResults.jsp
+++ b/src/main/webapp/WEB-INF/view/searchResults.jsp
@@ -69,7 +69,7 @@
<a href="#${doc.doc_id}" class="favorite"><la:message
key="labels.search_result_favorite" /> (${f:h(doc.favorite_count)})</a>
<span class="favorited"><la:message
- key="labels.search_result_favorited"/> <span class="favorited-count">(${f:h(doc.favoriteCount_l_x_dv)})</span></span>
+ key="labels.search_result_favorited"/> <span class="favorited-count">(${f:h(doc.favorite_count)})</span></span>
</c:if>
</div>
</div>
--
GitLab