Преглед на файлове

replace /crawl/ with /general/

Shinsuke Sugaya преди 9 години
родител
ревизия
38f7262b2e

+ 4 - 0
pom.xml

@@ -282,6 +282,8 @@
 								url="${maven.snapshot.repo.url}/org/codelibs/elasticsearch-configsync/1.7.1-SNAPSHOT/elasticsearch-configsync-1.7.1-20151008.061136-2.zip" />
 							<url
 								url="${maven.release.repo.url}/org/codelibs/elasticsearch-langfield/1.7.0/elasticsearch-langfield-1.7.0.zip" />
+							<url
+								url="http://maven.codelibs.org/archive/elasticsearch/plugin/kopf/elasticsearch-kopf-1.5.7.zip" />
 						</get>
 						<delete dir="${basedir}/plugins" />
 						<mkdir dir="${basedir}/plugins" />
@@ -293,6 +295,8 @@
 							src="${basedir}/target/plugins/elasticsearch-configsync-1.7.1-20151008.061136-2.zip" />
 						<unzip dest="${basedir}/plugins/langfield"
 							src="${basedir}/target/plugins/elasticsearch-langfield-1.7.0.zip" />
+						<unzip dest="${basedir}/plugins/kopf"
+							src="${basedir}/target/plugins/elasticsearch-kopf-1.5.7.zip" />
 					</tasks>
 				</configuration>
 				<goals>

+ 5 - 1
src/main/java/org/codelibs/fess/Constants.java

@@ -168,7 +168,7 @@ public class Constants extends CoreLibConstants {
 
     public static final String DEFAULT_IGNORE_FAILURE_TYPE = StringUtil.EMPTY;
 
-    public static final String DEFAULT_FAILURE_COUNT = "-1";
+    public static final Integer DEFAULT_FAILURE_COUNT = -1;
 
     public static final String DEFAULT_PURGE_DAY = "30";
 
@@ -327,4 +327,8 @@ public class Constants extends CoreLibConstants {
             "updatedBy", "updatedTime" };
 
     public static final String USER_INFO = "LoginInfo";
+
+    public static final String ELASTICSEARCH_WEB_URL_PROPERTY = "es.http.url";
+
+    public static final String ELASTICSEARCH_WEB_URL = "http://localhost:9201";
 }

+ 8 - 7
src/main/java/org/codelibs/fess/app/service/FailureUrlService.java

