Jelajahi Sumber

#2206 improve plugin page

Shinsuke Sugaya 6 tahun lalu
induk
melakukan
6bebe4f91d

+ 47 - 29
src/main/java/org/codelibs/fess/app/web/admin/plugin/AdminPluginAction.java

@@ -15,22 +15,25 @@
  */
 package org.codelibs.fess.app.web.admin.plugin;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.codelibs.fess.app.web.base.FessAdminAction;
 import org.codelibs.fess.helper.PluginHelper;
 import org.codelibs.fess.helper.PluginHelper.Artifact;
-import org.codelibs.fess.app.web.base.FessAdminAction;
-import org.codelibs.fess.util.RenderDataUtil;
+import org.codelibs.fess.helper.PluginHelper.ArtifactType;
 import org.lastaflute.web.Execute;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.ruts.process.ActionRuntime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
 public class AdminPluginAction extends FessAdminAction {
 
     private static final Logger logger = LoggerFactory.getLogger(AdminPluginAction.class);
@@ -41,8 +44,9 @@ public class AdminPluginAction extends FessAdminAction {
     @Override
     protected void setupHtmlData(final ActionRuntime runtime) {
         super.setupHtmlData(runtime);
-//        runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNamePlugin()));
-
+        runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNamePlugin()));
+        // runtime.registerData("availableArtifactItems", getAllAvailableArtifacts());
+        runtime.registerData("installedArtifactItems", getAllInstalledArtifacts());
     }
 
     @Execute
@@ -52,12 +56,20 @@ public class AdminPluginAction extends FessAdminAction {
     }
 
     @Execute
