fix #2657 tag support
This commit is contained in:
parent
029fefa48e
commit
27e51af84e
15 changed files with 390 additions and 58 deletions
|
@ -21,6 +21,7 @@ import java.io.InputStream;
|
|||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -45,12 +46,14 @@ import org.lastaflute.web.ruts.process.ActionRuntime;
|
|||
import org.lastaflute.web.servlet.request.stream.WrittenStreamOut;
|
||||
|
||||
import io.minio.GetObjectArgs;
|
||||
import io.minio.GetObjectTagsArgs;
|
||||
import io.minio.ListObjectsArgs;
|
||||
import io.minio.MakeBucketArgs;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.PutObjectArgs;
|
||||
import io.minio.RemoveObjectArgs;
|
||||
import io.minio.Result;
|
||||
import io.minio.SetObjectTagsArgs;
|
||||
import io.minio.errors.ErrorResponseException;
|
||||
import io.minio.messages.Item;
|
||||
|
||||
|
@ -85,10 +88,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
@Secured({ ROLE, ROLE + VIEW })
|
||||
public ActionResponse list(final OptionalThing<String> id) {
|
||||
saveToken();
|
||||
if (id.isPresent() && id.get() != null) {
|
||||
return asListHtml(decodePath(id.get()));
|
||||
}
|
||||
return redirect(getClass());
|
||||
return id.filter(StringUtil::isNotBlank).map(s -> asListHtml(decodePath(s))).orElse(redirect(getClass()));
|
||||
}
|
||||
|
||||
@Execute
|
||||
|
@ -116,12 +116,12 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
@Execute
|
||||
@Secured({ ROLE, ROLE + VIEW })
|
||||
public ActionResponse download(final String id) {
|
||||
final String[] values = decodeId(id);
|
||||
if (StringUtil.isEmpty(values[1])) {
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileNotFound(GLOBAL), () -> asListHtml(encodeId(values[0])));
|
||||
final PathInfo pi = convertToItem(id);
|
||||
if (StringUtil.isEmpty(pi.getName())) {
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileNotFound(GLOBAL), () -> asListHtml(encodeId(pi.getPath())));
|
||||
}
|
||||
final StreamResponse response = new StreamResponse(StringUtil.EMPTY);
|
||||
final String name = values[1];
|
||||
final String name = pi.getName();
|
||||
final String encodedName = URLEncoder.encode(name, Constants.UTF_8_CHARSET).replace("+", "%20");
|
||||
response.header("Content-Disposition", "attachment; filename=\"" + name + "\"; filename*=utf-8''" + encodedName);
|
||||
response.header("Pragma", "no-cache");
|
||||
|
@ -130,13 +130,13 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
response.contentTypeOctetStream();
|
||||
return response.stream(out -> {
|
||||
try {
|
||||
downloadObject(getObjectName(values[0], values[1]), out);
|
||||
downloadObject(getObjectName(pi.getPath(), pi.getName()), out);
|
||||
} catch (final StorageException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to download {}", values[1], e);
|
||||
logger.debug("Failed to download {}", pi.getName(), e);
|
||||
}
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileDownloadFailure(GLOBAL, values[1]),
|
||||
() -> asListHtml(encodeId(values[0])));
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileDownloadFailure(GLOBAL, pi.getName()),
|
||||
() -> asListHtml(encodeId(pi.getPath())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -144,20 +144,20 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
@Execute
|
||||
@Secured({ ROLE })
|
||||
public HtmlResponse delete(final String id) {
|
||||
final String[] values = decodeId(id);
|
||||
if (StringUtil.isEmpty(values[1])) {
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileNotFound(GLOBAL), () -> asListHtml(encodeId(values[0])));
|
||||
final PathInfo pi = convertToItem(id);
|
||||
if (StringUtil.isEmpty(pi.getName())) {
|
||||
throwValidationError(messages -> messages.addErrorsStorageFileNotFound(GLOBAL), () -> asListHtml(encodeId(pi.getPath())));
|
||||
}
|
||||
final String objectName = getObjectName(values[0], values[1]);
|
||||
final String objectName = getObjectName(pi.getPath(), pi.getName());
|
||||
try {
|
||||
deleteObject(objectName);
|
||||
} catch (final StorageException e) {
|
||||
logger.debug("Failed to delete {}", values[1], e);
|
||||
throwValidationError(messages -> messages.addErrorsFailedToDeleteFile(GLOBAL, values[1]),
|
||||
() -> asListHtml(encodeId(values[0])));
|
||||
logger.debug("Failed to delete {}", pi.getName(), e);
|
||||
throwValidationError(messages -> messages.addErrorsFailedToDeleteFile(GLOBAL, pi.getName()),
|
||||
() -> asListHtml(encodeId(pi.getPath())));
|
||||
}
|
||||
saveInfo(messages -> messages.addSuccessDeleteFile(GLOBAL, values[1]));
|
||||
return redirectWith(getClass(), moreUrl("list/" + encodeId(values[0])));
|
||||
saveInfo(messages -> messages.addSuccessDeleteFile(GLOBAL, pi.getName()));
|
||||
return redirectWith(getClass(), moreUrl("list/" + encodeId(pi.getPath())));
|
||||
}
|
||||
|
||||
@Execute
|
||||
|
@ -170,6 +170,62 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
return redirectWith(getClass(), moreUrl("list/" + encodeId(getObjectName(form.path, form.name))));
|
||||
}
|
||||
|
||||
@Execute
|
||||
@Secured({ ROLE })
|
||||
public HtmlResponse editTags(final TagForm form) {
|
||||
validate(form, messages -> {}, () -> asEditTagsHtml(form.path, form.name));
|
||||
saveToken();
|
||||
return asEditTagsHtml(form.path, form.name);
|
||||
}
|
||||
|
||||
@Execute
|
||||
@Secured({ ROLE })
|
||||
public HtmlResponse updateTags(final TagForm form) {
|
||||
validate(form, messages -> {}, () -> asEditTagsHtml(form.path, form.name));
|
||||
final String objectName = getObjectName(form.path, form.name);
|
||||
try {
|
||||
updateObjectTags(objectName, form.tags);
|
||||
} catch (final StorageException e) {
|
||||
logger.debug("Failed to update tags in {}", form.path, e);
|
||||
throwValidationError(messages -> messages.addErrorsStorageTagsUpdateFailure(GLOBAL, objectName),
|
||||
() -> asEditTagsHtml(form.path, form.name));
|
||||
}
|
||||
saveInfo(messages -> messages.addSuccessUpdateStorageTags(GLOBAL, objectName));
|
||||
return redirectWith(getClass(), moreUrl("list/" + encodeId(form.path)));
|
||||
}
|
||||
|
||||
public static void updateObjectTags(final String objectName, final Map<String, String> tagItems) {
|
||||
final Map<String, String> tags = new HashMap<>();
|
||||
tagItems.keySet().stream().filter(s -> s.startsWith("name")).forEach(nameKey -> {
|
||||
final String valueKey = nameKey.replace("name", "value");
|
||||
final String name = tagItems.get(nameKey);
|
||||
if (StringUtil.isNotBlank(name)) {
|
||||
tags.put(name, tagItems.get(valueKey));
|
||||
}
|
||||
});
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("tags: {} -> {}", tagItems, tags);
|
||||
}
|
||||
try {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final SetObjectTagsArgs args =
|
||||
SetObjectTagsArgs.builder().bucket(fessConfig.getStorageBucket()).object(objectName).tags(tags).build();
|
||||
createClient(fessConfig).setObjectTags(args);
|
||||
} catch (final Exception e) {
|
||||
throw new StorageException("Failed to update tags for " + objectName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getObjectTags(final String objectName) {
|
||||
try {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final GetObjectTagsArgs args = GetObjectTagsArgs.builder().bucket(fessConfig.getStorageBucket()).object(objectName).build();
|
||||
return createClient(fessConfig).getObjectTags(args).get();
|
||||
} catch (final Exception e) {
|
||||
throw new StorageException("Failed to get tags from " + objectName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void uploadObject(final String objectName, final MultipartFormFile uploadFile) {
|
||||
try (final InputStream in = uploadFile.getInputStream()) {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
|
@ -214,7 +270,8 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
|
||||
public static List<Map<String, Object>> getFileItems(final String prefix) {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final ArrayList<Map<String, Object>> list = new ArrayList<>();
|
||||
final List<Map<String, Object>> list = new ArrayList<>();
|
||||
final List<Map<String, Object>> fileList = new ArrayList<>();
|
||||
try {
|
||||
final MinioClient minioClient = createClient(fessConfig);
|
||||
final ListObjectsArgs args = ListObjectsArgs.builder().bucket(fessConfig.getStorageBucket())
|
||||
|
@ -225,15 +282,18 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
final Item item = result.get();
|
||||
final String objectName = item.objectName();
|
||||
map.put("id", encodeId(objectName));
|
||||
map.put("path", prefix);
|
||||
map.put("name", getName(objectName));
|
||||
map.put("hashCode", item.hashCode());
|
||||
map.put("size", item.size());
|
||||
map.put("directory", item.isDir());
|
||||
if (!item.isDir()) {
|
||||
map.put("lastModified", item.lastModified());
|
||||
fileList.add(map);
|
||||
} else {
|
||||
list.add(map);
|
||||
}
|
||||
list.add(map);
|
||||
if (list.size() > fessConfig.getStorageMaxItemsInPageAsInteger()) {
|
||||
if (list.size() + fileList.size() > fessConfig.getStorageMaxItemsInPageAsInteger()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +316,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
logger.debug("Failed to access {}", fessConfig.getStorageEndpoint(), e);
|
||||
}
|
||||
}
|
||||
list.addAll(fileList);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -268,25 +329,25 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
}
|
||||
|
||||
public static String decodePath(final String id) {
|
||||
final String[] values = decodeId(id);
|
||||
if (StringUtil.isEmpty(values[0]) && StringUtil.isEmpty(values[1])) {
|
||||
final PathInfo pi = convertToItem(id);
|
||||
if (StringUtil.isEmpty(pi.getPath()) && StringUtil.isEmpty(pi.getName())) {
|
||||
return StringUtil.EMPTY;
|
||||
}
|
||||
if (StringUtil.isEmpty(values[0])) {
|
||||
return values[1];
|
||||
if (StringUtil.isEmpty(pi.getPath())) {
|
||||
return pi.getName();
|
||||
}
|
||||
return values[0] + "/" + values[1];
|
||||
return pi.getPath() + "/" + pi.getName();
|
||||
}
|
||||
|
||||
public static String[] decodeId(final String id) {
|
||||
final String value = urlDecode(urlDecode(id));
|
||||
public static PathInfo convertToItem(final String id) {
|
||||
final String value = decodeId(id);
|
||||
final String[] values = split(value, "/").get(stream -> stream.filter(StringUtil::isNotEmpty).toArray(n -> new String[n]));
|
||||
if (values.length == 0) {
|
||||
// invalid?
|
||||
return new String[] { StringUtil.EMPTY, StringUtil.EMPTY };
|
||||
return new PathInfo(StringUtil.EMPTY, StringUtil.EMPTY);
|
||||
}
|
||||
if (values.length == 1) {
|
||||
return new String[] { StringUtil.EMPTY, values[0] };
|
||||
return new PathInfo(StringUtil.EMPTY, values[0]);
|
||||
}
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0; i < values.length - 1; i++) {
|
||||
|
@ -295,7 +356,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
}
|
||||
buf.append(values[i]);
|
||||
}
|
||||
return new String[] { buf.toString(), values[values.length - 1] };
|
||||
return new PathInfo(buf.toString(), values[values.length - 1]);
|
||||
}
|
||||
|
||||
protected static String createParentId(final String prefix) {
|
||||
|
@ -311,7 +372,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
}
|
||||
buf.append(values[i]);
|
||||
}
|
||||
return urlEncode(buf.toString());
|
||||
return encodeId(buf.toString());
|
||||
}
|
||||
return StringUtil.EMPTY;
|
||||
}
|
||||
|
@ -325,7 +386,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
}
|
||||
buf.append(s);
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
map.put("id", urlEncode(buf.toString()));
|
||||
map.put("id", encodeId(buf.toString()));
|
||||
map.put("name", s);
|
||||
list.add(map);
|
||||
}));
|
||||
|
@ -340,6 +401,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
return getPathPrefix(path) + name;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected static String urlEncode(final String str) {
|
||||
if (str == null) {
|
||||
return StringUtil.EMPTY;
|
||||
|
@ -347,6 +409,7 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
return URLEncoder.encode(str, Constants.UTF_8_CHARSET);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected static String urlDecode(final String str) {
|
||||
if (str == null) {
|
||||
return StringUtil.EMPTY;
|
||||
|
@ -355,18 +418,63 @@ public class AdminStorageAction extends FessAdminAction {
|
|||
}
|
||||
|
||||
protected static String encodeId(final String objectName) {
|
||||
return urlEncode(urlEncode(objectName));
|
||||
if (objectName == null) {
|
||||
return StringUtil.EMPTY;
|
||||
}
|
||||
return new String(Base64.getUrlEncoder().encode(objectName.getBytes(Constants.UTF_8_CHARSET)), Constants.UTF_8_CHARSET);
|
||||
}
|
||||
|
||||
private HtmlResponse asListHtml(final String prefix) {
|
||||
protected static String decodeId(final String id) {
|
||||
if (id == null) {
|
||||
return StringUtil.EMPTY;
|
||||
}
|
||||
return new String(Base64.getUrlDecoder().decode(id.getBytes(Constants.UTF_8_CHARSET)), Constants.UTF_8_CHARSET);
|
||||
}
|
||||
|
||||
private HtmlResponse asListHtml(final String path) {
|
||||
return asHtml(path_AdminStorage_AdminStorageJsp).useForm(ItemForm.class).renderWith(data -> {
|
||||
RenderDataUtil.register(data, "endpoint", fessConfig.getStorageEndpoint());
|
||||
RenderDataUtil.register(data, "bucket", fessConfig.getStorageBucket());
|
||||
RenderDataUtil.register(data, "path", prefix);
|
||||
RenderDataUtil.register(data, "pathItems", createPathItems(prefix));
|
||||
RenderDataUtil.register(data, "parentId", createParentId(prefix));
|
||||
RenderDataUtil.register(data, "fileItems", getFileItems(prefix));
|
||||
RenderDataUtil.register(data, "path", path);
|
||||
RenderDataUtil.register(data, "pathItems", createPathItems(path));
|
||||
RenderDataUtil.register(data, "parentId", createParentId(path));
|
||||
RenderDataUtil.register(data, "fileItems", getFileItems(path));
|
||||
});
|
||||
}
|
||||
|
||||
private HtmlResponse asEditTagsHtml(final String path, final String name) {
|
||||
return asHtml(path_AdminStorage_AdminStorageTagEditJsp).renderWith(data -> {
|
||||
RenderDataUtil.register(data, "endpoint", fessConfig.getStorageEndpoint());
|
||||
RenderDataUtil.register(data, "bucket", fessConfig.getStorageBucket());
|
||||
RenderDataUtil.register(data, "pathItems", createPathItems(path));
|
||||
RenderDataUtil.register(data, "parentId", encodeId(path));
|
||||
RenderDataUtil.register(data, "path", path);
|
||||
RenderDataUtil.register(data, "name", name);
|
||||
final Map<String, String> tags = new HashMap<>();
|
||||
getObjectTags(getObjectName(path, name)).entrySet().forEach(e -> {
|
||||
int index = tags.size() / 2 + 1;
|
||||
tags.put("name" + index, e.getKey());
|
||||
tags.put("value" + index, e.getValue());
|
||||
});
|
||||
RenderDataUtil.register(data, "savedTags", tags);
|
||||
});
|
||||
}
|
||||
|
||||
public static class PathInfo {
|
||||
private final String path;
|
||||
private final String name;
|
||||
|
||||
public PathInfo(final String path, final String name) {
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2012-2022 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.storage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
|
||||
|
||||
public class TagForm {
|
||||
|
||||
@Required
|
||||
public String path;
|
||||
|
||||
@Required
|
||||
@Size(max = 100)
|
||||
public String name;
|
||||
|
||||
public Map<String, String> tags = new HashMap<>();
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package org.codelibs.fess.app.web.api.admin.storage;
|
||||
|
||||
import static org.codelibs.fess.app.web.admin.storage.AdminStorageAction.decodeId;
|
||||
import static org.codelibs.fess.app.web.admin.storage.AdminStorageAction.convertToItem;
|
||||
import static org.codelibs.fess.app.web.admin.storage.AdminStorageAction.decodePath;
|
||||
import static org.codelibs.fess.app.web.admin.storage.AdminStorageAction.deleteObject;
|
||||
import static org.codelibs.fess.app.web.admin.storage.AdminStorageAction.downloadObject;
|
||||
|
@ -29,6 +29,7 @@ import java.util.Map;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.app.web.admin.storage.AdminStorageAction.PathInfo;
|
||||
import org.codelibs.fess.app.web.api.ApiResult;
|
||||
import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
|
||||
import org.codelibs.fess.exception.ResultOffsetExceededException;
|
||||
|
@ -62,18 +63,18 @@ public class ApiAdminStorageAction extends FessApiAdminAction {
|
|||
// GET /api/admin/storage/download/{id}/
|
||||
@Execute
|
||||
public StreamResponse get$download(final String id) {
|
||||
final String[] values = decodeId(id);
|
||||
if (StringUtil.isEmpty(values[1])) {
|
||||
final PathInfo pi = convertToItem(id);
|
||||
if (StringUtil.isEmpty(pi.getName())) {
|
||||
throwValidationErrorApi(messages -> messages.addErrorsStorageFileNotFound(GLOBAL));
|
||||
}
|
||||
return asStream(values[1]).contentTypeOctetStream().stream(out -> {
|
||||
return asStream(pi.getName()).contentTypeOctetStream().stream(out -> {
|
||||
try {
|
||||
downloadObject(getObjectName(values[0], values[1]), out);
|
||||
downloadObject(getObjectName(pi.getPath(), pi.getName()), out);
|
||||
} catch (final StorageException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to download {}", id, e);
|
||||
}
|
||||
throwValidationErrorApi(messages -> messages.addErrorsStorageFileDownloadFailure(GLOBAL, values[1]));
|
||||
throwValidationErrorApi(messages -> messages.addErrorsStorageFileDownloadFailure(GLOBAL, pi.getName()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -81,20 +82,20 @@ public class ApiAdminStorageAction extends FessApiAdminAction {
|
|||
// DELETE /api/admin/storage/delete/{id}/
|
||||
@Execute
|
||||
public JsonResponse<ApiResult> delete$delete(final String id) {
|
||||
final String[] values = decodeId(id);
|
||||
if (StringUtil.isEmpty(values[1])) {
|
||||
final PathInfo pi = convertToItem(id);
|
||||
if (StringUtil.isEmpty(pi.getName())) {
|
||||
throwValidationErrorApi(messages -> messages.addErrorsStorageAccessError(GLOBAL, "id is invalid"));
|
||||
}
|
||||
final String objectName = getObjectName(values[0], values[1]);
|
||||
final String objectName = getObjectName(pi.getPath(), pi.getName());
|
||||
try {
|
||||
deleteObject(objectName);
|
||||
saveInfo(messages -> messages.addSuccessDeleteFile(GLOBAL, values[1]));
|
||||
saveInfo(messages -> messages.addSuccessDeleteFile(GLOBAL, pi.getName()));
|
||||
return asJson(new ApiResult.ApiResponse().status(ApiResult.Status.OK).result());
|
||||
} catch (final StorageException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to delete {}", id, e);
|
||||
}
|
||||
throwValidationErrorApi(messages -> messages.addErrorsFailedToDeleteFile(GLOBAL, values[1]));
|
||||
throwValidationErrorApi(messages -> messages.addErrorsFailedToDeleteFile(GLOBAL, pi.getName()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -355,6 +355,9 @@ public interface FessHtmlPath {
|
|||
/** The path of the HTML: /admin/storage/admin_storage.jsp */
|
||||
HtmlNext path_AdminStorage_AdminStorageJsp = new HtmlNext("/admin/storage/admin_storage.jsp");
|
||||
|
||||
/** The path of the HTML: /admin/storage/admin_storage_tag_edit.jsp */
|
||||
HtmlNext path_AdminStorage_AdminStorageTagEditJsp = new HtmlNext("/admin/storage/admin_storage_tag_edit.jsp");
|
||||
|
||||
/** The path of the HTML: /admin/suggest/admin_suggest.jsp */
|
||||
HtmlNext path_AdminSuggest_AdminSuggestJsp = new HtmlNext("/admin/suggest/admin_suggest.jsp");
|
||||
|
||||
|
|
|
@ -3162,6 +3162,18 @@ public class FessLabels extends UserMessages {
|
|||
/** The key of the message: Download */
|
||||
public static final String LABELS_storage_button_download = "{labels.storage_button_download}";
|
||||
|
||||
/** The key of the message: Tags */
|
||||
public static final String LABELS_storage_button_tags = "{labels.storage_button_tags}";
|
||||
|
||||
/** The key of the message: Tag: */
|
||||
public static final String LABELS_storage_title_tag = "{labels.storage_title_tag}";
|
||||
|
||||
/** The key of the message: Tag Key */
|
||||
public static final String LABELS_storage_tag_key = "{labels.storage_tag_key}";
|
||||
|
||||
/** The key of the message: Tag Value */
|
||||
public static final String LABELS_storage_tag_value = "{labels.storage_tag_value}";
|
||||
|
||||
/** The key of the message: Your password needs to be updated. */
|
||||
public static final String LABELS_LOGIN_NEWPASSWORD = "{labels.login.newpassword}";
|
||||
|
||||
|
|
|
@ -434,6 +434,9 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: Directory name is invalid. */
|
||||
public static final String ERRORS_storage_directory_name_is_invalid = "{errors.storage_directory_name_is_invalid}";
|
||||
|
||||
/** The key of the message: Failed to update tags for {0} */
|
||||
public static final String ERRORS_storage_tags_update_failure = "{errors.storage_tags_update_failure}";
|
||||
|
||||
/** The key of the message: Updated parameters. */
|
||||
public static final String SUCCESS_update_crawler_params = "{success.update_crawler_params}";
|
||||
|
||||
|
@ -524,6 +527,9 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: Logged out. */
|
||||
public static final String SUCCESS_sso_logout = "{success.sso_logout}";
|
||||
|
||||
/** The key of the message: Updated tags for {0}. */
|
||||
public static final String SUCCESS_update_storage_tags = "{success.update_storage_tags}";
|
||||
|
||||
/** The key of the message: Created data. */
|
||||
public static final String SUCCESS_crud_create_crud_table = "{success.crud_create_crud_table}";
|
||||
|
||||
|
@ -2506,6 +2512,21 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.storage_tags_update_failure' with parameters.
|
||||
* <pre>
|
||||
* message: Failed to update tags for {0}
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsStorageTagsUpdateFailure(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(ERRORS_storage_tags_update_failure, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.update_crawler_params' with parameters.
|
||||
* <pre>
|
||||
|
@ -2935,6 +2956,21 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.update_storage_tags' with parameters.
|
||||
* <pre>
|
||||
* message: Updated tags for {0}.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addSuccessUpdateStorageTags(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new UserMessage(SUCCESS_update_storage_tags, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'success.crud_create_crud_table' with parameters.
|
||||
* <pre>
|
||||
|
|
|
@ -1076,7 +1076,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
/** The key of the configuration. e.g. true */
|
||||
String SMB_ROLE_FROM_FILE = "smb.role.from.file";
|
||||
|
||||
/** The key of the configuration. e.g. 1,2,4:2 */
|
||||
/** The key of the configuration. e.g. 1,2,4:2,5:1 */
|
||||
String SMB_AVAILABLE_SID_TYPES = "smb.available.sid.types";
|
||||
|
||||
/** The key of the configuration. e.g. true */
|
||||
|
@ -5011,7 +5011,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
|
||||
/**
|
||||
* Get the value for the key 'smb.available.sid.types'. <br>
|
||||
* The value is, e.g. 1,2,4:2 <br>
|
||||
* The value is, e.g. 1,2,4:2,5:1 <br>
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getSmbAvailableSidTypes();
|
||||
|
@ -10449,7 +10449,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
defaultMap.put(FessConfig.QUERY_FACET_QUERIES,
|
||||
"labels.facet_timestamp_title:labels.facet_timestamp_1day=timestamp:[now/d-1d TO *]\tlabels.facet_timestamp_1week=timestamp:[now/d-7d TO *]\tlabels.facet_timestamp_1month=timestamp:[now/d-1M TO *]\tlabels.facet_timestamp_1year=timestamp:[now/d-1y TO *]\nlabels.facet_contentLength_title:labels.facet_contentLength_10k=content_length:[0 TO 9999]\tlabels.facet_contentLength_10kto100k=content_length:[10000 TO 99999]\tlabels.facet_contentLength_100kto500k=content_length:[100000 TO 499999]\tlabels.facet_contentLength_500kto1m=content_length:[500000 TO 999999]\tlabels.facet_contentLength_1m=content_length:[1000000 TO *]\nlabels.facet_filetype_title:labels.facet_filetype_html=filetype:html\tlabels.facet_filetype_word=filetype:word\tlabels.facet_filetype_excel=filetype:excel\tlabels.facet_filetype_powerpoint=filetype:powerpoint\tlabels.facet_filetype_odt=filetype:odt\tlabels.facet_filetype_ods=filetype:ods\tlabels.facet_filetype_odp=filetype:odp\tlabels.facet_filetype_pdf=filetype:pdf\tlabels.facet_filetype_txt=filetype:txt\tlabels.facet_filetype_others=filetype:others\n");
|
||||
defaultMap.put(FessConfig.SMB_ROLE_FROM_FILE, "true");
|
||||
defaultMap.put(FessConfig.SMB_AVAILABLE_SID_TYPES, "1,2,4:2");
|
||||
defaultMap.put(FessConfig.SMB_AVAILABLE_SID_TYPES, "1,2,4:2,5:1");
|
||||
defaultMap.put(FessConfig.FILE_ROLE_FROM_FILE, "true");
|
||||
defaultMap.put(FessConfig.FTP_ROLE_FROM_FILE, "true");
|
||||
defaultMap.put(FessConfig.INDEX_BACKUP_TARGETS,
|
||||
|
|
|
@ -1045,6 +1045,10 @@ labels.storage_bucket_name=Bucket Name
|
|||
labels.storage_file=File
|
||||
labels.storage_folder_name=Folder Name
|
||||
labels.storage_button_download=Download
|
||||
labels.storage_button_tags=Tags
|
||||
labels.storage_title_tag=Tag:
|
||||
labels.storage_tag_key=Tag Key
|
||||
labels.storage_tag_value=Tag Value
|
||||
labels.login.newpassword=Your password needs to be updated.
|
||||
labels.login.placeholder_new_password=New Password
|
||||
labels.login.placeholder_confirm_new_password=Confirm New Password
|
||||
|
|
|
@ -1045,6 +1045,10 @@ labels.storage_bucket_name=Bucket Name
|
|||
labels.storage_file=File
|
||||
labels.storage_folder_name=Folder Name
|
||||
labels.storage_button_download=Download
|
||||
labels.storage_button_tags=Tags
|
||||
labels.storage_title_tag=Tag:
|
||||
labels.storage_tag_key=Tag Key
|
||||
labels.storage_tag_value=Tag Value
|
||||
labels.login.newpassword=Your password needs to be updated.
|
||||
labels.login.placeholder_new_password=New Password
|
||||
labels.login.placeholder_confirm_new_password=Confirm New Password
|
||||
|
|
|
@ -1045,6 +1045,10 @@ labels.storage_bucket_name=バケット名
|
|||
labels.storage_file=ファイル
|
||||
labels.storage_folder_name=フォルダ名
|
||||
labels.storage_button_download=ダウンロード
|
||||
labels.storage_button_tags=タグ
|
||||
labels.storage_title_tag=タグ:
|
||||
labels.storage_tag_key=タグキー
|
||||
labels.storage_tag_value=タグ値
|
||||
labels.login.newpassword=パスワードを更新する必要があります
|
||||
labels.login.placeholder_new_password=新しいパスワード
|
||||
labels.login.placeholder_confirm_new_password=新しいパスワードの確認
|
||||
|
|
|
@ -170,6 +170,7 @@ errors.storage_file_download_failure=Failed to download {0}.
|
|||
errors.storage_access_error=Storage access error: {0}
|
||||
errors.storage_no_upload_file=Upload file is required.
|
||||
errors.storage_directory_name_is_invalid=Directory name is invalid.
|
||||
errors.storage_tags_update_failure=Failed to update tags for {0}
|
||||
|
||||
success.update_crawler_params=Updated parameters.
|
||||
success.delete_doc_from_index=Started a process to delete the document from index.
|
||||
|
@ -201,6 +202,7 @@ success.install_plugin=Installing {0} plugin.
|
|||
success.delete_plugin=Deleting {0} plugin.
|
||||
success.upload_file_to_storage=Uploaded {0}
|
||||
success.sso_logout=Logged out.
|
||||
success.update_storage_tags=Updated tags for {0}.
|
||||
|
||||
success.crud_create_crud_table=Created data.
|
||||
success.crud_update_crud_table=Updated data.
|
||||
|
|
|
@ -166,6 +166,7 @@ errors.storage_file_download_failure=Failed to download {0}.
|
|||
errors.storage_access_error=Storage access error: {0}
|
||||
errors.storage_no_upload_file=Upload file is required.
|
||||
errors.storage_directory_name_is_invalid=Directory name is invalid.
|
||||
errors.storage_tags_update_failure=Failed to update tags for {0}
|
||||
|
||||
success.update_crawler_params=Updated parameters.
|
||||
success.delete_doc_from_index=Started a process to delete the document from index.
|
||||
|
@ -197,6 +198,7 @@ success.install_plugin=Installing {0} plugin.
|
|||
success.delete_plugin=Deleting {0} plugin.
|
||||
success.upload_file_to_storage=Uploaded {0}
|
||||
success.sso_logout=Logged out.
|
||||
success.update_storage_tags=Updated tags for {0}.
|
||||
|
||||
success.crud_create_crud_table=Created data.
|
||||
success.crud_update_crud_table=Updated data.
|
||||
|
|
|
@ -159,6 +159,7 @@ errors.storage_file_download_failure={0} のダウンロードに失敗しまし
|
|||
errors.storage_access_error=ストレージアクセスエラー: {0}
|
||||
errors.storage_no_upload_file=アップロードするファイルを指定してください。
|
||||
errors.storage_directory_name_is_invalid=ディレクトリ名が正しくありません。
|
||||
errors.storage_tags_update_failure={0}のタグの更新に失敗しました。
|
||||
|
||||
success.update_crawler_params = パラメータを更新しました。
|
||||
success.delete_doc_from_index = インデックスから文書を削除するプロセスを開始しました。
|
||||
|
@ -190,6 +191,7 @@ success.install_plugin=プラグイン {0} をインストールしています
|
|||
success.delete_plugin=プラグイン {0} を削除しています。
|
||||
success.upload_file_to_storage={0} をアップロードしました。
|
||||
success.sso_logout=ログアウトしました。
|
||||
success.update_storage_tags={0}のタグを更新しました。
|
||||
|
||||
success.crud_create_crud_table = データを作成しました。
|
||||
success.crud_update_crud_table = データを更新しました。
|
||||
|
|
|
@ -155,7 +155,7 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${not empty path and not empty parentId}">
|
||||
<tr data-href="${contextPath}/admin/storage/list/${f:u(data.parentId)}/">
|
||||
<tr data-href="${contextPath}/admin/storage/list/${f:u(data.parentId)}/">
|
||||
<td>..</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
@ -163,7 +163,7 @@
|
|||
</tr>
|
||||
</c:if>
|
||||
<c:if test="${not empty path and empty parentId}">
|
||||
<tr data-href="${contextPath}/admin/storage/">
|
||||
<tr data-href="${contextPath}/admin/storage/">
|
||||
<td>..</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
@ -199,6 +199,13 @@
|
|||
<la:message key="labels.storage_button_download"/>
|
||||
</a>
|
||||
<c:if test="${editable}">
|
||||
<a class="btn btn-primary btn-xs" role="button" name="editTags"
|
||||
href="${contextPath}/admin/storage/editTags?path=${f:u(data.path)}&name=${f:u(data.name)}"
|
||||
value="<la:message key="labels.storage_button_tags" />"
|
||||
>
|
||||
<em class="fa fa-tags"></em>
|
||||
<la:message key="labels.storage_button_tags"/>
|
||||
</a>
|
||||
<button type="button" class="btn btn-danger btn-xs"
|
||||
name="delete" data-toggle="modal"
|
||||
data-target="#confirmToDelete-${f:h(data.hashCode)}"
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<%@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.storage_configuration" /></title>
|
||||
<jsp:include page="/WEB-INF/view/common/admin/head.jsp"></jsp:include>
|
||||
</head>
|
||||
<body class="hold-transition 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="storage" />
|
||||
</jsp:include>
|
||||
<div class="content-wrapper">
|
||||
<div class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>
|
||||
<la:message key="labels.storage_configuration" />
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><la:link href="/admin/storage/">
|
||||
<la:message key="labels.crud_link_list" />
|
||||
</la:link></li>
|
||||
<li class="breadcrumb-item active"><la:message key="labels.crud_link_edit" /></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="content">
|
||||
<la:form action="/admin/storage/">
|
||||
<input type="hidden" name="path" value="${f:h(path)}">
|
||||
<input type="hidden" name="name" value="${f:h(name)}">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card card-outline card-success">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
<la:message key="labels.storage_title_tag" />
|
||||
<c:if test="${path!=null}">${f:h(path)}/</c:if>${f:h(name)}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<la:info id="msg" message="true">
|
||||
<div class="alert alert-info">${msg}</div>
|
||||
</la:info>
|
||||
<la:errors property="_global" />
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<la:message key="labels.storage_tag_key" />
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<la:message key="labels.storage_tag_value" />
|
||||
</div>
|
||||
</div>
|
||||
<c:forEach var="position" begin="1" end="${savedTags.size()/2}">
|
||||
<c:set var="nameKey">name${position}</c:set>
|
||||
<c:set var="valueKey">value${position}</c:set>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<input type="text" id="tags.${f:h(nameKey)}" name="tags.${f:h(nameKey)}" value="${f:h(savedTags.get(nameKey))}" class="form-control" placeholder="Name" >
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" id="tags.${f:h(valueKey)}" name="tags.${f:h(valueKey)}" value="${f:h(savedTags.get(valueKey))}" class="form-control" placeholder="Value" >
|
||||
</div>
|
||||
</div>
|
||||
</c:forEach>
|
||||
<c:set var="nameKey">name${Double.valueOf(savedTags.size()/2).intValue()+1}</c:set>
|
||||
<c:set var="valueKey">value${Double.valueOf(savedTags.size()/2).intValue()+1}</c:set>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<input type="text" id="tags.${f:h(nameKey)}" name="tags.${f:h(nameKey)}" value="${f:h(savedTags.get(nameKey))}" class="form-control" placeholder="Name" >
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" id="tags.${f:h(valueKey)}" name="tags.${f:h(valueKey)}" value="${f:h(savedTags.get(valueKey))}" class="form-control" placeholder="Value" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<la:link styleClass="btn btn-default" href="list/${parentId}">
|
||||
<em class="fa fa-arrow-circle-left"></em>
|
||||
<la:message key="labels.crud_button_back" />
|
||||
</la:link>
|
||||
<c:if test="${editable}">
|
||||
<button type="submit" class="btn btn-success" name="updateTags"
|
||||
value="<la:message key="labels.crud_button_update" />"
|
||||
>
|
||||
<em class="fa fa-pencil-alt"></em>
|
||||
<la:message key="labels.crud_button_update" />
|
||||
</button>
|
||||
</c:if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</la:form>
|
||||
</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