diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java index 5ffe5ec91015936a5ead6de4b96929aa921beece..440333c442a63eb4c1c2338532a4a9233ac1ed2f 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java @@ -182,6 +182,8 @@ public class FileElementImpl extends FormItemImpl previewEl.setCropSelectionEnabled(cropSelectionEnabled); previewEl.setMaxWithAndHeightToFitWithin(300, 200); previewEl.setVisible(true); + } else { + previewEl.setVisible(false); } // Mark associated component dirty, that it gets rerendered component.setDirty(true); diff --git a/src/main/java/org/olat/core/gui/components/image/ImageComponent.java b/src/main/java/org/olat/core/gui/components/image/ImageComponent.java index 970735bfde1b16c951591430081e02e97eb8f0b5..e3bcaa75e9b10dcf2e5681e05d87207a81f8b11f 100644 --- a/src/main/java/org/olat/core/gui/components/image/ImageComponent.java +++ b/src/main/java/org/olat/core/gui/components/image/ImageComponent.java @@ -30,20 +30,16 @@ import java.io.File; import java.util.Collections; import java.util.UUID; -import javax.servlet.http.HttpServletRequest; - import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.image.ImageService; import org.olat.core.commons.services.image.Size; import org.olat.core.commons.services.video.MovieService; -import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.dispatcher.mapper.MapperService; import org.olat.core.dispatcher.mapper.manager.MapperKey; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.AbstractComponent; import org.olat.core.gui.components.ComponentRenderer; import org.olat.core.gui.control.Disposable; -import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.render.ValidationResult; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -52,7 +48,7 @@ import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSMediaResource; +import org.olat.core.util.vfs.VFSMediaMapper; /** * Description: <br> @@ -68,12 +64,12 @@ public class ImageComponent extends AbstractComponent implements Disposable { private String alt; private final MapperKey mapperUrl; - private final MediaMapper mapper; + private final VFSMediaMapper mapper; // optional in case of video: poster image private VFSLeaf poster; private MapperKey posterMapperUrl; - private MediaMapper posterMapper; + private VFSMediaMapper posterMapper; private Size realSize; private Size scaledSize; @@ -86,11 +82,11 @@ public class ImageComponent extends AbstractComponent implements Disposable { */ public ImageComponent(UserSession usess, String name) { super(name); - mapper = new MediaMapper(); + mapper = new VFSMediaMapper(); String mapperId = UUID.randomUUID().toString(); mapperUrl = CoreSpringFactory.getImpl(MapperService.class).register(usess, mapperId, mapper); // optional poster frame for videos - posterMapper = new MediaMapper(); + posterMapper = new VFSMediaMapper(); mapperId = UUID.randomUUID().toString(); posterMapperUrl = CoreSpringFactory.getImpl(MapperService.class).register(usess, mapperId, posterMapper); // renderer provides own DOM ID @@ -313,16 +309,4 @@ public class ImageComponent extends AbstractComponent implements Disposable { return null; } - private static class MediaMapper implements Mapper { - private VFSLeaf mediaFile; - - public void setMediaFile(VFSLeaf mediaFile) { - this.mediaFile = mediaFile; - } - - @Override - public MediaResource handle(String relPath, HttpServletRequest request) { - return new VFSMediaResource(mediaFile); - } - } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/VFSLeafMapper.java b/src/main/java/org/olat/core/util/vfs/VFSMediaMapper.java similarity index 85% rename from src/main/java/org/olat/core/util/vfs/VFSLeafMapper.java rename to src/main/java/org/olat/core/util/vfs/VFSMediaMapper.java index 888c8d3efe790cef2e995dee28bc94506647edc7..ef0af8f2a6b17f7762d766182ba3c74c5c4d817d 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSLeafMapper.java +++ b/src/main/java/org/olat/core/util/vfs/VFSMediaMapper.java @@ -30,11 +30,18 @@ import org.olat.core.gui.media.MediaResource; * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public class VFSLeafMapper implements Mapper { +public class VFSMediaMapper implements Mapper { - private final VFSLeaf file; + private VFSLeaf file; - public VFSLeafMapper(VFSLeaf file) { + public VFSMediaMapper() { + } + + public VFSMediaMapper(VFSLeaf file) { + this.file = file; + } + + public void setMediaFile(VFSLeaf file) { this.file = file; } diff --git a/src/main/java/org/olat/modules/forms/EvaluationFormResponse.java b/src/main/java/org/olat/modules/forms/EvaluationFormResponse.java index da23d5d3817e182e8cbd7a02db9c6be65b118edd..5b3cae360b6f06c1862eacf58bf1593ada0ef385 100644 --- a/src/main/java/org/olat/modules/forms/EvaluationFormResponse.java +++ b/src/main/java/org/olat/modules/forms/EvaluationFormResponse.java @@ -35,6 +35,12 @@ public interface EvaluationFormResponse extends CreateInfo, ModifiedInfo { public Long getKey(); + /** + * The identifier of the evaluation form part / element. Several responses may + * have the same identifier. + * + * @return + */ public String getResponseIdentifier(); public BigDecimal getNumericalResponse(); diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java index 78a7f6f212426ddc4a1ac6a4727a4215b1a12bca..b7a10357c7088d439db464e73553ed857332519f 100644 --- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java +++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java @@ -88,7 +88,7 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager { @Override public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier, File file, String filename, EvaluationFormSession session) throws IOException { - Path relativePath = evaluationFormStorage.save(file, filename, responseIdentifier); + Path relativePath = evaluationFormStorage.save(file, filename); return evaluationFormResponseDao.createResponse(responseIdentifier, null, filename, relativePath, session); } @@ -107,7 +107,7 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager { Path relativePath = null; String filenameToSave = null; if (file != null) { - relativePath = evaluationFormStorage.save(file, filename, response.getResponseIdentifier()); + relativePath = evaluationFormStorage.save(file, filename); filenameToSave = filename; } return evaluationFormResponseDao.updateResponse(null, filenameToSave, relativePath, response); diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormStorage.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormStorage.java index 0c007e091e11b2c8dfbbc75d33b38f8f1a5118b7..3670329a824ba34c0d0218ff023eedef0821e49f 100644 --- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormStorage.java +++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormStorage.java @@ -25,6 +25,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Comparator; +import java.util.UUID; import javax.annotation.PostConstruct; @@ -42,7 +44,7 @@ import org.springframework.stereotype.Service; * */ @Service -public class EvaluationFormStorage { +class EvaluationFormStorage { private static final OLog log = Tracing.createLoggerFor(EvaluationFormStorage.class); @@ -74,44 +76,48 @@ public class EvaluationFormStorage { * * @param file the file to save * @param filename the filename of the new file - * @param responseIdentifier the identifier of the evaluation form response * @return the relative path of the saved file */ - public Path save(File file, String filename, String responseIdentifier) throws IOException { - Path responsePath = getResponsePath(responseIdentifier, filename); + Path save(File file, String filename) throws IOException { + Path responsePath = getResponsePath(filename); Path sourcePath = file.toPath(); Files.createDirectories(responsePath.getParent()); Files.copy(sourcePath, responsePath, StandardCopyOption.REPLACE_EXISTING); return getRelativePath(responsePath); } - public File load(Path relativePath) { + File load(Path relativePath) { return getAbsolutePath(relativePath).toFile(); } - public VFSLeaf resolve(Path relativePath) { + VFSLeaf resolve(Path relativePath) { return new OlatRootFileImpl("/" + relativePath.toString(), null); } - public void delete(Path relativePath) { - Path absolutePath = getAbsolutePath(relativePath); + void delete(Path relativePath) { + Path parentDir = relativePath.getParent(); + Path absolutePath = getAbsolutePath(parentDir); try { - Files.deleteIfExists(absolutePath); + Files.walk(absolutePath) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); } catch (IOException e) { log.warn("Cannot properly delete evaluation form response file. Path: " + absolutePath, e); } } - private Path getResponsePath(String responseIdentifier, String filename) { + private Path getResponsePath(String filename) { + String responseDirectory = UUID.randomUUID().toString().replace("-", "").toLowerCase(); return Paths.get( responsesDirectory.toString(), - getIndexTooken(responseIdentifier), - responseIdentifier, + getIndexTooken(responseDirectory), + responseDirectory, filename); } - private String getIndexTooken(String responseIdentifier) { - return responseIdentifier.replace("-", "").substring(0, 2).toLowerCase(); + private String getIndexTooken(String responseDirectory) { + return responseDirectory.substring(0, 3); } private Path getRelativePath(Path path) { diff --git a/src/main/java/org/olat/modules/forms/ui/CompareEvaluationsFormController.java b/src/main/java/org/olat/modules/forms/ui/CompareEvaluationsFormController.java index 34ee49689bed34cae22efc3cd7f434b9c33df90f..f78d1880c4f5497aa772d8fde814fb75b41a46ff 100644 --- a/src/main/java/org/olat/modules/forms/ui/CompareEvaluationsFormController.java +++ b/src/main/java/org/olat/modules/forms/ui/CompareEvaluationsFormController.java @@ -45,7 +45,7 @@ import org.olat.core.id.Identity; import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSLeafMapper; +import org.olat.core.util.vfs.VFSMediaMapper; import org.olat.core.util.xml.XStreamHelper; import org.olat.fileresource.FileResourceManager; import org.olat.modules.forms.EvaluationFormManager; @@ -225,7 +225,7 @@ public class CompareEvaluationsFormController extends FormBasicController { if (leaf != null) { filename = leaf.getName(); filesize = Formatter.formatBytes((leaf).getSize()); - mapperUri = registerCacheableMapper(ureq, "file-upload-" + element.getId() + "-" + leaf.getLastModified(), new VFSLeafMapper(leaf)); + mapperUri = registerCacheableMapper(ureq, "file-upload-" + element.getId() + "-" + leaf.getLastModified(), new VFSMediaMapper(leaf)); iconCss = CSSHelper.createFiletypeIconCssClassFor(leaf.getName()); if (leaf instanceof MetaTagged) { MetaTagged metaTaggedLeaf = (MetaTagged) leaf; @@ -233,7 +233,7 @@ public class CompareEvaluationsFormController extends FormBasicController { if (meta != null && meta.isThumbnailAvailable()) { VFSLeaf thumb = meta.getThumbnail(200, 200, false); if (thumb != null) { - thumbUri = registerCacheableMapper(ureq, "file-upload-thumb" + element.getId() + "-" + leaf.getLastModified(), new VFSLeafMapper(thumb));; + thumbUri = registerCacheableMapper(ureq, "file-upload-thumb" + element.getId() + "-" + leaf.getLastModified(), new VFSMediaMapper(thumb));; } } } diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormController.java index 9a728cdc77ea1514fee73f8a8c50bf2593910ef6..1b5357376933ea450221821f16bb5e244d02f1f0 100644 --- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormController.java +++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormController.java @@ -60,7 +60,6 @@ import org.olat.modules.forms.EvaluationFormManager; import org.olat.modules.forms.EvaluationFormResponse; import org.olat.modules.forms.EvaluationFormSession; import org.olat.modules.forms.EvaluationFormSessionStatus; -import org.olat.modules.forms.manager.EvaluationFormStorage; import org.olat.modules.forms.model.xml.AbstractElement; import org.olat.modules.forms.model.xml.FileUpload; import org.olat.modules.forms.model.xml.Form; @@ -88,7 +87,7 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class EvaluationFormController extends FormBasicController implements ValidatingController { - private static final OLog log = Tracing.createLoggerFor(EvaluationFormStorage.class); + private static final OLog log = Tracing.createLoggerFor(EvaluationFormController.class); private int count = 0; private final Form form; diff --git a/src/main/java/org/olat/modules/forms/ui/MimeTypeSetFactory.java b/src/main/java/org/olat/modules/forms/ui/MimeTypeSetFactory.java index ca91a1ae728aa068203c423053a1bb52dd32b7f8..0109cd857c8551b2a8ee61019a84955a453120a9 100644 --- a/src/main/java/org/olat/modules/forms/ui/MimeTypeSetFactory.java +++ b/src/main/java/org/olat/modules/forms/ui/MimeTypeSetFactory.java @@ -19,6 +19,7 @@ */ package org.olat.modules.forms.ui; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; @@ -26,13 +27,14 @@ import java.util.Set; import org.olat.core.gui.translator.Translator; + /** * * Initial date: 07.02.2018<br> * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -class MimeTypeSetFactory { +final class MimeTypeSetFactory { private static final String TYPE_ALL_KEY = "file.upload.mime.type.all"; @@ -41,13 +43,13 @@ class MimeTypeSetFactory { mimeTypeSets.put(TYPE_ALL_KEY, null); Set<String> pdf = new HashSet<>(); pdf.add("application/pdf"); - mimeTypeSets.put("file.upload.mime.type.pdf", pdf); + mimeTypeSets.put("file.upload.mime.type.pdf", Collections.unmodifiableSet(pdf)); Set<String> images = new HashSet<>(); images.add("image/gif"); images.add("image/jpg"); images.add("image/jpeg"); images.add("image/png"); - mimeTypeSets.put("file.upload.mime.type.image", images); + mimeTypeSets.put("file.upload.mime.type.image", Collections.unmodifiableSet(images)); Set<String> audios = new HashSet<>(); audios.add("audio/aac"); audios.add("audio/mp4"); @@ -55,10 +57,14 @@ class MimeTypeSetFactory { audios.add("audio/ogg"); audios.add("audio/wav"); audios.add("audio/webm"); - mimeTypeSets.put("file.upload.mime.type.audio", audios); + mimeTypeSets.put("file.upload.mime.type.audio", Collections.unmodifiableSet(audios)); Set<String> videos = new HashSet<>(); videos.add("video/mp4"); - mimeTypeSets.put("file.upload.mime.type.video", videos); + mimeTypeSets.put("file.upload.mime.type.video", Collections.unmodifiableSet(videos)); + } + + private MimeTypeSetFactory() { + // noninstantiable } static String[] getKeys() { diff --git a/src/main/java/org/olat/modules/portfolio/ui/media/FileMediaController.java b/src/main/java/org/olat/modules/portfolio/ui/media/FileMediaController.java index 78bc4b2c9e2bdac8fc2c87b6fbdc0c1440c63914..23775cb2f539c75684fc760b42b0e19eab88e606 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/media/FileMediaController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/media/FileMediaController.java @@ -32,7 +32,7 @@ import org.olat.core.util.Util; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSLeafMapper; +import org.olat.core.util.vfs.VFSMediaMapper; import org.olat.modules.portfolio.Media; import org.olat.modules.portfolio.MediaRenderingHints; import org.olat.modules.portfolio.manager.PortfolioFileStorage; @@ -73,7 +73,7 @@ public class FileMediaController extends BasicController { VFSItem item = container.resolve(media.getRootFilename()); if(item instanceof VFSLeaf) { VFSLeaf leaf = (VFSLeaf)item; - String mapperUri = registerCacheableMapper(ureq, "File-Media-" + media.getKey() + "-" + leaf.getLastModified(), new VFSLeafMapper(leaf)); + String mapperUri = registerCacheableMapper(ureq, "File-Media-" + media.getKey() + "-" + leaf.getLastModified(), new VFSMediaMapper(leaf)); mainVC.contextPut("mapperUri", mapperUri); String iconCss = CSSHelper.createFiletypeIconCssClassFor(leaf.getName()); mainVC.contextPut("fileIconCss", iconCss); diff --git a/src/test/java/org/olat/modules/forms/manager/EvaluationFormStorageTest.java b/src/test/java/org/olat/modules/forms/manager/EvaluationFormStorageTest.java index 21df65f8d9ab99c3839714d4d97da31b3319fb6f..1e875c1fcceae58e10352e7caf8e98b55a7ac8f0 100644 --- a/src/test/java/org/olat/modules/forms/manager/EvaluationFormStorageTest.java +++ b/src/test/java/org/olat/modules/forms/manager/EvaluationFormStorageTest.java @@ -62,14 +62,14 @@ public class EvaluationFormStorageTest extends OlatTestCase { public void shouldSaveNewFile() throws Exception { File file = getExistingFile(); - Path relativePath = sut.save(file, getRandomFilename(), getRandomIdentifier()); + Path relativePath = sut.save(file, getRandomFilename()); assertThat(relativePath).isNotNull(); } @Test public void shouldLoadFile() throws Exception { - Path relativePath = sut.save(getExistingFile(), getRandomFilename(), getRandomIdentifier()); + Path relativePath = sut.save(getExistingFile(), getRandomFilename()); File loadedFile = sut.load(relativePath); @@ -79,7 +79,7 @@ public class EvaluationFormStorageTest extends OlatTestCase { @Test public void shouldDeleteFile() throws Exception { assertThat(getExistingFile()).exists(); - Path relativePath = sut.save(getExistingFile(), getRandomFilename(), getRandomIdentifier()); + Path relativePath = sut.save(getExistingFile(), getRandomFilename()); File loadedFile = sut.load(relativePath); assertThat(loadedFile).exists(); @@ -97,8 +97,4 @@ public class EvaluationFormStorageTest extends OlatTestCase { return UUID.randomUUID().toString(); } - private String getRandomIdentifier() { - return UUID.randomUUID().toString(); - } - }