fix #2229 upload jar file
This commit is contained in:
parent
4a53458a92
commit
0001a8e909
14 changed files with 373 additions and 220 deletions
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
package org.codelibs.fess.app.web.admin.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
@ -22,9 +26,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.codelibs.core.io.CopyUtil;
|
||||
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.helper.PluginHelper.ArtifactType;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
import org.lastaflute.web.Execute;
|
||||
|
@ -37,6 +43,8 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AdminPluginAction.class);
|
||||
|
||||
private static final String UPLOAD = "upload";
|
||||
|
||||
@Override
|
||||
protected void setupHtmlData(final ActionRuntime runtime) {
|
||||
super.setupHtmlData(runtime);
|
||||
|
@ -53,7 +61,7 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
public HtmlResponse delete(final DeleteForm form) {
|
||||
validate(form, messages -> {}, () -> asHtml(path_AdminPlugin_AdminPluginJsp));
|
||||
verifyToken(() -> asHtml(path_AdminPlugin_AdminPluginJsp));
|
||||
final Artifact artifact = new Artifact(form.name, form.version);
|
||||
final Artifact artifact = new Artifact(form.name, form.version, null);
|
||||
deleteArtifact(artifact);
|
||||
saveInfo(messages -> messages.addSuccessDeletePlugin(GLOBAL, artifact.getFileName()));
|
||||
return redirect(getClass());
|
||||
|
@ -63,12 +71,48 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
public HtmlResponse install(final InstallForm form) {
|
||||
validate(form, messages -> {}, () -> asHtml(path_AdminPlugin_AdminPluginInstallpluginJsp));
|
||||
verifyToken(() -> asHtml(path_AdminPlugin_AdminPluginInstallpluginJsp));
|
||||
final Artifact artifact = getArtifactFromInstallForm(form);
|
||||
if (artifact == null) {
|
||||
throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asListHtml());
|
||||
if (UPLOAD.equals(form.id)) {
|
||||
if (form.jarFile == null) {
|
||||
throwValidationError(messages -> messages.addErrorsPluginFileIsNotFound(GLOBAL, form.id), () -> asListHtml());
|
||||
}
|
||||
if (!form.jarFile.getFileName().endsWith(".jar")) {
|
||||
throwValidationError(messages -> messages.addErrorsFileIsNotSupported(GLOBAL, form.jarFile.getFileName()),
|
||||
() -> asListHtml());
|
||||
}
|
||||
final String filename = form.jarFile.getFileName();
|
||||
final File tempFile = ComponentUtil.getSystemHelper().createTempFile("tmp-adminplugin-", ".jar");
|
||||
try (final InputStream is = form.jarFile.getInputStream(); final OutputStream os = new FileOutputStream(tempFile)) {
|
||||
CopyUtil.copy(is, os);
|
||||
} catch (final Exception e) {
|
||||
if (tempFile.exists() && !tempFile.delete()) {
|
||||
logger.warn("Failed to delete {}.", tempFile.getAbsolutePath());
|
||||
}
|
||||
logger.debug("Failed to copy " + filename, e);
|
||||
throwValidationError(messages -> messages.addErrorsFailedToInstallPlugin(GLOBAL, filename), () -> asListHtml());
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
final PluginHelper pluginHelper = ComponentUtil.getPluginHelper();
|
||||
final Artifact artifact =
|
||||
pluginHelper.getArtifactFromFileName(ArtifactType.UNKNOWN, filename, tempFile.getAbsolutePath());
|
||||
pluginHelper.installArtifact(artifact);
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Failed to install " + filename, e);
|
||||
} finally {
|
||||
if (tempFile.exists() && !tempFile.delete()) {
|
||||
logger.warn("Failed to delete {}.", tempFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
saveInfo(messages -> messages.addSuccessInstallPlugin(GLOBAL, form.jarFile.getFileName()));
|
||||
} else {
|
||||
final Artifact artifact = getArtifactFromInstallForm(form);
|
||||
if (artifact == null) {
|
||||
throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asListHtml());
|
||||
}
|
||||
installArtifact(artifact);
|
||||
saveInfo(messages -> messages.addSuccessInstallPlugin(GLOBAL, artifact.getFileName()));
|
||||
}
|
||||
installArtifact(artifact);
|
||||
saveInfo(messages -> messages.addSuccessInstallPlugin(GLOBAL, artifact.getFileName()));
|
||||
return redirect(getClass());
|
||||
}
|
||||
|
||||
|
@ -88,6 +132,11 @@ public class AdminPluginAction extends FessAdminAction {
|
|||
public static List<Map<String, String>> getAllAvailableArtifacts() {
|
||||
final PluginHelper pluginHelper = ComponentUtil.getPluginHelper();
|
||||
final List<Map<String, String>> result = new ArrayList<>();
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
map.put("id", UPLOAD);
|
||||
map.put("name", "");
|
||||
map.put("version", "");
|
||||
result.add(map);
|
||||
for (final PluginHelper.ArtifactType artifactType : PluginHelper.ArtifactType.values()) {
|
||||
result.addAll(Arrays.stream(pluginHelper.getAvailableArtifacts(artifactType)).map(AdminPluginAction::beanToMap)
|
||||
.collect(Collectors.toList()));
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.codelibs.fess.app.web.admin.plugin;
|
|||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.lastaflute.web.ruts.multipart.MultipartFormFile;
|
||||
import org.lastaflute.web.validation.Required;
|
||||
|
||||
public class InstallForm {
|
||||
|
@ -25,4 +26,5 @@ public class InstallForm {
|
|||
@Size(max = 400)
|
||||
public String id;
|
||||
|
||||
public MultipartFormFile jarFile;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import static org.codelibs.core.stream.StreamUtil.split;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
@ -65,7 +66,8 @@ public class PluginHelper {
|
|||
|
||||
protected LoadingCache<ArtifactType, Artifact[]> availableArtifacts = CacheBuilder.newBuilder().maximumSize(10)
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES).build(new CacheLoader<ArtifactType, Artifact[]>() {
|
||||
public Artifact[] load(ArtifactType key) {
|
||||
@Override
|
||||
public Artifact[] load(final ArtifactType key) {
|
||||
final List<Artifact> list = new ArrayList<>();
|
||||
for (final String url : getRepositories()) {
|
||||
if (url.endsWith(".yaml")) {
|
||||
|
@ -95,16 +97,16 @@ public class PluginHelper {
|
|||
|
||||
protected List<Artifact> loadArtifactsFromRepository(final String url) {
|
||||
final String content = getRepositoryContent(url);
|
||||
ObjectMapper objectMapper = new YAMLMapper();
|
||||
final ObjectMapper objectMapper = new YAMLMapper();
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<?, ?>> result = objectMapper.readValue(content, List.class);
|
||||
final List<Map<?, ?>> result = objectMapper.readValue(content, List.class);
|
||||
if (result != null) {
|
||||
return result.stream().map(o -> new Artifact((String) o.get("name"), (String) o.get("version"), (String) o.get("url")))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new PluginException("Failed to access " + url, e);
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +131,7 @@ public class PluginHelper {
|
|||
if (version.endsWith("SNAPSHOT")) {
|
||||
final String snapshotVersion = getSnapshotActualVersion(builder, pluginUrl, version);
|
||||
if (StringUtil.isNotBlank(snapshotVersion)) {
|
||||
String actualVersion = version.replace("SNAPSHOT", snapshotVersion);
|
||||
final String actualVersion = version.replace("SNAPSHOT", snapshotVersion);
|
||||
list.add(new Artifact(name, actualVersion, pluginUrl + version + "/" + name + "-" + actualVersion + ".jar"));
|
||||
} else if (logger.isDebugEnabled()) {
|
||||
logger.debug("Snapshot name is not found: " + name + "/" + version);
|
||||
|
@ -161,7 +163,7 @@ public class PluginHelper {
|
|||
final Document doc = builder.parse(is);
|
||||
final NodeList snapshotNodeList = doc.getElementsByTagName("snapshot");
|
||||
if (snapshotNodeList.getLength() > 0) {
|
||||
NodeList nodeList = snapshotNodeList.item(0).getChildNodes();
|
||||
final NodeList nodeList = snapshotNodeList.item(0).getChildNodes();
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
final Node node = nodeList.item(i);
|
||||
if ("timestamp".equalsIgnoreCase(node.getNodeName())) {
|
||||
|
@ -192,7 +194,7 @@ public class PluginHelper {
|
|||
public Artifact[] getInstalledArtifacts(final ArtifactType artifactType) {
|
||||
if (artifactType == ArtifactType.UNKNOWN) {
|
||||
final File[] jarFiles = ResourceUtil.getPluginJarFiles((d, n) -> {
|
||||
for (ArtifactType type : ArtifactType.values()) {
|
||||
for (final ArtifactType type : ArtifactType.values()) {
|
||||
if (n.startsWith(type.getId())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -216,12 +218,16 @@ public class PluginHelper {
|
|||
return list.toArray(new Artifact[list.size()]);
|
||||
}
|
||||
|
||||
protected Artifact getArtifactFromFileName(final ArtifactType artifactType, final String name) {
|
||||
String baseName = StringUtils.removeEndIgnoreCase(name, ".jar");
|
||||
List<String> nameList = new ArrayList<>();
|
||||
List<String> versionList = new ArrayList<>();
|
||||
protected Artifact getArtifactFromFileName(final ArtifactType artifactType, final String filename) {
|
||||
return getArtifactFromFileName(artifactType, filename, null);
|
||||
}
|
||||
|
||||
public Artifact getArtifactFromFileName(final ArtifactType artifactType, final String filename, final String url) {
|
||||
final String baseName = StringUtils.removeEndIgnoreCase(filename, ".jar");
|
||||
final List<String> nameList = new ArrayList<>();
|
||||
final List<String> versionList = new ArrayList<>();
|
||||
boolean isName = true;
|
||||
for (String value : baseName.split("-")) {
|
||||
for (final String value : baseName.split("-")) {
|
||||
if (isName && value.length() > 0 && value.charAt(0) >= '0' && value.charAt(0) <= '9') {
|
||||
isName = false;
|
||||
}
|
||||
|
@ -231,21 +237,31 @@ public class PluginHelper {
|
|||
versionList.add(value);
|
||||
}
|
||||
}
|
||||
return new Artifact(nameList.stream().collect(Collectors.joining("-")), versionList.stream().collect(Collectors.joining("-")));
|
||||
return new Artifact(nameList.stream().collect(Collectors.joining("-")), versionList.stream().collect(Collectors.joining("-")), url);
|
||||
}
|
||||
|
||||
public void installArtifact(final Artifact artifact) {
|
||||
final String fileName = artifact.getFileName();
|
||||
try (final CurlResponse response = Curl.get(artifact.getUrl()).execute()) {
|
||||
if (response.getHttpStatusCode() != 200) {
|
||||
throw new PluginException("HTTP Status " + response.getHttpStatusCode() + " : failed to get the artifact from "
|
||||
+ artifact.getUrl());
|
||||
final String url = artifact.getUrl();
|
||||
if (StringUtil.isBlank(url)) {
|
||||
throw new PluginException("url is blank: " + artifact.getName());
|
||||
} else if (url.startsWith("http:") || url.startsWith("https:")) {
|
||||
try (final CurlResponse response = Curl.get(url).execute()) {
|
||||
if (response.getHttpStatusCode() != 200) {
|
||||
throw new PluginException("HTTP Status " + response.getHttpStatusCode() + " : failed to get the artifact from " + url);
|
||||
}
|
||||
try (final InputStream in = response.getContentAsStream()) {
|
||||
CopyUtil.copy(in, ResourceUtil.getPluginPath(fileName).toFile());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new PluginException("Failed to install the artifact " + artifact.getName(), e);
|
||||
}
|
||||
try (final InputStream in = response.getContentAsStream()) {
|
||||
} else {
|
||||
try (final InputStream in = new FileInputStream(url)) {
|
||||
CopyUtil.copy(in, ResourceUtil.getPluginPath(fileName).toFile());
|
||||
} catch (final Exception e) {
|
||||
throw new PluginException("Failed to install the artifact " + artifact.getName(), e);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new PluginException("Failed to install the artifact " + artifact.getName(), e);
|
||||
}
|
||||
|
||||
switch (artifact.getType()) {
|
||||
|
@ -283,7 +299,7 @@ public class PluginHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public Artifact getArtifact(String name, String version) {
|
||||
public Artifact getArtifact(final String name, final String version) {
|
||||
if (StringUtil.isBlank(name) || StringUtil.isBlank(version)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.apache.commons.lang3.LocaleUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.codelibs.core.exception.IORuntimeException;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.core.misc.Pair;
|
||||
import org.codelibs.fess.Constants;
|
||||
|
@ -469,6 +470,14 @@ public class SystemHelper {
|
|||
return System.getProperty(Constants.FESS_LOG_LEVEL, Level.WARN.toString());
|
||||
}
|
||||
|
||||
public File createTempFile(String prefix, String suffix) {
|
||||
try {
|
||||
return File.createTempFile(prefix, suffix);
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
@ -484,5 +493,4 @@ public class SystemHelper {
|
|||
public String getProductVersion() {
|
||||
return productVersion;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2976,6 +2976,15 @@ public class FessLabels extends UserMessages {
|
|||
/** The key of the message: Install Plugin */
|
||||
public static final String LABELS_plugin_install_title = "{labels.plugin_install_title}";
|
||||
|
||||
/** The key of the message: Jar File */
|
||||
public static final String LABELS_plugin_jar_file = "{labels.plugin_jar_file}";
|
||||
|
||||
/** The key of the message: Local */
|
||||
public static final String LABELS_plugin_local_install = "{labels.plugin_local_install}";
|
||||
|
||||
/** The key of the message: Remote */
|
||||
public static final String LABELS_plugin_remote_install = "{labels.plugin_remote_install}";
|
||||
|
||||
/** The key of the message: Install */
|
||||
public static final String LABELS_crud_button_install = "{labels.crud_button_install}";
|
||||
|
||||
|
|
|
@ -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: {0} is not found. */
|
||||
public static final String ERRORS_plugin_file_is_not_found = "{errors.plugin_file_is_not_found}";
|
||||
|
||||
/** The key of the message: Failed to install {0}. */
|
||||
public static final String ERRORS_failed_to_install_plugin = "{errors.failed_to_install_plugin}";
|
||||
|
||||
/** The key of the message: The given query has unknown condition. */
|
||||
public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
|
||||
|
||||
|
@ -2034,6 +2040,36 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.plugin_file_is_not_found' with parameters.
|
||||
* <pre>
|
||||
* message: {0} is not found.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsPluginFileIsNotFound(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(ERRORS_plugin_file_is_not_found, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.failed_to_install_plugin' with parameters.
|
||||
* <pre>
|
||||
* message: Failed to install {0}.
|
||||
* </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.invalid_query_unknown' with parameters.
|
||||
* <pre>
|
||||
|
|
|
@ -983,4 +983,7 @@ labels.plugin_version=Version
|
|||
labels.plugin_delete=Delete
|
||||
labels.plugin_install=Install
|
||||
labels.plugin_install_title=Install Plugin
|
||||
labels.plugin_jar_file=Jar File
|
||||
labels.plugin_local_install=Local
|
||||
labels.plugin_remote_install=Remote
|
||||
labels.crud_button_install=Install
|
||||
|
|
|
@ -983,4 +983,7 @@ labels.plugin_version=Version
|
|||
labels.plugin_delete=Delete
|
||||
labels.plugin_install=Install
|
||||
labels.plugin_install_title=Install Plugin
|
||||
labels.plugin_jar_file=Jar File
|
||||
labels.plugin_local_install=Local
|
||||
labels.plugin_remote_install=Remote
|
||||
labels.crud_button_install=Install
|
||||
|
|
|
@ -983,4 +983,7 @@ labels.plugin_version=バージョン
|
|||
labels.plugin_delete=削除
|
||||
labels.plugin_install=インストール
|
||||
labels.plugin_install_title=プラグインのインストール
|
||||
labels.plugin_jar_file=Jarファイル
|
||||
labels.plugin_local_install=ローカル
|
||||
labels.plugin_remote_install=リモート
|
||||
labels.crud_button_install=インストール
|
||||
|
|
|
@ -137,6 +137,8 @@ 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.plugin_file_is_not_found={0} is not found.
|
||||
errors.failed_to_install_plugin=Failed to install {0}.
|
||||
|
||||
errors.invalid_query_unknown=The given query has unknown condition.
|
||||
errors.invalid_query_parse_error=The given query is invalid.
|
||||
|
|
|
@ -133,6 +133,8 @@ 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.plugin_file_is_not_found={0} is not found.
|
||||
errors.failed_to_install_plugin=Failed to install {0}.
|
||||
|
||||
errors.invalid_query_unknown=The given query has unknown condition.
|
||||
errors.invalid_query_parse_error=The given query is invalid.
|
||||
|
|
|
@ -23,7 +23,7 @@ constraints.NotNull.message = {item} は未入力です。
|
|||
constraints.Null.message = {item} は null でなければなりません。
|
||||
constraints.Past.message = {item} は過去の値にする必要があります。
|
||||
constraints.Pattern.message = {item} が 「{regexp}」 に一致しません。
|
||||
constraints.Size.message = {item}のサイズは {min} から {max} の範囲にしてください。
|
||||
constraints.Size.message = {item}のサイズは {min} 文字から {max} 文字の範囲にしてください。
|
||||
# ----------------------------------------------------------
|
||||
# Hibernate Validator
|
||||
# -------------------
|
||||
|
@ -139,6 +139,8 @@ errors.invalid_header_for_request_file=ヘッダー行が正しくありませ
|
|||
errors.could_not_delete_logged_in_user=ログインしているユーザーは削除できません。
|
||||
errors.failed_to_print_thread_dump=スレッドダンプの出力に失敗しました。
|
||||
errors.file_is_not_supported={0}はサポートされていません。
|
||||
errors.plugin_file_is_not_found={0}が見つかりません。
|
||||
errors.failed_to_install_plugin={0}のインストールに失敗しました。
|
||||
|
||||
errors.property_required={0}は必須です。
|
||||
errors.property_type_integer={0}は数値です。
|
||||
|
|
|
@ -1,131 +1,129 @@
|
|||
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><la:message key="labels.admin_brand_title" /> | <la:message
|
||||
key="labels.plugin_title" /></title>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
|
||||
<meta charset="UTF-8">
|
||||
<title><la:message key="labels.admin_brand_title" /> | <la:message key="labels.plugin_title" /></title>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
|
||||
</head>
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<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="system" />
|
||||
<jsp:param name="menuType" value="plugin" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
<la:message key="labels.plugin_title" />
|
||||
</h1>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/crud/breadcrumb.jsp"></jsp:include>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<la:message key="labels.crud_title_list" />
|
||||
</h3>
|
||||
<div class="btn-group pull-right">
|
||||
<la:link href="installplugin" styleClass="btn btn-success btn-xs">
|
||||
<em class="fa fa-plus"></em>
|
||||
<la:message key="labels.plugin_install" />
|
||||
</la:link>
|
||||
<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="system" />
|
||||
<jsp:param name="menuType" value="plugin" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
<la:message key="labels.plugin_title" />
|
||||
</h1>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/crud/breadcrumb.jsp"></jsp:include>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<la:message key="labels.crud_title_list" />
|
||||
</h3>
|
||||
<div class="btn-group pull-right">
|
||||
<la:link href="installplugin" styleClass="btn btn-success btn-xs">
|
||||
<em class="fa fa-plus"></em>
|
||||
<la:message key="labels.plugin_install" />
|
||||
</la:link>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<%-- Message --%>
|
||||
<div>
|
||||
<la:info id="msg" message="true">
|
||||
<div class="alert alert-info">${msg}</div>
|
||||
</la:info>
|
||||
<la:errors />
|
||||
</div>
|
||||
<%-- List --%>
|
||||
<div class="data-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<table class="table table-bordered table-striped dataTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><la:message key="labels.plugin_type" /></th>
|
||||
<th><la:message key="labels.plugin_name" /></th>
|
||||
<th><la:message key="labels.plugin_version" /></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<c:forEach var="artifact" varStatus="s" items="${installedArtifactItems}">
|
||||
<tr>
|
||||
<td>${f:h(artifact.type)}</td>
|
||||
<td>${f:h(artifact.name)}</td>
|
||||
<td>${f:h(artifact.version)}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger btn-xs" name="delete" data-toggle="modal"
|
||||
data-target='#confirmToDelete-${f:h(artifact.name)}-${f:h(artifact.version).replace(".", "\\.")}'
|
||||
value="<la:message key="labels.design_delete_button" />"
|
||||
>
|
||||
<em class="fa fa-trash"></em>
|
||||
<la:message key="labels.design_delete_button" />
|
||||
</button>
|
||||
<div class="modal modal-danger fade" id='confirmToDelete-${f:h(artifact.name)}-${f:h(artifact.version)}'
|
||||
tabindex="-1" role="dialog"
|
||||
>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title">
|
||||
<la:message key="labels.crud_title_delete" />
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
<la:message key="labels.crud_delete_confirmation" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">
|
||||
<la:message key="labels.crud_button_cancel" />
|
||||
</button>
|
||||
<la:form action="/admin/plugin/" styleClass="form-horizontal">
|
||||
<input type="hidden" name="name" value="${f:h(artifact.name)}">
|
||||
<input type="hidden" name="version" value="${f:h(artifact.version)}">
|
||||
<button type="submit" class="btn btn-outline btn-danger" name="delete"
|
||||
value="<la:message key="labels.crud_button_delete" />"
|
||||
>
|
||||
<em class="fa fa-trash"></em>
|
||||
<la:message key="labels.crud_button_delete" />
|
||||
</button>
|
||||
</la:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.data-wrapper -->
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<%-- Message --%>
|
||||
<div>
|
||||
<la:info id="msg" message="true">
|
||||
<div class="alert alert-info">${msg}</div>
|
||||
</la:info>
|
||||
<la:errors />
|
||||
</div>
|
||||
<%-- List --%>
|
||||
<div class="data-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<table class="table table-bordered table-striped dataTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><la:message key="labels.plugin_type" /></th>
|
||||
<th><la:message key="labels.plugin_name" /></th>
|
||||
<th><la:message key="labels.plugin_version" /></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<c:forEach var="artifact" varStatus="s"
|
||||
items="${installedArtifactItems}">
|
||||
<tr>
|
||||
<td>${f:h(artifact.type)}</td>
|
||||
<td>${f:h(artifact.name)}</td>
|
||||
<td>${f:h(artifact.version)}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger btn-xs" name="delete"
|
||||
data-toggle="modal" data-target='#confirmToDelete-${f:h(artifact.name)}-${f:h(artifact.version).replace(".", "\\.")}'
|
||||
value="<la:message key="labels.design_delete_button" />">
|
||||
<em class="fa fa-trash"></em>
|
||||
<la:message key="labels.design_delete_button" />
|
||||
</button>
|
||||
<div class="modal modal-danger fade" id='confirmToDelete-${f:h(artifact.name)}-${f:h(artifact.version)}'
|
||||
tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title">
|
||||
<la:message key="labels.crud_title_delete" />
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
<la:message key="labels.crud_delete_confirmation" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline pull-left"
|
||||
data-dismiss="modal">
|
||||
<la:message key="labels.crud_button_cancel" />
|
||||
</button>
|
||||
<la:form action="/admin/plugin/" styleClass="form-horizontal">
|
||||
<input type="hidden" name="name" value="${f:h(artifact.name)}">
|
||||
<input type="hidden" name="version" value="${f:h(artifact.version)}">
|
||||
<button type="submit" class="btn btn-outline btn-danger"
|
||||
name="delete"
|
||||
value="<la:message key="labels.crud_button_delete" />">
|
||||
<em class="fa fa-trash"></em>
|
||||
<la:message key="labels.crud_button_delete" />
|
||||
</button>
|
||||
</la:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.data-wrapper -->
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/footer.jsp"></jsp:include>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/foot.jsp"></jsp:include>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/footer.jsp"></jsp:include>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/foot.jsp"></jsp:include>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -1,77 +1,97 @@
|
|||
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><la:message key="labels.admin_brand_title" /> | <la:message
|
||||
key="labels.plugin_install_title" /></title>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
|
||||
<meta charset="UTF-8">
|
||||
<title><la:message key="labels.admin_brand_title" /> | <la:message key="labels.plugin_install_title" /></title>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
|
||||
</head>
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<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="system" />
|
||||
<jsp:param name="menuType" value="plugin" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
<la:message key="labels.plugin_install_title" />
|
||||
</h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<la:info id="msg" message="true">
|
||||
<div class="alert alert-info">${msg}</div>
|
||||
</la:info>
|
||||
<la:errors property="_global" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-primary">
|
||||
<la:form action="/admin/plugin/">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<la:message key="labels.plugin_install" />
|
||||
</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<la:errors property="selectedArtifact" />
|
||||
<la:select styleId="artifacts" property="id" styleClass="form-control">
|
||||
<c:forEach var="item" varStatus="s"
|
||||
items="${availableArtifactItems}">
|
||||
<la:option value="${f:h(item.id)}">${f:h(item.name)}-${f:h(item.version)}</la:option>
|
||||
</c:forEach>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-default"
|
||||
name="back"
|
||||
value="<la:message key="labels.crud_button_back" />">
|
||||
<em class="fa fa-arrow-circle-left"></em>
|
||||
<la:message key="labels.crud_button_back" />
|
||||
</button>
|
||||
<button type="submit" class="btn btn-warning"
|
||||
name="install"
|
||||
value="<la:message key="labels.crud_button_install" />">
|
||||
<em class="fa fa-plus"></em>
|
||||
<la:message key="labels.crud_button_install" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- /.box-footer -->
|
||||
</la:form>
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/footer.jsp"></jsp:include>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/foot.jsp"></jsp:include>
|
||||
<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="system" />
|
||||
<jsp:param name="menuType" value="plugin" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
<la:message key="labels.plugin_install_title" />
|
||||
</h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<la:info id="msg" message="true">
|
||||
<div class="alert alert-info">${msg}</div>
|
||||
</la:info>
|
||||
<la:errors property="_global" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-primary">
|
||||
<la:form action="/admin/plugin/install" enctype="multipart/form-data">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<la:message key="labels.plugin_install" />
|
||||
</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#remote" aria-controls="remote" role="tab"
|
||||
data-toggle="tab"
|
||||
><la:message key="labels.plugin_remote_install" /></a></li>
|
||||
<li role="presentation"><a href="#local" aria-controls="local" role="tab" data-toggle="tab"><la:message
|
||||
key="labels.plugin_local_install"
|
||||
/></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="remote">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<la:errors property="selectedArtifact" />
|
||||
<la:select styleId="artifacts" property="id" styleClass="form-control">
|
||||
<c:forEach var="item" varStatus="s" items="${availableArtifactItems}">
|
||||
<la:option value="${f:h(item.id)}">${f:h(item.name)}-${f:h(item.version)}</la:option>
|
||||
</c:forEach>
|
||||
</la:select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="local">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-md-2 control-label"><la:message key="labels.plugin_jar_file" /></label>
|
||||
<div>
|
||||
<input type="file" name="jarFile" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-default" name="back" value="<la:message key="labels.crud_button_back" />">
|
||||
<em class="fa fa-arrow-circle-left"></em>
|
||||
<la:message key="labels.crud_button_back" />
|
||||
</button>
|
||||
<button type="submit" class="btn btn-warning" name="install"
|
||||
value="<la:message key="labels.crud_button_install" />"
|
||||
>
|
||||
<em class="fa fa-plus"></em>
|
||||
<la:message key="labels.crud_button_install" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- /.box-footer -->
|
||||
</la:form>
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/footer.jsp"></jsp:include>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/foot.jsp"></jsp:include>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Reference in a new issue