@@ -159,15 +159,16 @@ public class FailureUrlService implements Serializable {
     }
 
     public List<String> getExcludedUrlList(final String configId) {
-        final String failureCountStr =
-                crawlerProperties.getProperty(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY, Constants.DEFAULT_FAILURE_COUNT);
+        final String failureCountStr = crawlerProperties.getProperty(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY);
         final String ignoreFailureType =
                 crawlerProperties.getProperty(Constants.IGNORE_FAILURE_TYPE_PROPERTY, Constants.DEFAULT_IGNORE_FAILURE_TYPE);
-        int failureCount;
-        try {
-            failureCount = Integer.parseInt(failureCountStr);
-        } catch (final NumberFormatException ignore) {
-            failureCount = 10;
+        int failureCount = Constants.DEFAULT_FAILURE_COUNT;
+        if (failureCountStr != null) {
+            try {
+                failureCount = Integer.parseInt(failureCountStr);
+            } catch (final NumberFormatException ignore) {
+                // ignore
+            }
         }
 
         if (failureCount < 0) {

+ 0 - 32
src/main/java/org/codelibs/fess/app/web/admin/crawl/CrawlSearchForm.java

@@ -1,32 +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.crawl;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author codelibs
- * @author Shunji Makino
- */
-public class CrawlSearchForm implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    public Map<String, String> searchParams = new HashMap<String, String>();
-}

+ 58 - 47
src/main/java/org/codelibs/fess/app/web/admin/crawl/AdminCrawlAction.java → src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java

@@ -14,7 +14,7 @@
  * governing permissions and limitations under the License.
  */
 
-package org.codelibs.fess.app.web.admin.crawl;
+package org.codelibs.fess.app.web.admin.general;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -27,7 +27,6 @@ import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.misc.DynamicProperties;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.annotation.Token;
-import org.codelibs.fess.app.web.admin.keymatch.AdminKeymatchAction;
 import org.codelibs.fess.app.web.base.FessAdminAction;
 import org.codelibs.fess.helper.SystemHelper;
 import org.codelibs.fess.util.ComponentUtil;
@@ -35,16 +34,13 @@ import org.lastaflute.web.Execute;
 import org.lastaflute.web.callback.ActionRuntime;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.util.LaRequestUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * @author shinsuke
  * @author Shunji Makino
  */
-public class AdminCrawlAction extends FessAdminAction {
+public class AdminGeneralAction extends FessAdminAction {
 
-    private static final Logger logger = LoggerFactory.getLogger(AdminKeymatchAction.class);
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           =========
@@ -53,67 +49,41 @@ public class AdminCrawlAction extends FessAdminAction {
     @Resource
     protected SystemHelper systemHelper;
 
-    public String getHelpLink() {
-        return systemHelper.getHelpLink("crawl");
-    }
-
     // ===================================================================================
     //                                                                               Hook
     //                                                                              ======
     @Override
     protected void setupHtmlData(final ActionRuntime runtime) {
         super.setupHtmlData(runtime);
-        runtime.registerData("helpLink", systemHelper.getHelpLink("crawl"));
+        runtime.registerData("helpLink", systemHelper.getHelpLink("general"));
         runtime.registerData("supportedSearchItems", getSupportedSearchItems());
+        runtime.registerData("dayItems", getDayItems());
     }
 
     // ===================================================================================
-
-    protected void updateForm(final CrawlEditForm form) {
-        form.diffCrawling = crawlerProperties.getProperty(Constants.DIFF_CRAWLING_PROPERTY, Constants.TRUE);
-        form.useAclAsRole = crawlerProperties.getProperty(Constants.USE_ACL_AS_ROLE, Constants.FALSE);
-        form.dayForCleanup = crawlerProperties.getProperty(Constants.DAY_FOR_CLEANUP_PROPERTY, "1");
-        form.crawlingThreadCount = crawlerProperties.getProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY, "5");
-        form.searchLog = crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE);
-        form.userInfo = crawlerProperties.getProperty(Constants.USER_INFO_PROPERTY, Constants.TRUE);
-        form.userFavorite = crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE);
-        form.webApiXml = crawlerProperties.getProperty(Constants.WEB_API_XML_PROPERTY, Constants.TRUE);
-        form.webApiJson = crawlerProperties.getProperty(Constants.WEB_API_JSON_PROPERTY, Constants.TRUE);
-        form.defaultLabelValue = crawlerProperties.getProperty(Constants.DEFAULT_LABEL_VALUE_PROPERTY, StringUtil.EMPTY);
-        form.appendQueryParameter = crawlerProperties.getProperty(Constants.APPEND_QUERY_PARAMETER_PROPERTY, Constants.FALSE);
-        form.supportedSearch = crawlerProperties.getProperty(Constants.SUPPORTED_SEARCH_FEATURE_PROPERTY, Constants.SUPPORTED_SEARCH_WEB);
-        form.ignoreFailureType =
-                crawlerProperties.getProperty(Constants.IGNORE_FAILURE_TYPE_PROPERTY, Constants.DEFAULT_IGNORE_FAILURE_TYPE);
-        form.failureCountThreshold =
-                crawlerProperties.getProperty(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY, Constants.DEFAULT_FAILURE_COUNT);
-        form.hotSearchWord = crawlerProperties.getProperty(Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY, Constants.TRUE);
-        form.csvFileEncoding = crawlerProperties.getProperty(Constants.CSV_FILE_ENCODING_PROPERTY, Constants.UTF_8);
-        form.purgeSearchLogDay = crawlerProperties.getProperty(Constants.PURGE_SEARCH_LOG_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
-        form.purgeJobLogDay = crawlerProperties.getProperty(Constants.PURGE_JOB_LOG_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
-        form.purgeUserInfoDay = crawlerProperties.getProperty(Constants.PURGE_USER_INFO_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
-        form.purgeByBots = crawlerProperties.getProperty(Constants.PURGE_BY_BOTS_PROPERTY, Constants.DEFAULT_PURGE_BY_BOTS);
-        form.notificationTo = crawlerProperties.getProperty(Constants.NOTIFICATION_TO_PROPERTY, StringUtil.EMPTY);
-        form.suggestSearchLog = crawlerProperties.getProperty(Constants.SUGGEST_SEARCH_LOG_PROPERTY, Constants.TRUE);
-        form.purgeSuggestSearchLogDay = crawlerProperties.getProperty(Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY, "30");
-    }
-
     //
     @Token(save = true, validate = false)
     @Execute
-    public HtmlResponse index(final CrawlEditForm form) {
-        return asHtml(path_AdminCrawl_IndexJsp).renderWith(data -> {
-            updateForm(form);
+    public HtmlResponse index() {
+        return asHtml(path_AdminGeneral_IndexJsp).useForm(EditForm.class, setup -> {
+            setup.setup(form -> {
+                updateForm(form);
+            });
         });
     }
 
     @Token(save = false, validate = true)
     @Execute
-    public HtmlResponse update(final CrawlEditForm form) {
+    public HtmlResponse update(final EditForm form) {
+        validate(form, messages -> {}, () -> {
+            return asHtml(path_AdminGeneral_IndexJsp);
+        });
+
         crawlerProperties.setProperty(Constants.DIFF_CRAWLING_PROPERTY,
                 form.diffCrawling != null && Constants.ON.equalsIgnoreCase(form.diffCrawling) ? Constants.TRUE : Constants.FALSE);
         crawlerProperties.setProperty(Constants.USE_ACL_AS_ROLE,
                 form.useAclAsRole != null && Constants.ON.equalsIgnoreCase(form.useAclAsRole) ? Constants.TRUE : Constants.FALSE);
-        crawlerProperties.setProperty(Constants.DAY_FOR_CLEANUP_PROPERTY, form.dayForCleanup);
+        crawlerProperties.setProperty(Constants.DAY_FOR_CLEANUP_PROPERTY, form.dayForCleanup.toString());
         crawlerProperties.setProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY, form.crawlingThreadCount);
         crawlerProperties.setProperty(Constants.SEARCH_LOG_PROPERTY,
                 form.searchLog != null && Constants.ON.equalsIgnoreCase(form.searchLog) ? Constants.TRUE : Constants.FALSE);
@@ -131,7 +101,7 @@ public class AdminCrawlAction extends FessAdminAction {
                         : Constants.FALSE);
         crawlerProperties.setProperty(Constants.SUPPORTED_SEARCH_FEATURE_PROPERTY, form.supportedSearch);
         crawlerProperties.setProperty(Constants.IGNORE_FAILURE_TYPE_PROPERTY, form.ignoreFailureType);
-        crawlerProperties.setProperty(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY, form.failureCountThreshold);
+        crawlerProperties.setProperty(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY, form.failureCountThreshold.toString());
         crawlerProperties.setProperty(Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY,
                 form.hotSearchWord != null && Constants.ON.equalsIgnoreCase(form.hotSearchWord) ? Constants.TRUE : Constants.FALSE);
         crawlerProperties.setProperty(Constants.CSV_FILE_ENCODING_PROPERTY, form.csvFileEncoding);
@@ -143,13 +113,54 @@ public class AdminCrawlAction extends FessAdminAction {
         crawlerProperties.setProperty(Constants.SUGGEST_SEARCH_LOG_PROPERTY,
                 form.suggestSearchLog != null && Constants.ON.equalsIgnoreCase(form.suggestSearchLog) ? Constants.TRUE : Constants.FALSE);
         crawlerProperties.setProperty(Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY, form.purgeSuggestSearchLogDay);
+        crawlerProperties.setProperty(Constants.ELASTICSEARCH_WEB_URL_PROPERTY, form.esHttpUrl);
 
         crawlerProperties.store();
         saveInfo(messages -> messages.addSuccessUpdateCrawlerParams(GLOBAL));
         return redirect(getClass());
     }
 
-    public List<String> getDayItems() {
+    protected void updateForm(final EditForm form) {
+        form.diffCrawling = crawlerProperties.getProperty(Constants.DIFF_CRAWLING_PROPERTY, Constants.TRUE);
+        form.useAclAsRole = crawlerProperties.getProperty(Constants.USE_ACL_AS_ROLE, Constants.FALSE);
+        form.dayForCleanup = getPropertyAsInteger(Constants.DAY_FOR_CLEANUP_PROPERTY, 1);
+        form.crawlingThreadCount = crawlerProperties.getProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY, "5");
+        form.searchLog = crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE);
+        form.userInfo = crawlerProperties.getProperty(Constants.USER_INFO_PROPERTY, Constants.TRUE);
+        form.userFavorite = crawlerProperties.getProperty(Constants.USER_FAVORITE_PROPERTY, Constants.FALSE);
+        form.webApiXml = crawlerProperties.getProperty(Constants.WEB_API_XML_PROPERTY, Constants.TRUE);
+        form.webApiJson = crawlerProperties.getProperty(Constants.WEB_API_JSON_PROPERTY, Constants.TRUE);
+        form.defaultLabelValue = crawlerProperties.getProperty(Constants.DEFAULT_LABEL_VALUE_PROPERTY, StringUtil.EMPTY);
+        form.appendQueryParameter = crawlerProperties.getProperty(Constants.APPEND_QUERY_PARAMETER_PROPERTY, Constants.FALSE);
+        form.supportedSearch = crawlerProperties.getProperty(Constants.SUPPORTED_SEARCH_FEATURE_PROPERTY, Constants.SUPPORTED_SEARCH_WEB);
+        form.ignoreFailureType =
+                crawlerProperties.getProperty(Constants.IGNORE_FAILURE_TYPE_PROPERTY, Constants.DEFAULT_IGNORE_FAILURE_TYPE);
+        form.failureCountThreshold = getPropertyAsInteger(Constants.FAILURE_COUNT_THRESHOLD_PROPERTY, Constants.DEFAULT_FAILURE_COUNT);
+        form.hotSearchWord = crawlerProperties.getProperty(Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY, Constants.TRUE);
+        form.csvFileEncoding = crawlerProperties.getProperty(Constants.CSV_FILE_ENCODING_PROPERTY, Constants.UTF_8);
+        form.purgeSearchLogDay = crawlerProperties.getProperty(Constants.PURGE_SEARCH_LOG_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
+        form.purgeJobLogDay = crawlerProperties.getProperty(Constants.PURGE_JOB_LOG_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
+        form.purgeUserInfoDay = crawlerProperties.getProperty(Constants.PURGE_USER_INFO_DAY_PROPERTY, Constants.DEFAULT_PURGE_DAY);
+        form.purgeByBots = crawlerProperties.getProperty(Constants.PURGE_BY_BOTS_PROPERTY, Constants.DEFAULT_PURGE_BY_BOTS);
+        form.notificationTo = crawlerProperties.getProperty(Constants.NOTIFICATION_TO_PROPERTY, StringUtil.EMPTY);
+        form.suggestSearchLog = crawlerProperties.getProperty(Constants.SUGGEST_SEARCH_LOG_PROPERTY, Constants.TRUE);
+        form.purgeSuggestSearchLogDay = crawlerProperties.getProperty(Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY, "30");
+        form.esHttpUrl = crawlerProperties.getProperty(Constants.ELASTICSEARCH_WEB_URL_PROPERTY, Constants.ELASTICSEARCH_WEB_URL);
+    }
+
+    private Integer getPropertyAsInteger(String key, int defaultValue) {
+        String value = crawlerProperties.getProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY);
+        if (value != null) {
+            try {
+                return Integer.valueOf(value);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+        return defaultValue;
+    }
+
+    private List<String> getDayItems() {
         final List<String> items = new ArrayList<String>();
         for (int i = 0; i < 32; i++) {
             items.add(Integer.valueOf(i).toString());

+ 49 - 32
src/main/java/org/codelibs/fess/app/web/admin/crawl/CrawlEditForm.java → src/main/java/org/codelibs/fess/app/web/admin/general/EditForm.java

@@ -14,90 +14,107 @@
  * governing permissions and limitations under the License.
  */
 
-package org.codelibs.fess.app.web.admin.crawl;
+package org.codelibs.fess.app.web.admin.general;
 
 import java.io.Serializable;
 
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Size;
+
+import org.lastaflute.web.validation.Required;
+
 /**
- * @author codelibs
+ * @author shinsuke
  * @author Shunji Makino
  */
-public class CrawlEditForm implements Serializable {
+public class EditForm implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String diffCrawling;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String useAclAsRole;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String serverRotation;
 
-    //@Required
-    //@IntRange(min = -1, max = 1000)
-    public String dayForCleanup;
+    @Required
+    @Max(1000)
+    @Min(-1)
+    public Integer dayForCleanup;
 
-    //@Required
-    //@LongRange(min = 0, max = 100)
+    @Required
+    @Max(100)
+    @Min(0)
     public String crawlingThreadCount;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String searchLog;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String userInfo;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String userFavorite;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String webApiXml;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String webApiJson;
 
-    //@Maxbytelength(maxbytelength = 1000)
+    @Size(max = 1000)
     public String defaultLabelValue;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String appendQueryParameter;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String supportedSearch;
 
-    //@Maxbytelength(maxbytelength = 1000)
+    @Size(max = 1000)
     public String ignoreFailureType;
 
-    //@IntRange(min = -1, max = 10000)
-    public String failureCountThreshold;
+    @Required
+    @Max(10000)
+    @Min(-1)
+    public Integer failureCountThreshold;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String hotSearchWord;
 
-    //@Required
-    //@Maxbytelength(maxbytelength = 20)
+    @Required
+    @Size(max = 20)
     public String csvFileEncoding;
 
-    //@IntRange(min = 0, max = 100000)
+    @Max(100000)
+    @Min(0)
     public String purgeSearchLogDay;
 
-    //@IntRange(min = 0, max = 100000)
+    @Max(100000)
+    @Min(0)
     public String purgeJobLogDay;
 
-    //@IntRange(min = 0, max = 100000)
+    @Max(100000)
+    @Min(0)
     public String purgeUserInfoDay;
 
-    //@Maxbytelength(maxbytelength = 1000)
+    @Size(max = 1000)
     public String purgeByBots;
 
-    //@Maxbytelength(maxbytelength = 1000)
+    @Size(max = 1000)
     public String notificationTo;
 
-    //@Maxbytelength(maxbytelength = 10)
+    @Size(max = 10)
     public String suggestSearchLog;
 
-    //@IntRange(min = 0, max = 100000)
+    @Max(100000)
+    @Min(0)
     public String purgeSuggestSearchLogDay;
+
+    @Size(max = 1000)
+    public String esHttpUrl;
 }

+ 28 - 28
src/main/java/org/codelibs/fess/dict/DictionaryManager.java

@@ -26,8 +26,10 @@ import java.util.List;
 import java.util.Map;
 
 import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
 
 import org.codelibs.core.io.FileUtil;
+import org.codelibs.core.misc.DynamicProperties;
 import org.codelibs.elasticsearch.runner.net.Curl;
 import org.codelibs.elasticsearch.runner.net.CurlResponse;
 import org.codelibs.fess.Constants;
@@ -38,7 +40,8 @@ import org.slf4j.LoggerFactory;
 public class DictionaryManager {
     private static final Logger logger = LoggerFactory.getLogger(DictionaryManager.class);
 
-    protected String esUrl = "http://localhost:9201";
+    @Resource
+    protected DynamicProperties crawlerProperties;
 
     protected List<DictionaryCreator> creatorList = new ArrayList<>();
 
@@ -50,7 +53,7 @@ public class DictionaryManager {
     }
 
     public DictionaryFile<? extends DictionaryItem>[] getDictionaryFiles() {
-        try (CurlResponse response = Curl.get(esUrl + "/_configsync/file").param("fields", "path,@timestamp").execute()) {
+        try (CurlResponse response = Curl.get(getUrl() + "/_configsync/file").param("fields", "path,@timestamp").execute()) {
             Map<String, Object> contentMap = response.getContentAsMap();
             @SuppressWarnings("unchecked")
             List<Map<String, Object>> fileList = (List<Map<String, Object>>) contentMap.get("file");
@@ -88,45 +91,42 @@ public class DictionaryManager {
     }
 
     public void store(DictionaryFile<? extends DictionaryItem> dictFile, File file) {
-        getDictionaryFile(dictFile.getId()).ifPresent(currentFile -> {
-            if (currentFile.getTimestamp().getTime() > dictFile.getTimestamp().getTime()) {
-                throw new DictionaryException(dictFile.getPath() + " was updated.");
-            }
-
-            // TODO use stream
-                try (CurlResponse response =
-                        Curl.post(esUrl + "/_configsync/file").param("path", dictFile.getPath()).body(FileUtil.readUTF8(file)).execute()) {
-                    Map<String, Object> contentMap = response.getContentAsMap();
-                    if (!Constants.TRUE.equalsIgnoreCase(contentMap.get("acknowledged").toString())) {
-                        throw new DictionaryException("Failed to update " + dictFile.getPath());
+        getDictionaryFile(dictFile.getId())
+                .ifPresent(currentFile -> {
+                    if (currentFile.getTimestamp().getTime() > dictFile.getTimestamp().getTime()) {
+                        throw new DictionaryException(dictFile.getPath() + " was updated.");
                     }
-                } catch (IOException e) {
-                    throw new DictionaryException("Failed to update " + dictFile.getPath(), e);
-                }
 
-            }).orElse(() -> {
-            throw new DictionaryException(dictFile.getPath() + " does not exist.");
-        });
+                    // TODO use stream
+                        try (CurlResponse response =
+                                Curl.post(getUrl() + "/_configsync/file").param("path", dictFile.getPath()).body(FileUtil.readUTF8(file))
+                                        .execute()) {
+                            Map<String, Object> contentMap = response.getContentAsMap();
+                            if (!Constants.TRUE.equalsIgnoreCase(contentMap.get("acknowledged").toString())) {
+                                throw new DictionaryException("Failed to update " + dictFile.getPath());
+                            }
+                        } catch (IOException e) {
+                            throw new DictionaryException("Failed to update " + dictFile.getPath(), e);
+                        }
+
+                    }).orElse(() -> {
+                    throw new DictionaryException(dictFile.getPath() + " does not exist.");
+                });
     }
 
     public InputStream getContentInputStream(DictionaryFile<? extends DictionaryItem> dictFile) {
         try {
-            return Curl.get(esUrl + "/_configsync/file").param("path", dictFile.getPath()).execute().getContentAsStream();
+            return Curl.get(getUrl() + "/_configsync/file").param("path", dictFile.getPath()).execute().getContentAsStream();
         } catch (IOException e) {
             throw new DictionaryException("Failed to access " + dictFile.getPath(), e);
         }
     }
 
-    public String getEsUrl() {
-        return esUrl;
-    }
-
-    public void setEsUrl(String esUrl) {
-        this.esUrl = esUrl;
-    }
-
     public void addCreator(DictionaryCreator creator) {
         creatorList.add(creator);
     }
 
+    protected String getUrl() {
+        return crawlerProperties.getProperty(Constants.ELASTICSEARCH_WEB_URL_PROPERTY, Constants.ELASTICSEARCH_WEB_URL);
+    }
 }

+ 2 - 0
src/main/java/org/codelibs/fess/helper/SuggestHelper.java

@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 
 import org.codelibs.core.lang.StringUtil;
@@ -42,6 +43,7 @@ public class SuggestHelper {
 
     public String badwordFileDir = "./solr/core1/conf/";
 
+    @PostConstruct
     public void init() {
         final Thread th = new Thread(() -> {
             // TODO replace with Elasticsearch

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

@@ -20,9 +20,6 @@ public interface FessHtmlPath {
     /** The path of the HTML: /admin/boostdocumentrule/index.jsp */
     HtmlNext path_AdminBoostdocumentrule_IndexJsp = new HtmlNext("/admin/boostdocumentrule/index.jsp");
 
-    /** The path of the HTML: /admin/crawl/index.jsp */
-    HtmlNext path_AdminCrawl_IndexJsp = new HtmlNext("/admin/crawl/index.jsp");
-
     /** The path of the HTML: /admin/crawlingsession/confirm.jsp */
     HtmlNext path_AdminCrawlingsession_ConfirmJsp = new HtmlNext("/admin/crawlingsession/confirm.jsp");
 
@@ -128,6 +125,9 @@ public interface FessHtmlPath {
     /** The path of the HTML: /admin/fileconfig/index.jsp */
     HtmlNext path_AdminFileconfig_IndexJsp = new HtmlNext("/admin/fileconfig/index.jsp");
 
+    /** The path of the HTML: /admin/general/index.jsp */
+    HtmlNext path_AdminGeneral_IndexJsp = new HtmlNext("/admin/general/index.jsp");
+
     /** The path of the HTML: /admin/group/confirm.jsp */
     HtmlNext path_AdminGroup_ConfirmJsp = new HtmlNext("/admin/group/confirm.jsp");
 

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

@@ -3613,6 +3613,9 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Toggle navigation */
     public static final String LABELS_admin_toggle_navi = "{labels.admin_toggle_navi}";
 
+    /** The key of the message: Search Server URL */
+    public static final String LABELS_es_http_url = "{labels.es_http_url}";
+
     /** The key of the message:  */
     public static final String LABELS_LABEL_TYPE_IDS = "{labels.labelTypeIds}";
 

+ 13 - 3
src/main/resources/app.xml

@@ -8,7 +8,6 @@
 	<include path="fess.xml"/>
 	<include path="fess_job.xml"/>
 	<include path="fess_api.xml"/>
-	<include path="fess_dict.xml"/>
 
 	<include path="crawler/client.xml" />
 	<include path="crawler/mimetype.xml" />
@@ -280,8 +279,6 @@
 	</component>
 
 	<component name="suggestHelper" class="org.codelibs.fess.helper.SuggestHelper">
-		<postConstruct name="init">
-		</postConstruct>
 	</component>
 
 	<component name="screenShotManager" class="org.codelibs.fess.screenshot.ScreenShotManager">
@@ -326,4 +323,17 @@
 	</component>
 -->
 
+	<component name="dictionaryManager" class="org.codelibs.fess.dict.DictionaryManager">
+		<postConstruct name="addCreator">
+			<arg>userDictCreator</arg>
+		</postConstruct>
+		<postConstruct name="addCreator">
+			<arg>synonymCreator</arg>
+		</postConstruct>
+	</component>
+
+	<component name="synonymCreator" class="org.codelibs.fess.dict.synonym.SynonymCreator">
+	</component>
+	<component name="userDictCreator" class="org.codelibs.fess.dict.kuromoji.KuromojiCreator">
+	</component>
 </components>

+ 0 - 21
src/main/resources/fess_dict.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE components PUBLIC "-//DBFLUTE//DTD LastaDi 1.0//EN"
-	"http://dbflute.org/meta/lastadi10.dtd">
-<components>
-	<component name="dictionaryManager" class="org.codelibs.fess.dict.DictionaryManager">
-		<property name="esUrl">"http://localhost:9201"</property>
-		<postConstruct name="addCreator">
-			<arg>userDictCreator</arg>
-		</postConstruct>
-		<postConstruct name="addCreator">
-			<arg>synonymCreator</arg>
-		</postConstruct>
-	</component>
-
-	<component name="synonymCreator" class="org.codelibs.fess.dict.synonym.SynonymCreator">
-	</component>
-
-	<component name="userDictCreator" class="org.codelibs.fess.dict.kuromoji.KuromojiCreator">
-	</component>
-
-</components>

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

@@ -1236,4 +1236,5 @@ labels.crud_title_details=Details
 labels.crud_title_confirm=Confirmation
 labels.admin_brand_title=Fess
 labels.admin_dashboard_title=Fess Dashboard
-labels.admin_toggle_navi=Toggle navigation
+labels.admin_toggle_navi=Toggle navigation
+labels.es_http_url=Search Server URL

+ 5 - 1
src/main/webapp/WEB-INF/view/admin/crawl/index.jsp → src/main/webapp/WEB-INF/view/admin/general/index.jsp

@@ -10,7 +10,7 @@
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
 			<jsp:param name="menuCategoryType" value="system" />
-			<jsp:param name="menuType" value="crawl" />
+			<jsp:param name="menuType" value="general" />
 		</jsp:include>
 
 		<div class="content-wrapper">
@@ -43,6 +43,10 @@
 									</div>
 
 									<%-- Form Fields --%>
+									<div class="form-group">
+											<label for="esHttpUrl"><la:message key="labels.es_http_url" /></label>
+											<la:text property="esHttpUrl" styleClass="form-control" />
+									</div>
 									<div class="form-group">
 											<label for="searchLog"><la:message key="labels.search_log_enabled" /></label>
 											<div styleClass="form-inline" >

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

@@ -32,7 +32,7 @@
 							<span><la:message key="labels.menu_wizard" /></span>
 						</la:link></li>
 
-					<li <c:if test="${param.menuType=='crawl'}">class="active"</c:if>><la:link href="/admin/crawl/">
+					<li <c:if test="${param.menuType=='general'}">class="active"</c:if>><la:link href="/admin/general/">
 							<i class='fa fa-angle-right'></i>
 							<span><la:message key="labels.menu_crawl_config" /></span>
 						</la:link></li>