浏览代码

#592 edit indexed docs

Shinsuke Sugaya 9 年之前
父节点
当前提交
d6f8f3f772

+ 47 - 47
src/main/java/org/codelibs/fess/app/web/admin/searchlist/AdminSearchlistAction.java

@@ -22,6 +22,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 
 import org.codelibs.core.lang.StringUtil;
+import org.codelibs.core.misc.Pair;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.app.service.SearchService;
 import org.codelibs.fess.app.web.CrudMode;
@@ -30,8 +31,8 @@ import org.codelibs.fess.entity.SearchRenderData;
 import org.codelibs.fess.es.client.FessEsClient;
 import org.codelibs.fess.exception.InvalidQueryException;
 import org.codelibs.fess.exception.ResultOffsetExceededException;
-import org.codelibs.fess.helper.ProcessHelper;
 import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.RenderDataUtil;
 import org.dbflute.optional.OptionalEntity;
 import org.elasticsearch.index.query.QueryBuilder;
@@ -64,9 +65,6 @@ public class AdminSearchlistAction extends FessAdminAction {
     @Resource
     protected QueryHelper queryHelper;
 
-    @Resource
-    protected ProcessHelper processHelper;
-
     @Resource
     protected SearchService searchService;
 
@@ -103,7 +101,6 @@ public class AdminSearchlistAction extends FessAdminAction {
         super.setupHtmlData(runtime);
 
         runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameSearchlist()));
-        runtime.registerData("isProcessRunning", processHelper.isProcessRunning());
     }
 
     // ===================================================================================
