lastanized RootAction
This commit is contained in:
parent
8b4e62dce9
commit
ded1bd6122
22 changed files with 1451 additions and 1309 deletions
2
pom.xml
2
pom.xml
|
@ -149,9 +149,7 @@
|
|||
<exclude>org/codelibs/fess/app/web/admin/RequestHeaderAction.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/base/AbstractLoginAction.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/ErrorAction.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/RootForm.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/LoginAction.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/RootAction.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/ErrorForm.java</exclude>
|
||||
<exclude>org/codelibs/fess/app/web/LoginForm.java</exclude>
|
||||
</excludes>
|
||||
|
|
|
@ -16,18 +16,21 @@
|
|||
|
||||
package org.codelibs.fess;
|
||||
|
||||
import org.codelibs.fess.mylasta.action.FessMessages;
|
||||
import org.lastaflute.web.validation.VaMessenger;
|
||||
|
||||
public class InvalidQueryException extends FessSystemException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String messageCode;
|
||||
private final VaMessenger<FessMessages> messageCode;
|
||||
|
||||
public InvalidQueryException(final String messageCode, final String message, final Throwable cause) {
|
||||
public InvalidQueryException(final VaMessenger<FessMessages> messageCode, final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
this.messageCode = messageCode;
|
||||
}
|
||||
|
||||
public InvalidQueryException(final String messageCode, final String message) {
|
||||
public InvalidQueryException(final VaMessenger<FessMessages> messageCode, final String message) {
|
||||
super(message);
|
||||
this.messageCode = messageCode;
|
||||
}
|
||||
|
@ -35,7 +38,7 @@ public class InvalidQueryException extends FessSystemException {
|
|||
/**
|
||||
* @return the messageCode
|
||||
*/
|
||||
public String getMessageCode() {
|
||||
public VaMessenger<FessMessages> getMessageCode() {
|
||||
return messageCode;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,81 +18,20 @@ package org.codelibs.fess.app.web;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.codelibs.fess.entity.FacetInfo;
|
||||
import org.codelibs.fess.entity.GeoInfo;
|
||||
import org.codelibs.fess.util.SearchParamMap;
|
||||
|
||||
public class RootForm implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SearchParamMap fields = new SearchParamMap();
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String query;
|
||||
|
||||
public String additional[];
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String sort;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 10)
|
||||
public String op;
|
||||
|
||||
//@IntegerType
|
||||
public String start;
|
||||
|
||||
//@IntegerType
|
||||
public String pn;
|
||||
|
||||
//@IntegerType
|
||||
public String num;
|
||||
|
||||
public String[] lang;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String queryId;
|
||||
|
||||
public SearchParamMap fields = new SearchParamMap();
|
||||
|
||||
// response redirect
|
||||
|
||||
//@Required(target = "go")
|
||||
//@Maxbytelength(maxbytelength = 4000)
|
||||
public String rt;
|
||||
|
||||
//@Required(target = "go,cache")
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String docId;
|
||||
|
||||
public String[] hq;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String hash;
|
||||
|
||||
// xml/json
|
||||
|
||||
//@Maxbytelength(maxbytelength = 20)
|
||||
public String type;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 255)
|
||||
public String callback;
|
||||
|
||||
public String[] fn;
|
||||
|
||||
// hotsearchword
|
||||
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String range;
|
||||
|
||||
// geo
|
||||
|
||||
public GeoInfo geo;
|
||||
|
||||
// facet
|
||||
|
||||
public FacetInfo facet;
|
||||
|
||||
// advance
|
||||
|
||||
public SearchParamMap options = new SearchParamMap();
|
||||
|
||||
}
|
||||
|
|
|
@ -29,11 +29,4 @@ public class BoostDocumentRuleSearchForm implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Map<String, String> searchParams = new HashMap<String, String>();
|
||||
|
||||
//@IntegerType
|
||||
public String pageNumber;
|
||||
|
||||
public String getCurrentPageNumber() {
|
||||
return pageNumber;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,185 @@
|
|||
*/
|
||||
package org.codelibs.fess.app.web.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.core.misc.DynamicProperties;
|
||||
import org.codelibs.core.net.URLUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.SSCConstants;
|
||||
import org.codelibs.fess.UnsupportedSearchException;
|
||||
import org.codelibs.fess.client.FessEsClient;
|
||||
import org.codelibs.fess.entity.LoginInfo;
|
||||
import org.codelibs.fess.helper.FieldHelper;
|
||||
import org.codelibs.fess.helper.LabelTypeHelper;
|
||||
import org.codelibs.fess.helper.OpenSearchHelper;
|
||||
import org.codelibs.fess.helper.QueryHelper;
|
||||
import org.codelibs.fess.helper.RoleQueryHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.helper.UserInfoHelper;
|
||||
import org.codelibs.fess.helper.ViewHelper;
|
||||
import org.codelibs.fess.screenshot.ScreenShotManager;
|
||||
import org.codelibs.fess.util.SearchParamMap;
|
||||
import org.lastaflute.web.callback.ActionRuntime;
|
||||
import org.lastaflute.web.response.ActionResponse;
|
||||
import org.lastaflute.web.response.render.RenderData;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
|
||||
public abstract class FessSearchAction extends FessBaseAction {
|
||||
|
||||
protected static final String LABEL_FIELD = "label";
|
||||
|
||||
@Resource
|
||||
protected FessEsClient fessEsClient;
|
||||
|
||||
@Resource
|
||||
protected ScreenShotManager screenShotManager;
|
||||
|
||||
@Resource
|
||||
protected LabelTypeHelper labelTypeHelper;
|
||||
|
||||
@Resource
|
||||
protected ViewHelper viewHelper;
|
||||
|
||||
@Resource
|
||||
protected QueryHelper queryHelper;
|
||||
|
||||
@Resource
|
||||
protected RoleQueryHelper roleQueryHelper;
|
||||
|
||||
@Resource
|
||||
protected UserInfoHelper userInfoHelper;
|
||||
|
||||
@Resource
|
||||
protected SystemHelper systemHelper;
|
||||
|
||||
@Resource
|
||||
protected FieldHelper fieldHelper;
|
||||
|
||||
@Resource
|
||||
protected OpenSearchHelper openSearchHelper;
|
||||
|
||||
@Resource
|
||||
protected DynamicProperties crawlerProperties;
|
||||
|
||||
@Resource
|
||||
protected HttpServletRequest request;
|
||||
|
||||
protected boolean searchLogSupport;
|
||||
|
||||
protected boolean favoriteSupport;
|
||||
|
||||
@Override
|
||||
public ActionResponse hookBefore(ActionRuntime runtime) { // application may override
|
||||
searchLogSupport = Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE));
|
||||
favoriteSupport = Constants.TRUE.equals(crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE));
|
||||
runtime.registerData("searchLogSupport", searchLogSupport);
|
||||
runtime.registerData("favoriteSupport", favoriteSupport);
|
||||
return super.hookBefore(runtime);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupHtmlData(ActionRuntime runtime) {
|
||||
super.setupHtmlData(runtime);
|
||||
runtime.registerData("osddLink", openSearchHelper.hasOpenSearchFile());
|
||||
runtime.registerData("helpPage", viewHelper.getPagePath("common/help"));
|
||||
}
|
||||
|
||||
protected void searchAvailable() {
|
||||
final String supportedSearch =
|
||||
crawlerProperties.getProperty(Constants.SUPPORTED_SEARCH_FEATURE_PROPERTY, Constants.SUPPORTED_SEARCH_WEB);
|
||||
if (Constants.SUPPORTED_SEARCH_NONE.equals(supportedSearch)) {
|
||||
throw new UnsupportedSearchException("A search is not supported: " + LaRequestUtil.getRequest().getRequestURL());
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Map<String, String>> buildLabelParams(RenderData data, SearchParamMap fields) {
|
||||
// label
|
||||
List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList();
|
||||
data.register("labelTypeItems", labelTypeItems);
|
||||
data.register("displayLabelTypeItems", labelTypeItems != null && !labelTypeItems.isEmpty());
|
||||
|
||||
if (!labelTypeItems.isEmpty() && !fields.containsKey(FessSearchAction.LABEL_FIELD)) {
|
||||
final String defaultLabelValue = crawlerProperties.getProperty(Constants.DEFAULT_LABEL_VALUE_PROPERTY, StringUtil.EMPTY);
|
||||
if (StringUtil.isNotBlank(defaultLabelValue)) {
|
||||
final String[] values = defaultLabelValue.split("\n");
|
||||
if (values != null && values.length > 0) {
|
||||
final List<String> list = new ArrayList<String>(values.length);
|
||||
for (final String value : values) {
|
||||
if (StringUtil.isNotBlank(value)) {
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
fields.put(FessSearchAction.LABEL_FIELD, list.toArray(new String[list.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, String> labelMap = new LinkedHashMap<String, String>();
|
||||
if (!labelTypeItems.isEmpty()) {
|
||||
for (final Map<String, String> map : labelTypeItems) {
|
||||
labelMap.put(map.get(Constants.ITEM_VALUE), map.get(Constants.ITEM_LABEL));
|
||||
}
|
||||
}
|
||||
request.setAttribute(Constants.LABEL_VALUE_MAP, labelMap);
|
||||
|
||||
return labelTypeItems;
|
||||
}
|
||||
|
||||
protected void buildUserParams(RenderData data) {
|
||||
|
||||
Locale locale = request.getLocale();
|
||||
if (locale == null) {
|
||||
locale = Locale.ENGLISH;
|
||||
}
|
||||
data.register("langItems", systemHelper.getLanguageItems(locale));
|
||||
|
||||
final HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
final Object obj = session.getAttribute(SSCConstants.USER_INFO);
|
||||
if (obj instanceof LoginInfo) {
|
||||
final LoginInfo loginInfo = (LoginInfo) obj;
|
||||
data.register("username", loginInfo.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void buildInitParams() {
|
||||
buildInitParamMap(viewHelper.getInitFacetParamMap(), Constants.FACET_QUERY, Constants.FACET_FORM);
|
||||
buildInitParamMap(viewHelper.getInitGeoParamMap(), Constants.GEO_QUERY, Constants.GEO_FORM);
|
||||
}
|
||||
|
||||
protected void buildInitParamMap(final Map<String, String> paramMap, final String queryKey, final String formKey) {
|
||||
if (!paramMap.isEmpty()) {
|
||||
final StringBuilder queryBuf = new StringBuilder(100);
|
||||
final StringBuilder formBuf = new StringBuilder(100);
|
||||
for (final Map.Entry<String, String> entry : paramMap.entrySet()) {
|
||||
queryBuf.append('&');
|
||||
queryBuf.append(URLUtil.encode(entry.getValue(), Constants.UTF_8));
|
||||
queryBuf.append('=');
|
||||
queryBuf.append(URLUtil.encode(entry.getKey(), Constants.UTF_8));
|
||||
formBuf.append("<input type=\"hidden\" name=\"");
|
||||
formBuf.append(StringEscapeUtils.escapeHtml4(entry.getValue()));
|
||||
formBuf.append("\" value=\"");
|
||||
formBuf.append(StringEscapeUtils.escapeHtml4(entry.getKey()));
|
||||
formBuf.append("\"/>");
|
||||
}
|
||||
request.setAttribute(queryKey, queryBuf.toString());
|
||||
request.setAttribute(formKey, formBuf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
80
src/main/java/org/codelibs/fess/app/web/cache/CacheAction.java
vendored
Normal file
80
src/main/java/org/codelibs/fess/app/web/cache/CacheAction.java
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.app.web.cache;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.StreamResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CacheAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheAction.class);
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
@Execute
|
||||
public StreamResponse index(final CacheForm form) {
|
||||
searchAvailable();
|
||||
|
||||
Map<String, Object> doc = null;
|
||||
try {
|
||||
doc = fessEsClient.getDocument(fieldHelper.docIndex, fieldHelper.docType, queryRequestBuilder -> {
|
||||
final TermQueryBuilder termQuery = QueryBuilders.termQuery(fieldHelper.docIdField, form.docId);
|
||||
queryRequestBuilder.setQuery(termQuery);
|
||||
queryRequestBuilder.addFields(queryHelper.getResponseFields());
|
||||
return true;
|
||||
}).get();
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Failed to request: " + form.docId, e);
|
||||
}
|
||||
if (doc == null) {
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsDocidNotFound(GLOBAL, form.docId);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
|
||||
final String content = viewHelper.createCacheContent(doc, form.hq);
|
||||
if (content == null) {
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsDocidNotFound(GLOBAL, form.docId);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
|
||||
return asStream((String) doc.get(fieldHelper.docIdField)).contentType("text/html; charset=UTF-8").data(
|
||||
content.getBytes(Constants.CHARSET_UTF_8));
|
||||
}
|
||||
|
||||
}
|
13
src/main/java/org/codelibs/fess/app/web/cache/CacheForm.java
vendored
Normal file
13
src/main/java/org/codelibs/fess/app/web/cache/CacheForm.java
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
package org.codelibs.fess.app.web.cache;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
|
||||
public class CacheForm extends RootForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//@Required(target = "go,cache")
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String docId;
|
||||
public String[] hq;
|
||||
|
||||
}
|
176
src/main/java/org/codelibs/fess/app/web/go/GoAction.java
Normal file
176
src/main/java/org/codelibs/fess/app/web/go/GoAction.java
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* 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.app.web.go;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.core.net.URLUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.codelibs.fess.es.exentity.ClickLog;
|
||||
import org.codelibs.fess.helper.CrawlingConfigHelper;
|
||||
import org.codelibs.fess.helper.SearchLogHelper;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.robot.util.CharUtil;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.lastaflute.web.util.LaResponseUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class GoAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
private static final Logger logger = LoggerFactory.getLogger(GoAction.class);
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
@Execute
|
||||
public HtmlResponse index(final GoForm form) throws IOException {
|
||||
searchAvailable();
|
||||
|
||||
Map<String, Object> doc = null;
|
||||
try {
|
||||
doc = fessEsClient.getDocument(fieldHelper.docIndex, fieldHelper.docType, queryRequestBuilder -> {
|
||||
final TermQueryBuilder termQuery = QueryBuilders.termQuery(fieldHelper.docIdField, form.docId);
|
||||
queryRequestBuilder.setQuery(termQuery);
|
||||
queryRequestBuilder.addFields(queryHelper.getResponseFields());
|
||||
return true;
|
||||
}).get();
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Failed to request: " + form.docId, e);
|
||||
}
|
||||
if (doc == null) {
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsDocidNotFound(GLOBAL, form.docId);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
final Object urlObj = doc.get(fieldHelper.urlField);
|
||||
if (urlObj == null) {
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsDocumentNotFound(GLOBAL, form.docId);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
final String url = urlObj.toString();
|
||||
|
||||
if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE))) {
|
||||
final String userSessionId = userInfoHelper.getUserCode();
|
||||
if (userSessionId != null) {
|
||||
final SearchLogHelper searchLogHelper = ComponentUtil.getSearchLogHelper();
|
||||
final ClickLog clickLog = new ClickLog();
|
||||
clickLog.setUrl(url);
|
||||
final long now = systemHelper.getCurrentTimeAsLong();
|
||||
clickLog.setRequestedTime(now);
|
||||
clickLog.setQueryRequestedTime(Long.parseLong(form.rt));
|
||||
clickLog.setUserSessionId(userSessionId);
|
||||
clickLog.setDocId(form.docId);
|
||||
long clickCount = 0;
|
||||
final Object count = doc.get(fieldHelper.clickCountField);
|
||||
if (count instanceof Long) {
|
||||
clickCount = ((Long) count).longValue();
|
||||
}
|
||||
clickLog.setClickCount(clickCount);
|
||||
searchLogHelper.addClickLog(clickLog);
|
||||
}
|
||||
}
|
||||
|
||||
String hash;
|
||||
if (StringUtil.isNotBlank(form.hash)) {
|
||||
final String value = URLUtil.decode(form.hash, Constants.UTF_8);
|
||||
final StringBuilder buf = new StringBuilder(value.length() + 100);
|
||||
for (final char c : value.toCharArray()) {
|
||||
if (CharUtil.isUrlChar(c) || c == ' ') {
|
||||
buf.append(c);
|
||||
} else {
|
||||
try {
|
||||
buf.append(URLEncoder.encode(String.valueOf(c), Constants.UTF_8));
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
// NOP
|
||||
}
|
||||
}
|
||||
}
|
||||
hash = buf.toString();
|
||||
} else {
|
||||
hash = StringUtil.EMPTY;
|
||||
}
|
||||
|
||||
if (isFileSystemPath(url)) {
|
||||
if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_FILE_PROXY_PROPERTY, Constants.TRUE))) {
|
||||
final CrawlingConfigHelper crawlingConfigHelper = ComponentUtil.getCrawlingConfigHelper();
|
||||
try {
|
||||
crawlingConfigHelper.writeContent(doc);
|
||||
return null;
|
||||
} catch (final Exception e) {
|
||||
logger.error("Failed to load: " + doc, e);
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsNotLoadFromServer(GLOBAL, url);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
} else if (Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_DESKTOP_PROPERTY, Constants.FALSE))) {
|
||||
final String path = url.replaceFirst("file:/+", "//");
|
||||
final File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsNotFoundOnFileSystem(GLOBAL, url);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
final Desktop desktop = Desktop.getDesktop();
|
||||
try {
|
||||
desktop.open(file);
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Could not open " + path, e);
|
||||
throwValidationError(messages -> {
|
||||
messages.addErrorsCouldNotOpenOnSystem(GLOBAL, url);
|
||||
}, () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
|
||||
LaResponseUtil.getResponse().setStatus(HttpServletResponse.SC_NO_CONTENT);
|
||||
return null;
|
||||
} else {
|
||||
LaResponseUtil.getResponse().sendRedirect(url + hash);
|
||||
}
|
||||
} else {
|
||||
LaResponseUtil.getResponse().sendRedirect(url + hash);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isFileSystemPath(final String url) {
|
||||
return url.startsWith("file:") || url.startsWith("smb:");
|
||||
}
|
||||
}
|
15
src/main/java/org/codelibs/fess/app/web/go/GoForm.java
Normal file
15
src/main/java/org/codelibs/fess/app/web/go/GoForm.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package org.codelibs.fess.app.web.go;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
|
||||
public class GoForm extends RootForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//@Required(target = "go,cache")
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String docId;
|
||||
|
||||
public String rt;
|
||||
|
||||
public String hash;
|
||||
}
|
50
src/main/java/org/codelibs/fess/app/web/help/HelpAction.java
Normal file
50
src/main/java/org/codelibs/fess/app/web/help/HelpAction.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.app.web.help;
|
||||
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
|
||||
public class HelpAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
|
||||
@Execute
|
||||
public HtmlResponse help(HelpForm form) {
|
||||
return asHtml(path_HelpJsp).renderWith(data -> {
|
||||
buildLabelParams(data, form.fields);
|
||||
buildUserParams(data);
|
||||
buildInitParams();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.codelibs.fess.app.web.help;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
|
||||
public class HelpForm extends RootForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
49
src/main/java/org/codelibs/fess/app/web/osdd/OsddAction.java
Normal file
49
src/main/java/org/codelibs/fess/app/web/osdd/OsddAction.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.app.web.osdd;
|
||||
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.lastaflute.web.util.LaResponseUtil;
|
||||
|
||||
public class OsddAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
|
||||
@Execute
|
||||
public HtmlResponse osdd(OsddForm form) {
|
||||
searchAvailable();
|
||||
openSearchHelper.write(LaResponseUtil.getResponse());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.codelibs.fess.app.web.osdd;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
|
||||
public class OsddForm extends RootForm {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.app.web.screenshot;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.codelibs.core.io.CopyUtil;
|
||||
import org.codelibs.core.io.OutputStreamUtil;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ScreenshotAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
private static final Logger logger = LoggerFactory.getLogger(ScreenshotAction.class);
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
//
|
||||
@Resource
|
||||
protected HttpServletResponse response;
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
@Execute
|
||||
public HtmlResponse index(final ScreenshotForm form) {
|
||||
searchAvailable();
|
||||
|
||||
OutputStream out = null;
|
||||
BufferedInputStream in = null;
|
||||
try {
|
||||
final Map<String, Object> doc = fessEsClient.getDocument(fieldHelper.docIndex, fieldHelper.docType, queryRequestBuilder -> {
|
||||
final TermQueryBuilder termQuery = QueryBuilders.termQuery(fieldHelper.docIdField, form.docId);
|
||||
queryRequestBuilder.setQuery(termQuery);
|
||||
queryRequestBuilder.addFields(queryHelper.getResponseFields());
|
||||
return true;
|
||||
}).get();
|
||||
final String url = doc == null ? null : (String) doc.get(fieldHelper.urlField);
|
||||
if (StringUtil.isBlank(form.queryId) || StringUtil.isBlank(url) || screenShotManager == null) {
|
||||
// 404
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
return null;
|
||||
}
|
||||
|
||||
final File screenShotFile = screenShotManager.getScreenShotFile(form.queryId, form.docId);
|
||||
if (screenShotFile == null) {
|
||||
// 404
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
screenShotManager.generate(doc);
|
||||
return null;
|
||||
}
|
||||
|
||||
response.setContentType(getImageMimeType(screenShotFile));
|
||||
|
||||
out = response.getOutputStream();
|
||||
in = new BufferedInputStream(new FileInputStream(screenShotFile));
|
||||
CopyUtil.copy(in, out);
|
||||
OutputStreamUtil.flush(out);
|
||||
} catch (final Exception e) {
|
||||
logger.error("Failed to response: " + form.docId, e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getImageMimeType(final File imageFile) {
|
||||
final String path = imageFile.getAbsolutePath();
|
||||
if (path.endsWith(".png")) {
|
||||
return "image/png";
|
||||
} else if (path.endsWith(".gif")) {
|
||||
return "image/gif";
|
||||
} else if (path.endsWith(".jpg") || path.endsWith(".jpeg")) {
|
||||
return "image/jpeg";
|
||||
} else {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.codelibs.fess.app.web.screenshot;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
|
||||
public class ScreenshotForm extends RootForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String docId;
|
||||
|
||||
public String queryId;
|
||||
|
||||
}
|
568
src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
Normal file
568
src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
Normal file
|
@ -0,0 +1,568 @@
|
|||
/*
|
||||
* 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.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.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.InvalidQueryException;
|
||||
import org.codelibs.fess.ResultOffsetExceededException;
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
import org.codelibs.fess.app.web.base.FessSearchAction;
|
||||
import org.codelibs.fess.client.FessEsClient.SearchConditionBuilder;
|
||||
import org.codelibs.fess.es.exentity.SearchLog;
|
||||
import org.codelibs.fess.es.exentity.UserInfo;
|
||||
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.lastaflute.taglib.function.LaFunctions;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.lastaflute.web.response.render.RenderData;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SearchAction extends FessSearchAction {
|
||||
|
||||
// ===================================================================================
|
||||
// Constant
|
||||
//
|
||||
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
|
||||
//
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
// ======
|
||||
|
||||
// ===================================================================================
|
||||
// Search Execute
|
||||
// ==============
|
||||
@Execute
|
||||
public HtmlResponse index(final SearchForm form) {
|
||||
return search(form);
|
||||
}
|
||||
|
||||
@Execute
|
||||
public HtmlResponse search(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);
|
||||
}
|
||||
}
|
||||
|
||||
return doSearch(form);
|
||||
}
|
||||
|
||||
@Execute
|
||||
public HtmlResponse prev(SearchForm form) {
|
||||
return doMove(form, -1);
|
||||
}
|
||||
|
||||
@Execute
|
||||
public HtmlResponse next(SearchForm form) {
|
||||
return doMove(form, 1);
|
||||
}
|
||||
|
||||
@Execute
|
||||
public HtmlResponse move(SearchForm form) {
|
||||
return doMove(form, 0);
|
||||
}
|
||||
|
||||
protected HtmlResponse doSearch(SearchForm form) {
|
||||
searchAvailable();
|
||||
|
||||
if (viewHelper.isUseSession()) {
|
||||
final HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
final Object resultsPerPage = session.getAttribute(Constants.RESULTS_PER_PAGE);
|
||||
if (resultsPerPage != null) {
|
||||
form.num = resultsPerPage.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil.isBlank(form.query)) {
|
||||
try {
|
||||
final String optionQuery = queryHelper.buildOptionQuery(form.options);
|
||||
form.query = optionQuery;
|
||||
} catch (final InvalidQueryException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(e.getMessage(), e);
|
||||
}
|
||||
throwValidationError(e.getMessageCode(), () -> asHtml(path_ErrorJsp));
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil.isBlank(form.query) && form.fields.isEmpty()) {
|
||||
// redirect to index page
|
||||
form.query = null;
|
||||
return redirect(SearchAction.class);
|
||||
}
|
||||
|
||||
return asHtml(path_SearchJsp).renderWith(data -> {
|
||||
updateSearchParams(form);
|
||||
List<Map<String, String>> labelTypeItems = buildLabelParams(data, form.fields);
|
||||
buildUserParams(data);
|
||||
doSearchInternal(data, form);
|
||||
data.register("displayQuery", getDisplayQuery(form, labelTypeItems));
|
||||
data.register("pagingQuery", getPagingQuery(form));
|
||||
});
|
||||
}
|
||||
|
||||
protected HtmlResponse doMove(SearchForm form, final int move) {
|
||||
int pageNum = getDefaultPageSize();
|
||||
if (StringUtil.isBlank(form.num)) {
|
||||
form.num = String.valueOf(getDefaultPageSize());
|
||||
} else {
|
||||
try {
|
||||
pageNum = Integer.parseInt(form.num);
|
||||
} catch (final NumberFormatException e) {
|
||||
form.num = String.valueOf(getDefaultPageSize());
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil.isBlank(form.pn)) {
|
||||
form.start = String.valueOf(DEFAULT_START_COUNT);
|
||||
} else {
|
||||
Integer pageNumber = Integer.parseInt(form.pn);
|
||||
if (pageNumber != null && pageNumber > 0) {
|
||||
pageNumber = pageNumber + move;
|
||||
if (pageNumber < 1) {
|
||||
pageNumber = 1;
|
||||
}
|
||||
form.start = String.valueOf((pageNumber - 1) * pageNum);
|
||||
} else {
|
||||
form.start = String.valueOf(DEFAULT_START_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
return doSearch(form);
|
||||
}
|
||||
|
||||
protected String doSearchInternal(RenderData data, 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 {
|
||||
Long.parseLong(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.getDocumentList(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();
|
||||
});
|
||||
} 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());
|
||||
data.register("moreLikeThisResponse", queryResponseList.getMoreLikeThisResponse());
|
||||
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.setSolrQuery(StringUtils.abbreviate(queryResponseList.getSolrQuery(), 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(SearchForm form) {
|
||||
if (form.facet == null) {
|
||||
form.facet = queryHelper.getDefaultFacetInfo();
|
||||
}
|
||||
|
||||
if (form.geo == null) {
|
||||
form.geo = queryHelper.getDefaultGeoInfo();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getDisplayQuery(RootForm form, List<Map<String, String>> labelTypeItems) {
|
||||
final StringBuilder buf = new StringBuilder(100);
|
||||
buf.append(form.query);
|
||||
if (!form.fields.isEmpty() && form.fields.containsKey(LABEL_FIELD)) {
|
||||
final String[] values = form.fields.get(LABEL_FIELD);
|
||||
final List<String> labelList = new ArrayList<String>();
|
||||
if (values != null) {
|
||||
for (final String v : values) {
|
||||
labelList.add(v);
|
||||
}
|
||||
}
|
||||
for (final String labelTypeValue : labelList) {
|
||||
for (final Map<String, String> map : labelTypeItems) {
|
||||
if (map.get(Constants.ITEM_VALUE).equals(labelTypeValue)) {
|
||||
buf.append(' ');
|
||||
buf.append(map.get(Constants.ITEM_LABEL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected void normalizePageNum(RootForm 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(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtil.isNotBlank(form.sort)) {
|
||||
buf.append("&sort=").append(LaFunctions.u(form.sort));
|
||||
}
|
||||
if (StringUtil.isNotBlank(form.op)) {
|
||||
buf.append("&op=").append(LaFunctions.u(form.op));
|
||||
}
|
||||
if (form.lang != null) {
|
||||
final Set<String> langSet = new HashSet<String>();
|
||||
for (final String lang : form.lang) {
|
||||
if (StringUtil.isNotBlank(lang) && lang.length() < 1000) {
|
||||
if (Constants.ALL_LANGUAGES.equals(lang)) {
|
||||
langSet.clear();
|
||||
break;
|
||||
}
|
||||
final String normalizeLang = systemHelper.normalizeLang(lang);
|
||||
if (normalizeLang != null) {
|
||||
langSet.add(normalizeLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!langSet.isEmpty()) {
|
||||
for (final String lang : langSet) {
|
||||
buf.append("&lang=").append(LaFunctions.u(lang));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!form.fields.isEmpty()) {
|
||||
for (final Map.Entry<String, String[]> entry : form.fields.entrySet()) {
|
||||
final String[] values = entry.getValue();
|
||||
if (values != null) {
|
||||
for (final String v : values) {
|
||||
if (StringUtil.isNotBlank(v)) {
|
||||
buf.append("&fields.").append(LaFunctions.u(entry.getKey())).append('=').append(LaFunctions.u(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.app.web.search;
|
||||
|
||||
import org.codelibs.fess.app.web.RootForm;
|
||||
import org.codelibs.fess.entity.FacetInfo;
|
||||
import org.codelibs.fess.entity.GeoInfo;
|
||||
import org.codelibs.fess.util.SearchParamMap;
|
||||
|
||||
public class SearchForm extends RootForm {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String additional[];
|
||||
|
||||
//@Maxbytelength(maxbytelength = 10)
|
||||
public String op;
|
||||
|
||||
//@IntegerType
|
||||
public String start;
|
||||
|
||||
//@IntegerType
|
||||
public String pn;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String queryId;
|
||||
|
||||
// response redirect
|
||||
|
||||
//@Required(target = "go")
|
||||
//@Maxbytelength(maxbytelength = 4000)
|
||||
public String rt;
|
||||
|
||||
//@Required(target = "go,cache")
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String docId;
|
||||
|
||||
public String[] hq;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 1000)
|
||||
public String hash;
|
||||
|
||||
// xml/json
|
||||
|
||||
//@Maxbytelength(maxbytelength = 20)
|
||||
public String type;
|
||||
|
||||
//@Maxbytelength(maxbytelength = 255)
|
||||
public String callback;
|
||||
|
||||
public String[] fn;
|
||||
|
||||
// hotsearchword
|
||||
|
||||
//@Maxbytelength(maxbytelength = 100)
|
||||
public String range;
|
||||
|
||||
// geo
|
||||
|
||||
public GeoInfo geo;
|
||||
|
||||
// facet
|
||||
|
||||
public FacetInfo facet;
|
||||
|
||||
// advance
|
||||
|
||||
public SearchParamMap options = new SearchParamMap();
|
||||
|
||||
}
|
|
@ -16,21 +16,6 @@
|
|||
|
||||
package org.codelibs.fess.helper;
|
||||
|
||||
/*
|
||||
* Copyright 2009-2014 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.
|
||||
*/
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -56,6 +41,7 @@ import org.codelibs.fess.entity.SearchQuery;
|
|||
import org.codelibs.fess.entity.SearchQuery.SortField;
|
||||
import org.codelibs.fess.util.QueryUtil;
|
||||
import org.codelibs.fess.util.SearchParamMap;
|
||||
import org.lastaflute.web.ruts.message.ActionMessages;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
|
||||
public class QueryHelper implements Serializable {
|
||||
|
@ -624,7 +610,8 @@ public class QueryHelper implements Serializable {
|
|||
final String value1 = split[0].trim();
|
||||
final String value2 = split[1].trim();
|
||||
if ("*".equals(value1) && "*".equals(value2)) {
|
||||
throw new InvalidQueryException("errors.invalid_query_str_range", "Invalid range: " + value);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryStrRange(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid range: " + value);
|
||||
}
|
||||
buf.append(prefix);
|
||||
buf.append(QueryUtil.escapeRangeValue(value1));
|
||||
|
@ -632,7 +619,8 @@ public class QueryHelper implements Serializable {
|
|||
buf.append(QueryUtil.escapeRangeValue(value2));
|
||||
buf.append(suffix);
|
||||
} else {
|
||||
throw new InvalidQueryException("errors.invalid_query_str_range", "Invalid range: " + value);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryStrRange(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid range: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,13 +718,17 @@ public class QueryHelper implements Serializable {
|
|||
buf.append('\\');
|
||||
}
|
||||
if (quoted) {
|
||||
throw new InvalidQueryException("errors.invalid_query_quoted", "Invalid quoted: " + query);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryQuoted(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid quoted: " + query);
|
||||
} else if (curlyBracket > 0) {
|
||||
throw new InvalidQueryException("errors.invalid_query_curly_bracket", "Invalid curly bracket: " + query);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryCurlyBracket(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid curly bracket: " + query);
|
||||
} else if (squareBracket > 0) {
|
||||
throw new InvalidQueryException("errors.invalid_query_square_bracket", "Invalid square bracket: " + query);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQuerySquareBracket(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid square bracket: " + query);
|
||||
} else if (parenthesis > 0) {
|
||||
throw new InvalidQueryException("errors.invalid_query_parenthesis", "Invalid parenthesis: " + query);
|
||||
throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryParenthesis(ActionMessages.GLOBAL_PROPERTY_KEY),
|
||||
"Invalid parenthesis: " + query);
|
||||
}
|
||||
if (buf.length() > 0) {
|
||||
addQueryPart(buf.toString(), valueList, sortFieldMap, highLightQueryList, fieldLogMap);
|
||||
|
|
|
@ -156,12 +156,14 @@
|
|||
<property name="roleSeparator">","</property>
|
||||
-->
|
||||
</component>
|
||||
<!--
|
||||
<component name="screenShotManager" class="org.codelibs.fess.screenshot.ScreenShotManager">
|
||||
<!--
|
||||
<postConstruct name="add">
|
||||
<arg>htmlScreenShotGenerator</arg>
|
||||
</postConstruct>
|
||||
-->
|
||||
</component>
|
||||
<!--
|
||||
<component name="webDriver" class="org.openqa.selenium.phantomjs.PhantomJSDriver">
|
||||
<arg>
|
||||
<component class="org.openqa.selenium.remote.DesiredCapabilities">
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
<div class="container">
|
||||
<p class="navbar-text pull-right">
|
||||
<c:if test="${!empty username}">
|
||||
<la:link href="/login/logout" styleClass="logout-link">
|
||||
<todo:link href="/login/logout" styleClass="logout-link">
|
||||
<la:message key="labels.logout" />
|
||||
</la:link>
|
||||
</todo:link>
|
||||
</c:if>
|
||||
<la:link href="/help" styleClass="help-link">
|
||||
<la:message key="labels.index_help" />
|
||||
|
@ -41,12 +41,14 @@
|
|||
alt="<la:message key="labels.index_title" />" />
|
||||
</h1>
|
||||
<div>
|
||||
<html:messages id="msg" message="true">
|
||||
<%-- TODO
|
||||
<la:messages id="msg" message="true">
|
||||
<div class="alert-message info">
|
||||
<bean:write name="msg" ignore="true" />
|
||||
</div>
|
||||
</html:messages>
|
||||
<html:errors header="errors.front_header"
|
||||
</la:messages>
|
||||
--%>
|
||||
<la:errors header="errors.front_header"
|
||||
footer="errors.front_footer" prefix="errors.front_prefix"
|
||||
suffix="errors.front_suffix" />
|
||||
</div>
|
||||
|
@ -65,7 +67,7 @@
|
|||
<p class="hotSearchWordBody ellipsis">
|
||||
<la:message key="labels.search_hot_search_word" />
|
||||
<c:forEach var="item" items="${fe:hsw(null, 5)}">
|
||||
<html:link href="search?query=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</html:link>
|
||||
<la:link href="search?query=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</la:link>
|
||||
</c:forEach>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -94,86 +96,86 @@
|
|||
<label for="contentNum"><la:message
|
||||
key="labels.index_num" /></label>
|
||||
<div class="input">
|
||||
<html:select property="num" styleId="numSearchOption"
|
||||
<la:select property="num" styleId="numSearchOption"
|
||||
styleClass="span4" style="display:block;">
|
||||
<option value="">
|
||||
<la:message key="labels.search_result_select_num" />
|
||||
</option>
|
||||
<html:option value="10">10</html:option>
|
||||
<html:option value="20">20</html:option>
|
||||
<html:option value="30">30</html:option>
|
||||
<html:option value="40">40</html:option>
|
||||
<html:option value="50">50</html:option>
|
||||
<html:option value="100">100</html:option>
|
||||
</html:select>
|
||||
<la:option value="10">10</la:option>
|
||||
<la:option value="20">20</la:option>
|
||||
<la:option value="30">30</la:option>
|
||||
<la:option value="40">40</la:option>
|
||||
<la:option value="50">50</la:option>
|
||||
<la:option value="100">100</la:option>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<label for="contentSort"><la:message
|
||||
key="labels.index_sort" /></label>
|
||||
<div class="input">
|
||||
<html:select property="sort" styleId="sortSearchOption"
|
||||
<la:select property="sort" styleId="sortSearchOption"
|
||||
styleClass="span4" style="display:block;">
|
||||
<option value="">
|
||||
<la:message key="labels.search_result_select_sort" />
|
||||
</option>
|
||||
<html:option value="created.asc">
|
||||
<la:option value="created.asc">
|
||||
<la:message key="labels.search_result_sort_created_asc" />
|
||||
</html:option>
|
||||
<html:option value="created.desc">
|
||||
</la:option>
|
||||
<la:option value="created.desc">
|
||||
<la:message key="labels.search_result_sort_created_desc" />
|
||||
</html:option>
|
||||
<html:option value="contentLength.asc">
|
||||
</la:option>
|
||||
<la:option value="contentLength.asc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_contentLength_asc" />
|
||||
</html:option>
|
||||
<html:option value="contentLength.desc">
|
||||
</la:option>
|
||||
<la:option value="contentLength.desc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_contentLength_desc" />
|
||||
</html:option>
|
||||
<html:option value="lastModified.asc">
|
||||
</la:option>
|
||||
<la:option value="lastModified.asc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_lastModified_asc" />
|
||||
</html:option>
|
||||
<html:option value="lastModified.desc">
|
||||
</la:option>
|
||||
<la:option value="lastModified.desc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_lastModified_desc" />
|
||||
</html:option>
|
||||
</la:option>
|
||||
<c:if test="${searchLogSupport}">
|
||||
<html:option value="clickCount_l_x_dv.asc">
|
||||
<la:option value="clickCount_l_x_dv.asc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_clickCount_asc" />
|
||||
</html:option>
|
||||
<html:option value="clickCount_l_x_dv.desc">
|
||||
</la:option>
|
||||
<la:option value="clickCount_l_x_dv.desc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_clickCount_desc" />
|
||||
</html:option>
|
||||
</la:option>
|
||||
</c:if><c:if test="${favoriteSupport}">
|
||||
<html:option value="favoriteCount_l_x_dv.asc">
|
||||
<la:option value="favoriteCount_l_x_dv.asc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_favoriteCount_asc" />
|
||||
</html:option>
|
||||
<html:option value="favoriteCount_l_x_dv.desc">
|
||||
</la:option>
|
||||
<la:option value="favoriteCount_l_x_dv.desc">
|
||||
<la:message
|
||||
key="labels.search_result_sort_favoriteCount_desc" />
|
||||
</html:option>
|
||||
</la:option>
|
||||
</c:if>
|
||||
</html:select>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<label for="contentLang"><la:message
|
||||
key="labels.index_lang" /></label>
|
||||
<div class="input">
|
||||
<html:select property="lang"
|
||||
<la:select property="lang"
|
||||
styleId="langSearchOption" multiple="true"
|
||||
styleClass="span4">
|
||||
<c:forEach var="item" items="${langItems}">
|
||||
<html:option value="${f:u(item.value)}">
|
||||
<la:option value="${f:u(item.value)}">
|
||||
${f:h(item.label)}
|
||||
</html:option>
|
||||
</la:option>
|
||||
</c:forEach>
|
||||
</html:select>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
<c:if test="${displayLabelTypeItems}">
|
||||
|
@ -181,15 +183,15 @@
|
|||
<label for="contentLabelType"><la:message
|
||||
key="labels.index_label" /></label>
|
||||
<div class="input">
|
||||
<html:select property="fields.label"
|
||||
<la:select property="fields.label"
|
||||
styleId="labelTypeSearchOption" multiple="true"
|
||||
styleClass="span4">
|
||||
<c:forEach var="item" items="${labelTypeItems}">
|
||||
<html:option value="${f:u(item.value)}">
|
||||
<la:option value="${f:u(item.value)}">
|
||||
${f:h(item.label)}
|
||||
</html:option>
|
||||
</la:option>
|
||||
</c:forEach>
|
||||
</html:select>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
</c:if>
|
||||
|
|
|
@ -80,9 +80,9 @@
|
|||
<p class="username">
|
||||
<la:message key="labels.searchheader_username" arg0="${f:h(username)}" />
|
||||
|
|
||||
<la:link href="/login/logout" styleClass="logout-link">
|
||||
<todo:link href="/login/logout" styleClass="logout-link">
|
||||
<la:message key="labels.logout" />
|
||||
</la:link>
|
||||
</todo:link>
|
||||
</p>
|
||||
</c:if>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue