Merge pull request #326 from kw-udon/lastaflute-dev

modify searchList action
This commit is contained in:
Shinsuke Sugaya 2015-09-28 22:59:47 +09:00
commit 0466b07c33
6 changed files with 275 additions and 288 deletions

View file

@ -95,14 +95,12 @@
<!-- TODO remove -->
<excludes>
<exclude>org/codelibs/fess/app/web/admin/WizardAction.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/SearchListForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/dict/UserDictForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/dict/SynonymForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/dict/UserDictAction.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/dict/SynonymAction.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/DocumentAction.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/DictForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/SearchListAction.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/DocumentForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/DataForm.java</exclude>
<exclude>org/codelibs/fess/app/web/admin/IndexAction.java</exclude>

View file

@ -1,277 +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.app.web.admin;
import java.beans.Beans;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.codelibs.core.beans.util.BeanUtil;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.core.misc.DynamicProperties;
import org.codelibs.fess.Constants;
import org.codelibs.fess.InvalidQueryException;
import org.codelibs.fess.ResultOffsetExceededException;
import org.codelibs.fess.annotation.Token;
import org.codelibs.fess.client.FessEsClient;
import org.codelibs.fess.client.FessEsClient.SearchConditionBuilder;
import org.codelibs.fess.crud.util.SAStrutsUtil;
import org.codelibs.fess.exception.SSCActionMessagesException;
import org.codelibs.fess.helper.FieldHelper;
import org.codelibs.fess.helper.JobHelper;
import org.codelibs.fess.helper.QueryHelper;
import org.codelibs.fess.helper.SystemHelper;
import org.codelibs.fess.util.QueryResponseList;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.lastaflute.taglib.function.LaFunctions;
import org.lastaflute.web.util.LaRequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SearchListAction implements Serializable {
private static final Logger logger = LoggerFactory.getLogger(SearchListAction.class);
private static final long serialVersionUID = 1L;
//@ActionForm
@Resource
protected SearchListForm searchListForm;
@Resource
protected FessEsClient fessEsClient;
@Resource
protected DynamicProperties crawlerProperties;
@Resource
protected HttpServletRequest request;
@Resource
protected SystemHelper systemHelper;
@Resource
protected FieldHelper fieldHelper;
@Resource
protected QueryHelper queryHelper;
@Resource
protected JobHelper jobHelper;
public List<Map<String, Object>> documentItems;
public String pageSize;
public String currentPageNumber;
public String allRecordCount;
public String allPageCount;
public boolean existNextPage;
public boolean existPrevPage;
public String currentStartRecordNumber;
public String currentEndRecordNumber;
public List<String> pageNumberList;
public String execTime;
public String getHelpLink() {
return systemHelper.getHelpLink("searchList");
}
//@Execute(validator = false)
public String index() {
return "index.jsp";
}
protected String doSearch() {
if (StringUtil.isBlank(searchListForm.query)) {
// redirect to index page
searchListForm.query = null;
return "index?redirect=true";
}
doSearchInternal();
return "index.jsp";
}
private String doSearchInternal() {
final String query = searchListForm.query;
// init pager
if (StringUtil.isBlank(searchListForm.start)) {
searchListForm.start = String.valueOf(Constants.DEFAULT_START_COUNT);
} else {
try {
Long.parseLong(searchListForm.start);
} catch (final NumberFormatException e) {
searchListForm.start = String.valueOf(Constants.DEFAULT_START_COUNT);
}
}
if (StringUtil.isBlank(searchListForm.num)) {
searchListForm.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
} else {
try {
final int num = Integer.parseInt(searchListForm.num);
if (num > 100) {
// max page size
searchListForm.num = "100";
}
} catch (final NumberFormatException e) {
searchListForm.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
}
}
final int offset = Integer.parseInt(searchListForm.start);
final int size = Integer.parseInt(searchListForm.num);
try {
documentItems =
fessEsClient.getDocumentList(fieldHelper.docIndex, fieldHelper.docType, searchRequestBuilder -> {
return SearchConditionBuilder.builder(searchRequestBuilder).administrativeAccess().offset(offset).size(size)
.responseFields(queryHelper.getResponseFields()).build();
});
} catch (final InvalidQueryException e) {
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage(), e);
}
throw new SSCActionMessagesException(e, e.getMessageCode());
} catch (final ResultOffsetExceededException e) {
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage(), e);
}
throw new SSCActionMessagesException(e, "errors.result_size_exceeded");
}
final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
final NumberFormat nf = NumberFormat.getInstance(LaRequestUtil.getRequest().getLocale());
nf.setMaximumIntegerDigits(2);
nf.setMaximumFractionDigits(2);
try {
execTime = nf.format((double) queryResponseList.getExecTime() / 1000);
} catch (final Exception e) {}
BeanUtil.copyBeanToBean(documentItems, this, option -> option.include("pageSize", "currentPageNumber", "allRecordCount",
"allPageCount", "existNextPage", "existPrevPage", "currentStartRecordNumber", "currentEndRecordNumber", "pageNumberList"));
return query;
}
//@Execute(validator = false)
public String search() {
return doSearch();
}
//@Execute(validator = false)
public String prev() {
return doMove(-1);
}
//@Execute(validator = false)
public String next() {
return doMove(1);
}
//@Execute(validator = false)
public String move() {
return doMove(0);
}
protected String doMove(final int move) {
int size = Constants.DEFAULT_PAGE_SIZE;
if (StringUtil.isBlank(searchListForm.num)) {
searchListForm.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
} else {
try {
size = Integer.parseInt(searchListForm.num);
} catch (final NumberFormatException e) {
searchListForm.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
}
}
if (StringUtil.isBlank(searchListForm.pn)) {
searchListForm.start = String.valueOf(Constants.DEFAULT_START_COUNT);
} else {
Integer pageNumber = Integer.parseInt(searchListForm.pn);
if (pageNumber != null && pageNumber > 0) {
pageNumber = pageNumber + move;
if (pageNumber < 1) {
pageNumber = 1;
}
searchListForm.start = String.valueOf((pageNumber - 1) * size);
} else {
searchListForm.start = String.valueOf(Constants.DEFAULT_START_COUNT);
}
}
return doSearch();
}
@Token(save = true, validate = false)
//@Execute(validator = true, input = "index")
public String confirmDelete() {
return "confirmDelete.jsp";
}
@Token(save = false, validate = true)
//@Execute(validator = true, input = "index")
public String delete() {
return deleteByQuery(searchListForm.docId);
}
private String deleteByQuery(final String docId) {
if (jobHelper.isCrawlProcessRunning()) {
throw new SSCActionMessagesException("errors.failed_to_start_solr_process_because_of_running");
}
final Thread thread = new Thread(() -> {
if (!jobHelper.isCrawlProcessRunning()) {
final long time = System.currentTimeMillis();
try {
final QueryBuilder query = QueryBuilders.termQuery(fieldHelper.docIdField, docId);
fessEsClient.deleteByQuery(fieldHelper.docIndex, fieldHelper.docType, query);
if (logger.isInfoEnabled()) {
logger.info("[EXEC TIME] index cleanup time: " + (System.currentTimeMillis() - time) + "ms");
}
} catch (final Exception e) {
logger.error("Failed to delete index (query=" + fieldHelper.docIdField + ":" + docId + ").", e);
}
} else {
if (logger.isInfoEnabled()) {
logger.info("could not start index cleanup process" + " because of running solr process.");
}
}
});
thread.start();
SAStrutsUtil.addSessionMessage("success.delete_solr_index");
return "search?query=" + LaFunctions.u(searchListForm.query) + "&redirect=true";
}
public boolean isSolrProcessRunning() {
return jobHelper.isCrawlProcessRunning();
}
}

