modify json api
This commit is contained in:
parent
0fe8bb94e7
commit
7f3ee40e37
39 changed files with 1260 additions and 1048 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
324
src/main/java/org/codelibs/fess/app/service/SearchService.java
Normal file
324
src/main/java/org/codelibs/fess/app/service/SearchService.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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, ",");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
170
src/main/java/org/codelibs/fess/entity/SearchRenderData.java
Normal file
170
src/main/java/org/codelibs/fess/entity/SearchRenderData.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue