modify json api

This commit is contained in:
Shinsuke Sugaya 2015-10-22 14:50:00 +09:00
parent 0fe8bb94e7
commit 7f3ee40e37
39 changed files with 1260 additions and 1048 deletions

View file

@ -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)) {

View file

@ -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;
}

View file

@ -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;
try {
chain.doFilter(new WebApiRequest(request, FAVORITE_API), new WebApiResponse(response));
WebApiUtil.validate();
if (Constants.FALSE.equals(crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE))) {
writeJsonResponse(9, null, "Unsupported operation.");
return;
}
body = "\"result\":\"ok\"";
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 {
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();
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;
}
}
}

View file

@ -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();
}
}

View file

@ -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());
}
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);
});
}

View file

@ -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) {

View file

@ -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, ",");

View file

@ -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;

View file

@ -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
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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,299 +130,60 @@ public class SearchAction extends FessSearchAction {
return asHtml(path_SearchJsp).renderWith(data -> {
updateSearchParams(form);
buildLabelParams(form.fields);
doSearchInternal(data, form);
form.lang = searchService.getLanguages(request, form);
try {
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);
}
}
} 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));
}
form.rt = Long.toString(systemHelper.getCurrentTimeAsLong());
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 {
int start = queryHelper.getDefaultStart();
if (StringUtil.isNotBlank(form.pn)) {
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;
int pageNumber = Integer.parseInt(form.pn);
if (pageNumber > 0) {
pageNumber = pageNumber + move;
if (pageNumber < 1) {
pageNumber = 1;
}
start = (pageNumber - 1) * form.getPageSize();
}
form.start = String.valueOf((pageNumber - 1) * pageNum);
} else {
form.start = String.valueOf(DEFAULT_START_COUNT);
} catch (final NumberFormatException e) {
// ignore
}
}
form.start = String.valueOf(start);
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);
}
}
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);
}
}
if (!langSet.isEmpty()) {
appendLangQuery(queryBuf, langSet);
}
}
}
final String query = queryBuf.toString().trim();
// init pager
if (StringUtil.isBlank(form.start)) {
form.start = String.valueOf(DEFAULT_START_COUNT);
} else {
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));
}
}
}
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());
}
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(')');
}
}
protected void updateSearchParams(final SearchForm form) {
if (form.facet == null) {
form.facet = queryHelper.getDefaultFacetInfo();
@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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> {

View file

@ -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;
}
}
}

View file

@ -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<String, String>();
protected Map<String, String> fieldBoostMap = new HashMap<>();
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;

View file

@ -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");

View file

@ -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)));
}
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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">

View file

@ -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>