View file

@ -0,0 +1,264 @@
/*
* 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.admin.searchlist;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
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.annotation.Token;
import org.codelibs.fess.app.web.base.FessAdminAction;
import org.codelibs.fess.client.FessEsClient;
import org.codelibs.fess.client.FessEsClient.SearchConditionBuilder;
import org.codelibs.fess.helper.FieldHelper;
import org.codelibs.fess.helper.JobHelper;
import org.codelibs.fess.helper.QueryHelper;
import org.codelibs.fess.helper.SystemHelper;
import org.codelibs.fess.util.QueryResponseList;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.lastaflute.taglib.function.LaFunctions;
import org.lastaflute.web.Execute;
import org.lastaflute.web.callback.ActionRuntime;
import org.lastaflute.web.response.HtmlResponse;
import org.lastaflute.web.response.render.RenderData;
import org.lastaflute.web.util.LaRequestUtil;
/**
* @author codelibs
* @author Keiichi Watanabe
*/
public class AdminSearchlistAction extends FessAdminAction {
// ===================================================================================
// Attribute
// =========
@Resource
private SystemHelper systemHelper;
@Resource
protected FessEsClient fessEsClient;
@Resource
protected FieldHelper fieldHelper;
@Resource
protected QueryHelper queryHelper;
@Resource
protected JobHelper jobHelper;
public List<Map<String, Object>> documentItems;
public String pageSize;
public String currentPageNumber;
public String allRecordCount;
public String allPageCount;
public boolean existNextPage;
public boolean existPrevPage;
public String currentStartRecordNumber;
public String currentEndRecordNumber;
public List<String> pageNumberList;
public String execTime;
// ===================================================================================
// Hook
// ======
@Override
protected void setupHtmlData(final ActionRuntime runtime) {
super.setupHtmlData(runtime);
runtime.registerData("helpLink", systemHelper.getHelpLink("searchList"));
}
// ===================================================================================
// Search Execute
// ==============
@Execute
public HtmlResponse index(final SearchListForm form) {
return asHtml(path_AdminSearchlist_IndexJsp);
}
protected HtmlResponse doSearch(final SearchListForm form) {
if (StringUtil.isBlank(form.query)) {
// redirect to index page
form.query = null;
return redirect(getClass());
}
return asHtml(path_AdminSearchlist_IndexJsp).renderWith(data -> {
doSearchInternal(data, form);
});
}
private void doSearchInternal(final RenderData data, final SearchListForm form) {
final String query = form.query;
// init pager
if (StringUtil.isBlank(form.start)) {
form.start = String.valueOf(Constants.DEFAULT_START_COUNT);
} else {
try {
Long.parseLong(form.start);
} catch (final NumberFormatException e) {
form.start = String.valueOf(Constants.DEFAULT_START_COUNT);
}
}
if (StringUtil.isBlank(form.num)) {
form.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
} else {
try {
final int num = Integer.parseInt(form.num);
if (num > 100) {
// max page size
form.num = "100";
}
} catch (final NumberFormatException e) {
form.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
}
}
final int offset = Integer.parseInt(form.start);
final int size = Integer.parseInt(form.num);
try {
documentItems =
fessEsClient.getDocumentList(fieldHelper.docIndex, fieldHelper.docType, searchRequestBuilder -> {
return SearchConditionBuilder.builder(searchRequestBuilder).administrativeAccess().offset(offset).size(size)
.responseFields(queryHelper.getResponseFields()).build();
});
} catch (final InvalidQueryException e) {
// TODO Log
} catch (final ResultOffsetExceededException e) {
// TODO Log
}
final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
final NumberFormat nf = NumberFormat.getInstance(LaRequestUtil.getRequest().getLocale());
nf.setMaximumIntegerDigits(2);
nf.setMaximumFractionDigits(2);
try {
String execTime = nf.format((double) queryResponseList.getExecTime() / 1000);
} catch (final Exception e) {}
copyBeanToBean(documentItems, this, option -> option.include("pageSize", "currentPageNumber", "allRecordCount", "allPageCount",
"existNextPage", "existPrevPage", "currentStartRecordNumber", "currentEndRecordNumber", "pageNumberList"));
}
//@Execute(validator = false)
public HtmlResponse search(final SearchListForm form) {
return doSearch(form);
}
//@Execute(validator = false)
public HtmlResponse prev(final SearchListForm form) {
return doMove(form, -1);
}
//@Execute(validator = false)
public HtmlResponse next(final SearchListForm form) {
return doMove(form, 1);
}
//@Execute(validator = false)
public HtmlResponse move(final SearchListForm form) {
return doMove(form, 0);
}
protected HtmlResponse doMove(final SearchListForm form, final int move) {
int size = Constants.DEFAULT_PAGE_SIZE;
if (StringUtil.isBlank(form.num)) {
form.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
} else {
try {
size = Integer.parseInt(form.num);
} catch (final NumberFormatException e) {
form.num = String.valueOf(Constants.DEFAULT_PAGE_SIZE);
}
}
if (StringUtil.isBlank(form.pn)) {
form.start = String.valueOf(Constants.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) * size);
} else {
form.start = String.valueOf(Constants.DEFAULT_START_COUNT);
}
}
return doSearch(form);
}
// -----------------------------------------------------
// Confirm
// -------
@Execute
public HtmlResponse confirmDelete(final SearchListForm form) {
return asHtml(path_AdminSearchlist_ConfirmDeleteJsp);
}
@Token(save = false, validate = true)
//@Execute(validator = true, input = "index")
public HtmlResponse delete(final SearchListForm form) {
return deleteByQuery(form);
}
private HtmlResponse deleteByQuery(final SearchListForm form) {
final String docId = form.docId;
if (jobHelper.isCrawlProcessRunning()) {
// TODO Error
}
final Thread thread = new Thread(() -> {
if (!jobHelper.isCrawlProcessRunning()) {
final long time = System.currentTimeMillis();
try {
final QueryBuilder query = QueryBuilders.termQuery(fieldHelper.docIdField, docId);
fessEsClient.deleteByQuery(fieldHelper.docIndex, fieldHelper.docType, query);
} catch (final Exception e) {
// TODO Log
}
}
} );
thread.start();
saveInfo(messages -> messages.addSuccessDeleteSolrIndex(GLOBAL));
final String contextPath = LaRequestUtil.getRequest().getContextPath();
return newHtmlResponseAsRediect(contextPath + "/search/?query=" + LaFunctions.u(form.query));
}
public boolean isSolrProcessRunning() {
return jobHelper.isCrawlProcessRunning();
}
}