@@ -192,9 +189,6 @@ public class AdminSearchlistAction extends FessAdminAction {
         verifyToken(() -> asListHtml());
         validate(form, messages -> {}, () -> asListHtml());
         final String docId = form.docId;
-        if (processHelper.isProcessRunning()) {
-            throwValidationError(messages -> messages.addErrorsCannotDeleteDocBecauseOfRunning(GLOBAL), () -> asListHtml());
-        }
         try {
             final QueryBuilder query = QueryBuilders.termQuery(fessConfig.getIndexFieldDocId(), docId);
             fessEsClient.deleteByQuery(fessConfig.getIndexDocumentUpdateIndex(), fessConfig.getIndexDocumentType(), query);
@@ -209,9 +203,6 @@ public class AdminSearchlistAction extends FessAdminAction {
     public HtmlResponse deleteall(final ListForm form) {
         verifyToken(() -> asListHtml());
         validate(form, messages -> {}, () -> asListHtml());
-        if (processHelper.isProcessRunning()) {
-            throwValidationError(messages -> messages.addErrorsCannotDeleteDocBecauseOfRunning(GLOBAL), () -> asListHtml());
-        }
         try {
             searchService.deleteByQuery(request, form);
             saveInfo(messages -> messages.addSuccessDeleteDocFromIndex(GLOBAL));
@@ -238,16 +229,16 @@ public class AdminSearchlistAction extends FessAdminAction {
     @Execute
     public HtmlResponse edit(final EditForm form) {
         validate(form, messages -> {}, () -> asListHtml());
-        // TODO load
+        final String docId = form.docId;
+        getDoc(form).ifPresent(entity -> {
+            form.doc = entity;
+            form.id = (String) entity.remove(fessConfig.getIndexFieldId());
+            form.version = (Long) entity.remove(fessConfig.getIndexFieldVersion());
+        }).orElse(() -> {
+            throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, docId), () -> asListHtml());
+        });
         saveToken();
-        if (form.crudMode.intValue() == CrudMode.EDIT) {
-            // back
-            form.crudMode = CrudMode.DETAILS;
-            return asListHtml();
-        } else {
-            form.crudMode = CrudMode.EDIT;
-            return asEditHtml();
-        }
+        return asEditHtml();
     }
 
     @Execute
@@ -277,23 +268,40 @@ public class AdminSearchlistAction extends FessAdminAction {
         validate(form, messages -> {}, () -> asEditHtml());
         // TODO verify
         verifyToken(() -> asEditHtml());
-        getDoc(form).ifPresent(entity -> {
-            try {
-                for (Map.Entry<String, Object> entry : form.doc.entrySet()) {
-                    entity.put(entry.getKey(), entry.getValue());
-                }
-                // TODO store does not work
-                fessEsClient.store(fessConfig.getIndexDocumentUpdateIndex(), fessConfig.getIndexDocumentType(), entity);
-                saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
-            } catch (final Exception e) {
-                logger.error("Failed to update " + entity, e);
-                throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
-                        () -> asEditHtml());
-            }
-        }).orElse(() -> {
-            throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asEditHtml());
+        getDoc(form).ifPresent(
+                entity -> {
+                    try {
+                        form.doc.entrySet().stream().map(e -> {
+                            // TODO converter
+                                return new Pair<>(e.getKey(), e.getValue());
+                            }).forEach(p -> entity.put(p.getFirst(), p.getSecond()));
+
+                        final String newId = ComponentUtil.getCrawlingInfoHelper().generateId(entity);
+                        String oldId = null;
+                        if (newId.equals(form.id)) {
+                            entity.put(fessConfig.getIndexFieldId(), form.id);
+                        } else {
+                            oldId = form.id;
+                            entity.put(fessConfig.getIndexFieldId(), newId);
+                        }
+                        entity.put(fessConfig.getIndexFieldVersion(), form.version);
+
+                        final String index = fessConfig.getIndexDocumentUpdateIndex();
+                        final String type = fessConfig.getIndexDocumentType();
+                        fessEsClient.store(index, type, entity);
+                        if (oldId != null) {
+                            fessEsClient.delete(index, type, oldId, form.version);
+                        }
+                        saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
+                    } catch (final Exception e) {
+                        logger.error("Failed to update " + entity, e);
+                        throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
+                                () -> asEditHtml());
+                    }
+                }).orElse(() -> {
+            throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.docId), () -> asEditHtml());
         });
-        return redirect(getClass());
+        return redirectWith(getClass(), moreUrl("search").params("q", form.q));
     }
 
     // ===================================================================================
@@ -314,17 +322,9 @@ public class AdminSearchlistAction extends FessAdminAction {
             return OptionalEntity.empty();
         case CrudMode.EDIT:
             if (form instanceof EditForm) {
-                final String docId = ((EditForm) form).id;
-                if (processHelper.isProcessRunning()) {
-                    break;
-                }
-                try {
-                    final QueryBuilder query = QueryBuilders.termQuery(fessConfig.getIndexFieldDocId(), docId);
-                    return fessEsClient.getDocumentByQuery(fessConfig.getIndexDocumentUpdateIndex(), fessConfig.getIndexDocumentType(),
-                            query);
-                } catch (final Exception e) {
-                    break;
-                }
+                final String docId = ((EditForm) form).docId;
+                final QueryBuilder query = QueryBuilders.termQuery(fessConfig.getIndexFieldDocId(), docId);
+                return fessEsClient.getDocumentByQuery(fessConfig.getIndexDocumentUpdateIndex(), fessConfig.getIndexDocumentType(), query);
             }
             break;
         default:

+ 2 - 0
src/main/java/org/codelibs/fess/app/web/admin/searchlist/CreateForm.java

@@ -29,6 +29,8 @@ public class CreateForm {
 
     public Map<String, Object> doc;
 
+    public String q;
+
     public void initialize() {
     }
 }

+ 3 - 2
src/main/java/org/codelibs/fess/app/web/admin/searchlist/EditForm.java

@@ -23,11 +23,12 @@ import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
  */
 public class EditForm extends CreateForm {
 
-    @Required
     public String id;
 
     @Required
+    public String docId;
+
     @ValidateTypeFailure
-    public Integer versionNo;
+    public Long version;
 
 }

+ 17 - 7
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -678,11 +678,21 @@ public class FessEsClient implements Client {
 
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
         SearchResponse response =
-                client.prepareSearch(index).setTypes(type).setSize(sizeForDelete).setQuery(queryBuilder)
-                        .setPreference(Constants.SEARCH_PREFERENCE_PRIMARY).execute()
-                        .actionGet(fessConfig.getIndexScrollSearchTimeoutTimeout());
-        return OptionalEntity.of(response.getHits().getAt(0).getSource());
-
+                client.prepareSearch(index).setTypes(type).setSize(1).setQuery(queryBuilder).addField(fessConfig.getIndexFieldId())
+                        .setPreference(Constants.SEARCH_PREFERENCE_PRIMARY).execute().actionGet(fessConfig.getIndexSearchTimeout());
+        SearchHits hits = response.getHits();
+        if (hits.getTotalHits() != 0) {
+            SearchHit hit = hits.getAt(0);
+            String id = hit.getId();
+            GetResponse getResponse =
+                    client.prepareGet(index, type, id).setPreference(Constants.SEARCH_PREFERENCE_PRIMARY).execute()
+                            .actionGet(fessConfig.getIndexSearchTimeout());
+            Map<String, Object> source = BeanUtil.copyMapToNewMap(getResponse.getSource());
+            source.put(fessConfig.getIndexFieldId(), id);
+            source.put(fessConfig.getIndexFieldVersion(), getResponse.getVersion());
+            return OptionalEntity.of(source);
+        }
+        return OptionalEntity.empty();
     }
 
     public List<Map<String, Object>> getDocumentList(final String index, final String type,
@@ -944,9 +954,9 @@ public class FessEsClient implements Client {
 
     public boolean store(final String index, final String type, final Object obj) {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
-        final Map<String, Object> source = BeanUtil.copyBeanToNewMap(obj);
+        final Map<String, Object> source = obj instanceof Map ? (Map<String, Object>) obj : BeanUtil.copyBeanToNewMap(obj);
         final String id = (String) source.remove(fessConfig.getIndexFieldId());
-        final Long version = (Long) source.remove("version");
+        final Long version = (Long) source.remove(fessConfig.getIndexFieldVersion());
         IndexResponse response;
         try {
             if (id == null) {

+ 3 - 0
src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java

@@ -563,6 +563,9 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Search... */
     public static final String LABELS_SIDEBAR_placeholder_search = "{labels.sidebar.placeholder_search}";
 
+    /** The key of the message: MENU */
+    public static final String LABELS_SIDEBAR_MENU = "{labels.sidebar.menu}";
+
     /** The key of the message: Copyright(C) 2009-2016 &lt;a href="https://github.com/codelibs"&gt;CodeLibs Project&lt;/a&gt;. &lt;span class="br-phone"&gt;&lt;/span&gt;All Rights Reserved. */
     public static final String LABELS_FOOTER_COPYRIGHT = "{labels.footer.copyright}";
 

+ 14 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -268,6 +268,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. _id */
     String INDEX_FIELD_ID = "index.field.id";
 
+    /** The key of the configuration. e.g. _version */
+    String INDEX_FIELD_VERSION = "index.field.version";
+
     /** The key of the configuration. e.g. lang */
     String INDEX_FIELD_LANG = "index.field.lang";
 
@@ -1788,6 +1791,13 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
     String getIndexFieldId();
 
+    /**
+     * Get the value for the key 'index.field.version'. <br>
+     * The value is, e.g. _version <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexFieldVersion();
+
     /**
      * Get the value for the key 'index.field.lang'. <br>
      * The value is, e.g. lang <br>
@@ -4418,6 +4428,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return get(FessConfig.INDEX_FIELD_ID);
         }
 
+        public String getIndexFieldVersion() {
+            return get(FessConfig.INDEX_FIELD_VERSION);
+        }
+
         public String getIndexFieldLang() {
             return get(FessConfig.INDEX_FIELD_LANG);
         }

+ 1 - 0
src/main/resources/fess_config.properties

@@ -140,6 +140,7 @@ index.field.expires=expires
 index.field.url=url
 index.field.doc_id=doc_id
 index.field.id=_id
+index.field.version=_version
 index.field.lang=lang
 index.field.has_cache=has_cache
 index.field.last_modified=last_modified

+ 1 - 0
src/main/resources/fess_label.properties

@@ -178,6 +178,7 @@ labels.menu_failure_url=Failure URL
 labels.menu_search_list=Search
 labels.menu_backup=Back Up
 labels.sidebar.placeholder_search=Search...
+labels.sidebar.menu=MENU
 labels.footer.copyright=Copyright(C) 2009-2016 <a href="https://github.com/codelibs">CodeLibs Project</a>. <span class="br-phone"></span>All Rights Reserved.
 labels.search=Search
 labels.search_result_status=Results <b>{2}</b><span class="hidden-phone"> -</span> <b>{3}</b> of <b>{1}</b> for <b>{0}</b>

+ 1 - 0
src/main/resources/fess_label_en.properties

@@ -178,6 +178,7 @@ labels.menu_failure_url=Failure URL
 labels.menu_search_list=Search
 labels.menu_backup=Back Up
 labels.sidebar.placeholder_search=Search...
+labels.sidebar.menu=MENU
 labels.footer.copyright=Copyright(C) 2009-2016 <a href="https://github.com/codelibs">CodeLibs Project</a>. <span class="br-phone"></span>All Rights Reserved.
 labels.search=Search
 labels.search_result_status=Results <b>{2}</b><span class="hidden-phone"> -</span> <b>{3}</b> of <b>{1}</b> for <b>{0}</b>

+ 1 - 0
src/main/resources/fess_label_ja.properties

@@ -174,6 +174,7 @@ labels.menu_failure_url=\u969c\u5bb3URL
 labels.menu_search_list=\u691c\u7d22
 labels.menu_backup=\u30d0\u30c3\u30af\u30a2\u30c3\u30d7
 labels.sidebar.placeholder_search=\u691c\u7d22...
+labels.sidebar.menu=\u30e1\u30cb\u30e5\u30fc
 labels.footer.copyright=Copyright(C) 2009-2016 <a href="https://github.com/codelibs">CodeLibs Project</a>. <span class="br-phone"></span>All Rights Reserved.
 labels.search=\u691c\u7d22
 labels.search_result_status=<b>{0}</b> \u306e\u691c\u7d22\u7d50\u679c<span class="br-phone"></span> <b>{1}</b> \u4ef6\u4e2d <b>{2}</b> - <b>{3}</b> \u4ef6\u76ee

+ 18 - 22
src/main/webapp/WEB-INF/view/admin/searchlist/admin_searchlist.jsp

@@ -43,7 +43,7 @@
 									</la:info>
 									<la:errors />
 								</div>
-								<la:form action="/admin/searchlist" styleClass="form-inline">
+								<la:form action="/admin/searchlist" styleClass="form-inline" method="GET">
 									<div class="form-group">
 										<label class="sr-only" for="sessionIdSearchBtn"></label>
 										<la:text styleClass="query form-control" property="q"
@@ -82,28 +82,24 @@
 														<h3 class="title">
 															<a href="${doc.url_link}">${f:h(doc.content_title)}</a>
 														</h3>
-														<div class="body col-sm-11">
+														<div class="body col-sm-10">
 															${doc.content_description}</div>
-														<button type="button"
-															class="btn btn-xs btn-danger col-sm-1"
-															data-toggle="modal" data-target="#confirmToDelete"
-															data-docid="${f:u(doc.doc_id)}"
-															data-title="${f:h(doc.content_title)}"
-															data-url="${f:h(doc.url_link)}"
-															<c:if test="${crawlerProcessRunning}">disable</c:if>>
-															<i class="fa fa-trash"></i>
-															<la:message key="labels.search_list_button_delete" />
-														</button>
-														<la:form action="/admin/searchlist/edit" styleClass="form-inline">
-																<input type="hidden" name="id" value="${doc.doc_id}" />
-																<input type="hidden" name="crudMode" value="4" />  <!-- FIXME -->
-																<input type="hidden" name="versionNo" value="1" /> <!-- FIXME -->
-																<button type="submit" class="btn btn-warning" name="update"
-																				value="<la:message key="labels.crud_button_update" />">
-																		<i class="fa fa-pencil"></i>
-																		<la:message key="labels.crud_button_update" />
-																</button>
-														</la:form>
+														<div class="body col-sm-2 text-right">
+															<la:link href="/admin/searchlist/edit?crudMode=2&amp;docId=${f:u(doc.doc_id)}&amp;q=${f:u(q)}"
+																styleClass="btn btn-xs btn-warning">
+																<i class="fa fa-pencil"></i>
+																<la:message key="labels.crud_button_update" />
+															</la:link>
+															<button type="button"
+																class="btn btn-xs btn-danger"
+																data-toggle="modal" data-target="#confirmToDelete"
+																data-docid="${f:u(doc.doc_id)}"
+																data-title="${f:h(doc.content_title)}"
+																data-url="${f:h(doc.url_link)}">
+																<i class="fa fa-trash"></i>
+																<la:message key="labels.search_list_button_delete" />
+															</button>
+														</div>
 													</li>
 												</c:forEach>
 											</ol>

+ 64 - 10
src/main/webapp/WEB-INF/view/admin/searchlist/admin_searchlist_edit.jsp

@@ -2,8 +2,7 @@
 <html>
 <head>
 <meta charset="UTF-8">
-<title><la:message key="labels.admin_brand_title" /> | <la:message
-		key="labels.search_list_configuration" /></title>
+<title><la:message key="labels.admin_brand_title" /> | <la:message key="labels.search_list_configuration" /></title>
 <jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
 </head>
 <body class="hold-transition skin-blue sidebar-mini">
@@ -19,7 +18,7 @@
 					<la:message key="labels.search_list_configuration" />
 				</h1>
 				<ol class="breadcrumb">
-					<li class="active"><la:link href="/admin/searchlist">
+					<li class="active"><la:link href="/admin/searchlist/search?q=${f:u(q)}">
 							<la:message key="labels.search_list_configuration" />
 						</la:link></li>
 				</ol>
@@ -27,15 +26,49 @@
 			<section class="content">
 				<la:form action="/admin/searchlist/" styleClass="form-horizontal">
 					<la:hidden property="crudMode" />
+					<la:hidden property="q" />
 					<c:if test="${crudMode==2}">
+						<la:hidden property="docId" />
 						<la:hidden property="id" />
+						<la:hidden property="version" />
 					</c:if>
 					<div class="row">
 						<div class="col-md-12">
-							<div
-								class="box <c:if test="${crudMode == 1}">box-success</c:if><c:if test="${crudMode == 2}">box-warning</c:if>">
+							<div class="box <c:if test="${crudMode == 1}">box-success</c:if><c:if test="${crudMode == 2}">box-warning</c:if>">
 								<div class="box-header with-border">
-									<jsp:include page="/WEB-INF/view/common/admin/crud/header.jsp"></jsp:include>
+									<h3 class="box-title">
+										<c:if test="${crudMode == null}">
+											<la:message key="labels.crud_title_list" />
+										</c:if>
+										<c:if test="${crudMode == 1}">
+											<la:message key="labels.crud_title_create" />
+										</c:if>
+										<c:if test="${crudMode == 2}">
+											<la:message key="labels.crud_title_edit" />
+										</c:if>
+										<c:if test="${crudMode == 3}">
+											<la:message key="labels.crud_title_delete" />
+										</c:if>
+										<c:if test="${crudMode == 4}">
+											<la:message key="labels.crud_title_details" />
+										</c:if>
+									</h3>
+									<div class="btn-group pull-right">
+										<c:choose>
+											<c:when test="${crudMode == null}">
+												<la:link href="createnew" styleClass="btn btn-success btn-xs">
+													<i class="fa fa-plus"></i>
+													<la:message key="labels.crud_link_create" />
+												</la:link>
+											</c:when>
+											<c:otherwise>
+												<la:link href="/admin/searchlist/search?q=${f:u(q)}" styleClass="btn btn-primary btn-xs">
+													<i class="fa fa-th-list"></i>
+													<la:message key="labels.crud_link_list" />
+												</la:link>
+											</c:otherwise>
+										</c:choose>
+									</div>
 								</div>
 								<!-- /.box-header -->
 								<div class="box-body">
@@ -46,8 +79,7 @@
 										<la:errors property="_global" />
 									</div>
 									<div class="form-group">
-										<label for="title" class="col-sm-3 control-label"><la:message
-												key="labels.user_surname" /></label>
+										<label for="title" class="col-sm-3 control-label">title</label>
 										<div class="col-sm-9">
 											<la:errors property="doc.title" />
 											<la:text property="doc.title" styleClass="form-control" />
@@ -56,8 +88,30 @@
 								</div>
 								<!-- /.box-body -->
 								<div class="box-footer">
-								    <input type="hidden" name="versionNo" value="1" /> <!-- FIXME -->
-									<jsp:include page="/WEB-INF/view/common/admin/crud/buttons.jsp"></jsp:include>
+									<c:if test="${crudMode == 1}">
+										<button type="submit" class="btn btn-default" name="search" value="<la:message key="labels.crud_button_back" />">
+											<i class="fa fa-arrow-circle-left"></i>
+											<la:message key="labels.crud_button_back" />
+										</button>
+										<button type="submit" class="btn btn-success" name="create"
+											value="<la:message key="labels.crud_button_create" />"
+										>
+											<i class="fa fa-plus"></i>
+											<la:message key="labels.crud_button_create" />
+										</button>
+									</c:if>
+									<c:if test="${crudMode == 2}">
+										<button type="submit" class="btn btn-default" name="search" value="back">
+											<i class="fa fa-arrow-circle-left"></i>
+											<la:message key="labels.crud_button_back" />
+										</button>
+										<button type="submit" class="btn btn-warning" name="update"
+											value="<la:message key="labels.crud_button_update" />"
+										>
+											<i class="fa fa-pencil"></i>
+											<la:message key="labels.crud_button_update" />
+										</button>
+									</c:if>
 								</div>
 								<!-- /.box-footer -->
 							</div>

+ 2 - 2
src/main/webapp/WEB-INF/view/common/admin/sidebar.jsp

@@ -6,7 +6,7 @@
 	<section class="sidebar">
 
 		<!-- search form -->
-		<form action="<%=request.getContextPath()%>/admin/searchlist/search" method="post"
+		<form action="<%=request.getContextPath()%>/admin/searchlist/search" method="GET"
 			class="sidebar-form">
 			<div class="input-group">
 				<input type="text" name="q" id="query" class="form-control"
@@ -23,7 +23,7 @@
 
 		<!-- Sidebar Menu -->
 		<ul class="sidebar-menu">
-			<li class="header">MENU</li>
+			<li class="header"><la:message key="labels.sidebar.menu" /></li>
 
 			<li
 				class="treeview <c:if test="${param.menuCategoryType=='dashboard'}">active</c:if>"><la:link