#2206 improve plugin page

This commit is contained in:
Shinsuke Sugaya 2019-08-15 20:20:46 +09:00
parent 96a5b16954
commit 6bebe4f91d
13 changed files with 255 additions and 46 deletions

View file

@ -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<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>> 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 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 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 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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

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

View file

@ -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;

View file

@ -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)

View file

@ -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>

View file

@ -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, "");

View file

@ -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

View file

@ -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>.

View file

@ -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.

View file

@ -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>

View file

@ -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