View file

@ -14,10 +14,14 @@
* governing permissions and limitations under the License.
*/
package org.codelibs.fess.app.web.admin;
package org.codelibs.fess.app.web.admin.searchlist;
import java.io.Serializable;
/**
* @author codelibs
* @author Keiichi Watanabe
*/
public class SearchListForm implements Serializable {
private static final long serialVersionUID = 1L;
@ -39,5 +43,4 @@ public class SearchListForm implements Serializable {
//@Required(target = "confirmDelete")
public String url;
}

View file

@ -37,7 +37,7 @@
<h3 class="box-title">
<la:message key="labels.search_list_configuration" />
</h3>
<la:form action="search" method="get">
<la:form>
<div class="input">
<la:text styleClass="query" property="query" title="Search" size="50" maxlength="1000" />
<input class="btn" type="submit" value="<la:message key="labels.search"/>" name="search" />
@ -79,7 +79,7 @@
</c:if>
</p>
</div>
<div id="result">
<div>
<ol>
@ -107,7 +107,7 @@
</ol>
</div>
</div>
<div class="row center">
<div class="pagination">
<ul>
@ -166,7 +166,7 @@
</div>
</div>
</div>
</div>
</section>
</div>
@ -175,4 +175,3 @@
<jsp:include page="/WEB-INF/view/common/admin2/foot.jsp"></jsp:include>
</body>
</html>

View file

@ -221,10 +221,10 @@
<span><la:message key="labels.menu.failure_url" /></span>
</la:link></li>
<li <c:if test="${param.menuType=='searchList'}">class="active"</c:if>><todo:link href="/admin/searchList/index">
<li <c:if test="${param.menuType=='searchList'}">class="active"</c:if>><la:link href="/admin/searchlist/index">
<i class='fa fa-angle-right'></i>
<span><la:message key="labels.menu.search_list" /></span>
</todo:link></li>
</la:link></li>
</ul>
</li>