UI for file assets
parent
c5d3125dcd
commit
a11c98614c
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.librecms.assets.FileAsset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsFileAssetCreateStep")
|
||||||
|
public class FileAssetCreateStep extends AbstractMvcAssetCreateStep<FileAsset> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
private String fileDescription;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String showCreateStep() {
|
||||||
|
return "org/librecms/ui/contentsection/assets/fileasset/create-fileasset.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return globalizationHelper
|
||||||
|
.getLocalizedTextsUtil(getBundle())
|
||||||
|
.getText("fileasset.label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return globalizationHelper
|
||||||
|
.getLocalizedTextsUtil(getBundle())
|
||||||
|
.getText("fileasset.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBundle() {
|
||||||
|
return MvcAssetStepsConstants.BUNDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<FileAsset> getAssetClass() {
|
||||||
|
return FileAsset.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String setAssetProperties(
|
||||||
|
final FileAsset asset, final Map<String, String[]> formParams
|
||||||
|
) {
|
||||||
|
fileDescription = Optional
|
||||||
|
.ofNullable(formParams.get("description"))
|
||||||
|
.filter(value -> value.length > 0)
|
||||||
|
.map(value -> value[0])
|
||||||
|
.orElse("");
|
||||||
|
asset.getDescription().addValue(
|
||||||
|
new Locale(getInitialLocale()), fileDescription
|
||||||
|
);
|
||||||
|
|
||||||
|
assetRepo.save(asset);
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"redirect:/%s/assets/%s/%s/@fileasset-edit",
|
||||||
|
getContentSectionLabel(),
|
||||||
|
getFolderPath(),
|
||||||
|
getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,403 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
|
import org.librecms.assets.FileAsset;
|
||||||
|
import org.librecms.contentsection.AssetRepository;
|
||||||
|
import org.librecms.ui.contentsections.AssetPermissionsChecker;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.activation.MimeType;
|
||||||
|
import javax.activation.MimeTypeParseException;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mvc.Controller;
|
||||||
|
import javax.mvc.Models;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.Part;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path(MvcAssetEditSteps.PATH_PREFIX + "fileasset-edit")
|
||||||
|
@Controller
|
||||||
|
@MvcAssetEditStepDef(
|
||||||
|
bundle = MvcAssetStepsConstants.BUNDLE,
|
||||||
|
descriptionKey = "fileasset.editstep.description",
|
||||||
|
labelKey = "fileasset.editstep.lable",
|
||||||
|
supportedAssetType = FileAsset.class
|
||||||
|
)
|
||||||
|
public class FileAssetEditStep extends AbstractMvcAssetEditStep {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
FileAssetEditStep.class
|
||||||
|
);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetStepsDefaultMessagesBundle messageBundle;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetUi assetUi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetRepository assetRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetPermissionsChecker assetPermissionsChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Models models;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FileAssetEditStepModel editStepModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends MvcAssetEditStep> getStepClass() {
|
||||||
|
return FileAssetEditStep.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() throws ContentSectionNotFoundException,
|
||||||
|
AssetNotFoundException {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
if (getAsset() instanceof FileAsset) {
|
||||||
|
editStepModel.setDescriptionValues(
|
||||||
|
getFileAsset()
|
||||||
|
.getDescription()
|
||||||
|
.getValues()
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.collect(
|
||||||
|
Collectors.toMap(
|
||||||
|
entry -> entry.getKey().toString(),
|
||||||
|
entry -> entry.getValue()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
final Set<Locale> descriptionLocales = getFileAsset()
|
||||||
|
.getDescription()
|
||||||
|
.getAvailableLocales();
|
||||||
|
editStepModel.setUnusedDescriptionLocales(
|
||||||
|
globalizationHelper
|
||||||
|
.getAvailableLocales()
|
||||||
|
.stream()
|
||||||
|
.filter(locale -> !descriptionLocales.contains(locale))
|
||||||
|
.map(Locale::toString)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
|
||||||
|
editStepModel.setFileName(getFileAsset().getFileName());
|
||||||
|
editStepModel.setMimeType(getFileAsset().getMimeType().toString());
|
||||||
|
editStepModel.setSize(getFileAsset().getSize());
|
||||||
|
|
||||||
|
final long size = getFileAsset().getSize();
|
||||||
|
if (size < 2048) {
|
||||||
|
editStepModel.setSizeLabel(String.format("%d Bytes", size));
|
||||||
|
} else if(size < 1024 * 1024) {
|
||||||
|
editStepModel.setSizeLabel(
|
||||||
|
String.format("%d kB", size / 1024)
|
||||||
|
);
|
||||||
|
} else if (size < 1024 * 1024 * 1024){
|
||||||
|
editStepModel.setSizeLabel(
|
||||||
|
String.format("%d MB", size / (1024 * 1024))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
editStepModel.setSizeLabel(
|
||||||
|
String.format("%d GB", size / (1024 * 1024 * 1024))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new AssetNotFoundException(
|
||||||
|
assetUi.showAssetNotFound(
|
||||||
|
getContentSection(), getAssetPath()
|
||||||
|
),
|
||||||
|
String.format(
|
||||||
|
"No asset for path %s found in section %s.",
|
||||||
|
getAssetPath(),
|
||||||
|
getContentSection().getLabel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public String showStep(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
return "org/librecms/ui/contentsection/assets/fileasset/edit-fileasset.xhtml";
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileAsset getFileAsset() {
|
||||||
|
return (FileAsset) getAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/description/add")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String addDescription(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@FormParam("locale") final String localeParam,
|
||||||
|
@FormParam("value") final String value
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
final Locale locale = new Locale(localeParam);
|
||||||
|
final FileAsset bookmark = getFileAsset();
|
||||||
|
bookmark.getDescription().addValue(locale, value);
|
||||||
|
|
||||||
|
assetRepo.save(bookmark);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/description/edit/{locale}")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String editDescription(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@PathParam("locale") final String localeParam,
|
||||||
|
@FormParam("value") final String value
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
final Locale locale = new Locale(localeParam);
|
||||||
|
final FileAsset bookmark = getFileAsset();
|
||||||
|
bookmark.getDescription().addValue(locale, value);
|
||||||
|
|
||||||
|
assetRepo.save(bookmark);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/description/remove/{locale}")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String removeDescription(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@PathParam("locale") final String localeParam
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
final Locale locale = new Locale(localeParam);
|
||||||
|
final FileAsset bookmark = getFileAsset();
|
||||||
|
bookmark.getDescription().removeValue(locale);
|
||||||
|
|
||||||
|
assetRepo.save(bookmark);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/upload")
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@AuthorizationRequired
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String removeDescription(
|
||||||
|
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
|
||||||
|
final String assetPath,
|
||||||
|
@Context final HttpServletRequest request
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (AssetNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetPermissionsChecker.canEditAsset(getAsset())) {
|
||||||
|
final FileAsset fileAsset = getFileAsset();
|
||||||
|
|
||||||
|
final Part part;
|
||||||
|
final String fileName;
|
||||||
|
try {
|
||||||
|
part = request.getPart("file");
|
||||||
|
final String contentDisposition = part.getHeader(
|
||||||
|
"content-disposition"
|
||||||
|
);
|
||||||
|
fileName = Arrays
|
||||||
|
.stream(contentDisposition.split(";"))
|
||||||
|
.filter(field -> field.startsWith("filename"))
|
||||||
|
.findAny()
|
||||||
|
.map(
|
||||||
|
field -> field
|
||||||
|
.substring(field.indexOf('=') + 1)
|
||||||
|
.trim().replace("\"", "")
|
||||||
|
).orElse("");
|
||||||
|
} catch (IOException | ServletException ex) {
|
||||||
|
LOGGER.error(
|
||||||
|
"Failed to upload file for FileAsset {}:", assetPath
|
||||||
|
);
|
||||||
|
LOGGER.error(ex);
|
||||||
|
models.put("uploadFailed", true);
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
final byte[] bytes = new byte[1024];
|
||||||
|
try (InputStream fileInputStream = part.getInputStream();
|
||||||
|
ByteArrayOutputStream fileDataOutputStream
|
||||||
|
= new ByteArrayOutputStream()) {
|
||||||
|
while (fileInputStream.read(bytes) != -1) {
|
||||||
|
fileDataOutputStream.writeBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAsset.setData(fileDataOutputStream.toByteArray());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error(
|
||||||
|
"Failed to upload file for FileAsset {}:", assetPath
|
||||||
|
);
|
||||||
|
LOGGER.error(ex);
|
||||||
|
|
||||||
|
models.put("uploadFailed", true);
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAsset.setFileName(fileName);
|
||||||
|
fileAsset.setSize(fileAsset.getData().length);
|
||||||
|
try (BufferedInputStream stream = new BufferedInputStream(
|
||||||
|
new ByteArrayInputStream(fileAsset.getData()))) {
|
||||||
|
fileAsset.setMimeType(
|
||||||
|
new MimeType(URLConnection
|
||||||
|
.guessContentTypeFromStream(stream))
|
||||||
|
);
|
||||||
|
} catch (IOException | MimeTypeParseException ex) {
|
||||||
|
LOGGER.error("Failed to get file type.", ex);
|
||||||
|
models.put("failedToGetType", true);
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
assetRepo.save(fileAsset);
|
||||||
|
|
||||||
|
return buildRedirectPathForStep();
|
||||||
|
} else {
|
||||||
|
return assetUi.showAccessDenied(
|
||||||
|
getContentSection(),
|
||||||
|
getAsset(),
|
||||||
|
messageBundle.get("asset.edit.denied"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.librecms.ui.contentsections.assets;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("CmsFileAssetEditStepModel")
|
||||||
|
public class FileAssetEditStepModel {
|
||||||
|
|
||||||
|
private Map<String, String> descriptionValues;
|
||||||
|
|
||||||
|
private List<String> descriptionLocales;
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
private String mimeType;
|
||||||
|
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
private String sizeLabel;
|
||||||
|
|
||||||
|
public Map<String, String> getDescriptionValues() {
|
||||||
|
return Collections.unmodifiableMap(descriptionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setDescriptionValues(
|
||||||
|
final Map<String, String> descriptionValues
|
||||||
|
) {
|
||||||
|
this.descriptionValues = new HashMap<>(descriptionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDescriptionLocales() {
|
||||||
|
return Collections.unmodifiableList(descriptionLocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUnusedDescriptionLocales(
|
||||||
|
final List<String> descriptionLocales
|
||||||
|
) {
|
||||||
|
this.descriptionLocales = new ArrayList<>(descriptionLocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setFileName(final String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setMimeType(final String mimeType) {
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSize(final long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSizeLabel() {
|
||||||
|
return sizeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSizeLabel(final String sizeLabel) {
|
||||||
|
this.sizeLabel = sizeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container">
|
||||||
|
<h1>#{CmsAssetsStepsDefaultMessagesBundle["fileasset.createform.title"]}</h1>
|
||||||
|
|
||||||
|
<c:forEach items="#{CmsFileAssetCreateStep.messages.entrySet()}"
|
||||||
|
var="message">
|
||||||
|
<div class="alert alert-#{message.key}" role="alert">
|
||||||
|
#{message.value}
|
||||||
|
</div>
|
||||||
|
</c:forEach>
|
||||||
|
|
||||||
|
<form action="#{mvc.basePath}/#{CmsFileAssetCreateStep.contentSectionLabel}/assets/#{CmsFileAssetCreateStep.folderPath}@create/#{CmsFileAssetCreateStep.assetType}"
|
||||||
|
method="post">
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.help']}"
|
||||||
|
inputId="name"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.name.label']}"
|
||||||
|
name="name"
|
||||||
|
pattern="^([a-zA-Z0-9_-]*)$"
|
||||||
|
required="true"
|
||||||
|
value="#{CmsFileAssetCreateStep.name}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<bootstrap:formGroupSelect
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.initial_locale.help']}"
|
||||||
|
inputId="locale"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.initial_locale.label']}"
|
||||||
|
name="locale"
|
||||||
|
options="#{CmsFileAssetCreateStep.availableLocales}"
|
||||||
|
required="true"
|
||||||
|
selectedOptions="#{[CmsFileAssetCreateStep.initialLocale]}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<bootstrap:formGroupText
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.title.help']}"
|
||||||
|
inputId="title"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.title.label']}"
|
||||||
|
name="title"
|
||||||
|
required="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<bootstrap:formGroupTextarea
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['createform.fileasset.description.help']}"
|
||||||
|
inputId="description"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['createform.fileasset.description.label']}"
|
||||||
|
name="description"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<a class="btn btn-warning"
|
||||||
|
href="#{mvc.basePath}/#{CmsFileAssetCreateStep.contentSectionLabel}/assetfolders/#{CmsFileAssetCreateStep.folderPath}">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['createform.cancel']}
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['createform.submit']}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
|
||||||
|
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/editstep.xhtml">
|
||||||
|
|
||||||
|
<ui:param name="stepControllerUrl"
|
||||||
|
value="@fileasset-edit"
|
||||||
|
/>
|
||||||
|
<ui:param name="title"
|
||||||
|
value="#{CmsAssetsStepsDefaultMessagesBundle.getMessage('fileasset.editstep.header', [MvcAssetEditStepModel.name])}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ui:define name="editStep">
|
||||||
|
|
||||||
|
<libreccm:localizedStringEditor
|
||||||
|
addButtonLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add_button.label']}"
|
||||||
|
addDialogCancelLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.cancel']}"
|
||||||
|
addDialogLocaleSelectHelp="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.locale.help']}"
|
||||||
|
addDialogLocaleSelectLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.locale.label']}"
|
||||||
|
addDialogSubmitLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.submit']}"
|
||||||
|
addDialogTitle="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.title']}"
|
||||||
|
addDialogValueHelp="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.value.help']}"
|
||||||
|
addDialogValueLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.add.value.label']}"
|
||||||
|
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@fileasset-edit/description/add"
|
||||||
|
editButtonLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit_button.label']}"
|
||||||
|
editDialogCancelLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit.cancel']}"
|
||||||
|
editDialogSubmitLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit.submit']}"
|
||||||
|
editDialogTitle="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit.title']}"
|
||||||
|
editDialogValueHelp="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit.value.help']}"
|
||||||
|
editDialogValueLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.edit.value.label']}"
|
||||||
|
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@fileasset-edit/description/edit"
|
||||||
|
editorId="description-editor"
|
||||||
|
hasUnusedLocales="#{!CmsFileAssetEditStep.unusedDescriptionLocales.isEmpty()}"
|
||||||
|
headingLevel="3"
|
||||||
|
objectIdentifier="#{CmsSelectedAssetModel.assetPath}"
|
||||||
|
readOnly="#{!MvcAssetEditStepModel.canEdit}"
|
||||||
|
removeButtonLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.remove_button.label']}"
|
||||||
|
removeDialogCancelLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.remove.cancel']}"
|
||||||
|
removeDialogSubmitLabel="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.remove.submit']}"
|
||||||
|
removeDialogText="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.remove.text']}"
|
||||||
|
removeDialogTitle="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.remove.title']}"
|
||||||
|
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@fileasset-edit/description/remove"
|
||||||
|
title="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.description.title']}"
|
||||||
|
unusedLocales="#{CmsFileAssetEditStep.unusedDescriptionLocales}"
|
||||||
|
useTextarea="true"
|
||||||
|
values="#{CmsFileAssetEditStep.descriptionValues}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<h3>#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.title']}</h3>
|
||||||
|
<c:if test="#{MvcAssetEditStepModel.canEdit}">
|
||||||
|
<div class="text-right">
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#file-upload-dialog"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="upload" />
|
||||||
|
<span class="sr-only">#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.button.label']}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div aria-hidden="true"
|
||||||
|
aria-labelledby="file-upload-dialog-title"
|
||||||
|
class="modal fade"
|
||||||
|
id="file-upload-dialog"
|
||||||
|
tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assets/#{CmsSelectedAssetModel.assetPath}/@fileasset-edit/upload"
|
||||||
|
enctype="multipart/formdata"
|
||||||
|
method="post">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title"
|
||||||
|
id="file-upload-dialog-title">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.title']}
|
||||||
|
</h4>
|
||||||
|
<button
|
||||||
|
aria-label="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.close']}"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="x" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<bootstrap:formGroupFile
|
||||||
|
help="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.help']}"
|
||||||
|
inputId="fileData"
|
||||||
|
label="#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.label']}"
|
||||||
|
name="fileData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-warning"
|
||||||
|
data-dismiss="modal"
|
||||||
|
type="button">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.close']}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success"
|
||||||
|
type="submit">
|
||||||
|
#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.upload.submit']}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</c:if>
|
||||||
|
<dl>
|
||||||
|
<div>
|
||||||
|
<dt>#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.name']}</dt>
|
||||||
|
<dd>#{CmsFileAssetEditStepModel.fileName}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.type']}</dt>
|
||||||
|
<dd>#{CmsFileAssetEditStepModel.mimeType}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>#{CmsAssetsStepsDefaultMessagesBundle['fileasset.editstep.file.size']}</dt>
|
||||||
|
<dd>#{CmsFileAssetEditStepModel.sizeLabel}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
Loading…
Reference in New Issue