-    public HtmlResponse delete(final PluginBean pluginBean) {
-        // TODO
+    public HtmlResponse delete(final DeleteForm form) {
+        validate(form, messages -> {}, () -> {
+            return asHtml(path_AdminPlugin_AdminPluginJsp);
+        });
+        verifyToken(() -> {
+            return asHtml(path_AdminPlugin_AdminPluginJsp);
+        });
+        Artifact artifact = new Artifact(form.name, form.version, null);
         try {
-            pluginHelper.deleteInstalledArtifact(new Artifact(pluginBean.name, pluginBean.version, null));
+            pluginHelper.deleteInstalledArtifact(artifact);
+            saveInfo(messages -> messages.addSuccessInstallPlugin(GLOBAL, artifact.getFileName()));
         } catch (Exception e) {
-
+            logger.warn("Failed to delete " + artifact.getFileName(), e);
+            saveError(messages -> messages.addErrorsFailedToDeletePlugin(GLOBAL, artifact.getFileName()));
         }
         return redirect(getClass());
     }
@@ -69,26 +81,32 @@ public class AdminPluginAction extends FessAdminAction {
     }
 
     private HtmlResponse asListHtml() {
-        return asHtml(path_AdminPlugin_AdminPluginJsp).renderWith(
-                data ->
-                        RenderDataUtil.register(data, "installedArtifactItems", getAllInstalledArtifacts()));
+        return asHtml(path_AdminPlugin_AdminPluginJsp);
+    }
+
+    private List<Map<String, String>> getAllAvailableArtifacts() {
+        final List<Map<String, String>> result = new ArrayList<>();
+        for (PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
+            result.addAll(Arrays.stream(pluginHelper.getAvailableArtifacts(artifactType)).map(artifact -> beanToMap(artifact))
+                    .collect(Collectors.toList()));
+        }
+        return result;
     }
 
-    private List<PluginBean> getAllInstalledArtifacts() {
-        final List<PluginBean> result = new ArrayList<>();
-        for(PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
-            result.addAll(
-                    Arrays.stream(pluginHelper.getInstalledArtifacts(artifactType))
-                            .map(artifact -> mappingToBean(PluginHelper.ArtifactType.getType(artifactType.getId()).toString(), artifact)).collect(Collectors.toList()));
+    private List<Map<String, String>> getAllInstalledArtifacts() {
+        final List<Map<String, String>> result = new ArrayList<>();
+        for (PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
+            result.addAll(Arrays.stream(pluginHelper.getInstalledArtifacts(artifactType)).map(artifact -> beanToMap(artifact))
+                    .collect(Collectors.toList()));
         }
         return result;
     }
 
-    private PluginBean mappingToBean(final String artifactType, final Artifact artifact) {
-        final PluginBean pluginBean = new PluginBean();
-        pluginBean.artifactType = artifactType;
-        pluginBean.name = artifact.getName();
-        pluginBean.version = artifact.getVersion();
-        return pluginBean;
+    private Map<String, String> beanToMap(final Artifact artifact) {
+        Map<String, String> item = new HashMap<>();
+        item.put("type", ArtifactType.getType(artifact).getId());
+        item.put("name", artifact.getName());
+        item.put("version", artifact.getVersion());
+        return item;
     }
 }

+ 31 - 0
src/main/java/org/codelibs/fess/app/web/admin/plugin/DeleteForm.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012-2019 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.plugin;
+
+import javax.validation.constraints.Size;
+
+import org.lastaflute.web.validation.Required;
+
+public class DeleteForm {
+
+    @Required
+    @Size(max = 100)
+    public String name;
+
+    @Size(max = 100)
+    public String version;
+
+}

+ 31 - 0
src/main/java/org/codelibs/fess/app/web/admin/plugin/InstallForm.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012-2019 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.plugin;
+
+import javax.validation.constraints.Size;
+
+import org.lastaflute.web.validation.Required;
+
+public class InstallForm {
+
+    @Required
+    @Size(max = 100)
+    public String name;
+
+    @Size(max = 100)
+    public String version;
+
+}

+ 0 - 7
src/main/java/org/codelibs/fess/app/web/admin/plugin/PluginBean.java

@@ -1,7 +0,0 @@
-package org.codelibs.fess.app.web.admin.plugin;
-
-public class PluginBean {
-    public String artifactType;
-    public String name;
-    public String version;
-}

+ 23 - 8
src/main/java/org/codelibs/fess/helper/PluginHelper.java

@@ -26,6 +26,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -50,16 +51,30 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-// TODO: refactoring, exception handling, improving codes
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
 public class PluginHelper {
     private static final Logger logger = LoggerFactory.getLogger(PluginHelper.class);
 
-    public Artifact[] getArtifacts(final ArtifactType artifactType) {
-        final List<Artifact> list = new ArrayList<>();
-        for (final String url : getRepositories()) {
-            list.addAll(processRepository(artifactType, url));
+    protected LoadingCache<ArtifactType, Artifact[]> availableArtifacts = CacheBuilder.newBuilder().maximumSize(10)
+            .expireAfterWrite(1, TimeUnit.MINUTES).build(new CacheLoader<ArtifactType, Artifact[]>() {
+                public Artifact[] load(ArtifactType key) {
+                    final List<Artifact> list = new ArrayList<>();
+                    for (final String url : getRepositories()) {
+                        list.addAll(processRepository(key, url));
+                    }
+                    return list.toArray(new Artifact[list.size()]);
+                }
+            });
+
+    public Artifact[] getAvailableArtifacts(final ArtifactType artifactType) {
+        try {
+            return availableArtifacts.get(artifactType);
+        } catch (final Exception e) {
+            throw new PluginException("Failed to access " + artifactType, e);
         }
-        return list.toArray(new Artifact[list.size()]);
     }
 
     protected String[] getRepositories() {
@@ -227,8 +242,8 @@ public class PluginHelper {
             return id;
         }
 
-        static public ArtifactType getType(final String name) {
-            if (name.startsWith(DATA_STORE.getId())) {
+        public static ArtifactType getType(final Artifact artifact) {
+            if (artifact.getName().startsWith(DATA_STORE.getId())) {
                 return DATA_STORE;
             }
             return UNKNOWN;

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

@@ -602,6 +602,9 @@ public class FessLabels extends UserMessages {
     /** The key of the message: Related Query */
     public static final String LABELS_menu_related_query = "{labels.menu_related_query}";
 
+    /** The key of the message: Plugin */
+    public static final String LABELS_menu_plugin = "{labels.menu_plugin}";
+
     /** The key of the message: Search... */
     public static final String LABELS_SIDEBAR_placeholder_search = "{labels.sidebar.placeholder_search}";
 
@@ -2949,6 +2952,24 @@ public class FessLabels extends UserMessages {
     /** The key of the message: Reload */
     public static final String LABELS_reload_doc_index_button = "{labels.reload_doc_index_button}";
 
+    /** The key of the message: Plugin Manager */
+    public static final String LABELS_plugin_management = "{labels.plugin_management}";
+
+    /** The key of the message: Plugin List */
+    public static final String LABELS_plugin_list_name = "{labels.plugin_list_name}";
+
+    /** The key of the message: Type */
+    public static final String LABELS_plugin_type = "{labels.plugin_type}";
+
+    /** The key of the message: Name */
+    public static final String LABELS_plugin_name = "{labels.plugin_name}";
+
+    /** The key of the message: Version */
+    public static final String LABELS_plugin_version = "{labels.plugin_version}";
+
+    /** The key of the message: Delete */
+    public static final String LABELS_plugin_delete = "{labels.plugin_delete}";
+
     /**
      * Assert the property is not null.
      * @param property The value of the property. (NotNull)

+ 72 - 0
src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java

@@ -347,6 +347,12 @@ public class FessMessages extends FessLabels {
     /** The key of the message: {0} is not supported. */
     public static final String ERRORS_file_is_not_supported = "{errors.file_is_not_supported}";
 
+    /** The key of the message: Failed to install {0} plugin. */
+    public static final String ERRORS_failed_to_install_plugin = "{errors.failed_to_install_plugin}";
+
+    /** The key of the message: Failed to delete {0} plugin. */
+    public static final String ERRORS_failed_to_delete_plugin = "{errors.failed_to_delete_plugin}";
+
     /** The key of the message: The given query has unknown condition. */
     public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
 
@@ -476,6 +482,12 @@ public class FessMessages extends FessLabels {
     /** The key of the message: Printed thread dump to log file. */
     public static final String SUCCESS_print_thread_dump = "{success.print_thread_dump}";
 
+    /** The key of the message: Installing {0} plugin. */
+    public static final String SUCCESS_install_plugin = "{success.install_plugin}";
+
+    /** The key of the message: Deleting {0} plugin. */
+    public static final String SUCCESS_delete_plugin = "{success.delete_plugin}";
+
     /** The key of the message: Created data. */
     public static final String SUCCESS_crud_create_crud_table = "{success.crud_create_crud_table}";
 
@@ -2028,6 +2040,36 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'errors.failed_to_install_plugin' with parameters.
+     * <pre>
+     * message: Failed to install {0} plugin.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsFailedToInstallPlugin(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(ERRORS_failed_to_install_plugin, arg0));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.failed_to_delete_plugin' with parameters.
+     * <pre>
+     * message: Failed to delete {0} plugin.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsFailedToDeletePlugin(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(ERRORS_failed_to_delete_plugin, arg0));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'errors.invalid_query_unknown' with parameters.
      * <pre>
@@ -2651,6 +2693,36 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'success.install_plugin' with parameters.
+     * <pre>
+     * message: Installing {0} plugin.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addSuccessInstallPlugin(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(SUCCESS_install_plugin, arg0));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'success.delete_plugin' with parameters.
+     * <pre>
+     * message: Deleting {0} plugin.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addSuccessDeletePlugin(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(SUCCESS_delete_plugin, arg0));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'success.crud_create_crud_table' with parameters.
      * <pre>

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

@@ -1202,6 +1202,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. maintenance */
     String ONLINE_HELP_NAME_MAINTENANCE = "online.help.name.maintenance";
 
+    /** The key of the configuration. e.g. plugin */
+    String ONLINE_HELP_NAME_PLUGIN = "online.help.name.plugin";
+
     /** The key of the configuration. e.g. ja */
     String ONLINE_HELP_SUPPORTED_LANGS = "online.help.supported.langs";
 
@@ -5218,6 +5221,13 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
     String getOnlineHelpNameMaintenance();
 
+    /**
+     * Get the value for the key 'online.help.name.plugin'. <br>
+     * The value is, e.g. plugin <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getOnlineHelpNamePlugin();
+
     /**
      * Get the value for the key 'online.help.supported.langs'. <br>
      * The value is, e.g. ja <br>
@@ -7905,6 +7915,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return get(FessConfig.ONLINE_HELP_NAME_MAINTENANCE);
         }
 
+        public String getOnlineHelpNamePlugin() {
+            return get(FessConfig.ONLINE_HELP_NAME_PLUGIN);
+        }
+
         public String getOnlineHelpSupportedLangs() {
             return get(FessConfig.ONLINE_HELP_SUPPORTED_LANGS);
         }
@@ -8659,6 +8673,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             defaultMap.put(FessConfig.ONLINE_HELP_NAME_SUGGEST, "suggest");
             defaultMap.put(FessConfig.ONLINE_HELP_NAME_SEARCHLOG, "searchlog");
             defaultMap.put(FessConfig.ONLINE_HELP_NAME_MAINTENANCE, "maintenance");
+            defaultMap.put(FessConfig.ONLINE_HELP_NAME_PLUGIN, "plugin");
             defaultMap.put(FessConfig.ONLINE_HELP_SUPPORTED_LANGS, "ja");
             defaultMap.put(FessConfig.SUGGEST_POPULAR_WORD_SEED, "0");
             defaultMap.put(FessConfig.SUGGEST_POPULAR_WORD_TAGS, "");

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

@@ -611,6 +611,7 @@ online.help.name.accesstoken=accesstoken
 online.help.name.suggest=suggest
 online.help.name.searchlog=searchlog
 online.help.name.maintenance=maintenance
+online.help.name.plugin=plugin
 
 online.help.supported.langs=ja
 

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

@@ -192,6 +192,7 @@ labels.menu_access_token=Access Token
 labels.menu_maintenance=Maintenance
 labels.menu_related_content=Related Content
 labels.menu_related_query=Related Query
+labels.menu_plugin=Plugin
 labels.sidebar.placeholder_search=Search...
 labels.sidebar.menu=MENU
 labels.footer.copyright=&copy;2019 <a href="https://github.com/codelibs">CodeLibs Project</a>.

+ 5 - 0
src/main/resources/fess_message.properties

@@ -137,12 +137,15 @@ errors.could_not_delete_logged_in_user=Could not delete logged in user.
 errors.unauthorized_request=Unauthorized request.
 errors.failed_to_print_thread_dump=Failed to print thread dump.
 errors.file_is_not_supported={0} is not supported.
+errors.failed_to_install_plugin=Failed to install {0} plugin.
+errors.failed_to_delete_plugin=Failed to delete {0} plugin.
 
 errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_parse_error=The given query is invalid.
 errors.invalid_query_sort_value=The given sort ({0}) is invalid.
 errors.invalid_query_unsupported_sort_field=The given sort ({0}) is not supported.
 errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
+errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
 
 errors.crud_invalid_mode=Invalid mode(expected value is {0}, but it's {1}).
 errors.crud_failed_to_create_instance=Failed to create a new data.
@@ -184,6 +187,8 @@ success.started_data_update=Started data update process.
 success.reindex_started=Started reindexing.
 success.bulk_process_started=Bulk process is started.
 success.print_thread_dump=Printed thread dump to log file.
+success.install_plugin=Installing {0} plugin.
+success.delete_plugin=Deleting {0} plugin.
 
 success.crud_create_crud_table=Created data.
 success.crud_update_crud_table=Updated data.

+ 2 - 2
src/main/webapp/WEB-INF/view/admin/plugin/admin_plugin.jsp

@@ -10,7 +10,7 @@
 <div class="wrapper">
     <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="log" />
+        <jsp:param name="menuCategoryType" value="system" />
         <jsp:param name="menuType" value="plugin" />
     </jsp:include>
     <div class="content-wrapper">
@@ -49,7 +49,7 @@
                                             <c:forEach var="artifact" varStatus="s"
                                                        items="${installedArtifactItems}">
                                                 <tr>
-                                                    <td>${f:h(artifact.artifactType)}</td>
+                                                    <td>${f:h(artifact.type)}</td>
                                                     <td>${f:h(artifact.name)}</td>
                                                     <td>${f:h(artifact.version)}</td>
                                                     <td>

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

@@ -76,6 +76,12 @@
 							<span><la:message key="labels.menu_access_token" /></span>
 						</la:link></li>
 
+					<li <c:if test="${param.menuType=='plugin'}">class="active"</c:if>><la:link
+							href="/admin/plugin/">
+							<em class='fa fa-genderless'></em>
+							<span><la:message key="labels.menu_plugin" /></span>
+						</la:link></li>
+
 				</ul></li>
 			<li
 				class="treeview <c:if test="${param.menuCategoryType=='crawl'}">active</c:if>"><a