diff --git a/src/main/java/org/olat/admin/bc/BriefcaseAdminController.java b/src/main/java/org/olat/admin/bc/BriefcaseAdminController.java index e6536024605eff11e7f8ccf346a7f320eadbf45b..83636a2fb20a4f000d455f1c3ddf1fc80e52de26 100644 --- a/src/main/java/org/olat/admin/bc/BriefcaseAdminController.java +++ b/src/main/java/org/olat/admin/bc/BriefcaseAdminController.java @@ -23,6 +23,7 @@ import java.io.File; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -32,7 +33,6 @@ import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; -import org.olat.core.util.vfs.meta.MetaInfoFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -47,7 +47,7 @@ public class BriefcaseAdminController extends FormBasicController { @Autowired private TaskExecutorManager taskExecutor; @Autowired - private MetaInfoFactory metaInfoFactory; + private VFSRepositoryService vfsRepositoryService; public BriefcaseAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, "bc_admin"); @@ -88,23 +88,10 @@ public class BriefcaseAdminController extends FormBasicController { logInfo("Start reset of thumbnails", null); String metaRoot = FolderConfig.getCanonicalMetaRoot(); - File metaRootFile = new File(metaRoot); - resetThumbnails(metaRootFile); + vfsRepositoryService.resetThumbnails(new File(metaRoot)); flc.contextPut("recalculating", Boolean.FALSE); logInfo("Finished reset of thumbnails in " + (System.currentTimeMillis() - start) + " (ms)", null); } - - private void resetThumbnails(File directory) { - for(File file:directory.listFiles()) { - if(file.isHidden()) { - //do nothing - } else if(file.isDirectory()) { - resetThumbnails(file); - } else if(file.getName().endsWith(".xml")) { - metaInfoFactory.resetThumbnails(file); - } - } - } } } diff --git a/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java b/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java index 5becf07bee417a0552aa200e18e63e67742c4e79..101f9c47e1c5ea6ec37859df925d03af95a89626 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java +++ b/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java @@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletRequest; import org.olat.commons.info.InfoMessage; import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.commons.info.manager.MailFormatter; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.date.DateComponentFactory; @@ -73,7 +75,6 @@ import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.info.InfoCourseNodeConfiguration; import org.olat.group.BusinessGroup; import org.olat.modules.ModuleConfiguration; @@ -122,6 +123,8 @@ public class InfoDisplayController extends FormBasicController { private UserManager userManager; @Autowired private InfoMessageFrontendManager infoMessageManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; private LockResult lockEntry; private MailFormatter sendMailFormatter; @@ -538,14 +541,12 @@ public class InfoDisplayController extends FormBasicController { Long infoKey = Long.valueOf(Long.parseLong(query[1])); VFSLeaf attachment = infoKeyToAttachment.get(infoKey); if(attachment != null && attachment.canMeta() == VFSConstants.YES) { - MetaInfo meta = attachment.getMetaInfo(); - if (meta.getUUID().equals(query[2])) { - if (meta.isThumbnailAvailable()) { - VFSLeaf thumb = meta.getThumbnail(200, 200, false); - if(thumb != null) { - // Positive lookup, send as response - return new VFSMediaResource(thumb); - } + VFSMetadata meta = attachment.getMetaInfo(); + if (meta.getUuid().equals(query[2])) { + VFSLeaf thumb = vfsRepositoryService.getThumbnail(attachment, meta, 200, 200, false); + if(thumb != null) { + // Positive lookup, send as response + return new VFSMediaResource(thumb); } } } diff --git a/src/main/java/org/olat/commons/memberlist/ui/MembersPrintController.java b/src/main/java/org/olat/commons/memberlist/ui/MembersPrintController.java index 32da7f36402094fa816ae79b77ee50641d16a39b..8878b5383fd9ea2d987c6b2d9cc0fb112ee2ce69 100644 --- a/src/main/java/org/olat/commons/memberlist/ui/MembersPrintController.java +++ b/src/main/java/org/olat/commons/memberlist/ui/MembersPrintController.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest; import org.olat.basesecurity.BaseSecurityModule; import org.olat.commons.memberlist.model.CurriculumElementInfos; import org.olat.commons.memberlist.model.CurriculumMemberInfos; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -50,7 +51,6 @@ import org.olat.core.util.Util; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.members.Member; import org.olat.user.DisplayPortraitManager; import org.olat.user.UserManager; @@ -73,9 +73,12 @@ public class MembersPrintController extends BasicController { @Autowired private UserManager userManager; @Autowired + private BaseSecurityModule securityModule; + @Autowired private DisplayPortraitManager portraitManager; @Autowired - private BaseSecurityModule securityModule; + private VFSRepositoryService vfsRepositoryService; + public MembersPrintController(UserRequest ureq, WindowControl wControl, Translator translator, List<Identity> owners, List<Identity> coaches, List<Identity> participants, List<Identity> waiting, Map<Long,CurriculumMemberInfos> curriculumInfos, @@ -193,8 +196,7 @@ public class MembersPrintController extends BasicController { String username = userManager.getUsername(key); VFSLeaf portrait = portraitManager.getLargestVFSPortrait(username); if(portrait.canMeta() == VFSConstants.YES) { - MetaInfo meta = portrait.getMetaInfo(); - portrait = meta.getThumbnail(300, 300, false); + portrait = vfsRepositoryService.getThumbnail(portrait, 300, 300, false); } if(portrait != null) { diff --git a/src/main/java/org/olat/core/commons/modules/bc/FileInfo.java b/src/main/java/org/olat/core/commons/modules/bc/FileInfo.java index 178c9c54e02d09bb12a18d45bd0edd915f1546d6..43cceb1e66fe1939dcccfb129508c48920f1b433 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FileInfo.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FileInfo.java @@ -28,7 +28,7 @@ package org.olat.core.commons.modules.bc; import java.util.Date; -import org.olat.core.util.vfs.meta.MetaInfo; +import org.olat.core.commons.services.vfs.VFSMetadata; /** * Initial Date: 11.02.2005 <br> @@ -37,14 +37,14 @@ import org.olat.core.util.vfs.meta.MetaInfo; */ public class FileInfo { private String relPath; - private MetaInfo metaInfo; + private VFSMetadata metaInfo; private Date lastModified; /** * @param relPath e.g. chapter1/info.pdf -> will be used as title in notifications * @param metaInfo * @param lastModified */ - public FileInfo(String relPath, MetaInfo metaInfo, Date lastModified) { + public FileInfo(String relPath, VFSMetadata metaInfo, Date lastModified) { this.relPath = relPath; this.metaInfo = metaInfo; this.lastModified = lastModified; @@ -54,7 +54,7 @@ public class FileInfo { * @return the author */ public Long getAuthorIdentityKey() { - return metaInfo == null ? null : metaInfo.getAuthorIdentityKey(); + return metaInfo == null || metaInfo.getAuthor() == null ? null : metaInfo.getAuthor().getKey(); } /** @@ -75,7 +75,7 @@ public class FileInfo { * Get the file meta info or NULL if no meta info exists * @return */ - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return metaInfo; } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java index e7377580f23be2637d9494b9773f595354a97e9a..2690eb474d85f77b45d43412c7dc02169a5af721 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java @@ -44,6 +44,8 @@ import org.olat.core.commons.modules.bc.meta.MetaInfoFormController; import org.olat.core.commons.modules.bc.version.RevisionListController; import org.olat.core.commons.modules.bc.version.VersionCommentController; import org.olat.core.commons.services.image.ImageService; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -79,7 +81,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.core.util.vfs.version.Versionable; import org.olat.core.util.vfs.version.Versions; import org.springframework.beans.factory.annotation.Autowired; @@ -151,6 +152,8 @@ public class FileUploadController extends FormBasicController { private ImageService imageHelper; @Autowired private VFSLockManager vfsLockManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; private String subfolderPath; private TextElement targetSubPath ; @@ -729,12 +732,14 @@ public class FileUploadController extends FormBasicController { private void finishSuccessfullUpload(String filePath, VFSItem item, UserRequest ureq) { if (item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { // create meta data - MetaInfo meta = item.getMetaInfo(); + VFSMetadata meta = item.getMetaInfo(); if (metaDataCtr != null) { meta = metaDataCtr.getMetaInfo(meta); } meta.setAuthor(getIdentity()); - meta.clearThumbnails();//clear write the meta + //clear write the meta + vfsRepositoryService.updateMetadata(meta); + vfsRepositoryService.resetThumbnails((VFSLeaf)item); } if(item == null) { @@ -885,8 +890,7 @@ public class FileUploadController extends FormBasicController { return validateFilename(metaDataCtr.getFilename(), metaDataCtr.getFilenameEl()); } - boolean allOk = validateFilename(fileEl); - return allOk; + return validateFilename(fileEl); } private boolean validateFilename(FileElement itemEl) { diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderManager.java b/src/main/java/org/olat/core/commons/modules/bc/FolderManager.java index 7a508ba94cf4f70edc59742833a60ef6b3785caa..d5b3e0eb1122d8b8348035dfb4b7e672e114c222 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderManager.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderManager.java @@ -31,6 +31,7 @@ import java.util.Date; import java.util.List; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.helpers.Settings; import org.olat.core.util.WebappHelper; import org.olat.core.util.vfs.LocalFolderImpl; @@ -40,7 +41,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.SystemItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; /** * Initial Date: 18.12.2002 @@ -90,7 +90,7 @@ public class FolderManager { if(leaf.canMeta() == VFSConstants.YES) { long lastModified = leaf.getLastModified(); if (lastModified > newerThan) { - MetaInfo meta = leaf.getMetaInfo(); + VFSMetadata meta = leaf.getMetaInfo(); String bcrootPath = relPath.getRelPath(); String bcRelPath = bcrootPath.substring(basePathlen); fileInfos.add(new FileInfo(bcRelPath, meta, new Date(lastModified))); diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java b/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java index 158ecf45fae1c9dc145ae64fbeb458038b77e4af..5d69dbc670628f3f6400c85eeeb05c56c050b42d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java @@ -27,6 +27,7 @@ package org.olat.core.commons.modules.bc; import java.io.File; +import java.nio.file.Path; import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.helpers.Settings; @@ -145,6 +146,10 @@ public class FolderModule extends AbstractSpringModule { return FolderConfig.getCanonicalRoot(); } + public Path getCanonicalRootPath() { + return FolderConfig.getCanonicalRootPath(); + } + public String getCanonicalTmpDir() { return FolderConfig.getCanonicalTmpDir(); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java index 9be9f7a1a9ef58deb22a5e4853529dd5a4dbbef0..2f95a91523e66b72ff8f1e5e08bd18600e880cd5 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java @@ -37,6 +37,8 @@ import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.ui.LicenseUIFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -55,7 +57,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.core.util.vfs.util.ContainerAndFile; import org.springframework.beans.factory.annotation.Autowired; @@ -83,6 +84,8 @@ public class CmdCreateFile extends FormBasicController implements FolderCommand private LicenseModule licenseModule; @Autowired private FolderLicenseHandler licenseHandler; + @Autowired + private VFSRepositoryService vfsRepositoryService; protected CmdCreateFile(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -192,16 +195,16 @@ public class CmdCreateFile extends FormBasicController implements FolderCommand notifyFinished(ureq); } else { if(item.canMeta() == VFSConstants.YES) { - MetaInfo meta = item.getMetaInfo(); + VFSMetadata meta = item.getMetaInfo(); meta.setAuthor(ureq.getIdentity()); if (licenseModule.isEnabled(licenseHandler)) { License license = licenseService.createDefaultLicense(licenseHandler, getIdentity()); - meta.setLicenseTypeKey(String.valueOf(license.getLicenseType().getKey())); + meta.setLicenseType(license.getLicenseType()); meta.setLicenseTypeName(license.getLicenseType().getName()); meta.setLicensor(license.getLicensor()); meta.setLicenseText(LicenseUIFactory.getLicenseText(license)); } - meta.write(); + vfsRepositoryService.updateMetadata(meta); } // start HTML editor with the folders root folder as base and the file diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFolder.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFolder.java index fdc92feb2389061ff0d720975b5836543ca16bc2..25b08a0291be4adf3b573352e4aa1fb191490ced 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFolder.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFolder.java @@ -29,6 +29,8 @@ package org.olat.core.commons.modules.bc.commands; import org.olat.core.commons.modules.bc.FolderEvent; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -42,7 +44,7 @@ import org.olat.core.util.FileUtils; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.meta.MetaInfo; +import org.springframework.beans.factory.annotation.Autowired; /** * A panel with a FolderComponent and a CreateFolderForm. @@ -58,6 +60,9 @@ public class CmdCreateFolder extends FormBasicController implements FolderComman private String folderName; private String target; private TextElement textElement; + + @Autowired + private VFSRepositoryService vfsRepositoryService; public CmdCreateFolder(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -131,9 +136,9 @@ public class CmdCreateFolder extends FormBasicController implements FolderComman VFSItem item = currentContainer.createChildContainer(name); if (item instanceof VFSContainer && item.canMeta() == VFSConstants.YES) { // update meta data - MetaInfo meta = item.getMetaInfo(); + VFSMetadata meta = item.getMetaInfo(); meta.setAuthor(ureq.getIdentity()); - meta.write(); + vfsRepositoryService.updateMetadata(meta); status = FolderCommandStatus.STATUS_FAILED; fireEvent(ureq, new FolderEvent(FolderEvent.NEW_FOLDER_EVENT, folderName)); diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java index b3c522b6f09fb0211030013ad4da64b001935a8b..2e1720c9b0824da4c80c75f0a3fece7f53130604 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java @@ -28,8 +28,10 @@ import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FileSelection; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -45,7 +47,6 @@ 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.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; /** * @@ -186,9 +187,7 @@ public class CmdDownloadZip implements FolderCommand { vfsFiles.add(item); // update download counter if (item.canMeta() == VFSConstants.YES) { - MetaInfo meta = item.getMetaInfo(); - meta.increaseDownloadCount(); - meta.write(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).increaseDownloadCount(item); } } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java index 0f3ffbba8c1f867df27d9abcfbca1c1b715b1d9d..13b135f9e6c13dbece94d4c6ad3bc1eb7b052685 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java @@ -26,7 +26,6 @@ package org.olat.core.commons.modules.bc.commands; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderEvent; import org.olat.core.commons.modules.bc.components.FolderComponent; import org.olat.core.commons.modules.bc.components.ListRenderer; @@ -34,6 +33,8 @@ import org.olat.core.commons.modules.bc.meta.MetaInfoController; import org.olat.core.commons.modules.bc.meta.MetaInfoFormController; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Controller; @@ -52,7 +53,7 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; +import org.springframework.beans.factory.annotation.Autowired; public class CmdEditMeta extends BasicController implements FolderCommand { @@ -64,11 +65,13 @@ public class CmdEditMeta extends BasicController implements FolderCommand { private FolderComponent folderComponent; private Translator translator; - private final VFSLockManager vfsLockManager; + @Autowired + private VFSLockManager vfsLockManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; protected CmdEditMeta(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, Util.createPackageTranslator(MetaInfoController.class, ureq.getLocale())); - vfsLockManager = CoreSpringFactory.getImpl(VFSLockManager.class); } /** @@ -147,10 +150,10 @@ public class CmdEditMeta extends BasicController implements FolderCommand { @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == metaInfoCtr && event == Event.DONE_EVENT) { - MetaInfo meta = metaInfoCtr.getMetaInfo(); + VFSMetadata meta = metaInfoCtr.getMetaInfo(); String fileName = metaInfoCtr.getFilename(); if(meta != null) { - meta.write(); + vfsRepositoryService.updateMetadata(meta); if (metaInfoCtr.isFileRenamed()) { // IMPORTANT: First rename the meta data because underlying file // has to exist in order to work properly on it's meta data. diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java index 18cb04a7f35364f9b5ef5b89d153446e4f45f1b2..9b2ede24f6a0bc5108be9d0caa2a30766381e667 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java @@ -31,9 +31,11 @@ import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderLoggingAction; import org.olat.core.commons.modules.bc.FolderManager; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -53,7 +55,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSMediaResource; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; public class CmdServeResource implements FolderCommand { @@ -89,9 +90,7 @@ public class CmdServeResource implements FolderCommand { if(vfsItem == null) { folderComponent.updateChildren(); } else if (vfsItem.canMeta() == VFSConstants.YES) { - MetaInfo meta = vfsItem.getMetaInfo(); - meta.increaseDownloadCount(); - meta.write(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).increaseDownloadCount(vfsItem); } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeThumbnailResource.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeThumbnailResource.java index d3a7f53685e4d586bd0b6c56f9d547efaedee7ac..918e00017e3fd49db94a658c4e07bd26e7fa4edc 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeThumbnailResource.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeThumbnailResource.java @@ -26,7 +26,9 @@ package org.olat.core.commons.modules.bc.commands; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -39,12 +41,17 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSMediaResource; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; public class CmdServeThumbnailResource implements FolderCommand { private int status = FolderCommandStatus.STATUS_SUCCESS; + private final VFSRepositoryService vfsRepositoryservice; + + public CmdServeThumbnailResource() { + vfsRepositoryservice = CoreSpringFactory.getImpl(VFSRepositoryService.class); + } + @Override public Controller execute(FolderComponent folderComponent, UserRequest ureq, WindowControl wControl, Translator translator) { VFSSecurityCallback inheritedSecCallback = VFSManager.findInheritedSecurityCallback(folderComponent.getCurrentContainer()); @@ -63,12 +70,9 @@ public class CmdServeThumbnailResource implements FolderCommand { } if(vfsLeaf != null && vfsLeaf.canMeta() == VFSConstants.YES) { - MetaInfo info = vfsLeaf.getMetaInfo(); - if(info != null && info.isThumbnailAvailable()) { - VFSLeaf thumbnail = info.getThumbnail(200, 200, false); - if(thumbnail != null) { - mr = new VFSMediaResource(thumbnail); - } + VFSLeaf thumbnail = vfsRepositoryservice.getThumbnail(vfsLeaf, 200, 200, false); + if(thumbnail != null) { + mr = new VFSMediaResource(thumbnail); } } if(mr == null) { diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java index 282ca08944bab47e5c7173ea002c94582474b21e..a1334855f360f927938f0b287e596663fe4de91e 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java @@ -35,6 +35,8 @@ import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.components.FolderComponent; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Controller; @@ -55,7 +57,7 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; +import org.springframework.beans.factory.annotation.Autowired; public class CmdUnzip extends BasicController implements FolderCommand { @@ -64,6 +66,9 @@ public class CmdUnzip extends BasicController implements FolderCommand { private Translator translator; private DialogBoxController lockedFiledCtr; + @Autowired + private VFSRepositoryService vfsRepositoryService; + public CmdUnzip(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); } @@ -201,10 +206,10 @@ public class CmdUnzip extends BasicController implements FolderCommand { return false; } } else if (zipContainer.canMeta() == VFSConstants.YES) { - MetaInfo info = zipContainer.getMetaInfo(); + VFSMetadata info = zipContainer.getMetaInfo(); if(info != null && ureq.getIdentity() != null) { info.setAuthor(ureq.getIdentity()); - info.write(); + vfsRepositoryService.updateMetadata(info); } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdZip.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdZip.java index 1c85da693dd15dd7c62f14573a34c191710000f6..87a48c3b13543e95a373138b3757729743bab030 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdZip.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdZip.java @@ -32,6 +32,8 @@ import java.util.List; import org.olat.core.commons.modules.bc.FileSelection; import org.olat.core.commons.modules.bc.FolderEvent; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -48,7 +50,7 @@ import org.olat.core.util.vfs.VFSConstants; 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.meta.MetaInfo; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -67,6 +69,9 @@ public class CmdZip extends FormBasicController implements FolderCommand { private FileSelection selection; private TextElement textElement; + @Autowired + private VFSRepositoryService vfsRepositoryService; + protected CmdZip(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); } @@ -172,9 +177,9 @@ public class CmdZip extends FormBasicController implements FolderCommand { fireEvent(ureq, FOLDERCOMMAND_FINISHED); } else { if(zipFile.canMeta() == VFSConstants.YES) { - MetaInfo info = zipFile.getMetaInfo(); + VFSMetadata info = zipFile.getMetaInfo(); info.setAuthor(ureq.getIdentity()); - info.write(); + vfsRepositoryService.updateMetadata(info); } fireEvent(ureq, new FolderEvent(FolderEvent.ZIP_EVENT, selection.renderAsHtml())); diff --git a/src/main/java/org/olat/core/commons/modules/bc/comparators/MetaTitleComparator.java b/src/main/java/org/olat/core/commons/modules/bc/comparators/MetaTitleComparator.java index 9d82e0569ba28a0ec7e462a726fd5bafef5ef0f3..f6021e4d38dedf2f634a676ec71628f198e4d5f2 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/comparators/MetaTitleComparator.java +++ b/src/main/java/org/olat/core/commons/modules/bc/comparators/MetaTitleComparator.java @@ -23,7 +23,7 @@ import java.text.Collator; import java.util.Comparator; import java.util.Locale; -import org.olat.core.util.vfs.meta.MetaInfo; +import org.olat.core.commons.services.vfs.VFSMetadata; /** * Compares the title of two MetaInfo objects based on a given collator @@ -33,7 +33,7 @@ import org.olat.core.util.vfs.meta.MetaInfo; * * @author gwassmann */ -public class MetaTitleComparator implements Comparator<MetaInfo> { +public class MetaTitleComparator implements Comparator<VFSMetadata> { private final Collator collator; public MetaTitleComparator(Collator collator) { @@ -45,7 +45,7 @@ public class MetaTitleComparator implements Comparator<MetaInfo> { } @Override - public int compare(MetaInfo m1, MetaInfo m2) { + public int compare(VFSMetadata m1, VFSMetadata m2) { if(m1 == null) return -1; if(m2 == null) return 1; diff --git a/src/main/java/org/olat/core/commons/modules/bc/comparators/TitleComparator.java b/src/main/java/org/olat/core/commons/modules/bc/comparators/TitleComparator.java index aff2f27d4fd7b1e759e667d543522ff430b8e9a3..f4958ca23937404528827d498caef45f37cbc593 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/comparators/TitleComparator.java +++ b/src/main/java/org/olat/core/commons/modules/bc/comparators/TitleComparator.java @@ -23,9 +23,9 @@ import java.text.Collator; import java.util.Comparator; import java.util.Locale; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.meta.MetaInfo; /** * Compare the title, the filename and the last modification date @@ -63,7 +63,7 @@ public class TitleComparator implements Comparator<VFSItem> { if(item == null) return null; String name = null; - MetaInfo m = item.getMetaInfo(); + VFSMetadata m = item.getMetaInfo(); if(m != null) { name = m.getTitle(); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java index 96690738428976cc75fada9f6af26ff82f225b86..126ec4d53c1551a5b67d5b8bb818a7f40eaf554e 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java @@ -27,8 +27,11 @@ package org.olat.core.commons.modules.bc.components; import java.text.DateFormat; +import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FileSelection; @@ -39,6 +42,8 @@ import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseHandler; import org.olat.core.commons.services.license.LicenseModule; import org.olat.core.commons.services.license.ui.LicenseRenderer; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.components.form.flexible.impl.NameValuePair; import org.olat.core.gui.control.winmgr.AJAXFlags; import org.olat.core.gui.render.StringOutput; @@ -59,8 +64,6 @@ import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VirtualContainer; import org.olat.core.util.vfs.filters.SystemItemFilter; import org.olat.core.util.vfs.lock.LockInfo; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; import org.olat.core.util.vfs.version.Versionable; import org.olat.core.util.vfs.version.Versions; import org.olat.user.UserManager; @@ -89,6 +92,7 @@ public class ListRenderer { /** View thumbnail */ public static final String PARAM_SERV_THUMBNAIL = "servthumb"; + private VFSRepositoryService vfsRepositoryService; private VFSLockManager lockManager; private UserManager userManager; boolean licensesEnabled ; @@ -117,6 +121,10 @@ public class ListRenderer { if(userManager == null) { userManager = CoreSpringFactory.getImpl(UserManager.class); } + if(vfsRepositoryService == null) { + vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + } + LicenseModule licenseModule = CoreSpringFactory.getImpl(LicenseModule.class); LicenseHandler licenseHandler = CoreSpringFactory.getImpl(FolderLicenseHandler.class); licensesEnabled = licenseModule.isEnabled(licenseHandler); @@ -130,7 +138,8 @@ public class ListRenderer { return; } - boolean canVersion = FolderConfig.versionsEnabled(fc.getCurrentContainer()); + VFSContainer currentContainer = fc.getCurrentContainer(); + boolean canVersion = FolderConfig.versionsEnabled(currentContainer); String sortOrder = fc.getCurrentSortOrder(); boolean sortAsc = fc.isCurrentSortAsc(); String sortCss = (sortAsc ? "o_orderby_asc" : "o_orderby_desc"); @@ -171,9 +180,17 @@ public class ListRenderer { sb.append("<tbody>"); + String relPath = currentContainer.getRelPath(); + Map<String,VFSMetadata> metadatas = Collections.emptyMap(); + if(relPath != null) { + List<VFSMetadata> m = vfsRepositoryService.getChildren(relPath); + metadatas = m.stream().collect(Collectors.toMap(VFSMetadata::getFilename, v -> v, (u, v) -> u)); + } + for (int i = 0; i < children.size(); i++) { VFSItem child = children.get(i); - appendRenderedFile(fc, child, currentContainerPath, sb, ubu, translator, iframePostEnabled, canVersion, i); + VFSMetadata metadata = metadatas.get(child.getName()); + appendRenderedFile(fc, child, metadata, currentContainerPath, sb, ubu, translator, iframePostEnabled, canVersion, i); } sb.append("</tbody></table>"); } // getRenderedDirectoryContent @@ -184,7 +201,7 @@ public class ListRenderer { * @param f The file or folder to render * @param sb StringOutput to append generated html code */ - private void appendRenderedFile(FolderComponent fc, VFSItem child, String currentContainerPath, StringOutput sb, URLBuilder ubu, Translator translator, + private void appendRenderedFile(FolderComponent fc, VFSItem child, VFSMetadata metadata, String currentContainerPath, StringOutput sb, URLBuilder ubu, Translator translator, boolean iframePostEnabled, boolean canContainerVersion, int pos) { // assume full access unless security callback tells us something different. @@ -208,13 +225,7 @@ public class ListRenderer { leaf = (VFSLeaf)child; } boolean isContainer = (leaf == null); // if not a leaf, it must be a container... - - MetaInfo metaInfo = null; - if(child.canMeta() == VFSConstants.YES) { - metaInfo = child.getMetaInfo(); - } - - boolean lockedForUser = lockManager.isLockedForMe(child, metaInfo, fc.getIdentityEnvironnement().getIdentity(), fc.getIdentityEnvironnement().getRoles()); + boolean lockedForUser = lockManager.isLockedForMe(child, metadata, fc.getIdentityEnvironnement().getIdentity(), fc.getIdentityEnvironnement().getRoles()); String name = child.getName(); boolean xssErrors = StringHelper.xssScanForErrors(name); @@ -289,23 +300,23 @@ public class ListRenderer { } //file metadata as tooltip - if (metaInfo != null) { + if (metadata != null) { boolean hasMeta = false; sb.append("<div id='o_sel_doc_tooltip_").append(pos).append("' class='o_bc_meta' style='display:none;'>"); - if (StringHelper.containsNonWhitespace(metaInfo.getTitle())) { - String title = StringHelper.escapeHtml(metaInfo.getTitle()); + if (StringHelper.containsNonWhitespace(metadata.getTitle())) { + String title = StringHelper.escapeHtml(metadata.getTitle()); sb.append("<h5>").append(Formatter.escapeDoubleQuotes(title)).append("</h5>"); hasMeta = true; } - if (StringHelper.containsNonWhitespace(metaInfo.getComment())) { + if (StringHelper.containsNonWhitespace(metadata.getComment())) { sb.append("<div class=\"o_comment\">"); - String comment = StringHelper.escapeHtml(metaInfo.getComment()); + String comment = StringHelper.escapeHtml(metadata.getComment()); sb.append(Formatter.escapeDoubleQuotes(comment)); sb.append("</div>"); hasMeta = true; } - if(metaInfo.isThumbnailAvailable() && !xssErrors) { + if(!isContainer && !xssErrors && vfsRepositoryService.isThumbnailAvailable(leaf, metadata) ) { sb.append("<div class='o_thumbnail' style='background-image:url("); ubu.buildURI(sb, new String[] { PARAM_SERV_THUMBNAIL}, new String[] { "x" }, pathAndName, AJAXFlags.MODE_NORMAL); sb.append("); background-repeat:no-repeat; background-position:50% 50%;'></div>"); @@ -313,14 +324,13 @@ public class ListRenderer { } // first try author info from metadata (creator) - String author = metaInfo.getCreator(); + String author = metadata.getCreator(); // fallback use file author (uploader) if(StringHelper.containsNonWhitespace(author)) { // } else { - author = metaInfo.getAuthor(); - if(!"-".equals(author)) { - author = UserManager.getInstance().getUserDisplayName(author); + if(metadata.getAuthor() != null) { + author = userManager.getUserDisplayName(metadata.getAuthor()); } else { author = null; } @@ -379,25 +389,23 @@ public class ListRenderer { // license if (licensesEnabled) { - MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class); - License license = metaInfoFactory.getLicense(metaInfo); + License license = vfsRepositoryService.getLicense(metadata); LicenseRenderer licenseRenderer = new LicenseRenderer(translator.getLocale()); licenseRenderer.render(sb, license, true); sb.append("</td><td>"); } if(canContainerVersion) { - if (canVersion) - if (versions != null) { - sb.append("<span class='text-muted small'>"); - sb.append(versions.getRevisionNr()); - sb.append("</span>"); - } + if (canVersion && versions != null) { + sb.append("<span class='text-muted small'>") + .append(versions.getRevisionNr()) + .append("</span>"); + } sb.append("</td><td>"); } //locked - boolean locked = lockManager.isLocked(child, metaInfo); + boolean locked = lockManager.isLocked(child, metadata); if(locked) { LockInfo lock = lockManager.getLock(child); sb.append("<i class=\"o_icon o_icon_locked\" title=\""); diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java index 5ae4df91cef48fd90bc2db3dc17a250ea8828033..2d4ac8145e42d6c68b72a708f70c446cbe2b90fb 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java @@ -23,12 +23,13 @@ import java.text.DateFormat; import java.util.HashSet; import java.util.Set; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderLicenseHandler; import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseModule; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.ui.LicenseUIFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -45,12 +46,11 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.folder.FolderHelper; import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; +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.VFSLockManager; import org.olat.core.util.vfs.lock.LockInfo; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -81,6 +81,8 @@ public class MetaInfoController extends FormBasicController { private LicenseService licenseService; @Autowired private FolderLicenseHandler licenseHandler; + @Autowired + private VFSRepositoryService vfsRepositoryService; /** * Use this controller for editing meta data of an existing file. @@ -129,7 +131,7 @@ public class MetaInfoController extends FormBasicController { // filename uifactory.addStaticTextElement("mf.filename", item.getName(), formLayout); - MetaInfo meta = item == null ? null : item.getMetaInfo(); + VFSMetadata meta = item == null ? null : item.getMetaInfo(); // title String titleVal = StringHelper.escapeHtml(meta != null ? meta.getTitle() : null); @@ -141,8 +143,7 @@ public class MetaInfoController extends FormBasicController { // license if (licenseModule.isEnabled(licenseHandler)) { - MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class); - License license = metaInfoFactory.getOrCreateLicense(meta, getIdentity()); + License license = vfsRepositoryService.getOrCreateLicense(meta, getIdentity()); boolean isNoLicense = !licenseService.isNoLicense(license.getLicenseType()); boolean isFreetext = licenseService.isFreetext(license.getLicenseType()); @@ -226,7 +227,7 @@ public class MetaInfoController extends FormBasicController { setMetaFieldsVisible(false); } - if(meta != null && !meta.isDirectory()) { + if(meta != null && !(item instanceof VFSContainer)) { LockInfo lock = vfsLockManager.getLock(item); //locked String lockedTitle = getTranslator().translate("mf.locked"); @@ -258,14 +259,14 @@ public class MetaInfoController extends FormBasicController { uifactory.addStaticTextElement("mf.lockedBy", lockedDetails, formLayout); // username - String author = StringHelper.escapeHtml(userManager.getUserDisplayName(meta.getAuthorIdentityKey())); + String author = StringHelper.escapeHtml(userManager.getUserDisplayName(meta.getAuthor())); uifactory.addStaticTextElement("mf.author", author, formLayout); // filesize uifactory.addStaticTextElement("mf.size", StringHelper.escapeHtml(sizeText), formLayout); // last modified date - String lastModified = StringHelper.formatLocaleDate(meta.getLastModified(), getLocale()); + String lastModified = Formatter.getInstance(getLocale()).formatDate(meta.getFileLastModified()); uifactory.addStaticTextElement("mf.lastModified", lastModified, formLayout); // file type @@ -303,13 +304,13 @@ public class MetaInfoController extends FormBasicController { /** * @return True if one or more metadata fields are non-emtpy. */ - private boolean hasMetadata(MetaInfo meta) { + private boolean hasMetadata(VFSMetadata meta) { if (meta != null) { return StringHelper.containsNonWhitespace(meta.getCreator()) || StringHelper.containsNonWhitespace(meta.getPublisher()) || StringHelper.containsNonWhitespace(meta.getSource()) || StringHelper.containsNonWhitespace(meta.getCity()) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[0]) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[1]) || StringHelper.containsNonWhitespace(meta.getPages()) || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()) - || StringHelper.containsNonWhitespace(meta.getLicenseTypeKey()) || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) + || meta.getLicenseType() != null || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) || StringHelper.containsNonWhitespace(meta.getLicenseText()) || StringHelper.containsNonWhitespace(meta.getLicensor()); } return false; diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java index 55c374a537e9bfb2cb7ec92bb000979b5a8cbb72..ac12db606603bf3c1501cc738f9d86cdc1adc91a 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java @@ -35,6 +35,8 @@ import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.license.ui.LicenseSelectionConfig; import org.olat.core.commons.services.license.ui.LicenseUIFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -61,8 +63,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.lock.LockInfo; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -76,7 +76,6 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class MetaInfoFormController extends FormBasicController { private VFSItem item; - //private MetaInfo meta; private FormLink moreMetaDataLink; private String initialFilename; private TextElement filename, title, publisher, creator, sourceEl, city, pages, language, url, comment, publicationMonth, publicationYear; @@ -96,7 +95,7 @@ public class MetaInfoFormController extends FormBasicController { @Autowired private VFSLockManager vfsLockManager; @Autowired - private MetaInfoFactory metaInfoFactory; + private VFSRepositoryService vfsRepositoryService; @Autowired private LicenseModule licenseModule; @Autowired @@ -187,7 +186,7 @@ public class MetaInfoFormController extends FormBasicController { } setFormContextHelp("Folders#_metadata"); - MetaInfo meta = item == null ? null : item.getMetaInfo(); + VFSMetadata meta = item == null ? null : item.getMetaInfo(); // title String titleVal = (meta != null ? meta.getTitle() : null); @@ -206,7 +205,7 @@ public class MetaInfoFormController extends FormBasicController { // license if (licenseModule.isEnabled(licenseHandler)) { - License license = metaInfoFactory.getOrCreateLicense(meta, getIdentity()); + License license = vfsRepositoryService.getOrCreateLicense(meta, getIdentity()); LicenseSelectionConfig licenseSelectionConfig = LicenseUIFactory .createLicenseSelectionConfig(licenseHandler, license.getLicenseType()); @@ -272,7 +271,8 @@ public class MetaInfoFormController extends FormBasicController { url = uifactory.addTextElement("url", "mf.url", -1, urlVal, formLayout); /* static fields */ - String sizeText, typeText; + String sizeText; + String typeText; if (item instanceof VFSLeaf) { sizeText = Formatter.formatBytes(((VFSLeaf) item).getSize()); typeText = FolderHelper.extractFileType(item.getName(), getLocale()); @@ -299,7 +299,7 @@ public class MetaInfoFormController extends FormBasicController { if (!isSubform) { - if(meta != null && !meta.isDirectory()) { + if(meta != null && !(item instanceof VFSContainer)) { LockInfo lock = vfsLockManager.getLock(item); //locked String lockedTitle = getTranslator().translate("mf.locked"); @@ -331,14 +331,14 @@ public class MetaInfoFormController extends FormBasicController { } // username - String author = userManager.getUserDisplayName(meta == null ? null : meta.getAuthorIdentityKey()); + String author = userManager.getUserDisplayName(meta == null ? null : meta.getAuthor()); uifactory.addStaticTextElement("mf.author", StringHelper.escapeHtml(author), formLayout); // filesize uifactory.addStaticTextElement("mf.size", StringHelper.escapeHtml(sizeText), formLayout); // last modified date - String lastModified = meta == null ? "" : StringHelper.formatLocaleDate(meta.getLastModified(), getLocale()); + String lastModified = meta == null ? "" : Formatter.getInstance(getLocale()).formatDate(meta.getFileLastModified()); uifactory.addStaticTextElement("mf.lastModified", lastModified, formLayout); // file type @@ -362,7 +362,7 @@ public class MetaInfoFormController extends FormBasicController { formLayout.add(extUrlCont); } - if (!isSubform && meta != null && meta.isDirectory()) { + if (!isSubform && meta != null && item instanceof VFSContainer) { // Don't show any meta data except title and comment if the item is // a directory. // Hide the metadata. @@ -384,13 +384,13 @@ public class MetaInfoFormController extends FormBasicController { /** * @return True if one or more metadata fields are non-emtpy. */ - private boolean hasMetadata(MetaInfo meta) { + private boolean hasMetadata(VFSMetadata meta) { if (meta != null) { return StringHelper.containsNonWhitespace(meta.getCreator()) || StringHelper.containsNonWhitespace(meta.getPublisher()) || StringHelper.containsNonWhitespace(meta.getSource()) || StringHelper.containsNonWhitespace(meta.getCity()) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[0]) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[1]) || StringHelper.containsNonWhitespace(meta.getPages()) || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()) - || StringHelper.containsNonWhitespace(meta.getLicenseTypeKey()) || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) + || meta.getLicenseType() != null || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) || StringHelper.containsNonWhitespace(meta.getLicenseText()) || StringHelper.containsNonWhitespace(meta.getLicensor()); } return false; @@ -432,7 +432,7 @@ public class MetaInfoFormController extends FormBasicController { filename.setValue(name); } - public MetaInfo getMetaInfo(MetaInfo meta) { + public VFSMetadata getMetaInfo(VFSMetadata meta) { meta.setCreator(creator.getValue()); meta.setComment(comment.getValue()); meta.setTitle(title.getValue()); @@ -444,7 +444,7 @@ public class MetaInfoFormController extends FormBasicController { meta.setUrl(url.getValue()); meta.setPages(pages.getValue()); License license = getLicenseFromFormItems(); - meta.setLicenseTypeKey(license.getLicenseType() != null? String.valueOf(license.getLicenseType().getKey()): ""); + meta.setLicenseType(license.getLicenseType() == null ? null : license.getLicenseType()); meta.setLicenseTypeName(license.getLicenseType() != null? license.getLicenseType().getName(): ""); meta.setLicensor(license.getLicensor() != null? license.getLicensor(): ""); meta.setLicenseText(LicenseUIFactory.getLicenseText(license)); @@ -478,7 +478,7 @@ public class MetaInfoFormController extends FormBasicController { /** * @return The updated MeatInfo object */ - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { if (!isSubform && (item instanceof VFSLeaf) && (locked != null && locked.isEnabled())) { //isSubForm boolean alreadyLocked = vfsLockManager.isLocked(item); @@ -492,7 +492,7 @@ public class MetaInfoFormController extends FormBasicController { } } - MetaInfo meta = item == null ? null : item.getMetaInfo(); + VFSMetadata meta = item == null ? null : item.getMetaInfo(); if(meta == null) { return null; } @@ -501,7 +501,7 @@ public class MetaInfoFormController extends FormBasicController { @Override protected boolean validateFormLogic(UserRequest ureq) { - boolean valid = true; + boolean valid = super.validateFormLogic(ureq); // validate publication month String monthStr = publicationMonth.getValue(); diff --git a/src/main/java/org/olat/core/commons/modules/bc/notifications/FolderNotificationsHandler.java b/src/main/java/org/olat/core/commons/modules/bc/notifications/FolderNotificationsHandler.java index 7faf68314093ee8db142d6a6d3d41ad2d97a97f9..25d3ec27525bdbe73937c247f18df9ffbd3a5365 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/notifications/FolderNotificationsHandler.java +++ b/src/main/java/org/olat/core/commons/modules/bc/notifications/FolderNotificationsHandler.java @@ -43,6 +43,7 @@ import org.olat.core.commons.services.notifications.SubscriptionInfo; import org.olat.core.commons.services.notifications.manager.NotificationsUpgradeHelper; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; import org.olat.core.commons.services.notifications.model.TitleItem; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.translator.Translator; import org.olat.core.gui.util.CSSHelper; import org.olat.core.id.context.BusinessControlFactory; @@ -51,7 +52,6 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.repository.RepositoryEntry; @@ -115,7 +115,7 @@ public class FolderNotificationsHandler implements NotificationsHandler { // skip this file, continue with next item in folder continue; } - MetaInfo metaInfo = fi.getMetaInfo(); + VFSMetadata metaInfo = fi.getMetaInfo(); String iconCssClass = null; if (metaInfo != null) { if (metaInfo.getTitle() != null) { diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java new file mode 100644 index 0000000000000000000000000000000000000000..d778f06ba3b71b003c0ec9fe01b999bfbf064263 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java @@ -0,0 +1,141 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +import java.util.Date; + +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.id.CreateInfo; +import org.olat.core.id.Identity; +import org.olat.core.id.ModifiedInfo; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { + + public String getUuid(); + + public void setUuid(String id); + + public String getRelativePath(); + + public String getFilename(); + + public Date getFileLastModified(); + + public long getFileSize(); + + public boolean isDirectory(); + + public String getIconCssClass(); + + public String getUri(); + + public String getProtocol(); + + public Identity getAuthor(); + + public void setAuthor(Identity author); + + public String getTitle(); + + public void setTitle(String title); + + public String getComment(); + + public void setComment(String text); + + public int getDownloadCount(); + + public String getCreator(); + + public void setCreator(String creator); + + public String getPublisher(); + + public void setPublisher(String publisher); + + public String getCity(); + + public void setCity(String city); + + public String[] getPublicationDate(); + + public void setPublicationDate(String month, String year); + + + public String getUrl(); + + public void setUrl(String url); + + public String getSource(); + + public void setSource(String source); + + public String getLanguage(); + + public void setLanguage(String language); + + public String getPages(); + + public void setPages(String pages); + + + public Boolean getCannotGenerateThumbnails(); + + public void setCannotGenerateThumbnails(Boolean val); + + + public LicenseType getLicenseType(); + + public void setLicenseType(LicenseType type); + + public String getLicenseTypeName(); + + public void setLicenseTypeName(String name); + + public String getLicenseText(); + + public void setLicenseText(String text); + + public String getLicensor(); + + public void setLicensor(String licensor); + + + public boolean isLocked(); + + public void setLocked(boolean locked); + + public Identity getLockedBy(); + + public void setLockedBy(Identity lockedBy); + + public Date getLockedDate(); + + public void setLockedDate(Date date); + + public void copyValues(VFSMetadata metadata); + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSMetadataRef.java b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadataRef.java new file mode 100644 index 0000000000000000000000000000000000000000..d231dc6c14d95cc2f52e967654ec4651fa0b8a8d --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadataRef.java @@ -0,0 +1,37 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +import org.olat.core.commons.services.vfs.model.VFSMetadataRefImpl; + +/** + * + * Initial date: 13 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface VFSMetadataRef { + + public Long getKey(); + + public static VFSMetadataRef valueOf(final Long key) { + return new VFSMetadataRefImpl(key); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java new file mode 100644 index 0000000000000000000000000000000000000000..a36b0d7baebf7f753e123fdc5b9fd4c509549b22 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java @@ -0,0 +1,30 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSRepositoryModule { + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java new file mode 100644 index 0000000000000000000000000000000000000000..6a2200e0d7482a5214b0cb348b7e596f53b1f26b --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java @@ -0,0 +1,131 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +import java.io.File; +import java.util.List; + +import org.olat.core.commons.services.license.License; +import org.olat.core.id.Identity; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSItem; +import org.olat.core.util.vfs.VFSLeaf; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface VFSRepositoryService { + + public VFSMetadata getMetadataFor(VFSItem path); + + public VFSMetadata getMetadataFor(File file); + + /** + * The list of direct children in the specified + * relative path. + * + * @param relativePath The relative path + * @return A list of metadata + */ + public List<VFSMetadata> getChildren(String relativePath); + + /** + * The list of direct children in the directory + * specified by the metadata. + * + * @param metadata The metadata of the directory + * @return A list of metadata + */ + public List<VFSMetadata> getChildren(VFSMetadataRef parentMetadata); + + public VFSMetadata updateMetadata(VFSMetadata data); + + public void deleteMetadata(VFSMetadata data); + + public void deleteMetadata(File file); + + /** + * Copy the metadata from one file to the other. + * + * @param source The source file + * @param target The target file + * @param parentTarget The parent container of the target (useful if the target is not fully initialized) + */ + public void copyTo(VFSLeaf source, VFSLeaf target, VFSContainer parentTarget); + + public VFSMetadata rename(VFSMetadata data, String newName); + + public void increaseDownloadCount(VFSItem item); + + /** + * Copy the binaries data saved in ZIP files. + * + * @param metadata The metadata + * @param binaries The binaries + */ + public void copyBinaries(VFSMetadata metadata, byte[] binaries); + + + public boolean isThumbnailAvailable(VFSItem item); + + /** + * Use this if you have already collected the metadata has it is + * database query free. + * + * @param item The file (mandatory) + * @param metadata The metadata object (mandatory) + * @return true if the thumbnail can eventually be generated or are available + */ + public boolean isThumbnailAvailable(VFSItem item, VFSMetadata metadata); + + public VFSLeaf getThumbnail(VFSLeaf file, int maxWidth, int maxHeight, boolean fill); + + /** + * This method prevent reloading the metadata + * + * @param file The file + * @param metadata The metadata of the file if you already have it + * @param maxWidth + * @param maxHeight + * @param fill + * @return + */ + public VFSLeaf getThumbnail(VFSLeaf file, VFSMetadata metadata, int maxWidth, int maxHeight, boolean fill); + + public void resetThumbnails(VFSLeaf file); + + /** + * If the specified file is a directory, it will recursively + * reset the thumbnails of all files. + * + * @param file A file in /bcroot/ + */ + public void resetThumbnails(File file); + + + + public License getLicense(VFSMetadata meta); + + public License getOrCreateLicense(VFSMetadata meta, Identity itentity); + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSThumbnailMetadata.java b/src/main/java/org/olat/core/commons/services/vfs/VFSThumbnailMetadata.java new file mode 100644 index 0000000000000000000000000000000000000000..1db21aaaa9c7241005058cf91d73e2f60e769ad8 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSThumbnailMetadata.java @@ -0,0 +1,51 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +import org.olat.core.id.CreateInfo; +import org.olat.core.id.ModifiedInfo; + +/** + * + * Initial date: 14 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface VFSThumbnailMetadata extends ModifiedInfo, CreateInfo { + + public Long getKey(); + + public long getFileSize(); + + public boolean isFill(); + + public int getFinalHeight(); + + public int getFinalWidth(); + + public int getMaxHeight(); + + public int getMaxWidth(); + + public String getFilename(); + + public VFSMetadata getOwner(); + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/MetaInfoReader.java b/src/main/java/org/olat/core/commons/services/vfs/manager/MetaInfoReader.java new file mode 100644 index 0000000000000000000000000000000000000000..eef6992e7271649c59fa290da73ed82d7dc76c0a --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/MetaInfoReader.java @@ -0,0 +1,389 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Serializable; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.FileUtils; +import org.olat.core.util.StringHelper; +import org.olat.core.util.filter.FilterFactory; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + * Initial date: 12 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class MetaInfoReader { + + private static final OLog log = Tracing.createLoggerFor(MetaInfoReader.class); + + private static SAXParser saxParser; + static { + try { + saxParser = SAXParserFactory.newInstance().newSAXParser(); + } catch(Exception ex) { + log.error("", ex); + } + } + + private final VFSMetadataImpl meta; + private final List<Thumbnail> thumbnails = new ArrayList<>(); + + private LicenseService licenseService; + private final BaseSecurity securityManager; + + public MetaInfoReader(VFSMetadataImpl meta, LicenseService licenseService, BaseSecurity securityManager) { + this.meta = meta; + this.licenseService = licenseService; + this.securityManager = securityManager; + } + + public VFSMetadataImpl getMetadata() { + return meta; + } + + public List<Thumbnail> getThumbnails() { + return thumbnails; + } + + public void fromBinaries(byte[] binaries) { + try(InputStream in = new ByteArrayInputStream(binaries)) { + synchronized(saxParser) { + saxParser.parse(in, new MetaHandler(null)); + } + } catch(Exception ex) { + log.error("Error while parsing binaries", ex); + } + } + + public boolean parseSAX(File fMeta) { + if (fMeta == null || !fMeta.exists() || fMeta.isDirectory()) return false; + + try(InputStream in = new FileInputStream(fMeta); + BufferedInputStream bis = new BufferedInputStream(in, FileUtils.BSIZE)) { + synchronized(saxParser) { + saxParser.parse(bis, new MetaHandler(fMeta)); + } + } catch (SAXParseException ex) { + if(!parseSAXFiltered(fMeta)) { + log.warn("SAX Parser error while parsing " + fMeta, ex); + } + } catch(Exception ex) { + log.error("Error while parsing " + fMeta, ex); + } + return true; + } + + /** + * Try to rescue xml files with invalid characters + * @param fMeta + * @return true if rescue is successful + */ + private boolean parseSAXFiltered(File fMeta) { + String original = FileUtils.load(fMeta, "UTF-8"); + if(original == null) return false; + + String filtered = FilterFactory.getXMLValidCharacterFilter().filter(original); + if(!original.equals(filtered)) { + try { + synchronized(saxParser) { + InputSource in = new InputSource(new StringReader(filtered)); + saxParser.parse(in, new MetaHandler(fMeta)); + } + return true; + } catch (Exception e) { + //only a fallback, fail silently + } + } + return false; + } + + /** + * Writes the meta data to file. If no changes have been made, + * does not write anything. + * @return True upon success. + */ + public static final byte[] toBinaries(VFSMetadata metadata) { + if (metadata == null) return new byte[0]; + + try(ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStreamWriter sw = new OutputStreamWriter(out, Charset.forName("UTF-8"))) { + + sw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + sw.write("<meta"); + if(StringHelper.containsNonWhitespace(metadata.getUuid())) { + sw.write(" uuid=\"" + metadata.getUuid() + "\""); + } + sw.write(">"); + + Long authorIdentKey = metadata.getAuthor() == null ? null : metadata.getAuthor().getKey(); + Long lockedByIdentKey = metadata.getLockedBy() == null ? null : metadata.getLockedBy().getKey(); + Date lockedDate = metadata.getLockedDate(); + Long licenseTypeKey = metadata.getLicenseType() == null ? null : metadata.getLicenseType().getKey(); + String[] publicationDates = metadata.getPublicationDate(); + String pubYear = publicationDates[0]; + String pubMonth = publicationDates[1]; + + sw.write("<author><![CDATA[" + (authorIdentKey == null ? "" : authorIdentKey.toString()) + "]]></author>"); + sw.write("<lock locked=\"" + metadata.isLocked() + "\"" + (lockedDate == null ? "" : " date=\"" + lockedDate.getTime() + "\"") + "><![CDATA[" + (lockedByIdentKey == null ? "" : lockedByIdentKey) + "]]></lock>"); + sw.write("<comment><![CDATA[" + filterForCData(metadata.getComment()) + "]]></comment>"); + sw.write("<title><![CDATA[" + filterForCData(metadata.getTitle()) + "]]></title>"); + sw.write("<publisher><![CDATA[" + filterForCData(metadata.getPublisher()) + "]]></publisher>"); + sw.write("<creator><![CDATA[" + filterForCData(metadata.getCreator()) + "]]></creator>"); + sw.write("<source><![CDATA[" + filterForCData(metadata.getSource()) + "]]></source>"); + sw.write("<city><![CDATA[" + filterForCData(metadata.getCity()) + "]]></city>"); + sw.write("<pages><![CDATA[" + filterForCData(metadata.getPages()) + "]]></pages>"); + sw.write("<language><![CDATA[" + filterForCData(metadata.getLanguage()) + "]]></language>"); + sw.write("<url><![CDATA[" + filterForCData(metadata.getUrl()) + "]]></url>"); + sw.write("<licenseTypeKey><![CDATA[" + licenseTypeKey + "]]></licenseTypeKey>"); + sw.write("<licenseTypeName><![CDATA[" + filterForCData(metadata.getLicenseTypeName()) + "]]></licenseTypeName>"); + sw.write("<licenseText><![CDATA[" + filterForCData(metadata.getLicenseText()) + "]]></licenseText>"); + sw.write("<licensor><![CDATA[" + filterForCData(metadata.getLicensor()) + "]]></licensor>"); + sw.write("<publicationDate><month><![CDATA[" + (pubMonth != null ? pubMonth.trim() : "") + "]]></month><year><![CDATA[" + (pubYear != null ? pubYear.trim() : "") + "]]></year></publicationDate>"); + sw.write("<downloadCount><![CDATA[" + metadata.getDownloadCount() + "]]></downloadCount>"); + if(metadata instanceof VFSMetadataImpl) { + Boolean cannotGenerateThumbnail = ((VFSMetadataImpl)metadata).getCannotGenerateThumbnails(); + sw.write("<thumbnails cannotGenerateThumbnail=\"" + (cannotGenerateThumbnail == null ? "" : cannotGenerateThumbnail) + "\"></thumbnails>"); + } + sw.write("</meta>"); + sw.flush(); + return out.toByteArray(); + } catch (Exception e) { + return new byte[0]; + } + } + + private static final String filterForCData(String original) { + if(StringHelper.containsNonWhitespace(original)) { + return FilterFactory.getXMLValidCharacterFilter().filter(original); + } + return ""; + } + + private class MetaHandler extends DefaultHandler { + + private StringBuilder current; + private final File fMeta; + + public MetaHandler(File fMeta) { + this.fMeta = fMeta; + } + + @Override + public final void startElement(String uri, String localName, String qName, Attributes attributes) { + if("meta".equals(qName)) { + meta.setUuid(attributes.getValue("uuid")); + } else if ("lock".equals(qName)) { + meta.setLocked("true".equals(attributes.getValue("locked"))); + String date = attributes.getValue("date"); + if (date != null && date.length() > 0) { + meta.setLockedDate(new Date(Long.parseLong(date))); + } + } else if ("thumbnails".equals(qName)) { + String valueStr = attributes.getValue("cannotGenerateThumbnail"); + if(StringHelper.containsNonWhitespace(valueStr)) { + meta.setCannotGenerateThumbnails(Boolean.valueOf(valueStr).booleanValue()); + } + }else if ("thumbnail".equals(qName)) { + Thumbnail thumbnail = new Thumbnail(); + thumbnail.setMaxHeight(Integer.parseInt(attributes.getValue("maxHeight"))); + thumbnail.setMaxWidth(Integer.parseInt(attributes.getValue("maxWidth"))); + thumbnail.setFinalHeight(Integer.parseInt(attributes.getValue("finalHeight"))); + thumbnail.setFinalWidth(Integer.parseInt(attributes.getValue("finalWidth"))); + thumbnail.setFill("true".equals(attributes.getValue("fill"))); + thumbnails.add(thumbnail); + } + } + + @Override + public final void characters(char[] ch, int start, int length) { + if(length == 0) return; + if(current == null) { + current = new StringBuilder(); + } + current.append(ch, start, length); + } + + @Override + public final void endElement(String uri, String localName, String qName) { + if(current == null) return; + + if("comment".equals(qName)) { + meta.setComment(current.toString()); + } else if ("author".equals(qName)) { + Long authorKey = getLong(); + if(authorKey != null) { + meta.setAuthor(securityManager.loadIdentityByKey(authorKey)); + } + } else if ("lock".equals(qName)) { + Long lockedByKey = getLong(); + if(lockedByKey != null) { + meta.setLockedBy(securityManager.loadIdentityByKey(lockedByKey)); + } + } else if ("title".equals(qName)) { + meta.setTitle(current.toString()); + } else if ("publisher".equals(qName)) { + meta.setPublisher(current.toString()); + } else if ("source".equals(qName)) { + meta.setSource(current.toString()); + } else if ("city".equals(qName)) { + meta.setCity(current.toString()); + } else if ("pages".equals(qName)) { + meta.setPages(current.toString()); + } else if ("language".equals(qName)) { + meta.setLanguage(current.toString()); + } else if ("downloadCount".equals(qName)) { + Long key = getLong(); + if(key != null) { + meta.setDownloadCount(key.intValue()); + } + } else if ("month".equals(qName)) { + meta.setPubMonth(current.toString()); + } else if ("year".equals(qName)) { + meta.setPubYear(current.toString()); + } else if (qName.equals("creator")) { + meta.setCreator(current.toString()); + } else if (qName.equals("url")) { + meta.setUrl(current.toString()); + } else if (qName.equals("licenseTypeKey")) { + // + } else if (qName.equals("licenseTypeName")) { + String licenseTypeName = current.toString().trim(); + if(StringHelper.containsNonWhitespace(licenseTypeName)) { + meta.setLicenseTypeName(current.toString()); + meta.setLicenseType(licenseService.loadLicenseTypeByName(licenseTypeName)); + } + } else if (qName.equals("licenseText")) { + meta.setLicenseText(current.toString()); + } else if (qName.equals("licensor")) { + meta.setLicensor(current.toString()); + } else if (qName.equals("thumbnail")) { + if(fMeta != null) { + String finalName = current.toString(); + File thumbnailFile = new File(fMeta.getParentFile(), finalName); + thumbnails.get(thumbnails.size() - 1).setThumbnailFile(thumbnailFile); + } + } + current = null; + } + + private Long getLong() { + try { + String val = current.toString(); + if(StringHelper.isLong(val)) { + return Long.valueOf(val); + } + } catch (NumberFormatException nEx) { + //nothing to say + } + return null; + } + } + + public static class Thumbnail implements Serializable { + + private static final long serialVersionUID = 29491661959555446L; + + private int maxWidth; + private int maxHeight; + private int finalWidth; + private int finalHeight; + private boolean fill = false; + private File thumbnailFile; + + public int getMaxWidth() { + return maxWidth; + } + + public void setMaxWidth(int maxWidth) { + this.maxWidth = maxWidth; + } + + public int getMaxHeight() { + return maxHeight; + } + + public void setMaxHeight(int maxHeight) { + this.maxHeight = maxHeight; + } + + public int getFinalWidth() { + return finalWidth; + } + + public void setFinalWidth(int finalWidth) { + this.finalWidth = finalWidth; + } + + public int getFinalHeight() { + return finalHeight; + } + + public void setFinalHeight(int finalHeight) { + this.finalHeight = finalHeight; + } + + public boolean isFill() { + return fill; + } + + public void setFill(boolean fill) { + this.fill = fill; + } + + public File getThumbnailFile() { + return thumbnailFile; + } + + public void setThumbnailFile(File thumbnailFile) { + this.thumbnailFile = thumbnailFile; + } + + public boolean exists() { + return thumbnailFile != null && thumbnailFile.exists(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..58b2a64c1fd47152a0c070abc74059b8f929a98e --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java @@ -0,0 +1,204 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSMetadataRef; +import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class VFSMetadataDAO { + + @Autowired + private DB dbInstance; + + public VFSMetadata createMetadata(String uuid, String relativePath, String filename, + Date fileLastModified, long size, boolean directory, String uri, String uriProtocol, + VFSMetadata parent) { + VFSMetadataImpl metadata = new VFSMetadataImpl(); + metadata.setCreationDate(new Date()); + metadata.setLastModified(metadata.getCreationDate()); + metadata.setUuid(uuid); + metadata.setRelativePath(relativePath); + metadata.setFilename(filename); + metadata.setDirectory(directory); + metadata.setFileLastModified(fileLastModified); + metadata.setFileSize(size); + metadata.setUri(uri); + metadata.setProtocol(uriProtocol); + metadata.setParent(parent); + dbInstance.getCurrentEntityManager().persist(metadata); + metadata.setMaterializedPathKeys(getMaterializedPathKeys((VFSMetadataImpl)parent, metadata)); + metadata = dbInstance.getCurrentEntityManager().merge(metadata); + return metadata; + } + + public VFSMetadata createMetadata(VFSMetadataImpl metadata, String relativePath, String filename, + Date fileLastModified, long size, boolean directory, String uri, String uriProtocol, + VFSMetadata parent) { + + metadata.setCreationDate(new Date()); + metadata.setLastModified(metadata.getCreationDate()); + if(metadata.getUuid() == null) { + metadata.setUuid(UUID.randomUUID().toString()); + } + metadata.setRelativePath(relativePath); + metadata.setFilename(filename); + metadata.setDirectory(directory); + metadata.setFileLastModified(fileLastModified); + metadata.setFileSize(size); + metadata.setUri(uri); + metadata.setProtocol(uriProtocol); + metadata.setParent(parent); + dbInstance.getCurrentEntityManager().persist(metadata); + metadata.setMaterializedPathKeys(getMaterializedPathKeys((VFSMetadataImpl)parent, metadata)); + metadata = dbInstance.getCurrentEntityManager().merge(metadata); + return metadata; + } + + /** + * Calculate the materialized path from the parent element. + * + * @param parent The parent element (can be null if the element is a root one) + * @param element The curriculum element + * @return The materialized path of the specified element + */ + private String getMaterializedPathKeys(VFSMetadataImpl parent, VFSMetadataImpl element) { + if(parent != null) { + String parentPathOfKeys = parent.getMaterializedPathKeys(); + if(parentPathOfKeys == null || "/".equals(parentPathOfKeys)) { + parentPathOfKeys = ""; + } + return parentPathOfKeys + element.getKey() + "/"; + } + return "/" + element.getKey() + "/"; + } + + public VFSMetadata getMetadata(String uuid) { + StringBuilder sb = new StringBuilder(256); + sb.append("select metadata from filemetadata metadata") + .append(" left join fetch metadata.author as author") + .append(" left join fetch author.user as authorUser") + .append(" left join fetch metadata.licenseType as licenseType") + .append(" where metadata.uuid=:uuid"); + + + List<VFSMetadata> metadata = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSMetadata.class) + .setParameter("uuid", uuid) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return metadata == null || metadata.isEmpty() ? null : metadata.get(0); + } + + public VFSMetadata getMetadata(String relativePath, String filename, boolean directory) { + StringBuilder sb = new StringBuilder(256); + sb.append("select metadata from filemetadata metadata") + .append(" left join fetch metadata.author as author") + .append(" left join fetch author.user as authorUser") + .append(" left join fetch metadata.licenseType as licenseType") + .append(" where metadata.filename=:filename and metadata.relativePath=:relativePath and metadata.directory=:directory"); + + List<VFSMetadata> metadata = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSMetadata.class) + .setParameter("filename", filename) + .setParameter("relativePath", relativePath) + .setParameter("directory", Boolean.valueOf(directory)) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return metadata == null || metadata.isEmpty() ? null : metadata.get(0); + } + + /** + * This is an exact match to find the direct children of a specific + * directory. + * + * @param relativePath The relative path + * @return A list of metadata + */ + public List<VFSMetadata> getMetadatas(String relativePath) { + StringBuilder sb = new StringBuilder(256); + sb.append("select metadata from filemetadata metadata") + .append(" left join fetch metadata.author as author") + .append(" left join fetch author.user as authorUser") + .append(" left join fetch metadata.licenseType as licenseType") + .append(" where metadata.relativePath=:relativePath"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSMetadata.class) + .setParameter("relativePath", relativePath) + .getResultList(); + } + + /** + * This is an exact match to find the direct children of the specific + * directory described by its metadata. + * + * @param relativePath The relative path + * @return A list of metadata + */ + public List<VFSMetadata> getMetadatas(VFSMetadataRef parentMetadata) { + StringBuilder sb = new StringBuilder(256); + sb.append("select metadata from filemetadata metadata") + .append(" left join fetch metadata.author as author") + .append(" left join fetch author.user as authorUser") + .append(" left join fetch metadata.licenseType as licenseType") + .append(" where metadata.parent.key=:parentKey"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSMetadata.class) + .setParameter("parentKey", parentMetadata.getKey()) + .getResultList(); + } + + public VFSMetadata updateMetadata(VFSMetadata metadata) { + ((VFSMetadataImpl)metadata).setLastModified(new Date()); + return dbInstance.getCurrentEntityManager().merge(metadata); + } + + public void removeMetadata(VFSMetadata metadata) { + dbInstance.getCurrentEntityManager().remove(metadata); + } + + public void increaseDownloadCount(String relativePath, String filename) { + String updateQuery = "update vfsmetadatadownloadcount set downloadCount=downloadCount+1 where filename=:filename and relativePath=:relativePath"; + dbInstance.getCurrentEntityManager() + .createQuery(updateQuery) + .setParameter("filename", filename) + .setParameter("relativePath", relativePath) + .executeUpdate(); + } + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0aeb6ebe2f1ebe7044775ffa56c5aef276082ea3 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java @@ -0,0 +1,609 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Date; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.modules.bc.FolderLicenseHandler; +import org.olat.core.commons.modules.bc.FolderModule; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException; +import org.olat.core.commons.services.thumbnail.FinalSize; +import org.olat.core.commons.services.thumbnail.ThumbnailService; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSMetadataRef; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSThumbnailMetadata; +import org.olat.core.commons.services.vfs.manager.MetaInfoReader.Thumbnail; +import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; +import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.FileUtils; +import org.olat.core.util.StringHelper; +import org.olat.core.util.vfs.LocalFileImpl; +import org.olat.core.util.vfs.VFSConstants; +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.VFSManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class VFSRepositoryServiceImpl implements VFSRepositoryService { + + private static final OLog log = Tracing.createLoggerFor(VFSRepositoryServiceImpl.class); + private static final String CANONICAL_ROOT_REL_PATH = "/"; + + @Autowired + private DB dbInstance; + @Autowired + private FolderModule folderModule; + @Autowired + private VFSMetadataDAO metadataDao; + @Autowired + private VFSThumbnailDAO thumbnailDao; + @Autowired + private LicenseService licenseService; + @Autowired + private FolderLicenseHandler licenseHandler; + @Autowired + private ThumbnailService thumbnailService; + @Autowired + private BaseSecurity securityManager; + + @Override + public VFSMetadata getMetadataFor(VFSItem path) { + File file = toFile(path); + return getMetadataFor(file); + } + + @Override + public VFSMetadata getMetadataFor(File file) { + String relativePath = getRelativePath(file.getParentFile()); + if(relativePath.equals("..")) { + return null; + } + if(relativePath.equals("")) { + relativePath = CANONICAL_ROOT_REL_PATH; + } + + String filename = file.getName(); + VFSMetadata metadata = metadataDao.getMetadata(relativePath, filename, file.isDirectory()); + if(metadata == null) { + String uuid = UUID.randomUUID().toString(); + String uri = file.toURI().toString(); + boolean directory = file.isDirectory(); + long size = directory ? 0l : file.length(); + + VFSMetadata parent = getMetadataFor(file.getParentFile()); + metadata = metadataDao.createMetadata(uuid, relativePath, filename, new Date(), size, directory, uri, "file", parent); + } + return metadata; + } + + /** + * This method doesn't create missing database entry. + * + * @param file The file + * @return A metadata object or null if not found + */ + private VFSMetadata loadMetadata(File file) { + if(file == null) return null; + + String relativePath = getRelativePath(file.getParentFile()); + if(relativePath.equals("..")) { + return null; + } + if(relativePath.equals("")) { + relativePath = CANONICAL_ROOT_REL_PATH; + } + + String filename = file.getName(); + return metadataDao.getMetadata(relativePath, filename, file.isDirectory()); + } + + private File toFile(VFSItem item) { + String relPath = item.getRelPath(); + return relPath == null ? null : VFSManager.olatRootFile(relPath); + } + + @Override + public List<VFSMetadata> getChildren(String relativePath) { + if(relativePath == null) return new ArrayList<>(); + if(!relativePath.equals(CANONICAL_ROOT_REL_PATH) && relativePath.startsWith("/")) { + relativePath = relativePath.substring(1, relativePath.length()); + } + return metadataDao.getMetadatas(relativePath); + } + + @Override + public List<VFSMetadata> getChildren(VFSMetadataRef parentMetadata) { + return metadataDao.getMetadatas(parentMetadata); + } + + /** + * The relative path contains /bcroot/ + * + * @param file + * @return + */ + private String getRelativePath(File file) { + return folderModule.getCanonicalRootPath().relativize(file.toPath()).toString(); + } + + private String getRelativePath(VFSItem item) { + String relativePath = item.getRelPath(); + if(!relativePath.equals(CANONICAL_ROOT_REL_PATH) && relativePath.startsWith("/")) { + relativePath = relativePath.substring(1, relativePath.length()); + } + return relativePath; + } + + @Override + public VFSMetadata updateMetadata(VFSMetadata data) { + return metadataDao.updateMetadata(data); + } + + @Override + public void deleteMetadata(VFSMetadata data) { + List<VFSThumbnailMetadata> thumbnails = thumbnailDao.loadByMetadata(data); + for(VFSThumbnailMetadata thumbnail:thumbnails) { + VFSItem item = VFSManager.olatRootLeaf("/" + data.getRelativePath(), thumbnail.getFilename()); + if(item != null && item.exists()) { + item.deleteSilently(); + } + thumbnailDao.removeThumbnail(thumbnail); + } + metadataDao.removeMetadata(data); + } + + @Override + public void deleteMetadata(File file) { + VFSMetadata metadata = loadMetadata(file); + if(metadata != null) { + deleteMetadata(metadata); + } + } + + @Override + public void copyBinaries(VFSMetadata metadata, byte[] binaries) { + if(binaries == null || binaries.length == 0) return; + + MetaInfoReader reader = new MetaInfoReader((VFSMetadataImpl)metadata, licenseService, securityManager); + reader.fromBinaries(binaries); + } + + @Override + public void copyTo(VFSLeaf source, VFSLeaf target, VFSContainer parentTarget) { + if(source.canMeta() != VFSConstants.YES || target.canMeta() != VFSConstants.YES) return; + + VFSMetadataImpl sourceMetadata = (VFSMetadataImpl)loadMetadata(toFile(source)); + if(sourceMetadata != null) { + File targetFile = toFile(target); + if(targetFile != null) { + VFSMetadata targetMetadata = loadMetadata(targetFile); + if(targetMetadata == null) { + VFSMetadata parentMetadata = getMetadataFor(parentTarget); + String relativePath = this.getRelativePath(targetFile.getParentFile()); + targetMetadata = metadataDao.createMetadata(UUID.randomUUID().toString(), relativePath, targetFile.getName(), + new Date(), targetFile.length(), false, targetFile.toURI().toString(), "file", parentMetadata); + } + targetMetadata.copyValues(sourceMetadata); + metadataDao.updateMetadata(targetMetadata); + } + } + } + + @Override + public VFSMetadata rename(VFSMetadata data, String newName) { + ((VFSMetadataImpl)data).setFilename(newName); + Path newFile = Paths.get(folderModule.getCanonicalRoot(), data.getRelativePath(), newName); + String uri = newFile.toFile().toURI().toString(); + ((VFSMetadataImpl)data).setUri(uri); + return metadataDao.updateMetadata(data); + } + + @Override + public void increaseDownloadCount(VFSItem item) { + String relPath = item.getRelPath(); + if(StringHelper.containsNonWhitespace(relPath)) { + metadataDao.increaseDownloadCount(relPath, item.getName()); + } + } + + @Override + public VFSLeaf getThumbnail(VFSLeaf file, VFSMetadata metadata, int maxWidth, int maxHeight, boolean fill) { + VFSLeaf thumbnailLeaf = null; + + VFSContainer parentContainer = file.getParentContainer(); + String relativePath = getRelativePath(parentContainer); + if(relativePath != null) { + VFSThumbnailMetadata thumbnail = thumbnailDao.findThumbnail(relativePath, file.getName(), fill, maxWidth, maxHeight); + if(thumbnail == null) { + thumbnailLeaf = generateThumbnail(file, metadata, fill, maxWidth, maxHeight); + } else { + VFSItem item = parentContainer.resolve(thumbnail.getFilename()); + if(item instanceof VFSLeaf) { + thumbnailLeaf = (VFSLeaf)item; + } + } + } + return thumbnailLeaf; + } + + @Override + public VFSLeaf getThumbnail(VFSLeaf file, int maxWidth, int maxHeight, boolean fill) { + VFSLeaf thumbnailLeaf = null; + + VFSContainer parentContainer = file.getParentContainer(); + String relativePath = getRelativePath(parentContainer); + if(relativePath != null) { + VFSThumbnailMetadata thumbnail = thumbnailDao.findThumbnail(relativePath, file.getName(), fill, maxWidth, maxHeight); + if(thumbnail == null) { + VFSMetadata metadata = metadataDao.getMetadata(relativePath, file.getName(), false); + thumbnailLeaf = generateThumbnail(file, metadata, fill, maxWidth, maxHeight); + } else { + VFSItem item = parentContainer.resolve(thumbnail.getFilename()); + if(item instanceof VFSLeaf) { + thumbnailLeaf = (VFSLeaf)item; + } + } + } + return thumbnailLeaf; + } + + private VFSLeaf generateThumbnail(VFSLeaf file, VFSMetadata metadata, boolean fill, int maxWidth, int maxHeight) { + String name = file.getName(); + String extension = FileUtils.getFileSuffix(name); + String nameOnly = name.substring(0, name.length() - extension.length() - 1); + String thumbnailExtension = preferedThumbnailType(extension); + String thumbnailName = generateFilenameForThumbnail(nameOnly, thumbnailExtension, fill, maxWidth, maxHeight); + + VFSContainer parentContainer = file.getParentContainer(); + VFSLeaf thumbnailLeaf = parentContainer.createChildLeaf(thumbnailName); + if(thumbnailService.isThumbnailPossible(thumbnailLeaf)) { + try { + FinalSize finalSize = thumbnailService.generateThumbnail(file, thumbnailLeaf, maxWidth, maxHeight, fill); + if(finalSize == null) { + thumbnailLeaf = null; + metadata.setCannotGenerateThumbnails(Boolean.TRUE); + metadataDao.updateMetadata(metadata); + } else { + thumbnailDao.createThumbnailMetadata(metadata, thumbnailName, thumbnailLeaf.getSize(), + fill, maxWidth, maxHeight, finalSize.getWidth(), finalSize.getHeight()); + } + } catch (CannotGenerateThumbnailException e) { + metadata.setCannotGenerateThumbnails(Boolean.TRUE); + metadataDao.updateMetadata(metadata); + thumbnailLeaf = null; + } + } + return thumbnailLeaf; + } + + private String preferedThumbnailType(String extension) { + if(extension.equalsIgnoreCase("png") || extension.equalsIgnoreCase("gif")) { + return extension; + } + if(extension.equalsIgnoreCase("pdf")) { + return "png"; + } + return "jpg"; + } + + @Override + public boolean isThumbnailAvailable(VFSItem item, VFSMetadata metadata) { + if(metadata == null) return false; + + if(metadata.isDirectory() || (metadata.getCannotGenerateThumbnails() != null && metadata.getCannotGenerateThumbnails().booleanValue())) { + return false; + } + return thumbnailService.isThumbnailPossible((VFSLeaf)item); + } + + @Override + public boolean isThumbnailAvailable(VFSItem item) { + if(item instanceof VFSContainer) return false; + + File originFile = toFile(item); + if(originFile == null || originFile.isHidden()) { + return false; + } + + VFSMetadata metadata = loadMetadata(originFile); + if(metadata != null && metadata.getCannotGenerateThumbnails() != null && metadata.getCannotGenerateThumbnails().booleanValue()) { + return false; + } + return thumbnailService.isThumbnailPossible((VFSLeaf)item); + } + + @Override + public void resetThumbnails(VFSLeaf file) { + VFSContainer parentContainer = file.getParentContainer(); + String relativePath = getRelativePath(parentContainer); + if(relativePath == null) return; + + List<VFSThumbnailMetadata> thumbnails = thumbnailDao.findThumbnails(relativePath, file.getName()); + for(VFSThumbnailMetadata thumbnail:thumbnails) { + VFSItem item = parentContainer.resolve(thumbnail.getFilename()); + if(item != null) { + item.deleteSilently(); + } + thumbnailDao.removeThumbnail(thumbnail); + } + } + + @Override + public void resetThumbnails(File file) { + if(file.isFile()) { + VFSLeaf leaf = new LocalFileImpl(file); + if(leaf.getRelPath() != null) { + resetThumbnails(leaf); + } + } else if(file.isDirectory()) { + try { + Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { + VFSLeaf leaf = new LocalFileImpl(path.toFile()); + if(leaf.getRelPath() != null) { + resetThumbnails(leaf); + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + log.error("", e); + } + } + } + + /** + * Get the license of the MetaInfo + * + * @param meta + * @return the license or null if no license is stored in the MetaInfo + */ + @Override + public License getLicense(VFSMetadata meta) { + License license = null; + boolean hasLicense = meta != null && StringHelper.containsNonWhitespace(meta.getLicenseTypeName()); + if (hasLicense) { + String licenseTypeName = meta.getLicenseTypeName(); + LicenseType licenseType = null; + if(meta.getLicenseType() != null) { + licenseType = meta.getLicenseType(); + } else { + licenseType = licenseService.loadLicenseTypeByName(licenseTypeName); + } + if (licenseType == null) { + licenseType = licenseService.createLicenseType(licenseTypeName); + licenseType.setText(meta.getLicenseText()); + licenseService.saveLicenseType(licenseType); + } + license = licenseService.createLicense(licenseType); + license.setLicensor(meta.getLicensor()); + if (licenseService.isFreetext(licenseType)) { + license.setFreetext(meta.getLicenseText()); + } + } + return license; + } + + /** + * Get the license of the MetaInfo or create a new default license: + * + * @param meta + * @param itentity the current user + * @return + */ + @Override + public License getOrCreateLicense(VFSMetadata meta, Identity itentity) { + License license = getLicense(meta); + if (license == null) { + license = licenseService.createDefaultLicense(licenseHandler, itentity); + } + return license; + } + + public void migrateDirectories(File folder) throws IOException { + Deque<VFSMetadata> parentLine = new LinkedList<>(); + AtomicInteger migrationCounter = new AtomicInteger(0); + + Files.walkFileTree(folder.toPath(), new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + File directory = dir.toFile(); + if(directory.isHidden() || directory.getName().equals("__MACOSX")) { + return FileVisitResult.SKIP_SUBTREE; + } + VFSMetadata parent = parentLine.peekLast(); + VFSMetadata metadata = migrateMetadata(dir.toFile(), parent); + parentLine.add(metadata); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + File f = file.toFile(); + if(!f.isHidden() && !f.getName().equals("__MACOSX")) { + migrateMetadata(file.toFile(), parentLine.getLast()); + + migrationCounter.incrementAndGet(); + if(migrationCounter.get() % 25 == 0) { + dbInstance.commitAndCloseSession(); + } else { + dbInstance.commit(); + } + if(migrationCounter.get() % 100 == 0) { + log.info("Metadata: num. of files migrated: " + migrationCounter); + } + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + parentLine.pollLast(); + dbInstance.commitAndCloseSession(); + return FileVisitResult.CONTINUE; + } + }); + } + + public VFSMetadata migrate(File file, VFSMetadata parent) { + String relativePath = getRelativePath(file.getParentFile()); + if(relativePath.equals("..")) { + return null; + } + if(relativePath.equals("")) { + relativePath = CANONICAL_ROOT_REL_PATH; + } + + String filename = file.getName(); + VFSMetadata metadata = metadataDao.getMetadata(relativePath, filename, file.isDirectory()); + if(metadata == null) { + if(parent == null) { + parent = migrate(file.getParentFile(), null); + } + metadata = migrateMetadata(file, parent); + } + return metadata; + } + + private VFSMetadata migrateMetadata(File file, VFSMetadata parent) { + VFSMetadata metadata = null; + String metaPath = getCanonicalMetaPath(file); + String relativePath = getRelativePath(file.getParentFile()); + if(relativePath.equals("..")) { + return null; + } + if(relativePath.equals("")) { + relativePath = CANONICAL_ROOT_REL_PATH; + } + + boolean directory = file.isDirectory(); + long size = directory ? 0l : file.length(); + + Date fileLastModified = new Date(file.lastModified()); + if(metaPath != null) { + File metaFile = new File(metaPath); + if(metaFile.exists()) { + List<Thumbnail> thumbnails = null; + VFSMetadataImpl xmlMetadata = new VFSMetadataImpl(); + MetaInfoReader metaReader = new MetaInfoReader(xmlMetadata, licenseService, securityManager); + if(metaReader.parseSAX(metaFile)) { + xmlMetadata = metaReader.getMetadata(); + thumbnails = metaReader.getThumbnails(); + } + metadata = metadataDao.createMetadata(xmlMetadata, relativePath, file.getName(), fileLastModified, + size, directory, file.toURI().toString(), "file", parent); + migrateThumbnails(metadata, file, thumbnails); + } + } + + if(metadata == null) { + metadata = metadataDao.createMetadata(UUID.randomUUID().toString(), relativePath, file.getName(), fileLastModified, + size, directory, file.toURI().toString(), "file", parent); + } + return metadata; + } + + private String generateFilenameForThumbnail(File file, boolean fill, int maxWidth, int maxHeight) { + StringBuilder sb = new StringBuilder(128); + sb.append("._oo_th_").append(fill).append("_").append(maxWidth).append("_").append(maxHeight) + .append("_").append(file.getName()); + return sb.toString(); + } + + private String generateFilenameForThumbnail(String name, String extension, boolean fill, int maxWidth, int maxHeight) { + StringBuilder sb = new StringBuilder(128); + sb.append("._oo_th_").append(fill).append("_").append(maxWidth).append("_").append(maxHeight) + .append("_").append(name).append(".").append(extension); + return sb.toString(); + } + + private void migrateThumbnails(VFSMetadata metadata, File file, List<Thumbnail> thumbnails) { + if(thumbnails == null || thumbnails.isEmpty()) return; + + // do copy them + for(Thumbnail thumbnail:thumbnails) { + try { + File thumbnailFile = thumbnail.getThumbnailFile(); + if(thumbnailFile.exists()) { + String filename = generateFilenameForThumbnail(file, thumbnail.isFill(), thumbnail.getMaxWidth(), thumbnail.getMaxHeight()); + thumbnailDao.createThumbnailMetadata(metadata, filename, thumbnailFile.length(), + thumbnail.isFill(), thumbnail.getMaxWidth(), thumbnail.getMaxHeight(), + thumbnail.getFinalWidth(), thumbnail.getFinalHeight()); + File target = new File(file.getParentFile(), filename); + Files.move(thumbnailFile.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + log.error("", e); + } + } + } + + private String getCanonicalMetaPath(File originFile) { + String canonicalMetaPath; + if (originFile == null || !originFile.exists()) { + canonicalMetaPath = null; + } else { + String relPath = FolderConfig.getCanonicalRootPath().relativize(originFile.toPath()).toString(); + StringBuilder metaSb = new StringBuilder(128); + metaSb.append(FolderConfig.getCanonicalMetaRoot()).append("/").append(relPath); + if (originFile.isDirectory()) { + metaSb.append("/.xml"); + } else { + metaSb.append(".xml"); + } + canonicalMetaPath = metaSb.toString(); + } + return canonicalMetaPath; + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAO.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..074ee1d97e2b3e78d90656e577652bc8667e910b --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAO.java @@ -0,0 +1,134 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.Date; +import java.util.List; + +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSMetadataRef; +import org.olat.core.commons.services.vfs.VFSThumbnailMetadata; +import org.olat.core.commons.services.vfs.model.VFSThumbnailMetadataImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 14 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class VFSThumbnailDAO { + + @Autowired + private DB dbInstance; + + public VFSThumbnailMetadata createThumbnailMetadata(VFSMetadata metadata, String filename, + long size, boolean fill, int maxWidth, int maxHeight, int finalWidth, int finalHeight) { + VFSThumbnailMetadataImpl thumbnail = new VFSThumbnailMetadataImpl(); + thumbnail.setCreationDate(new Date()); + thumbnail.setLastModified(thumbnail.getCreationDate()); + thumbnail.setFilename(filename); + thumbnail.setFileSize(size); + thumbnail.setFill(fill); + thumbnail.setMaxWidth(maxWidth); + thumbnail.setMaxHeight(maxHeight); + thumbnail.setFinalWidth(finalWidth); + thumbnail.setFinalHeight(finalHeight); + thumbnail.setOwner(metadata); + dbInstance.getCurrentEntityManager().persist(thumbnail); + return thumbnail; + } + + public VFSThumbnailMetadata loadByKey(Long key) { + List<VFSThumbnailMetadata> metas = dbInstance.getCurrentEntityManager() + .createNamedQuery("loadThumbnailByKey", VFSThumbnailMetadata.class) + .setParameter("thumbnailKey", key) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return metas == null || metas.isEmpty() ? null : metas.get(0); + } + + public List<VFSThumbnailMetadata> loadByMetadata(VFSMetadataRef metadata) { + String q = "select thumb from vfsthumbnail thumb where thumb.owner.key=:metadataKey"; + return dbInstance.getCurrentEntityManager() + .createQuery(q, VFSThumbnailMetadata.class) + .setParameter("metadataKey", metadata.getKey()) + .getResultList(); + } + + public VFSThumbnailMetadata findThumbnail(String relativePath, String filename, boolean fill, int maxWidth, int maxHeight) { + StringBuilder sb = new StringBuilder(); + sb.append("select thumb from vfsthumbnail thumb") + .append(" inner join thumb.owner as meta") + .append(" where meta.filename=:filename and meta.relativePath=:relativePath") + .append(" and thumb.maxWidth=:maxWidth and thumb.maxHeight=:maxHeight and thumb.fill=:fill"); + + List<VFSThumbnailMetadata> metas = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSThumbnailMetadata.class) + .setParameter("filename", filename) + .setParameter("relativePath", relativePath) + .setParameter("maxWidth", Integer.valueOf(maxWidth)) + .setParameter("maxHeight", Integer.valueOf(maxHeight)) + .setParameter("fill", Boolean.valueOf(fill)) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return metas == null || metas.isEmpty() ? null : metas.get(0); + } + + public List<VFSThumbnailMetadata> findThumbnails(String relativePath, String filename) { + StringBuilder sb = new StringBuilder(); + sb.append("select thumb from vfsthumbnail thumb") + .append(" inner join thumb.owner as meta") + .append(" where meta.filename=:filename and meta.relativePath=:relativePath"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSThumbnailMetadata.class) + .setParameter("filename", filename) + .setParameter("relativePath", relativePath) + .getResultList(); + } + + public VFSThumbnailMetadata findThumbnail(VFSMetadata owner, boolean fill, int maxWidth, int maxHeight) { + StringBuilder sb = new StringBuilder(); + sb.append("select thumb from vfsthumbnail thumb") + .append(" inner join thumb.owner as meta") + .append(" where meta.key=:ownerKey and thumb.maxWidth=:maxWidth and thumb.maxHeight=:maxHeight and thumb.fill=:fill"); + + List<VFSThumbnailMetadata> metas = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSThumbnailMetadata.class) + .setParameter("ownerKey", owner.getKey()) + .setParameter("maxWidth", Integer.valueOf(maxWidth)) + .setParameter("maxHeight", Integer.valueOf(maxHeight)) + .setParameter("fill", Boolean.valueOf(fill)) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return metas == null || metas.isEmpty() ? null : metas.get(0); + } + + public void removeThumbnail(VFSThumbnailMetadata thumbnail) { + dbInstance.getCurrentEntityManager().remove(thumbnail); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java new file mode 100644 index 0000000000000000000000000000000000000000..870ab3505a25a881c74a17907c68fc14c82b9615 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java @@ -0,0 +1,139 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.io.InputStream; + +import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.IdentityImpl; +import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.model.LicenseTypeImpl; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; +import org.olat.core.id.Identity; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.version.RevisionFileImpl; +import org.olat.core.util.vfs.version.VFSRevision; +import org.olat.core.util.vfs.version.Versions; +import org.olat.core.util.vfs.version.VersionsFileImpl; +import org.olat.core.util.xml.XStreamHelper; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.security.ExplicitTypePermission; + +/** + * + * Initial date: 13 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSXStream { + + private static XStream mystream; + static { + mystream = XStreamHelper.createXStreamInstance(); + XStream.setupDefaultSecurity(mystream); + Class<?>[] types = new Class[] { + VersionsFileImpl.class, Versions.class, RevisionFileImpl.class, VFSRevision.class, + VFSMetadata.class, VFSMetadataImpl.class, Identity.class, IdentityImpl.class, + LicenseType.class, LicenseTypeImpl.class + }; + mystream.addPermission(new ExplicitTypePermission(types)); + + mystream.alias("versions", VersionsFileImpl.class); + mystream.alias("revision", RevisionFileImpl.class); + mystream.omitField(VersionsFileImpl.class, "currentVersion"); + mystream.omitField(VersionsFileImpl.class, "versionFile"); + mystream.omitField(RevisionFileImpl.class, "current"); + mystream.omitField(RevisionFileImpl.class, "container"); + mystream.omitField(RevisionFileImpl.class, "file"); + mystream.omitField(VFSMetadataImpl.class, "originFile"); + mystream.omitField(VFSMetadataImpl.class, "metaFile"); + mystream.aliasAttribute(VFSMetadataImpl.class, "cannotGenerateThumbnails", "cannotGenerateThumbnail"); + mystream.aliasAttribute(VFSMetadataImpl.class, "author", "authorIdentKey"); + mystream.aliasAttribute(VFSMetadataImpl.class, "licenseType", "licenseTypeKey"); + mystream.alias("metadata", VFSMetadataImpl.class); + mystream.omitField(VFSMetadataImpl.class, "thumbnail"); + mystream.omitField(VFSMetadataImpl.class, "thumbnails"); + + mystream.registerLocalConverter(VFSMetadataImpl.class, "licenseType", new LicenseTypeConverter()); + mystream.registerLocalConverter(VFSMetadataImpl.class, "author", new IdentityConverter()); + } + + public static final Object read(InputStream in) { + return XStreamHelper.readObject(mystream, in); + } + + public static final Object read(VFSLeaf leaf) { + return XStreamHelper.readObject(mystream, leaf); + } + + public static final void write(VFSLeaf leaf, Versions versions) { + XStreamHelper.writeObject(mystream, leaf, versions); + } + + private static class LicenseTypeConverter implements SingleValueConverter { + + @Override + public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { + return type.equals(LicenseType.class) || type.equals(LicenseTypeImpl.class); + } + + @Override + public String toString(Object obj) { + if(obj instanceof LicenseType) { + Long key = ((LicenseType)obj).getKey(); + return key == null ? null : key.toString(); + } + return null; + } + + @Override + public Object fromString(String str) { + return CoreSpringFactory.getImpl(LicenseService.class).loadLicenseTypeByKey(str); + } + } + + private static class IdentityConverter implements SingleValueConverter { + + @Override + public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { + return type.equals(Identity.class) || type.equals(IdentityImpl.class); + } + + @Override + public String toString(Object obj) { + if(obj instanceof Identity) { + Long key = ((Identity)obj).getKey(); + return key == null ? null : key.toString(); + } + return null; + } + + @Override + public Object fromString(String str) { + Long identityKey = Long.valueOf(str); + return CoreSpringFactory.getImpl(BaseSecurity.class).loadIdentityByKey(identityKey); + } + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataDownloadCount.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataDownloadCount.java new file mode 100644 index 0000000000000000000000000000000000000000..e01db2e8d31cd984c6296ee6af8a7e27193ab8ff --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataDownloadCount.java @@ -0,0 +1,109 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 13 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="vfsmetadatadownloadcount") +@Table(name="o_vfs_metadata") +public class VFSMetadataDownloadCount implements Persistable { + + private static final long serialVersionUID = 8572616184723339987L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Column(name="f_download_count", nullable=false, insertable=false, updatable=true) + private int downloadCount; + @Column(name="f_filename", nullable=false, insertable=false, updatable=false) + private String filename; + @Column(name="f_relative_path", nullable=false, insertable=false, updatable=false) + private String relativePath; + + @Override + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + public int getDownloadCount() { + return downloadCount; + } + + public void setDownloadCount(int downloadCount) { + this.downloadCount = downloadCount; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getRelativePath() { + return relativePath; + } + + public void setRelativePath(String relativePath) { + this.relativePath = relativePath; + } + + @Override + public int hashCode() { + return getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) { + return true; + } + if(obj instanceof VFSMetadataDownloadCount) { + VFSMetadataDownloadCount count = (VFSMetadataDownloadCount)obj; + return getKey().equals(count.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..bc0e8993f125225f3c43e88c29dc3d2d86786340 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java @@ -0,0 +1,524 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.olat.basesecurity.IdentityImpl; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.model.LicenseTypeImpl; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.gui.util.CSSHelper; +import org.olat.core.id.Identity; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="filemetadata") +@Table(name="o_vfs_metadata") +public class VFSMetadataImpl implements Persistable, VFSMetadata { + + private static final long serialVersionUID = 1360000029480576628L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="lastmodified", nullable=false, insertable=true, updatable=true) + private Date lastModified; + + @Column(name="f_uuid", nullable=false, insertable=true, updatable=true) + private String uuid; + @Column(name="f_filename", nullable=false, insertable=true, updatable=true) + private String filename; + @Column(name="f_relative_path", nullable=false, insertable=true, updatable=true) + private String relativePath; + @Column(name="f_directory", nullable=false, insertable=true, updatable=true) + private boolean directory; + @Column(name="f_lastmodified", nullable=false, insertable=true, updatable=true) + private Date fileLastModified; + @Column(name="f_size", nullable=false, insertable=true, updatable=true) + private long fileSize; + @Column(name="f_uri", nullable=false, insertable=true, updatable=true) + private String uri; + @Column(name="f_uri_protocol", nullable=false, insertable=true, updatable=true) + private String protocol; + + @Column(name="f_cannot_thumbnails", nullable=true, insertable=true, updatable=true) + private Boolean cannotGenerateThumbnails; + @Column(name="f_download_count", nullable=true, insertable=true, updatable=true) + private int downloadCount; + + @Column(name="f_comment", nullable=true, insertable=true, updatable=true) + private String comment; + @Column(name="f_title", nullable=true, insertable=true, updatable=true) + private String title; + @Column(name="f_publisher", nullable=true, insertable=true, updatable=true) + private String publisher; + @Column(name="f_creator", nullable=true, insertable=true, updatable=true) + private String creator; + @Column(name="f_source", nullable=true, insertable=true, updatable=true) + private String source; + @Column(name="f_city", nullable=true, insertable=true, updatable=true) + private String city; + @Column(name="f_pages", nullable=true, insertable=true, updatable=true) + private String pages; + @Column(name="f_language", nullable=true, insertable=true, updatable=true) + private String language; + @Column(name="f_url", nullable=true, insertable=true, updatable=true) + private String url; + @Column(name="f_pub_month", nullable=true, insertable=true, updatable=true) + private String pubMonth; + @Column(name="f_pub_year", nullable=true, insertable=true, updatable=true) + private String pubYear; + + @ManyToOne(targetEntity=LicenseTypeImpl.class, optional=true) + @JoinColumn(name="fk_license_type", nullable=true, insertable=true, updatable=true) + private LicenseType licenseType; + @Column(name="f_license_type_name", nullable=true, insertable=true, updatable=true) + private String licenseTypeName; + @Column(name="f_license_text", nullable=true, insertable=true, updatable=true) + private String licenseText; + @Column(name="f_licensor", nullable=true, insertable=true, updatable=true) + private String licensor; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="f_locked_date", nullable=true, insertable=true, updatable=true) + private Date lockedDate; + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_locked_identity", nullable=true, insertable=true, updatable=true) + private Identity lockedBy; + @Column(name="f_locked", nullable=true, insertable=true, updatable=true) + private boolean locked; + + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_author", nullable=true, insertable=true, updatable=true) + private Identity author; + + @Column(name="f_m_path_keys", nullable=true, insertable=true, updatable=true) + private String materializedPathKeys; + + @ManyToOne(targetEntity=VFSMetadataImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_parent", nullable=true, insertable=true, updatable=true) + private VFSMetadata parent; + + @Override + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date date) { + creationDate = date; + } + + @Override + public Date getLastModified() { + return lastModified; + } + + @Override + public void setLastModified(Date date) { + lastModified = date; + } + + @Override + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + @Override + public Date getFileLastModified() { + return fileLastModified; + } + + public void setFileLastModified(Date date) { + fileLastModified = date; + } + + @Override + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + @Override + public boolean isDirectory() { + return directory; + } + + public void setDirectory(boolean directory) { + this.directory = directory; + } + + @Override + public String getIconCssClass() { + String cssClass; + if (isDirectory()) { + cssClass = CSSHelper.CSS_CLASS_FILETYPE_FOLDER; + } else { + cssClass = CSSHelper.createFiletypeIconCssClassFor(getFilename()); + } + return cssClass; + } + + @Override + public String getRelativePath() { + return relativePath; + } + + public void setRelativePath(String relativePath) { + this.relativePath = relativePath; + } + + @Override + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + @Override + public int getDownloadCount() { + return downloadCount; + } + + public void setDownloadCount(int downloadCount) { + this.downloadCount = downloadCount; + } + + @Override + public String getComment() { + return comment; + } + + @Override + public void setComment(String comment) { + this.comment = comment; + } + + @Override + public String getCreator() { + return creator; + } + + @Override + public void setCreator(String creator) { + this.creator = creator; + } + + @Override + public String getCity() { + return city; + } + + @Override + public void setCity(String city) { + this.city = city; + } + + @Override + public String getLanguage() { + return language; + } + + @Override + public void setLanguage(String language) { + this.language = language; + } + + @Override + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public String getPublisher() { + return publisher; + } + + @Override + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + @Override + public String getSource() { + return source; + } + + @Override + public void setSource(String source) { + this.source = source; + } + + @Override + public String getPages() { + return pages; + } + + @Override + public void setPages(String pages) { + this.pages = pages; + } + + @Override + public String getUrl() { + return url; + } + + @Override + public void setUrl(String url) { + this.url = url; + } + + public String getPubMonth() { + return pubMonth; + } + + public void setPubMonth(String pubMonth) { + this.pubMonth = pubMonth; + } + + public String getPubYear() { + return pubYear; + } + + public void setPubYear(String pubYear) { + this.pubYear = pubYear; + } + + @Override + public String[] getPublicationDate() { + return new String[] { pubYear, pubMonth }; + } + + @Override + public void setPublicationDate(String month, String year) { + setPubMonth(month); + setPubYear(year); + } + + @Override + public LicenseType getLicenseType() { + return licenseType; + } + + @Override + public void setLicenseType(LicenseType licenseType) { + this.licenseType = licenseType; + } + + @Override + public String getLicenseTypeName() { + return licenseTypeName; + } + + @Override + public void setLicenseTypeName(String licenseTypeName) { + this.licenseTypeName = licenseTypeName; + } + + @Override + public String getLicenseText() { + return licenseText; + } + + @Override + public void setLicenseText(String licenseText) { + this.licenseText = licenseText; + } + + @Override + public String getLicensor() { + return licensor; + } + + @Override + public void setLicensor(String licensor) { + this.licensor = licensor; + } + + @Override + public Identity getAuthor() { + return author; + } + + @Override + public void setAuthor(Identity author) { + this.author = author; + } + + @Override + public Date getLockedDate() { + return lockedDate; + } + + @Override + public void setLockedDate(Date lockedDate) { + this.lockedDate = lockedDate; + } + + @Override + public Identity getLockedBy() { + return lockedBy; + } + + @Override + public void setLockedBy(Identity lockedBy) { + this.lockedBy = lockedBy; + } + + @Override + public boolean isLocked() { + return locked; + } + + @Override + public void setLocked(boolean locked) { + this.locked = locked; + } + + public Boolean getCannotGenerateThumbnails() { + return cannotGenerateThumbnails; + } + + public void setCannotGenerateThumbnails(Boolean cannotGenerateThumbnails) { + this.cannotGenerateThumbnails = cannotGenerateThumbnails; + } + + public String getMaterializedPathKeys() { + return materializedPathKeys; + } + + public void setMaterializedPathKeys(String materializedPathKeys) { + this.materializedPathKeys = materializedPathKeys; + } + + public VFSMetadata getParent() { + return parent; + } + + public void setParent(VFSMetadata parent) { + this.parent = parent; + } + + @Override + public void copyValues(VFSMetadata fromMeta) { + setAuthor(fromMeta.getAuthor()); + setComment(fromMeta.getComment()); + setCity(fromMeta.getCity()); + setCreator(fromMeta.getCreator()); + setLanguage(fromMeta.getLanguage()); + setPages(fromMeta.getPages()); + setPublicationDate(fromMeta.getPublicationDate()[1], fromMeta.getPublicationDate()[0]); + setPublisher(fromMeta.getPublisher()); + setSource(fromMeta.getSource()); + setTitle(fromMeta.getTitle()); + setUrl(fromMeta.getUrl()); + setLicenseType(fromMeta.getLicenseType()); + setLicenseTypeName(fromMeta.getLicenseTypeName()); + setLicensor(fromMeta.getLicensor()); + setLicenseText(fromMeta.getLicenseText()); + } + + @Override + public int hashCode() { + return getKey() == null ? 7386459 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof VFSMetadataImpl) { + VFSMetadataImpl meta = (VFSMetadataImpl)obj; + return getKey().equals(meta.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataRefImpl.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataRefImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ac9fedd3fdc9c2d460373802c507166bfa5f6aa0 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataRefImpl.java @@ -0,0 +1,59 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.model; + +import org.olat.core.commons.services.vfs.VFSMetadataRef; + +/** + * + * Initial date: 13 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSMetadataRefImpl implements VFSMetadataRef { + + private final Long key; + + public VFSMetadataRefImpl(Long key) { + this.key = key; + } + + @Override + public Long getKey() { + return key; + } + + @Override + public int hashCode() { + return key == null ? 860573 : key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) { + return true; + } + if(obj instanceof VFSMetadataRefImpl) { + VFSMetadataRefImpl ref = (VFSMetadataRefImpl)obj; + return key != null && key.equals(ref.key); + } + return false; + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSThumbnailMetadataImpl.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSThumbnailMetadataImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e78a3821fff0d300011eac27b152ae65478f5a32 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSThumbnailMetadataImpl.java @@ -0,0 +1,206 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSThumbnailMetadata; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 14 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="vfsthumbnail") +@Table(name="o_vfs_thumbnail") +@NamedQuery(name="loadThumbnailByKey", query="select thumb from vfsthumbnail thumb where thumb.key=:thumbnailKey") +public class VFSThumbnailMetadataImpl implements Persistable, VFSThumbnailMetadata { + + private static final long serialVersionUID = -6149766723435220075L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="lastmodified", nullable=false, insertable=true, updatable=true) + private Date lastModified; + + @Column(name="f_size", nullable=false, insertable=true, updatable=true) + private long fileSize; + @Column(name="f_max_width", nullable=false, insertable=true, updatable=true) + private int maxWidth; + @Column(name="f_max_height", nullable=false, insertable=true, updatable=true) + private int maxHeight; + @Column(name="f_final_width", nullable=false, insertable=true, updatable=true) + private int finalWidth; + @Column(name="f_final_height", nullable=false, insertable=true, updatable=true) + private int finalHeight; + @Column(name="f_fill", nullable=false, insertable=true, updatable=true) + private boolean fill = false; + @Column(name="f_filename", nullable=false, insertable=true, updatable=true) + private String filename; + + @ManyToOne(targetEntity=VFSMetadataImpl.class,fetch=FetchType.LAZY,optional=false) + @JoinColumn(name="fk_metadata", nullable=false, insertable=true, updatable=false) + private VFSMetadata owner; + + @Override + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + @Override + public Date getLastModified() { + return lastModified; + } + + @Override + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + @Override + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + @Override + public int getMaxWidth() { + return maxWidth; + } + + public void setMaxWidth(int maxWidth) { + this.maxWidth = maxWidth; + } + + @Override + public int getMaxHeight() { + return maxHeight; + } + + public void setMaxHeight(int maxHeight) { + this.maxHeight = maxHeight; + } + + @Override + public int getFinalWidth() { + return finalWidth; + } + + public void setFinalWidth(int finalWidth) { + this.finalWidth = finalWidth; + } + + @Override + public int getFinalHeight() { + return finalHeight; + } + + public void setFinalHeight(int finalHeight) { + this.finalHeight = finalHeight; + } + + @Override + public boolean isFill() { + return fill; + } + + public void setFill(boolean fill) { + this.fill = fill; + } + + @Override + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + @Override + public VFSMetadata getOwner() { + return owner; + } + + public void setOwner(VFSMetadata owner) { + this.owner = owner; + } + + @Override + public int hashCode() { + return getKey() == null ? 7386459 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof VFSThumbnailMetadataImpl) { + VFSThumbnailMetadataImpl meta = (VFSThumbnailMetadataImpl)obj; + return getKey().equals(meta.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResource.java b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResource.java index 638b6f9ad739d30758a29f37ad305005e4db12da..e3fbac08d6f15237f7a9bb9ba225a08bb934027d 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResource.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResource.java @@ -25,6 +25,8 @@ import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; import java.util.Date; +import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.commons.services.webdav.servlets.ConcurrentDateFormat; import org.olat.core.commons.services.webdav.servlets.WebResource; import org.olat.core.logging.OLog; @@ -34,7 +36,6 @@ import org.olat.core.util.vfs.VFSConstants; 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.meta.MetaInfo; /** * @@ -151,9 +152,7 @@ public class VFSResource implements WebResource { public void increaseDownloadCount() { try { if (item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { - MetaInfo meta = item.getMetaInfo(); - meta.increaseDownloadCount(); - meta.write(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).increaseDownloadCount(item); } } catch (Exception e) { log.error("Cannot increase download counter: " + item, e); diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java index 2be220bae49a5cb0cc85842f99eca47bb1748d36..c63fbe62ded5c1c34bc5852a5cdde4934518720f 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java @@ -33,6 +33,8 @@ import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.ui.LicenseUIFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.commons.services.webdav.servlets.WebResource; import org.olat.core.commons.services.webdav.servlets.WebResourceRoot; import org.olat.core.id.Identity; @@ -47,7 +49,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSStatus; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.core.util.vfs.version.Versionable; import org.olat.core.util.vfs.version.VersionsManager; @@ -222,12 +223,14 @@ public class VFSResourceRoot implements WebResourceRoot { } if(identity != null && childLeaf.canMeta() == VFSConstants.YES) { - MetaInfo infos = childLeaf.getMetaInfo(); - if(infos != null && !infos.hasAuthorIdentity()) { + VFSMetadata infos = childLeaf.getMetaInfo(); + if(infos != null && infos.getAuthor() != null) { infos.setAuthor(identity); addLicense(infos, identity); - infos.clearThumbnails(); - //infos.write(); the clearThumbnails call write() + + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + vfsRepositoryService.updateMetadata(infos); + vfsRepositoryService.resetThumbnails(childLeaf); } } @@ -243,13 +246,13 @@ public class VFSResourceRoot implements WebResourceRoot { return true; } - private void addLicense(MetaInfo meta, Identity identity) { + private void addLicense(VFSMetadata meta, Identity identity) { LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); LicenseModule licenseModule = CoreSpringFactory.getImpl(LicenseModule.class); FolderLicenseHandler licenseHandler = CoreSpringFactory.getImpl(FolderLicenseHandler.class); if (licenseModule.isEnabled(licenseHandler)) { License license = licenseService.createDefaultLicense(licenseHandler, identity); - meta.setLicenseTypeKey(String.valueOf(license.getLicenseType().getKey())); + meta.setLicenseType(license.getLicenseType()); meta.setLicenseTypeName(license.getLicenseType().getName()); meta.setLicensor(license.getLicensor()); meta.setLicenseText(LicenseUIFactory.getLicenseText(license)); diff --git a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java index 8a5ea6acd92a3c1ca15328b170d8fedb0b3f9208..48d6fdb1e0d5649f200fa2b796ec0325d95f3ee1 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java +++ b/src/main/java/org/olat/core/commons/services/webdav/servlets/WebDAVDispatcherImpl.java @@ -1212,7 +1212,7 @@ public class WebDAVDispatcherImpl // Generating lock id - String lockToken = lockManager.generateLockToken(lock, usess.getIdentity().getKey()); + String lockToken = lockManager.generateLockToken(lock, usess.getIdentity()); if (resource.isDirectory() && lock.getDepth() == maxDepth) { // Locking a collection (and all its member resources) diff --git a/src/main/java/org/olat/core/gui/control/generic/folder/OlatRootFolderTreeModel.java b/src/main/java/org/olat/core/gui/control/generic/folder/OlatRootFolderTreeModel.java index f5f09ba03a276feae1fe849b36cf495e3cb91462..ac1f8e3404870d8d50912ceb2aa38b64822ba78d 100644 --- a/src/main/java/org/olat/core/gui/control/generic/folder/OlatRootFolderTreeModel.java +++ b/src/main/java/org/olat/core/gui/control/generic/folder/OlatRootFolderTreeModel.java @@ -28,12 +28,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; /** * This TreeModel is intended for OlatRootFolderImpl and OlatRootFileImpl. @@ -109,13 +109,13 @@ public class OlatRootFolderTreeModel extends GenericTreeModel { */ private OlatRootFolderTreeNode createNode(VFSItem item) { OlatRootFolderTreeNode node = new OlatRootFolderTreeNode(item, this); - MetaInfo meta = item.getMetaInfo(); + VFSMetadata meta = item.getMetaInfo(); if (meta != null) { String title = meta.getTitle(); if (StringHelper.containsNonWhitespace(title)) { node.setTitle(title); } else { - node.setTitle(meta.getName()); + node.setTitle(meta.getFilename()); } } node.setUserObject(item.getRelPath()); diff --git a/src/main/java/org/olat/core/util/ZipUtil.java b/src/main/java/org/olat/core/util/ZipUtil.java index 3b2f960db3a2708649549ff2b17414e25c29be90..7c224da97841772b9b8d65857af9d486d992466b 100644 --- a/src/main/java/org/olat/core/util/ZipUtil.java +++ b/src/main/java/org/olat/core/util/ZipUtil.java @@ -49,6 +49,9 @@ import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.manager.MetaInfoReader; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.logging.OLATRuntimeException; @@ -66,7 +69,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.SystemItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.core.util.vfs.version.Versionable; /** @@ -149,12 +151,15 @@ public class ZipUtil { * @param targetDir The directory to unzip the file to * @param the identity of who unzip the file * @param versioning enabled or not - * @return True if successfull, false otherwise + * @return True if successful, false otherwise */ public static boolean unzip(VFSLeaf zipLeaf, VFSContainer targetDir, Identity identity, boolean versioning) { - InputStream in = zipLeaf.getInputStream(); - boolean unzipped = unzip(in, targetDir, identity, versioning); - FileUtils.closeSafely(in); + boolean unzipped = false; + try(InputStream in = zipLeaf.getInputStream()) { + unzipped = unzip(in, targetDir, identity, versioning); + } catch(Exception e) { + log.error("", e); + } return unzipped; } @@ -164,9 +169,12 @@ public class ZipUtil { * @param targetDir The directory to unzip the file to * @param the identity of who unzip the file * @param versioning enabled or not - * @return True if successfull, false otherwise + * @return True if successful, false otherwise */ private static boolean unzip(InputStream in, VFSContainer targetDir, Identity identity, boolean versioning) { + + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + try(ZipInputStream oZip = new ZipInputStream(in)) { // unzip files ZipEntry oEntr = oZip.getNextEntry(); @@ -202,9 +210,9 @@ public class ZipUtil { VFSLeaf newEntry = (VFSLeaf)createIn.resolve(name); if(newEntry == null) { newEntry = createIn.createChildLeaf(name); - OutputStream out = newEntry.getOutputStream(false); - if (!FileUtils.copy(oZip, out)) return false; - FileUtils.closeSafely(out); + if (!copy(oZip, newEntry)) { + return false; + } } else if (newEntry instanceof Versionable) { Versionable versionable = (Versionable)newEntry; if(versionable.getVersions().isVersioned()) { @@ -212,25 +220,25 @@ public class ZipUtil { } } if(newEntry != null && identity != null && newEntry.canMeta() == VFSConstants.YES) { - MetaInfo info = newEntry.getMetaInfo(); + VFSMetadata info = newEntry.getMetaInfo(); if(info != null) { info.setAuthor(identity); - info.write(); + vfsRepositoryService.updateMetadata(info); } } } else { VFSLeaf newEntry = createIn.createChildLeaf(name); if (newEntry != null) { - OutputStream out = newEntry.getOutputStream(false); - if (!FileUtils.copy(oZip, out)) return false; - FileUtils.closeSafely(out); + if (!copy(oZip, newEntry)) { + return false; + } if(identity != null && newEntry.canMeta() == VFSConstants.YES) { - MetaInfo info = newEntry.getMetaInfo(); + VFSMetadata info = newEntry.getMetaInfo(); if(info != null) { info.setAuthor(identity); - info.write(); + vfsRepositoryService.updateMetadata(info); } } } @@ -246,6 +254,15 @@ public class ZipUtil { return true; } // unzip + private static boolean copy(ZipInputStream oZip, VFSLeaf newEntry) { + try(OutputStream out = newEntry.getOutputStream(false)) { + return FileUtils.copy(oZip, out); + } catch(Exception e) { + log.error("", e); + return false; + } + } + /** * Unzip a file to a directory using the versioning system of VFS and a ZIP * library which handle encoding errors. It may results in special characters @@ -322,7 +339,7 @@ public class ZipUtil { VFSLeaf newEntry = (VFSLeaf)createIn.resolve(name); if(newEntry == null) { newEntry = createIn.createChildLeaf(name); - if (!VFSManager.copyContent(new ShieldInputStream(oZip), newEntry)) { + if (!copyShielded(oZip, newEntry)) { return false; } } else if (newEntry instanceof Versionable) { @@ -335,7 +352,7 @@ public class ZipUtil { } else { VFSLeaf newEntry = createIn.createChildLeaf(name); if (newEntry != null) { - if (!VFSManager.copyContent(new ShieldInputStream(oZip), newEntry)) { + if (!copyShielded(oZip, newEntry)) { return false; } unzipMetadata(identity, extra, newEntry); @@ -352,22 +369,41 @@ public class ZipUtil { return true; } // unzip + private static boolean copyShielded(net.sf.jazzlib.ZipInputStream oZip, VFSLeaf newEntry) { + try(InputStream in = new ShieldInputStream(oZip)) { + return VFSManager.copyContent(in, newEntry); + } catch(Exception e) { + log.error("", e); + return false; + } + } + + private static boolean copyShielded(VFSLeaf leaf, ZipOutputStream out) { + try(OutputStream sout = new ShieldOutputStream(out)) { + return VFSManager.copyContent(leaf, sout); + } catch(Exception e) { + log.error("", e); + return false; + } + } + private static void unzipMetadata(Identity identity, byte[] extra, VFSLeaf newEntry) { if(newEntry.canMeta() != VFSConstants.YES || ((extra == null || extra.length == 0) && identity == null)) { return; } - MetaInfo info = newEntry.getMetaInfo(); + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + VFSMetadata info = vfsRepositoryService.getMetadataFor(newEntry); if(info == null) { return; } if(extra != null) { - info.writeBinary(extra); + vfsRepositoryService.copyBinaries(info, extra); } else { info.setAuthor(identity); - info.write(); } + vfsRepositoryService.updateMetadata(info); } /** @@ -511,6 +547,9 @@ public class ZipUtil { // try it windows style, backslash is also valid format st = new StringTokenizer(subDirPath, "\\", false); } + + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + VFSContainer currentPath = base; while (st.hasMoreTokens()) { String nextSubpath = st.nextToken(); @@ -522,10 +561,10 @@ public class ZipUtil { vfsSubpath = currentPath.createChildContainer(nextSubpath); if (vfsSubpath == null) return null; if (identity != null && vfsSubpath.canMeta() == VFSConstants.YES) { - MetaInfo info = vfsSubpath.getMetaInfo(); + VFSMetadata info = vfsSubpath.getMetaInfo(); if(info != null) { info.setAuthor(identity); - info.write(); + vfsRepositoryService.updateMetadata(info); } } } @@ -658,11 +697,11 @@ public class ZipUtil { VFSLeaf leaf = (VFSLeaf)vfsItem; ZipEntry entry = new ZipEntry(itemName); if(leaf.canMeta() == VFSConstants.YES) { - byte[] metadata = leaf.getMetaInfo().readBinary(); + byte[] metadata = MetaInfoReader.toBinaries(leaf.getMetaInfo()); entry.setExtra(metadata); } out.putNextEntry(entry); - VFSManager.copyContent(leaf, new ShieldOutputStream(out)); + copyShielded(leaf, out); out.closeEntry(); } } catch (IOException ioe) { diff --git a/src/main/java/org/olat/core/util/mail/ui/SendDocumentsByEMailController.java b/src/main/java/org/olat/core/util/mail/ui/SendDocumentsByEMailController.java index 958076bb1659c648746b6c419927ee2f54e334cb..2a96f228b0475d798cf9fb65ec8ed7f2fc851c0f 100644 --- a/src/main/java/org/olat/core/util/mail/ui/SendDocumentsByEMailController.java +++ b/src/main/java/org/olat/core/util/mail/ui/SendDocumentsByEMailController.java @@ -22,6 +22,7 @@ package org.olat.core.util.mail.ui; import java.io.File; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.UUID; @@ -36,6 +37,7 @@ import org.olat.core.commons.modules.bc.commands.FolderCommand; import org.olat.core.commons.modules.bc.commands.FolderCommandHelper; import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; import org.olat.core.commons.modules.bc.components.FolderComponent; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -72,7 +74,6 @@ 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.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -110,8 +111,7 @@ public class SendDocumentsByEMailController extends FormBasicController implemen private BaseSecurity securityManager; public SendDocumentsByEMailController(UserRequest ureq, WindowControl wControl) { - super(ureq, wControl, null, Util.createPackageTranslator(MetaInfo.class, ureq.getLocale(), - Util.createPackageTranslator(MailModule.class, ureq.getLocale()))); + super(ureq, wControl, null, Util.createPackageTranslator(MailModule.class, ureq.getLocale())); setBasePackage(MailModule.class); allowAttachments = !FolderConfig.getSendDocumentLinkOnly(); @@ -229,7 +229,7 @@ public class SendDocumentsByEMailController extends FormBasicController implemen attachments = new ArrayList<>(); long fileSize = 0l; for (VFSLeaf file : files) { - MetaInfo infos = null; + VFSMetadata infos = null; if (file.canMeta() == VFSConstants.YES) { infos = file.getMetaInfo(); } @@ -270,7 +270,7 @@ public class SendDocumentsByEMailController extends FormBasicController implemen bodyElement.setValue(bodySb.toString()); } - protected void appendToSubject(VFSLeaf file, MetaInfo infos, StringBuilder sb) { + protected void appendToSubject(VFSLeaf file, VFSMetadata infos, StringBuilder sb) { if (sb.length() > 0) sb.append(", "); if (infos != null && StringHelper.containsNonWhitespace(infos.getTitle())) { @@ -280,11 +280,11 @@ public class SendDocumentsByEMailController extends FormBasicController implemen } } - protected void appendMetadatas(VFSLeaf file, MetaInfo infos, StringBuilder sb) { + protected void appendMetadatas(VFSLeaf file, VFSMetadata infos, StringBuilder sb) { if (infos == null) { appendMetadata("mf.filename", file.getName(), sb); } else { - appendMetadata("mf.filename", infos.getName(), sb); + appendMetadata("mf.filename", infos.getFilename(), sb); String title = infos.getTitle(); if (StringHelper.containsNonWhitespace(title)) { appendMetadata("mf.title", title, sb); @@ -322,15 +322,15 @@ public class SendDocumentsByEMailController extends FormBasicController implemen if (StringHelper.containsNonWhitespace(url)) { appendMetadata("mf.url", url, sb); } - String author = userManager.getUserDisplayName(infos.getAuthorIdentityKey()); + String author = userManager.getUserDisplayName(infos.getAuthor()); if (StringHelper.containsNonWhitespace(author)) { appendMetadata("mf.author", author, sb); } String size = Formatter.formatBytes(file.getSize()); appendMetadata("mf.size", size, sb); - long lastModifiedDate = infos.getLastModified(); - if (lastModifiedDate > 0) { - appendMetadata("mf.lastModified", StringHelper.formatLocaleDate(lastModifiedDate, getLocale()), sb); + Date lastModifiedDate = infos.getFileLastModified(); + if (lastModifiedDate != null) { + appendMetadata("mf.lastModified", Formatter.getInstance(getLocale()).formatDate(lastModifiedDate), sb); } String type = FolderHelper.extractFileType(file.getName(), getLocale()); if (StringHelper.containsNonWhitespace(type)) { @@ -347,7 +347,7 @@ public class SendDocumentsByEMailController extends FormBasicController implemen sb.append(translate(i18nKey)).append(": ").append(value).append('\n'); } - protected void appendPublicationDate(MetaInfo infos, StringBuilder sb) { + protected void appendPublicationDate(VFSMetadata infos, StringBuilder sb) { String[] publicationDate = infos.getPublicationDate(); if (publicationDate == null || publicationDate.length != 2) return; @@ -411,7 +411,7 @@ public class SendDocumentsByEMailController extends FormBasicController implemen List<Identity> invalidTos = getInvalidToAddressesFromTextBoxList(); userListBox.clearError(); - if (invalidTos.size() > 0) { + if (!invalidTos.isEmpty()) { String[] invalidTosArray = new String[invalidTos.size()]; userListBox.setErrorKey("mailhelper.error.addressinvalid", invalidTos.toArray(invalidTosArray)); allOk &= false; diff --git a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java index fc0a5d37589791c964fd4de178a29683cbdc93b8..3fb6e3653944102612d23a1487bc23bf83d9d70d 100644 --- a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java +++ b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java @@ -26,8 +26,8 @@ package org.olat.core.util.vfs; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; /** @@ -121,7 +121,7 @@ public abstract class AbstractVirtualContainer implements VFSContainer { } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return null; } diff --git a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java index ddf28ef0e0419e1d8cc7e74bedd83052fcf80135..c2f68241d8fea393ef305dab56ff3493c047b01f 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java @@ -39,6 +39,7 @@ import java.nio.file.Path; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -140,7 +141,7 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { CoreSpringFactory.getImpl(VersionsManager.class).rename(this, newname); } if(canMeta() == VFSConstants.YES) { - getMetaInfo().rename(newname); + CoreSpringFactory.getImpl(VFSRepositoryService.class).rename(getMetaInfo(), newname); } boolean ren = f.renameTo(nf); if (ren) { @@ -162,7 +163,7 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { } // Versioning makes a copy of the metadata, delete metadata after it if(canMeta() == VFSConstants.YES) { - getMetaInfo().delete(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } return deleteBasefile(); } @@ -170,7 +171,7 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { @Override public VFSStatus deleteSilently() { if(canMeta() == VFSConstants.YES) { - getMetaInfo().delete(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } CoreSpringFactory.getImpl(VersionsManager.class).delete(this, true); return deleteBasefile(); diff --git a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java index 0be27157ac49189a02f4641050f146c01ed2cba3..37b4e727fc0bf5126c21aa62e429c2c1b5e3c0be 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java @@ -36,6 +36,7 @@ import java.util.List; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -204,10 +205,12 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { if(s instanceof Versionable && ((Versionable)s).getVersions().isVersioned()) { ((Versionable)s).getVersions().copy(this); } - - boolean copyMetaData = source.canMeta() == VFSConstants.YES && canMeta() == VFSConstants.YES; - if(copyMetaData) { - source.getMetaInfo().moveCopyToDir(this, false); + + if(s.canMeta() == VFSConstants.YES) { + VFSItem target = resolve(sourcename); + if(target instanceof VFSLeaf && target.canMeta() == VFSConstants.YES) { + CoreSpringFactory.getImpl(VFSRepositoryService.class).copyTo(s, (VFSLeaf)target, this); + } } } else { throw new RuntimeException("neither a leaf nor a container!"); @@ -259,7 +262,7 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { } // Versioning makes a copy of the metadata, delete metadata after it if(canMeta() == VFSConstants.YES) { - getMetaInfo().deleteAll(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } // now delete the directory itself @@ -278,7 +281,7 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { } if(canMeta() == VFSConstants.YES) { - getMetaInfo().deleteAll(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } CoreSpringFactory.getImpl(VersionsManager.class).delete(this, true); // now delete the directory itself diff --git a/src/main/java/org/olat/core/util/vfs/LocalImpl.java b/src/main/java/org/olat/core/util/vfs/LocalImpl.java index f0fba5b8d95d519210c5ff10c561108e4b25e91c..9951b01f5dc8b7db740815c749bd06f15dfc9e47 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalImpl.java @@ -31,9 +31,9 @@ import java.nio.file.Path; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; /** * <P> @@ -137,18 +137,20 @@ public abstract class LocalImpl implements VFSItem, JavaIOItem { @Override public VFSStatus canMeta() { - Path bFile = getBasefile().toPath(); + File f = getBasefile(); + Path bFile = f.toPath(); Path bcRoot = FolderConfig.getCanonicalRootPath(); return bFile.startsWith(bcRoot) && !bFile.startsWith(FolderConfig.getCanonicalMetaRootPath()) && !bFile.startsWith(FolderConfig.getCanonicalVersionRootPath()) + && !f.isHidden() ? VFSConstants.YES : VFSConstants.NO; } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { if(canMeta() == VFSConstants.YES) { - return CoreSpringFactory.getImpl(MetaInfoFactory.class).createMetaInfoFor(getBasefile()); + return CoreSpringFactory.getImpl(VFSRepositoryService.class).getMetadataFor(getBasefile()); } return null; } diff --git a/src/main/java/org/olat/core/util/vfs/MergeSource.java b/src/main/java/org/olat/core/util/vfs/MergeSource.java index 2e448325ceb096af480ef018477476bb876e062a..bd2726d21e617aaf1df87e880186756a3ba91055 100644 --- a/src/main/java/org/olat/core/util/vfs/MergeSource.java +++ b/src/main/java/org/olat/core/util/vfs/MergeSource.java @@ -30,11 +30,11 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.logging.AssertException; import org.olat.core.util.CodeHelper; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; /** * Initial Date: 23.06.2005 <br> @@ -313,7 +313,7 @@ public class MergeSource extends AbstractVirtualContainer { } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return null; } diff --git a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java index 37dc55d280d1686327b863ad1b14bdfbfcbc76b7..2d5b8232d4f45ba37d17c055b647ef328d9bf425 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java +++ b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java @@ -28,9 +28,9 @@ package org.olat.core.util.vfs; import java.util.List; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; /** * <P> @@ -160,7 +160,7 @@ public class NamedContainerImpl extends AbstractVirtualContainer { } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return getDelegate().getMetaInfo(); } diff --git a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java index 1cf4fcd8d345448801f8df5dcc01189f31d9f67e..931f82fa27d32232d1d614c7f12fa3467bbcdfe3 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java +++ b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java @@ -22,8 +22,8 @@ package org.olat.core.util.vfs; import java.io.InputStream; import java.io.OutputStream; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; /** * <h3>Description:</h3> @@ -154,7 +154,7 @@ public class NamedLeaf implements VFSLeaf { } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return delegate.getMetaInfo(); } diff --git a/src/main/java/org/olat/core/util/vfs/VFSItem.java b/src/main/java/org/olat/core/util/vfs/VFSItem.java index a44f0d0c35296bbd0f7188ff2d00b95aaed5dd09..b9cbee85dae572fb3d3e4fd4e5309e6fb42a44bc 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSItem.java +++ b/src/main/java/org/olat/core/util/vfs/VFSItem.java @@ -26,8 +26,8 @@ package org.olat.core.util.vfs; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; /** @@ -138,7 +138,7 @@ public interface VFSItem { /** * @return The metadata if the item can metadata or null if not */ - public MetaInfo getMetaInfo(); + public VFSMetadata getMetaInfo(); /** * Get the local security callback for this item. diff --git a/src/main/java/org/olat/core/util/vfs/VFSLockManager.java b/src/main/java/org/olat/core/util/vfs/VFSLockManager.java index 9772db9c81406fbb809977ba6f62cd1063d32e45..e326475c15e9c127bc78afe653db542511b0f73a 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSLockManager.java +++ b/src/main/java/org/olat/core/util/vfs/VFSLockManager.java @@ -19,10 +19,10 @@ */ package org.olat.core.util.vfs; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.util.vfs.lock.LockInfo; -import org.olat.core.util.vfs.meta.MetaInfo; /** * The manager which locks / unlokcs the files @@ -47,7 +47,7 @@ public interface VFSLockManager { * @param loadedInfo The up-to-date meta info * @return */ - public boolean isLocked(VFSItem item, MetaInfo loadedInfo); + public boolean isLocked(VFSItem item, VFSMetadata loadedInfo); /** * @@ -66,7 +66,7 @@ public interface VFSLockManager { * @param roles * @return true if there is a lock owned by someone else, or there is a WebDAV lock on the item */ - public boolean isLockedForMe(VFSItem item, MetaInfo loadedInfo, Identity me, Roles roles); + public boolean isLockedForMe(VFSItem item, VFSMetadata loadedInfo, Identity me, Roles roles); public LockInfo getLock(VFSItem item); @@ -86,5 +86,5 @@ public interface VFSLockManager { /** * Method the generate the Lock-Token */ - public String generateLockToken(LockInfo lock, Long identityKey); + public String generateLockToken(LockInfo lock, Identity identity); } diff --git a/src/main/java/org/olat/core/util/vfs/VFSManager.java b/src/main/java/org/olat/core/util/vfs/VFSManager.java index 1163bcf1ee0b6fdfe6a9b5cd0c9a832df56c22e9..69de8d3ea226e5caa5dd26ad76c4b9889db10526 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSManager.java +++ b/src/main/java/org/olat/core/util/vfs/VFSManager.java @@ -36,7 +36,9 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; @@ -60,6 +62,11 @@ public class VFSManager { return new LocalFileImpl(file, null); } + public static LocalFileImpl olatRootLeaf(String relPath, String filename) { + File file = new File(FolderConfig.getCanonicalRoot() + relPath, filename); + return new LocalFileImpl(file, null); + } + public static LocalFolderImpl olatRootContainer(String fileRelPath) { File file = new File(FolderConfig.getCanonicalRoot() + fileRelPath); return new LocalFolderImpl(file, null); @@ -723,8 +730,7 @@ public class VFSManager { } if(withMetadata && source.canMeta() == VFSConstants.YES && target.canMeta() == VFSConstants.YES) { - VFSContainer parentTargetContainer = target.getParentContainer(); - source.getMetaInfo().moveCopyToDir(parentTargetContainer, false); + CoreSpringFactory.getImpl(VFSRepositoryService.class).copyTo(source, target, target.getParentContainer()); } } else { // source or target is null diff --git a/src/main/java/org/olat/core/util/vfs/lock/LockInfo.java b/src/main/java/org/olat/core/util/vfs/lock/LockInfo.java index 07bff06e5745bffbd42fdc72b923a274c5fb4559..037d085e1a12be52dc3c5cbaa1799ca43c3fb978 100644 --- a/src/main/java/org/olat/core/util/vfs/lock/LockInfo.java +++ b/src/main/java/org/olat/core/util/vfs/lock/LockInfo.java @@ -30,6 +30,7 @@ import org.olat.core.commons.services.webdav.servlets.FastHttpDateFormat; import org.olat.core.commons.services.webdav.servlets.WebDAVDispatcherImpl; import org.olat.core.commons.services.webdav.servlets.WebResource; import org.olat.core.commons.services.webdav.servlets.XMLWriter; +import org.olat.core.id.Identity; /** * Holds a lock information. @@ -44,7 +45,7 @@ public class LockInfo { private String scope = "exclusive"; private int depth = 0; private String owner = ""; - private Vector<String> tokens = new Vector<String>(); + private Vector<String> tokens = new Vector<>(); private long expiresAt = 0; private Date creationDate = new Date(); @@ -58,6 +59,12 @@ public class LockInfo { this.vfsLock = vfsLock; this.webdavLock = webdavLock; } + + public LockInfo(Identity lockedBy, boolean webdavLock, boolean vfsLock) { + this.lockedBy = lockedBy == null ? null : lockedBy.getKey(); + this.vfsLock = vfsLock; + this.webdavLock = webdavLock; + } public Long getLockedBy() { return lockedBy; diff --git a/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java b/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java index 089be1ac8c94ec8eed7080e34b158fadbeee01d4..f4de045c6485beae41e17ef879ef7c2202067206 100644 --- a/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java +++ b/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java @@ -28,6 +28,9 @@ import java.util.UUID; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.commons.services.webdav.manager.VFSResource; import org.olat.core.commons.services.webdav.servlets.WebResource; import org.olat.core.helpers.Settings; @@ -37,12 +40,16 @@ import org.olat.core.util.vfs.LocalImpl; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLockManager; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFileImpl; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("vfsLockManager") public class VFSLockManagerImpl implements VFSLockManager { + + @Autowired + private DB dbInstance; + @Autowired + private VFSRepositoryService fileService; /** * Repository of the locks put on single resources. @@ -70,6 +77,9 @@ public class VFSLockManagerImpl implements VFSLockManager { * Value : LockInfo */ private Vector<LockInfo> collectionLocks = new Vector<>(); + + @Autowired + private VFSRepositoryService vfsRepositoryService; @Override public boolean isLocked(VFSItem item) { @@ -77,7 +87,7 @@ public class VFSLockManagerImpl implements VFSLockManager { } @Override - public boolean isLocked(VFSItem item, MetaInfo loadedInfo) { + public boolean isLocked(VFSItem item, VFSMetadata loadedInfo) { File file = extractFile(item); if(file != null && fileLocks.containsKey(file)) { LockInfo lock = fileLocks.get(file); @@ -89,7 +99,7 @@ public class VFSLockManagerImpl implements VFSLockManager { } } - Long lockedBy = getMetaLockedBy(item, loadedInfo); + Identity lockedBy = getMetaLockedBy(item, loadedInfo); return (lockedBy != null); } @@ -102,7 +112,7 @@ public class VFSLockManagerImpl implements VFSLockManager { * @return true If the lock owner is someone else or if it's a WebDAV lock */ @Override - public boolean isLockedForMe(VFSItem item, MetaInfo loadedInfo, Identity me, Roles roles) { + public boolean isLockedForMe(VFSItem item, VFSMetadata loadedInfo, Identity me, Roles roles) { File file = extractFile(item); if(file != null && fileLocks.containsKey(file)) { LockInfo lock = fileLocks.get(file); @@ -115,13 +125,13 @@ public class VFSLockManagerImpl implements VFSLockManager { } } - Long lockedBy = getMetaLockedBy(item, loadedInfo); - return (lockedBy != null && !lockedBy.equals(me.getKey())); + Identity lockedBy = getMetaLockedBy(item, loadedInfo); + return (lockedBy != null && !lockedBy.getKey().equals(me.getKey())); } - private Long getMetaLockedBy(VFSItem item, MetaInfo loadedInfo) { - MetaInfoFileImpl info = loadedInfo == null ? getMetaInfo(item) : (MetaInfoFileImpl)loadedInfo; - Long lockedBy = null; + private Identity getMetaLockedBy(VFSItem item, VFSMetadata loadedInfo) { + VFSMetadata info = loadedInfo == null ? getMetaInfo(item) : loadedInfo; + Identity lockedBy = null; if(info != null) { if(!info.isLocked()) { return null; @@ -131,22 +141,24 @@ public class VFSLockManagerImpl implements VFSLockManager { return lockedBy; } - private MetaInfoFileImpl getMetaInfo(VFSItem item) { - MetaInfo info = null; + private VFSMetadata getMetaInfo(VFSItem item) { + VFSMetadata info = null; if (item != null && item.canMeta() == VFSConstants.YES) { - info = item.getMetaInfo(); + info = fileService.getMetadataFor(item); } - return (MetaInfoFileImpl)info; + return info; } @Override public boolean lock(VFSItem item, Identity identity, Roles roles) { if (item != null && item.canMeta() == VFSConstants.YES) { - MetaInfoFileImpl info = (MetaInfoFileImpl)item.getMetaInfo(); - info.setLockedBy(identity.getKey()); + VFSMetadata info = item.getMetaInfo(); + info.setLockedBy(identity); info.setLockedDate(new Date()); info.setLocked(true); - info.write(); + vfsRepositoryService.updateMetadata(info); + dbInstance.commit(); + System.out.println("lock:" + info.getKey()); File file = extractFile(item); if(file != null && fileLocks.containsKey(file)) { @@ -169,13 +181,14 @@ public class VFSLockManagerImpl implements VFSLockManager { @Override public boolean unlock(VFSItem item, Identity identity, Roles roles) { if (item != null && item.canMeta() == VFSConstants.YES) { - MetaInfoFileImpl info = (MetaInfoFileImpl)item.getMetaInfo(); + VFSMetadata info = item.getMetaInfo(); if(info == null) return false; info.setLockedBy(null); info.setLockedDate(null); info.setLocked(false); - info.write(); + vfsRepositoryService.updateMetadata(info); + dbInstance.commit(); boolean unlocked = false; File file = extractFile(item); @@ -223,7 +236,7 @@ public class VFSLockManagerImpl implements VFSLockManager { */ public LockInfo getVFSLock(WebResource resource) { VFSItem item = extractItem(resource); - MetaInfoFileImpl info = getMetaInfo(item); + VFSMetadata info = getMetaInfo(item); if(info != null && info.isLocked()) { File file = extractFile(item); LockInfo lock = null; @@ -237,7 +250,7 @@ public class VFSLockManagerImpl implements VFSLockManager { lock = new LockInfo(info.getLockedBy(), false, true); lock.setWebResource(resource); lock.setCreationDate(info.getLockedDate()); - lock.setOwner(Settings.getServerContextPathURI() + "/Identity/" + info.getLockedBy()); + lock.setOwner(Settings.getServerContextPathURI() + "/Identity/" + info.getLockedBy().getKey()); lock.setDepth(1); lock.addToken(generateLockToken(lock, info.getLockedBy())); fileLocks.put(file, lock); @@ -257,11 +270,11 @@ public class VFSLockManagerImpl implements VFSLockManager { } } - MetaInfoFileImpl info = getMetaInfo(item); + VFSMetadata info = getMetaInfo(item); if(info != null && info.isLocked()) { LockInfo lock = new LockInfo(info.getLockedBy(), false, true); lock.setCreationDate(info.getLockedDate()); - lock.setOwner(Settings.getServerContextPathURI() + "/Identity/" + info.getLockedBy()); + lock.setOwner(Settings.getServerContextPathURI() + "/Identity/" + info.getLockedBy().getKey()); lock.setDepth(1); lock.addToken(generateLockToken(lock, info.getLockedBy())); fileLocks.put(file, lock); @@ -276,7 +289,7 @@ public class VFSLockManagerImpl implements VFSLockManager { * + time in milliseconds seems to disturb the WebDAV client of Mac OS X 10.9 */ @Override - public String generateLockToken(LockInfo lock, Long identityKey) { + public String generateLockToken(LockInfo lock, Identity identity) { return UUID.randomUUID().toString(); } @@ -367,8 +380,8 @@ public class VFSLockManagerImpl implements VFSLockManager { //check if someone else as not set a lock on the resource if(resource instanceof VFSResource) { VFSResource vfsResource = (VFSResource)resource; - Long lockedBy = getMetaLockedBy(vfsResource.getItem(), null); - if(lockedBy != null && !lockedBy.equals(identity.getKey())) { + Identity lockedBy = getMetaLockedBy(vfsResource.getItem(), null); + if(lockedBy != null && !lockedBy.getKey().equals(identity.getKey())) { return true; } } diff --git a/src/main/java/org/olat/core/util/vfs/meta/MetaInfo.java b/src/main/java/org/olat/core/util/vfs/meta/MetaInfo.java deleted file mode 100644 index 64894dc857f954631b31367b8dfb837494d00939..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/meta/MetaInfo.java +++ /dev/null @@ -1,249 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ -package org.olat.core.util.vfs.meta; - -import java.util.Date; - -import org.olat.core.id.Identity; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSLeaf; - -public interface MetaInfo { - - /** - * Rename the given meta info file - * - * @param meta - * @param newName - */ - public void rename(String newName); - - /** - * Move/Copy the given meta info to the target directory. - * - * @param targetDir - * @param move - */ - public void moveCopyToDir(VFSItem target, boolean move); - - /** - * Delete all associated meta info including sub files/directories - */ - public void deleteAll(); - - /** - * Copy values from froMeta into this object except name, download count and UUID. - * - * @param fromMeta the metadata to copy from - */ - public void copyValues(MetaInfo fromMeta); - - /** - * Delete this meta info - * - * @return True upon success. - */ - public boolean delete(); - - /** - * @return the unique id of the file or create one if it previously not exists - */ - public String getUUID(); - - /** - * @return The last modification date of the metadata - */ - public Date getMetaLastModified(); - - /** - * @return name of the initial author (OLAT user name) - */ - public String getAuthor(); - - public Long getAuthorIdentityKey(); - - public boolean hasAuthorIdentity(); - - /** - * Corresponds to DublinCore:description - * - * @return comment - */ - public String getComment(); - - public String getName(); - - /** - * DublinCore compatible - */ - public String getTitle(); - - /** - * DublinCore compatible - */ - public String getPublisher(); - - /** - * In this context, the creator is the person or organization that is - * primarily responsible for making the content. The author, by contrast, is - * an OLAT user who uploaded the file. - * - * @return The writer of the resource - */ - public String getCreator(); - - /** - * DublinCore compatible - */ - public String getSource(); - - /** - * @return The city or location of publication - */ - public String getCity(); - - public String getPages(); - - /** - * DublinCore compatible - */ - public String getLanguage(); - - public String getUrl(); - - /** - * Corresponds to DublinCore:date + refinement - * - * @return The date in form of a {year, month} array. - */ - public String[] getPublicationDate(); - - /** - * @return True if this is a directory - */ - public boolean isDirectory(); - - /** - * @return Last modified timestamp - */ - public long getLastModified(); - - /** - * @return size of file - */ - public long getSize(); - - /** - * @return formatted representation of size of file - */ - public String getFormattedSize(); - - public void setAuthor(Identity identy); - - /** - * @param string - */ - public void setComment(String string); - - public void setTitle(String title); - - public void setPublisher(String publisher); - - public void setCreator(String creator); - - public void setSource(String source); - - public void setCity(String city); - - public void setPages(String pages); - - public void setLanguage(String language); - - public void setUrl(String url); - - public void setPublicationDate(String month, String year); - - public String getLicenseTypeKey(); - - public void setLicenseTypeKey(String key); - - public String getLicenseTypeName(); - - public void setLicenseTypeName(String name); - - public String getLicenseText(); - - public void setLicenseText(String text); - - public String getLicensor(); - - public void setLicensor(String licensor); - - - public boolean isThumbnailAvailable(); - - /** - * The - * - * - * @param maxWidth - * @param maxHeight - * @param fill True if you want to fill the surface defined above (overflow are cut) - * @return - */ - public VFSLeaf getThumbnail(int maxWidth, int maxHeight, boolean fill); - - /** - * Thumbnails are cleared and the metadata file is written on the disk - */ - public void clearThumbnails(); - - /** - * Writes the meta data to file. If no changes have been made, does not - * write anything. - * - * @return True upon success. - */ - public boolean write(); - - public byte[] readBinary(); - - public void writeBinary(byte[] data); - - /** - * Increases the download count by one. - */ - public void increaseDownloadCount(); - - /** - * @return The download count - */ - public int getDownloadCount(); - - /** - * @return An icon css class that represents this type of file - */ - public String getIconCssClass(); -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFactory.java b/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFactory.java deleted file mode 100644 index 2113d653e3d267b3a65dc4695e5b929b97d9faf6..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFactory.java +++ /dev/null @@ -1,166 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ -package org.olat.core.util.vfs.meta; - -import java.io.File; - -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.modules.bc.FolderConfig; -import org.olat.core.commons.modules.bc.FolderLicenseHandler; -import org.olat.core.commons.services.license.License; -import org.olat.core.commons.services.license.LicenseHandler; -import org.olat.core.commons.services.license.LicenseService; -import org.olat.core.commons.services.license.LicenseType; -import org.olat.core.commons.services.thumbnail.ThumbnailService; -import org.olat.core.id.Identity; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; -import org.olat.core.util.StringHelper; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service("metaInfoFactory") -public class MetaInfoFactory { - - private static final OLog log = Tracing.createLoggerFor(MetaInfoFactory.class); - - @Autowired - private ThumbnailService thumbnailService; - - public MetaInfo createMetaInfoFor(VFSItem path) { - File file = getOriginFile(path); - return createMetaInfoFor(file); - } - - public MetaInfo createMetaInfoFor(File file) { - if(file == null) { - return null; - } - String canonicalMetaPath = getCanonicalMetaPath(file, false); - if (canonicalMetaPath == null) { - return null; - } - - File metaFile = new File(canonicalMetaPath); - MetaInfoFileImpl meta = new MetaInfoFileImpl(metaFile, file); - meta.setThumbnailService(thumbnailService); - return meta; - } - - public MetaInfo createMetaShadowInfoFor(File metaFile) { - MetaInfoFileImpl meta = new MetaInfoFileImpl(metaFile); - meta.setThumbnailService(thumbnailService); - return meta; - } - - public void resetThumbnails(File metafile) { - try { - new MetaInfoFileImpl(metafile).clearThumbnails(); - } catch (Exception e) { - log.error("", e); - } - } - - public void deleteMetaFile(File file) { - String metaPath = getCanonicalMetaPath(file, true); - File metaFile = new File(metaPath); - new MetaInfoFileImpl(metaFile).delete(); - } - - protected static String getCanonicalMetaPath(VFSItem olatRelPathImpl) { - File f = getOriginFile(olatRelPathImpl); - return getCanonicalMetaPath(f, false); - } - - protected static String getCanonicalMetaPath(File originFile, boolean lenient) { - String canonicalMetaPath; - if (originFile == null || (!lenient && !originFile.exists())) { - canonicalMetaPath = null; - } else { - String relPath = FolderConfig.getCanonicalRootPath().relativize(originFile.toPath()).toString(); - StringBuilder metaSb = new StringBuilder(128); - metaSb.append(FolderConfig.getCanonicalMetaRoot()).append("/").append(relPath); - if (originFile.isDirectory()) { - metaSb.append("/.xml"); - } else { - metaSb.append(".xml"); - } - canonicalMetaPath = metaSb.toString(); - } - return canonicalMetaPath; - } - - private static File getOriginFile(VFSItem olatRelPathImpl) { - String relPath = olatRelPathImpl.getRelPath(); - if(relPath == null) return null; - return VFSManager.olatRootFile(relPath); - } - - /** - * Get the license of the MetaInfo - * - * @param meta - * @return the license or null if no license is stored in the MetaInfo - */ - public License getLicense(MetaInfo meta) { - License license = null; - boolean hasLicense = meta != null && StringHelper.containsNonWhitespace(meta.getLicenseTypeName()); - if (hasLicense) { - String licenseTypeName = meta.getLicenseTypeName(); - LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); - LicenseType licenseType = licenseService.loadLicenseTypeByName(licenseTypeName); - if (licenseType == null) { - licenseType = licenseService.createLicenseType(licenseTypeName); - licenseType.setText(meta.getLicenseText()); - licenseService.saveLicenseType(licenseType); - } - license = licenseService.createLicense(licenseType); - license.setLicensor(meta.getLicensor()); - if (licenseService.isFreetext(licenseType)) { - license.setFreetext(meta.getLicenseText()); - } - } - return license; - } - - /** - * Get the license of the MetaInfo or create a new default license: - * - * @param meta - * @param itentity the current user - * @return - */ - public License getOrCreateLicense(MetaInfo meta, Identity itentity) { - LicenseHandler licenseHandler = CoreSpringFactory.getImpl(FolderLicenseHandler.class); - License license = getLicense(meta); - if (license == null) { - LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); - license = licenseService.createDefaultLicense(licenseHandler, itentity); - } - return license; - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFileImpl.java b/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFileImpl.java deleted file mode 100644 index 91e6f91106e260fed15dc0cf5da0a07ae0da6b58..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/meta/MetaInfoFileImpl.java +++ /dev/null @@ -1,1070 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -* <p> -*/ - -package org.olat.core.util.vfs.meta; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.Serializable; -import java.io.StringReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.olat.basesecurity.BaseSecurity; -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException; -import org.olat.core.commons.services.thumbnail.FinalSize; -import org.olat.core.commons.services.thumbnail.ThumbnailService; -import org.olat.core.gui.util.CSSHelper; -import org.olat.core.id.Identity; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; -import org.olat.core.util.FileUtils; -import org.olat.core.util.Formatter; -import org.olat.core.util.StringHelper; -import org.olat.core.util.filter.FilterFactory; -import org.olat.core.util.vfs.LocalFileImpl; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSLeaf; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * Initial Date: 08.07.2003 - * - * @author Mike Stock<br> - * - * Comment: - * Meta files are in a shadow filesystem with the same directory structure as - * their original files. Meta info for directories is stored in a file called - * ".xml" residing in the respective directory. Meta info for files is stored - * in a file with ".xml" appended to its filename. - * - */ -public class MetaInfoFileImpl implements MetaInfo, Serializable { - - private static final long serialVersionUID = -3521950840094823106L; - private static final OLog log = Tracing.createLoggerFor(MetaInfoFileImpl.class); - - private static transient SAXParser saxParser; - static { - try { - saxParser = SAXParserFactory.newInstance().newSAXParser(); - } catch(Exception ex) { - log.error("", ex); - } - } - - // meta data - private String uuid; - private Long authorIdentKey; - private Long lockedByIdentKey; - private String comment = ""; - private String title; - private String publisher; - private String creator; - private String source; - private String city; - private String pages; - private String language; - private String url; - private String pubMonth; - private String pubYear; - private String licenseTypeKey; - private String licenseTypeName; - private String licenseText; - private String licensor; - private Date lockedDate; - private int downloadCount; - private boolean locked; - - // internal - private File originFile = null; - private File metaFile = null; - - private boolean cannotGenerateThumbnail = false; - private final List<Thumbnail> thumbnails = new ArrayList<>(); - private transient ThumbnailService thumbnailService; - - - // make it a factory - private MetaInfoFileImpl() { - // - } - - public MetaInfoFileImpl(File metaFile) { - this.metaFile = metaFile; - parseSAX(metaFile); - } - - protected MetaInfoFileImpl(File metaFile, File originFile) { - this.metaFile = metaFile; - this.originFile = originFile; - // set - if (!parseSAX(metaFile)) { - metaFile.getParentFile().mkdirs(); - if(uuid == null) { - generateUUID(); - } - write(); - } - } - - public void setThumbnailService(ThumbnailService thumbnailService) { - this.thumbnailService = thumbnailService; - } - - /** - * Rename the given meta info file - * - * @param meta - * @param newName - */ - @Override - public void rename(String newName) { - // rename meta info file name - if (isDirectory()) { // rename the directory, which is the parent of the actual ".xml" file - File metaFileDirectory = metaFile.getParentFile(); - if(!metaFileDirectory.renameTo(new File(metaFileDirectory.getParentFile(), newName))) { - log.error("Cannot rename meta directory: " + this, null); - } - } else if(!metaFile.renameTo(new File(metaFile.getParentFile(), newName + ".xml"))) { // rename the file - log.error("Cannot rename meta file: " + this, null); - } - } - - /** - * Move/Copy the given meta info to the target directory. - * @param targetDir - * @param move - */ - @Override - public void moveCopyToDir(VFSItem target, boolean move) { - File fSource = metaFile; - File fTarget = new File(MetaInfoFactory.getCanonicalMetaPath(target)); - if (isDirectory()) { // move/copy whole meta directory - fSource = fSource.getParentFile(); - fTarget = fTarget.getParentFile(); - } else if (target instanceof VFSContainer) { - //getCanonicalMetaPath give the path to the xml file where the metadatas are saved - if(fTarget.getName().equals(".xml")) { - fTarget = fTarget.getParentFile(); - } - } - - if (move) { - FileUtils.moveFileToDir(fSource, fTarget); - } else { - //copy - Map<String,String> pathToUuid = new HashMap<>(); - File mTarget = new File(fTarget, fSource.getName()); - collectUUIDRec(mTarget, pathToUuid); - - if(FileUtils.copyFileToDir(fSource, fTarget, "copy metadata")) { - File endTarget = new File(fTarget, fSource.getName()); - postMetaCopy(endTarget, pathToUuid); - } - } - } - - private void collectUUIDRec(File mTarget, Map<String,String> pathToUuid) { - try { - if(mTarget.exists()) { - if(mTarget.isDirectory()) { - //TODO - } else { - MetaInfoFileImpl copyMeta = new MetaInfoFileImpl(); - copyMeta.metaFile = mTarget; - if (copyMeta.parseSAX(mTarget)) { - pathToUuid.put(mTarget.getCanonicalPath(), copyMeta.getUUID()); - } - } - } - } catch (IOException e) { - log.error("cannot collect current UUID before copy", e); - } - } - - private void postMetaCopy(File endTarget, Map<String,String> pathToUuid) { - if(!endTarget.exists()) { - return; - } - - try { - if(endTarget.isDirectory()) { - for(File subEndTarget:endTarget.listFiles(new XmlFilter())) { - postMetaCopy(subEndTarget, pathToUuid); - } - } else { - MetaInfoFileImpl copyMeta = new MetaInfoFileImpl(); - copyMeta.metaFile = endTarget; - if (copyMeta.parseSAX(endTarget)) { - String tempUuid = pathToUuid.get(endTarget.getCanonicalPath()); - if(StringHelper.containsNonWhitespace(tempUuid)) { - copyMeta.uuid = tempUuid; - } else { - copyMeta.generateUUID(); - } - copyMeta.clearThumbnails();//clear write the meta - } - } - } catch (IOException e) { - log.error("Cannot generate a new uuid on copy", e); - } - } - - /** - * Delete all associated meta info including sub files/directories - * @param meta - */ - @Override - public void deleteAll() { - if (isDirectory()) { // delete whole meta directory (where the ".xml" resides within) - FileUtils.deleteDirsAndFiles(metaFile.getParentFile(), true, true); - } else { // delete this single meta file - delete(); - } - } - - /** - * Copy values from fromMeta into this object except name. - * @param fromMeta - */ - @Override - public void copyValues(MetaInfo fromMeta) { - setAuthorIdentKey(fromMeta.getAuthorIdentityKey()); - setComment(fromMeta.getComment()); - setCity(fromMeta.getCity()); - setCreator(fromMeta.getCreator()); - setLanguage(fromMeta.getLanguage()); - setPages(fromMeta.getPages()); - setPublicationDate(fromMeta.getPublicationDate()[1], fromMeta.getPublicationDate()[0]); - setPublisher(fromMeta.getPublisher()); - setSource(fromMeta.getSource()); - setTitle(fromMeta.getTitle()); - setUrl(fromMeta.getUrl()); - setLicenseTypeKey(fromMeta.getLicenseTypeKey()); - setLicenseTypeName(fromMeta.getLicenseTypeName()); - setLicensor(fromMeta.getLicensor()); - setLicenseText(fromMeta.getLicenseText()); - } - - public boolean isLocked() { - return locked; - } - - public void setLocked(boolean locked) { - this.locked = locked; - if(!locked) { - lockedByIdentKey = null; - lockedDate = null; - } - } - - public Identity getLockedByIdentity() { - if(lockedByIdentKey != null) { - return CoreSpringFactory.getImpl(BaseSecurity.class).loadIdentityByKey(lockedByIdentKey); - } - return null; - } - - public Long getLockedBy() { - return lockedByIdentKey; - } - - public void setLockedBy(Long lockedBy) { - this.lockedByIdentKey = lockedBy; - } - - public Date getLockedDate() { - return lockedDate; - } - - public void setLockedDate(Date lockedDate) { - this.lockedDate = lockedDate; - } - - /** - * Writes the meta data to file. If no changes have been made, - * does not write anything. - * @return True upon success. - */ - @Override - public boolean write() { - if (metaFile == null) return false; - - try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(metaFile)); - OutputStreamWriter sw = new OutputStreamWriter(bos, Charset.forName("UTF-8"))) { - - sw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - sw.write("<meta"); - if(StringHelper.containsNonWhitespace(uuid)) { - sw.write(" uuid=\"" + uuid + "\""); - } - sw.write(">"); - sw.write("<author><![CDATA[" + (authorIdentKey == null ? "" : authorIdentKey.toString()) + "]]></author>"); - sw.write("<lock locked=\"" + locked + "\"" + (lockedDate == null ? "" : " date=\"" + lockedDate.getTime() + "\"") + "><![CDATA[" + (lockedByIdentKey == null ? "" : lockedByIdentKey) + "]]></lock>"); - sw.write("<comment><![CDATA[" + filterForCData(comment) + "]]></comment>"); - sw.write("<title><![CDATA[" + filterForCData(title) + "]]></title>"); - sw.write("<publisher><![CDATA[" + filterForCData(publisher) + "]]></publisher>"); - sw.write("<creator><![CDATA[" + filterForCData(creator) + "]]></creator>"); - sw.write("<source><![CDATA[" + filterForCData(source) + "]]></source>"); - sw.write("<city><![CDATA[" + filterForCData(city) + "]]></city>"); - sw.write("<pages><![CDATA[" + filterForCData(pages) + "]]></pages>"); - sw.write("<language><![CDATA[" + filterForCData(language) + "]]></language>"); - sw.write("<url><![CDATA[" + filterForCData(url) + "]]></url>"); - sw.write("<licenseTypeKey><![CDATA[" + filterForCData(licenseTypeKey) + "]]></licenseTypeKey>"); - sw.write("<licenseTypeName><![CDATA[" + filterForCData(licenseTypeName) + "]]></licenseTypeName>"); - sw.write("<licenseText><![CDATA[" + filterForCData(licenseText) + "]]></licenseText>"); - sw.write("<licensor><![CDATA[" + filterForCData(licensor) + "]]></licensor>"); - sw.write("<publicationDate><month><![CDATA[" + (pubMonth != null ? pubMonth.trim() : "") + "]]></month><year><![CDATA[" + (pubYear != null ? pubYear.trim() : "") + "]]></year></publicationDate>"); - sw.write("<downloadCount><![CDATA[" + downloadCount + "]]></downloadCount>"); - sw.write("<thumbnails cannotGenerateThumbnail=\"" + cannotGenerateThumbnail + "\">"); - for(Thumbnail thumbnail:thumbnails) { - sw.write("<thumbnail maxHeight=\""); - sw.write(Integer.toString(thumbnail.getMaxHeight())); - sw.write("\" maxWidth=\""); - sw.write(Integer.toString(thumbnail.getMaxWidth())); - sw.write("\" finalHeight=\""); - sw.write(Integer.toString(thumbnail.getFinalHeight())); - sw.write("\" finalWidth=\""); - sw.write(Integer.toString(thumbnail.getFinalWidth())); - sw.write("\">"); - sw.write("<![CDATA[" + thumbnail.getThumbnailFile().getName() + "]]>"); - sw.write("</thumbnail>"); - } - sw.write("</thumbnails>"); - sw.write("</meta>"); - } catch (Exception e) { - return false; - } - return true; - } - - private String filterForCData(String original) { - if(StringHelper.containsNonWhitespace(original)) { - return FilterFactory.getXMLValidCharacterFilter().filter(original); - } - return ""; - } - - /** - * Delete this meta info - * - * @return True upon success. - */ - @Override - public boolean delete() { - if (metaFile == null) return false; - - for(Thumbnail thumbnail:thumbnails) { - File file = thumbnail.getThumbnailFile(); - if(file != null && file.exists()) { - try { - Files.delete(file.toPath()); - } catch (IOException e) { - log.error("Cannot delete thumbnail", e); - } - } - } - - boolean deleted = false; - try { - deleted = Files.deleteIfExists(metaFile.toPath()); - } catch (IOException e) { - log.error("Cannot delete metadata file", e); - } - return deleted; - } - - @Override - public byte[] readBinary() { - byte[] content = null; - try(InputStream in = new FileInputStream(metaFile); - BufferedInputStream bis = new BufferedInputStream(in, FileUtils.BSIZE); - ByteArrayOutputStream out = new ByteArrayOutputStream()) { - FileUtils.cpio(bis, out, ""); - content = out.toByteArray(); - } catch(IOException e) { - log.error("", e); - } - return content; - } - - @Override - public void writeBinary(byte[] data) { - if(data == null || data.length == 0) return; - - try(InputStream in = new ByteArrayInputStream(data)) { - synchronized(saxParser) { - MetaInfoFileImpl tmp = new MetaInfoFileImpl(); - tmp.metaFile = metaFile; - saxParser.parse(in, new MetaHandler(tmp)); - copyValues(tmp); - // restore last values - setDownloadCount(tmp.getDownloadCount()); - write(); - } - } catch(Exception e) { - log.error("", e); - } - } - - /** - * The parser is synchronized. Normally for such small files, this is - * the quicker way. Creation of a SAXParser is really time consuming. - * An other possibility would be to use a pool of parser. - * @param fMeta - * @return - */ - private boolean parseSAX(File fMeta) { - if (fMeta == null || !fMeta.exists() || fMeta.isDirectory()) return false; - - try(InputStream in = new FileInputStream(fMeta); - BufferedInputStream bis = new BufferedInputStream(in, FileUtils.BSIZE)) { - //the performance gain of the SAX Parser over the DOM Parser allow - //this to be synchronized (factor 5 to 10 quicker) - synchronized(saxParser) { - saxParser.parse(bis, new MetaHandler(this)); - if(uuid == null) { - generateUUID(); - write(); - } - } - } catch (SAXParseException ex) { - if(!parseSAXFiltered(fMeta)) { - //OLAT-5383,OLAT-5468: lowered error to warn to reduce error noise - log.warn("SAX Parser error while parsing " + fMeta, ex); - } - } catch(Exception ex) { - log.error("Error while parsing " + fMeta, ex); - } - return true; - } - - /** - * Try to rescue xml files with invalid characters - * @param fMeta - * @return true if rescue is successful - */ - private boolean parseSAXFiltered(File fMeta) { - String original = FileUtils.load(fMeta, "UTF-8"); - if(original == null) return false; - - String filtered = FilterFactory.getXMLValidCharacterFilter().filter(original); - if(!original.equals(filtered)) { - try { - synchronized(saxParser) { - InputSource in = new InputSource(new StringReader(filtered)); - saxParser.parse(in, new MetaHandler(this)); - } - write();//update with the new filtered write method - return true; - } catch (Exception e) { - //only a fallback, fail silently - } - } - return false; - } - - /* ------------------------- Getters ------------------------------ */ - - /** - * @return name of the initial author - */ - @Override - public String getAuthor() { - if (authorIdentKey == null) { - return "-"; - } else { - try { - Identity identity = CoreSpringFactory.getImpl(BaseSecurity.class).loadIdentityByKey(authorIdentKey); - if (identity == null) { - log.warn("Found no idenitiy with key='" + authorIdentKey + "'"); - return "-"; - } - return identity.getName(); - } catch (Exception e) { - return "-"; - } - } - } - - @Override - public String getUUID() { - return uuid; - } - - public void setUUID(String uuid) { - this.uuid = uuid; - } - - public void generateUUID() { - uuid = UUID.randomUUID().toString().replace("-", ""); - } - - @Override - public Long getAuthorIdentityKey() { - return authorIdentKey; - } - - @Override - public boolean hasAuthorIdentity() { - return (authorIdentKey != null); - } - - @Override - public String getComment() { return comment; } - - @Override - public String getName() { return originFile.getName(); } - - @Override - public boolean isDirectory() { return originFile.isDirectory(); } - - @Override - public long getLastModified() { - return originFile.lastModified(); - } - - @Override - public Date getMetaLastModified() { - if(metaFile == null) return null; - long lastModified = metaFile.lastModified(); - return lastModified > 0 ? new Date(lastModified) : null; - } - - @Override - public long getSize() { return originFile.length(); } - - @Override - public String getFormattedSize() { return Formatter.formatBytes(getSize()); } - - @Override - public void setAuthor(Identity identity) { - if (identity == null) { - log.warn("Found no idenity"); - authorIdentKey = null; - return; - } - authorIdentKey = identity.getKey(); - } - - @Override - public void setComment(String string) { comment = string; } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Name [" + getName()); - sb.append("] Author [" + getAuthor()); - sb.append("] Comment [" + getComment()); - sb.append("] IsDirectory [" + isDirectory()); - sb.append("] Size [" + getFormattedSize()); - sb.append("] LastModified [" + new Date(getLastModified()) + "]"); - return sb.toString(); - } - - @Override - public String getCity() { - return city; - } - - @Override - public String getLanguage() { - return language; - } - - @Override - public String getPages() { - return pages; - } - - @Override - public String[] getPublicationDate() { - return new String[] { pubYear, pubMonth }; - } - - @Override - public String getPublisher() { - return publisher; - } - - @Override - public String getCreator() { - return creator; - } - - @Override - public String getSource() { - return source; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public String getUrl() { - return url; - } - - @Override - public void setCity(String city) { - this.city = city; - } - - @Override - public void setLanguage(String language) { - this.language = language; - } - - @Override - public void setPages(String pages) { - this.pages = pages; - } - - @Override - public void setPublicationDate(String month, String year) { - this.pubMonth = month; - this.pubYear = year; - } - - @Override - public void setPublisher(String publisher) { - this.publisher = publisher; - } - - public void setWriter(String writer) { - this.creator = writer; - } - - @Override - public void setCreator(String creator) { - this.creator = creator; - } - - @Override - public void setSource(String source) { - this.source = source; - } - - @Override - public void setTitle(String title) { - this.title = title; - } - - @Override - public void setUrl(String url) { - this.url = url; - } - - @Override - public String getLicenseTypeKey() { - return licenseTypeKey; - } - - @Override - public void setLicenseTypeKey(String key) { - this.licenseTypeKey = key; - } - - @Override - public String getLicenseTypeName() { - return licenseTypeName; - } - - @Override - public void setLicenseTypeName(String name) { - this.licenseTypeName = name; - } - - @Override - public String getLicenseText() { - return licenseText; - } - - @Override - public void setLicenseText(String text) { - this.licenseText = text; - } - - @Override - public String getLicensor() { - return licensor; - } - - @Override - public void setLicensor(String licensor) { - this.licensor = licensor != null? licensor: ""; - } - - @Override - public boolean isThumbnailAvailable() { - if(isDirectory()) return false; - if(originFile.isHidden()) return false; - if(cannotGenerateThumbnail) return false; - - VFSLeaf originLeaf = new LocalFileImpl(originFile); - if(thumbnailService == null) { - thumbnailService = CoreSpringFactory.getImpl(ThumbnailService.class); - } - return thumbnailService.isThumbnailPossible(originLeaf); - } - - @Override - public VFSLeaf getThumbnail(int maxWidth, int maxHeight, boolean fill) { - if(isDirectory()) return null; - Thumbnail thumbnailInfo = getThumbnailInfo(maxWidth, maxHeight, fill); - if(thumbnailInfo == null) { - return null; - } - return new LocalFileImpl(thumbnailInfo.getThumbnailFile()); - } - - /** - * Thumbnails are cleared and the XML file is written on the disk - */ - @Override - public void clearThumbnails() { - cannotGenerateThumbnail = false; - for(Thumbnail thumbnail:thumbnails) { - File thumbnailFile = thumbnail.getThumbnailFile(); - if(thumbnailFile != null && thumbnailFile.exists()) { - try { - Files.delete(thumbnailFile.toPath()); - } catch (IOException e) { - log.error("Cannot delete thumbnail", e); - } - } - } - thumbnails.clear(); - write(); - } - - private Thumbnail getThumbnailInfo(int maxWidth, int maxHeight, boolean fill) { - for(Thumbnail thumbnail:thumbnails) { - if(maxHeight == thumbnail.getMaxHeight() && maxWidth == thumbnail.getMaxWidth() - && thumbnail.exists()) { - return thumbnail; - } - } - - //generate a file name - File metaLoc = metaFile.getParentFile(); - String name = originFile.getName(); - String extension = FileUtils.getFileSuffix(name); - String nameOnly = name.substring(0, name.length() - extension.length() - 1); - String randuuid = UUID.randomUUID().toString(); - String thumbnailExtension = preferedThumbnailType(extension); - File thumbnailFile = new File(metaLoc, nameOnly + "_" + randuuid + "_" + maxHeight + "x" + maxWidth + (fill ? "xfill" : "") + "." + thumbnailExtension); - - //generate thumbnail - long start = 0l; - if(log.isDebug()) start = System.currentTimeMillis(); - - VFSLeaf thumbnailLeaf = new LocalFileImpl(thumbnailFile); - VFSLeaf originLeaf = new LocalFileImpl(originFile); - if(thumbnailService == null) { - thumbnailService = CoreSpringFactory.getImpl(ThumbnailService.class); - } - if(thumbnailService != null &&thumbnailService.isThumbnailPossible(thumbnailLeaf)) { - try { - if(thumbnails.isEmpty()) { - //be paranoid - cannotGenerateThumbnail = true; - write(); - } - log.info("Start thumbnail: " + thumbnailLeaf); - - FinalSize finalSize = thumbnailService.generateThumbnail(originLeaf, thumbnailLeaf, maxWidth, maxHeight, fill); - if(finalSize == null) { - return null; - } else { - Thumbnail thumbnail = new Thumbnail(); - thumbnail.setMaxHeight(maxHeight); - thumbnail.setMaxWidth(maxWidth); - thumbnail.setFinalHeight(finalSize.getHeight()); - thumbnail.setFinalWidth(finalSize.getWidth()); - thumbnail.setFill(true); - thumbnail.setThumbnailFile(thumbnailFile); - thumbnails.add(thumbnail); - cannotGenerateThumbnail = false; - write(); - log.info("Create thumbnail: " + thumbnailLeaf); - if(log.isDebug()) { - log.debug("Creation of thumbnail takes (ms): " + (System.currentTimeMillis() - start)); - } - return thumbnail; - } - } catch (CannotGenerateThumbnailException e) { - //don't try every time to create the thumbnail. - cannotGenerateThumbnail = true; - write(); - return null; - } - } - return null; - } - - private String preferedThumbnailType(String extension) { - if(extension.equalsIgnoreCase("png") || extension.equalsIgnoreCase("gif")) { - return extension; - } - if(extension.equalsIgnoreCase("pdf")) { - return "png"; - } - return "jpg"; - } - - @Override - public void increaseDownloadCount() { - downloadCount++; - } - - @Override - public int getDownloadCount() { - return downloadCount; - } - - public void setDownloadCount(int count) { - downloadCount = count; - } - - public void setAuthorIdentKey(Long authorIdentKey) { - this.authorIdentKey = authorIdentKey; - } - - @Override - public String getIconCssClass() { - String cssClass; - if (isDirectory()) { - cssClass = CSSHelper.CSS_CLASS_FILETYPE_FOLDER; - } else { - cssClass = CSSHelper.createFiletypeIconCssClassFor(getName()); - } - return cssClass; - } - - public static class XmlFilter implements FileFilter { - @Override - public boolean accept(File file) { - return file.getName().endsWith(".xml"); - } - } - - private static class MetaHandler extends DefaultHandler { - - private StringBuilder current; - private final MetaInfoFileImpl meta; - - public MetaHandler(MetaInfoFileImpl meta) { - this.meta = meta; - } - - @Override - public final void startElement(String uri, String localName, String qName, Attributes attributes) { - if("meta".equals(qName)) { - meta.setUUID(attributes.getValue("uuid")); - } else if ("lock".equals(qName)) { - meta.setLocked("true".equals(attributes.getValue("locked"))); - String date = attributes.getValue("date"); - if (date != null && date.length() > 0) { - meta.setLockedDate(new Date(Long.parseLong(date))); - } - } else if ("thumbnails".equals(qName)) { - String valueStr = attributes.getValue("cannotGenerateThumbnail"); - if(StringHelper.containsNonWhitespace(valueStr)) { - meta.cannotGenerateThumbnail = Boolean.valueOf(valueStr); - } - } else if ("thumbnail".equals(qName)) { - Thumbnail thumbnail = new Thumbnail(); - thumbnail.setMaxHeight(Integer.parseInt(attributes.getValue("maxHeight"))); - thumbnail.setMaxWidth(Integer.parseInt(attributes.getValue("maxWidth"))); - thumbnail.setFinalHeight(Integer.parseInt(attributes.getValue("finalHeight"))); - thumbnail.setFinalWidth(Integer.parseInt(attributes.getValue("finalWidth"))); - thumbnail.setFill("true".equals(attributes.getValue("fill"))); - meta.thumbnails.add(thumbnail); - } - } - - @Override - public final void characters(char[] ch, int start, int length) { - if(length == 0) return; - if(current == null) { - current = new StringBuilder(); - } - current.append(ch, start, length); - } - - @Override - public final void endElement(String uri, String localName, String qName) { - if(current == null) return; - - if("comment".equals(qName)) { - meta.comment = current.toString(); - } else if ("author".equals(qName)) { - try { - meta.authorIdentKey = Long.valueOf(current.toString()); - } catch (NumberFormatException nEx) { - //nothing to say - } - } else if ("lock".equals(qName)) { - try { - meta.lockedByIdentKey = Long.valueOf(current.toString()); - } catch (NumberFormatException nEx) { - //nothing to say - } - } else if ("title".equals(qName)) { - meta.title = current.toString(); - } else if ("publisher".equals(qName)) { - meta.publisher = current.toString(); - } else if ("source".equals(qName)) { - meta.source = current.toString(); - } else if ("city".equals(qName)) { - meta.city = current.toString(); - } else if ("pages".equals(qName)) { - meta.pages = current.toString(); - } else if ("language".equals(qName)) { - meta.language = current.toString(); - } else if ("downloadCount".equals(qName)) { - try { - meta.downloadCount = Integer.valueOf(current.toString()); - } catch (NumberFormatException nEx) { - //nothing to say - } - } else if ("month".equals(qName)) { - meta.pubMonth = current.toString(); - } else if ("year".equals(qName)) { - meta.pubYear = current.toString(); - } else if (qName.equals("creator")) { - meta.creator = current.toString(); - } else if (qName.equals("url")) { - meta.url = current.toString(); - } else if (qName.equals("licenseTypeKey")) { - meta.licenseTypeKey = current.toString(); - } else if (qName.equals("licenseTypeName")) { - meta.licenseTypeName = current.toString(); - } else if (qName.equals("licenseText")) { - meta.licenseText = current.toString(); - } else if (qName.equals("licensor")) { - meta.licensor = current.toString(); - } else if (qName.equals("thumbnail")) { - String finalName = current.toString(); - File thumbnailFile = new File(meta.metaFile.getParentFile(), finalName); - meta.thumbnails.get(meta.thumbnails.size() - 1).setThumbnailFile(thumbnailFile); - } - current = null; - } - - } - - public static class Thumbnail implements Serializable { - - private static final long serialVersionUID = 29491661959555446L; - - private int maxWidth; - private int maxHeight; - private int finalWidth; - private int finalHeight; - private boolean fill = false; - private File thumbnailFile; - - public int getMaxWidth() { - return maxWidth; - } - - public void setMaxWidth(int maxWidth) { - this.maxWidth = maxWidth; - } - - public int getMaxHeight() { - return maxHeight; - } - - public void setMaxHeight(int maxHeight) { - this.maxHeight = maxHeight; - } - - public int getFinalWidth() { - return finalWidth; - } - - public void setFinalWidth(int finalWidth) { - this.finalWidth = finalWidth; - } - - public int getFinalHeight() { - return finalHeight; - } - - public void setFinalHeight(int finalHeight) { - this.finalHeight = finalHeight; - } - - public boolean isFill() { - return fill; - } - - public void setFill(boolean fill) { - this.fill = fill; - } - - public File getThumbnailFile() { - return thumbnailFile; - } - - public void setThumbnailFile(File thumbnailFile) { - this.thumbnailFile = thumbnailFile; - } - - public boolean exists() { - return thumbnailFile != null && thumbnailFile.exists(); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java b/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java index 49dabd53945f61774f09002d8d28695df7a88ad6..ba11edb7aa0c6d288e10cc80145749ccd5173bf0 100644 --- a/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java +++ b/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java @@ -22,9 +22,10 @@ package org.olat.core.util.vfs.restapi; import java.io.InputStream; import java.io.OutputStream; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.vfs.VFSLeaf; @@ -37,6 +38,8 @@ import org.olat.core.util.vfs.VFSLeaf; */ public class VFSStreamingOutput implements StreamingOutput { + private static final OLog log = Tracing.createLoggerFor(VFSStreamingOutput.class); + private final VFSLeaf leaf; public VFSStreamingOutput(VFSLeaf leaf) { @@ -44,9 +47,11 @@ public class VFSStreamingOutput implements StreamingOutput { } @Override - public void write(OutputStream output) throws WebApplicationException { - InputStream in = leaf.getInputStream(); - FileUtils.copy(in, output); - FileUtils.closeSafely(in); + public void write(OutputStream output) { + try(InputStream in = leaf.getInputStream()) { + FileUtils.copy(in, output); + } catch(Exception e) { + log.error("", e); + } } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/util/ContainerAndFile.java b/src/main/java/org/olat/core/util/vfs/util/ContainerAndFile.java index b4980b66292ee14a3bd58c25e73d42dcf8d9894d..4ddf5f0f0f64e0ca63677fbfb4bbb880df36e2aa 100644 --- a/src/main/java/org/olat/core/util/vfs/util/ContainerAndFile.java +++ b/src/main/java/org/olat/core/util/vfs/util/ContainerAndFile.java @@ -29,11 +29,7 @@ package org.olat.core.util.vfs.util; import org.olat.core.util.vfs.VFSContainer; /** - * Description:<br> - * TODO: HP_Besitzer Class Description for ContainerAndFile - * - * <P> - * Initial Date: 15.03.2006 <br> + * Initial Date: 15.03.2006 * * @author HP_Besitzer */ diff --git a/src/main/java/org/olat/core/util/vfs/util/VFSUtil.java b/src/main/java/org/olat/core/util/vfs/util/VFSUtil.java deleted file mode 100644 index 357b242a1f07c9c7811c0ececb346f2222979fde..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/util/VFSUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -* <p> -*/ - -package org.olat.core.util.vfs.util; - -import org.olat.core.util.vfs.VFSContainer; - -/** - * Initial Date: 17.01.2006 - * - * @author Felix Jost - * - * Description: - * some utils for the VFS - */ -public class VFSUtil { - - - /** - * calculates a new vfscontainer and a filename where the container's base is where the file resides.<br> - * e.g.<br> - * container: /usr/local/olat/courses/123/coursefolder and filename: docs/bla/blu.doc<br> - * -> container /usr/local/olat/courses/123/coursefolder/docs/bla and filename: blu.doc - * - * @param oldRoot - * @param fileName - * @return - */ - public static ContainerAndFile calculateSubRoot(VFSContainer oldRoot, String fileUri) { - VFSContainer newC; - String newFile; - int sla = fileUri.lastIndexOf('/'); - if (sla != -1) { - String root = fileUri.substring(0,sla); - newFile = fileUri.substring(sla+1); - newC = (VFSContainer)oldRoot.resolve(root); - } else { - newC = oldRoot; - newFile = fileUri; - } - return new ContainerAndFile(newC, newFile); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java b/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java index 25b27b6a6230f38507ded5480cbaf22a295fc001..df713e6f7c1458c0ce2bbb43df5da6781a829d72 100644 --- a/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java @@ -21,9 +21,9 @@ package org.olat.core.util.vfs.version; import java.io.InputStream; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.meta.MetaInfo; /** * @@ -48,7 +48,7 @@ public class RevisionFileImpl implements VFSRevision { private VFSContainer container; private String revisionNr; private String filename; - private MetaInfo metadata; + private VFSMetadata metadata; /** * Only for the VersionsFileManager or XStream @@ -140,11 +140,11 @@ public class RevisionFileImpl implements VFSRevision { this.name = name; } - public MetaInfo getMetadata() { + public VFSMetadata getMetadata() { return metadata; } - public void setMetadata(MetaInfo metadata) { + public void setMetadata(VFSMetadata metadata) { this.metadata = metadata; } diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java index 869ebf3e413d4a0c485457085ec847e4242b3941..f29bb05f5fafcf390af482bcc46a1fbcc5daf4e4 100644 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java +++ b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java @@ -38,8 +38,10 @@ import java.util.zip.Adler32; import java.util.zip.Checksum; import org.apache.commons.io.FileUtils; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.manager.VFSXStream; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -61,16 +63,9 @@ import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.SystemItemFilter; import org.olat.core.util.vfs.filters.VFSItemSuffixFilter; import org.olat.core.util.vfs.filters.VFSLeafFilter; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; -import org.olat.core.util.vfs.meta.MetaInfoFileImpl; -import org.olat.core.util.xml.XStreamHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.security.ExplicitTypePermission; - /** * * Description:<br> @@ -90,32 +85,13 @@ public class VersionsFileManager implements VersionsManager { private static final Versions NOT_VERSIONED = new NotVersioned(); private static final Pattern TAG_PATTERN = Pattern.compile("\\s*[<>]\\s*"); - private static XStream mystream; - static { - mystream = XStreamHelper.createXStreamInstance(); - XStream.setupDefaultSecurity(mystream); - Class<?>[] types = new Class[] { - VersionsFileImpl.class, Versions.class, RevisionFileImpl.class, VFSRevision.class, - MetaInfoFileImpl.class, MetaInfoFileImpl.Thumbnail.class - }; - mystream.addPermission(new ExplicitTypePermission(types)); - - mystream.alias("versions", VersionsFileImpl.class); - mystream.alias("revision", RevisionFileImpl.class); - mystream.omitField(VersionsFileImpl.class, "currentVersion"); - mystream.omitField(VersionsFileImpl.class, "versionFile"); - mystream.omitField(RevisionFileImpl.class, "current"); - mystream.omitField(RevisionFileImpl.class, "container"); - mystream.omitField(RevisionFileImpl.class, "file"); - - mystream.alias("metadata", MetaInfoFileImpl.class); - mystream.alias("thumbnail", MetaInfoFileImpl.Thumbnail.class); - } private File rootFolder; private File rootVersionFolder; private VFSContainer rootVersionsContainer; + @Autowired + private VFSRepositoryService vfsRepositoryService; @Autowired private FolderVersioningConfigurator versioningConfigurator; @@ -211,7 +187,7 @@ public class VersionsFileManager implements VersionsManager { try { VFSContainer fVersionContainer = fVersions.getParentContainer(); - VersionsFileImpl versions = (VersionsFileImpl) XStreamHelper.readObject(mystream, fVersions); + VersionsFileImpl versions = (VersionsFileImpl) VFSXStream.read(fVersions); versions.setVersionFile(fVersions); versions.setCurrentVersion((Versionable) leaf); if (versions.getRevisionNr() == null || versions.getRevisionNr().length() == 0) { @@ -284,7 +260,7 @@ public class VersionsFileManager implements VersionsManager { } targetVersionsImpl.setRevisionNr(getNextRevisionNr(targetVersionsImpl)); - XStreamHelper.writeObject(mystream, fTargetVersions, targetVersionsImpl); + VFSXStream.write(fTargetVersions, targetVersionsImpl); return allOk; } @@ -317,15 +293,17 @@ public class VersionsFileManager implements VersionsManager { newRevision.setUuid(revUuid); //copy -> the files revision - InputStream revisionIn = revision.getInputStream(); - - VFSLeaf target = fNewVersions.getParentContainer().createChildLeaf(uuid); - if (VFSManager.copyContent(revisionIn, target)) { - targetVersions.setComment(revision.getComment()); - targetVersions.getRevisions().add(newRevision); - targetVersions.setRevisionNr(getNextRevisionNr(targetVersions)); - targetVersions.setAuthor(revision.getAuthor()); - return true; + try(InputStream revisionIn = revision.getInputStream()) { + VFSLeaf target = fNewVersions.getParentContainer().createChildLeaf(uuid); + if (VFSManager.copyContent(revisionIn, target)) { + targetVersions.setComment(revision.getComment()); + targetVersions.getRevisions().add(newRevision); + targetVersions.setRevisionNr(getNextRevisionNr(targetVersions)); + targetVersions.setAuthor(revision.getAuthor()); + return true; + } + } catch(Exception e) { + log.error("", e); } return false; } @@ -400,37 +378,39 @@ public class VersionsFileManager implements VersionsManager { if (restoredItem instanceof VFSLeaf) { VFSLeaf restoredLeaf = (VFSLeaf) restoredItem; - InputStream inStream = revision.getInputStream(); - if (VFSManager.copyContent(inStream, restoredLeaf)) { - VFSLeaf versionFile = getCanonicalVersionXmlFile(restoredLeaf, true); - Versions versions = readVersions(restoredLeaf, versionFile); - if (versions instanceof VersionsFileImpl) { - versions.getRevisions().remove(revision); - ((VersionsFileImpl) versions).setRevisionNr(getNextRevisionNr(versions)); - if (revision instanceof RevisionFileImpl) { - VFSLeaf fileToDelete = ((RevisionFileImpl)revision).getFile(); - if(fileToDelete != null) { - fileToDelete.deleteSilently(); + try(InputStream inStream = revision.getInputStream()) { + if (VFSManager.copyContent(inStream, restoredLeaf)) { + VFSLeaf versionFile = getCanonicalVersionXmlFile(restoredLeaf, true); + Versions versions = readVersions(restoredLeaf, versionFile); + if (versions instanceof VersionsFileImpl) { + versions.getRevisions().remove(revision); + ((VersionsFileImpl) versions).setRevisionNr(getNextRevisionNr(versions)); + if (revision instanceof RevisionFileImpl) { + VFSLeaf fileToDelete = ((RevisionFileImpl)revision).getFile(); + if(fileToDelete != null) { + fileToDelete.deleteSilently(); + } } } - } - if (restoreDeletedFile && revision instanceof RevisionFileImpl) { - MetaInfo versionedMetadata = ((RevisionFileImpl)revision).getMetadata(); - MetaInfoFileImpl metadata = (MetaInfoFileImpl)restoredItem.getMetaInfo(); - if(versionedMetadata != null && metadata != null) { - metadata.copyValues(versionedMetadata); - // make sure the restored file is not locked - metadata.setLocked(false); - metadata.setLockedBy(null); - metadata.setLockedDate(null); - // restore last values - metadata.setUUID(versionedMetadata.getUUID()); - metadata.setDownloadCount(versionedMetadata.getDownloadCount()); - metadata.write(); + if (restoreDeletedFile && revision instanceof RevisionFileImpl) { + VFSMetadata versionedMetadata = ((RevisionFileImpl)revision).getMetadata(); + VFSMetadata metadata = restoredItem.getMetaInfo(); + if(versionedMetadata != null && metadata != null) { + metadata.copyValues(versionedMetadata); + // make sure the restored file is not locked + metadata.setLocked(false); + metadata.setLockedBy(null); + metadata.setLockedDate(null); + // restore last values + metadata.setUuid(versionedMetadata.getUuid()); + vfsRepositoryService.updateMetadata(metadata); + } } + VFSXStream.write(versionFile, versions); + return true; } - XStreamHelper.writeObject(mystream, versionFile, versions); - return true; + } catch(Exception e) { + log.error("", e); } } return false; @@ -478,7 +458,7 @@ public class VersionsFileManager implements VersionsManager { } VFSLeaf versionFile = getCanonicalVersionXmlFile(currentFile, true); - XStreamHelper.writeObject(mystream, versionFile, versions); + VFSXStream.write(versionFile, versions); if (currentVersion.getVersions() instanceof VersionsFileImpl) { ((VersionsFileImpl) currentVersion.getVersions()).update(versions); } @@ -509,7 +489,7 @@ public class VersionsFileManager implements VersionsManager { File dir = ((JavaIOItem)container).getBasefile(); File file = new File(dir, originFilename); if(!file.exists()) { - CoreSpringFactory.getImpl(MetaInfoFactory.class).deleteMetaFile(file); + vfsRepositoryService.deleteMetadata(file); } } } @@ -651,24 +631,24 @@ public class VersionsFileManager implements VersionsManager { String versionNr = getNextRevisionNr(versions); String currentAuthor = versions.getAuthor(); - long lastModifiedDate = 0; + Date lastModifiedDate = null; - MetaInfo metaInfo = null; + VFSMetadata metaInfo = null; if (currentFile.canMeta() == VFSConstants.YES) { metaInfo = currentFile.getMetaInfo(); if(metaInfo != null) { - metaInfo.clearThumbnails(); - if(currentAuthor == null) { - currentAuthor = metaInfo.getAuthor(); + vfsRepositoryService.resetThumbnails(currentFile); + if(currentAuthor == null && metaInfo.getAuthor() != null) { + currentAuthor = metaInfo.getAuthor().getName(); } lastModifiedDate = metaInfo.getLastModified(); } } - if(lastModifiedDate <= 0) { + if(lastModifiedDate == null) { Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); - lastModifiedDate = cal.getTimeInMillis(); + lastModifiedDate = cal.getTime(); } RevisionFileImpl newRevision = new RevisionFileImpl(); @@ -678,13 +658,13 @@ public class VersionsFileManager implements VersionsManager { newRevision.setRevisionNr(versionNr); newRevision.setComment(versions.getComment()); newRevision.setAuthor(currentAuthor); - newRevision.setLastModified(lastModifiedDate); - newRevision.setMetadata(metaInfo); + newRevision.setLastModified(lastModifiedDate.getTime()); + //TODO metadata newRevision.setMetadata(metaInfo); if (versions.getRevisions().isEmpty() && currentVersion instanceof VFSItem) { - MetaInfo currentMeta = ((VFSItem)currentVersion).getMetaInfo(); - if(currentMeta != null) { - versions.setCreator(currentMeta.getAuthor()); + VFSMetadata currentMeta = ((VFSItem)currentVersion).getMetaInfo(); + if(currentMeta != null && currentMeta.getAuthor() != null) { + versions.setCreator(currentMeta.getAuthor().getName()); } } @@ -705,7 +685,7 @@ public class VersionsFileManager implements VersionsManager { versions.setComment(comment); versions.getRevisions().add(newRevision); versions.setRevisionNr(getNextRevisionNr(versions)); - XStreamHelper.writeObject(mystream, versionFile, versions); + VFSXStream.write(versionFile, versions); if (currentVersion.getVersions() instanceof VersionsFileImpl) { ((VersionsFileImpl) currentVersion.getVersions()).update(versions); } @@ -802,7 +782,7 @@ public class VersionsFileManager implements VersionsManager { versions.setRevisionNr(getNextRevisionNr(versions)); VFSLeaf fVersions = localVersionContainer.createChildLeaf(fVersion.getName()); if(fVersions != null) { - XStreamHelper.writeObject(mystream, fVersions, versions); + VFSXStream.write(fVersions, versions); } return fVersions; } @@ -1063,7 +1043,7 @@ public class VersionsFileManager implements VersionsManager { private Versions isOrphan(VFSLeaf potentialOrphan) { try { if(potentialOrphan.exists()) { - return (VersionsFileImpl) XStreamHelper.readObject(mystream, potentialOrphan); + return (VersionsFileImpl) VFSXStream.read(potentialOrphan); } return null; } catch (Exception e) { diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java index 7d28a5598501658167d4b218e2e2939ac9bb1228..242c3b901e0bc221f6a01c39fc2284a7f1ce659e 100644 --- a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java +++ b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java @@ -33,6 +33,7 @@ import org.olat.basesecurity.GroupRoles; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.context.BusinessControlFactory; @@ -44,7 +45,6 @@ import org.olat.core.util.io.SystemFilenameFilter; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentHelper; @@ -824,8 +824,8 @@ class GTANotifications { String author = null; VFSItem item = container.resolve(file.getName()); if(item.canMeta() == VFSConstants.YES) { - MetaInfo info = item.getMetaInfo(); - Long identityKey = info.getAuthorIdentityKey(); + VFSMetadata info = item.getMetaInfo(); + Identity identityKey = info.getAuthor(); if(identityKey != null) { author = userManager.getUserDisplayName(identityKey); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/DirectoryController.java b/src/main/java/org/olat/course/nodes/gta/ui/DirectoryController.java index 32e9521c0c69f944fea7fccad7893f88615060ab..8eb55a18b0a6e34c23397d0145e679aa3a97540f 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/DirectoryController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/DirectoryController.java @@ -25,6 +25,7 @@ import java.util.Date; import java.util.List; import org.olat.core.commons.modules.singlepage.SinglePageController; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.download.DisplayOrDownloadComponent; @@ -51,7 +52,6 @@ import org.olat.core.util.io.SystemFileFilter; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.gta.ui.component.DownloadDocumentMapper; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -130,9 +130,9 @@ public class DirectoryController extends BasicController implements Activateable VFSItem item = documentsContainer.resolve(document.getName()); lastModified = format.formatDateAndTime(new Date(item.getLastModified())); if(item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - if(metaInfo != null && metaInfo.getAuthorIdentityKey() != null) { - uploadedBy = userManager.getUserDisplayName(metaInfo.getAuthorIdentityKey()); + VFSMetadata metaInfo = item.getMetaInfo(); + if(metaInfo != null && metaInfo.getAuthor() != null) { + uploadedBy = userManager.getUserDisplayName(metaInfo.getAuthor()); } } } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/EditSolutionController.java b/src/main/java/org/olat/course/nodes/gta/ui/EditSolutionController.java index 923e0f51a29633a67e0618708a9be0b1c27a0796..eae532a4927d778aa6973f2677ff2678945dcde2 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/EditSolutionController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/EditSolutionController.java @@ -24,6 +24,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FileElement; @@ -40,8 +42,8 @@ import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.gta.model.Solution; +import org.springframework.beans.factory.annotation.Autowired; /** @@ -60,6 +62,9 @@ public class EditSolutionController extends FormBasicController { private final File solutionDir; private final VFSContainer solutionContainer; private final String filenameToReplace; + + @Autowired + private VFSRepositoryService vfsRepositoryService; public EditSolutionController(UserRequest ureq, WindowControl wControl, File solutionDir, VFSContainer solutionContainer) { @@ -172,9 +177,9 @@ public class EditSolutionController extends FormBasicController { VFSItem uploadedItem = solutionContainer.resolve(filename); if(uploadedItem.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = uploadedItem.getMetaInfo(); + VFSMetadata metaInfo = uploadedItem.getMetaInfo(); metaInfo.setAuthor(ureq.getIdentity()); - metaInfo.write(); + vfsRepositoryService.updateMetadata(metaInfo); } } catch(Exception ex) { logError("", ex); diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTASampleSolutionsEditController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTASampleSolutionsEditController.java index 20136ed7bc155101918bd8eb2d9183f7325e3a73..5bbf2e75aadd30bb52a61aea4e4c290cc54719dc 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTASampleSolutionsEditController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTASampleSolutionsEditController.java @@ -25,6 +25,8 @@ import java.util.List; import org.olat.core.commons.editor.htmleditor.HTMLEditorController; import org.olat.core.commons.editor.htmleditor.WysiwygFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -49,7 +51,6 @@ 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.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.GTACourseNode; import org.olat.course.nodes.gta.GTAManager; import org.olat.course.nodes.gta.model.Solution; @@ -66,7 +67,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class GTASampleSolutionsEditController extends FormBasicController { - private FormLink addSolutionLink, createSolutionLink; + private FormLink addSolutionLink; + private FormLink createSolutionLink; private SolutionTableModel solutionModel; private FlexiTableElement solutionTable; @@ -74,7 +76,8 @@ public class GTASampleSolutionsEditController extends FormBasicController { private EditSolutionController addSolutionCtrl; private EditSolutionController editSolutionCtrl; private NewSolutionController newSolutionCtrl; - private HTMLEditorController newSolutionEditorCtrl, editSolutionEditorCtrl; + private HTMLEditorController newSolutionEditorCtrl; + private HTMLEditorController editSolutionEditorCtrl; private final File solutionDir; private final boolean readOnly; @@ -88,6 +91,8 @@ public class GTASampleSolutionsEditController extends FormBasicController { private UserManager userManager; @Autowired private GTAManager gtaManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; public GTASampleSolutionsEditController(UserRequest ureq, WindowControl wControl, GTACourseNode gtaNode, CourseEnvironment courseEnv, boolean readOnly) { @@ -139,9 +144,9 @@ public class GTASampleSolutionsEditController extends FormBasicController { VFSItem item = solutionContainer.resolve(filename); if(item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - if(metaInfo.getAuthorIdentityKey() != null) { - author = userManager.getUserDisplayName(metaInfo.getAuthorIdentityKey()); + VFSMetadata metaInfo = item.getMetaInfo(); + if(metaInfo.getAuthor() != null) { + author = userManager.getUserDisplayName(metaInfo.getAuthor()); } } @@ -295,9 +300,9 @@ public class GTASampleSolutionsEditController extends FormBasicController { item = solutionContainer.createChildLeaf(documentName); } if(item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); + VFSMetadata metaInfo = item.getMetaInfo(); metaInfo.setAuthor(getIdentity()); - metaInfo.write(); + vfsRepositoryService.updateMetadata(metaInfo); } newSolutionEditorCtrl = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), diff --git a/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java b/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java index 45bd958a8e62df377aadbeeeb55334f398d24279..f416c816541adc6361134b51aeba75594e1ee1a9 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java @@ -32,6 +32,8 @@ import java.util.List; import org.olat.core.commons.editor.htmleditor.HTMLEditorController; import org.olat.core.commons.editor.htmleditor.WysiwygFactory; import org.olat.core.commons.modules.singlepage.SinglePageController; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -59,7 +61,6 @@ import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.GTACourseNode; import org.olat.course.nodes.gta.GTAManager; import org.olat.course.nodes.gta.Task; @@ -101,10 +102,12 @@ class SubmitDocumentsController extends FormBasicController { private final boolean readOnly; private final Date deadline; + @Autowired + private GTAManager gtaManager; @Autowired private UserManager userManager; @Autowired - private GTAManager gtaManager; + private VFSRepositoryService vfsRepositoryService; public SubmitDocumentsController(UserRequest ureq, WindowControl wControl, Task assignedTask, File documentsDir, VFSContainer documentsContainer, int maxDocs, GTACourseNode cNode, @@ -184,9 +187,9 @@ class SubmitDocumentsController extends FormBasicController { String uploadedBy = null; VFSItem item = documentsContainer.resolve(filename); if(item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - if(metaInfo != null && metaInfo.getAuthorIdentityKey() != null) { - uploadedBy = userManager.getUserDisplayName(metaInfo.getAuthorIdentityKey()); + VFSMetadata metaInfo = item.getMetaInfo(); + if(metaInfo != null) { + uploadedBy = userManager.getUserDisplayName(metaInfo.getAuthor()); } } @@ -417,9 +420,9 @@ class SubmitDocumentsController extends FormBasicController { VFSItem downloadedFile = documentsContainer.resolve(filename); if(downloadedFile != null && downloadedFile.canMeta() == VFSConstants.YES) { - MetaInfo metadata = downloadedFile.getMetaInfo(); + VFSMetadata metadata = downloadedFile.getMetaInfo(); metadata.setAuthor(ureq.getIdentity()); - metadata.write(); + vfsRepositoryService.updateMetadata(metadata); } } catch (IOException e) { logError("", e); @@ -475,9 +478,9 @@ class SubmitDocumentsController extends FormBasicController { // add missing identity in meta info item = documentsContainer.resolve(documentName); if(item != null && item.canMeta() == VFSConstants.YES) { - MetaInfo metadata = item.getMetaInfo(); + VFSMetadata metadata = item.getMetaInfo(); metadata.setAuthor(ureq.getIdentity()); - metadata.write(); + vfsRepositoryService.updateMetadata(metadata); } newDocumentEditorCtrl = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), diff --git a/src/main/java/org/olat/course/nodes/pf/manager/PFNotifications.java b/src/main/java/org/olat/course/nodes/pf/manager/PFNotifications.java index 52e8b1a6e1be4b1f50030c09ccbc1e9be2025884..52c61efd327012a4563272d9aff8a5ba51106da1 100644 --- a/src/main/java/org/olat/course/nodes/pf/manager/PFNotifications.java +++ b/src/main/java/org/olat/course/nodes/pf/manager/PFNotifications.java @@ -37,13 +37,13 @@ import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.groupsandrights.CourseGroupManager; @@ -125,7 +125,7 @@ public class PFNotifications { SubscriptionListItem subListItem; for (Iterator<FileInfo> it_infos = fInfos.iterator(); it_infos.hasNext();) { FileInfo fi = it_infos.next(); - MetaInfo metaInfo = fi.getMetaInfo(); + VFSMetadata metaInfo = fi.getMetaInfo(); String filePath = fi.getRelPath(); Date modDate = fi.getLastModified(); String action = "upload"; @@ -154,7 +154,7 @@ public class PFNotifications { if (metaInfo != null) { iconCssClass = metaInfo.getIconCssClass(); } - if (metaInfo != null && !metaInfo.getName().startsWith(".")) { + if (metaInfo != null && !metaInfo.getFilename().startsWith(".")) { subListItem = new SubscriptionListItem(desc, urlToSend, businessPath, modDate, iconCssClass); items.add(subListItem); } diff --git a/src/main/java/org/olat/course/nodes/ta/AbstractTaskNotificationHandler.java b/src/main/java/org/olat/course/nodes/ta/AbstractTaskNotificationHandler.java index fbca21b5c7c31d4738e32f065f0c9de8494d36e4..ef9fdcd86ca409033d09e051bf4fe0e6b2382a32 100644 --- a/src/main/java/org/olat/course/nodes/ta/AbstractTaskNotificationHandler.java +++ b/src/main/java/org/olat/course/nodes/ta/AbstractTaskNotificationHandler.java @@ -44,6 +44,7 @@ import org.olat.core.commons.services.notifications.manager.NotificationsUpgrade import org.olat.core.commons.services.notifications.model.SubscriptionListItem; import org.olat.core.commons.services.notifications.model.TitleItem; import org.olat.core.commons.services.notifications.ui.ContextualSubscriptionController; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.translator.Translator; @@ -53,7 +54,6 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; @@ -101,7 +101,7 @@ public abstract class AbstractTaskNotificationHandler { SubscriptionListItem subListItem; for (Iterator<FileInfo> it_infos = fInfos.iterator(); it_infos.hasNext();) { FileInfo fi = it_infos.next(); - MetaInfo metaInfo = fi.getMetaInfo(); + VFSMetadata metaInfo = fi.getMetaInfo(); String filePath = fi.getRelPath(); if(logDebug) log.debug("filePath=", filePath); String fullUserName = getUserNameFromFilePath(metaInfo, filePath); @@ -134,12 +134,11 @@ public abstract class AbstractTaskNotificationHandler { * @param filePath E.g. '/username/abgabe.txt' * @return 'firstname lastname' */ - protected String getUserNameFromFilePath(MetaInfo info, String filePath) { + protected String getUserNameFromFilePath(VFSMetadata info, String filePath) { // remove first '/' try { if(info != null) { - Long identityKey = info.getAuthorIdentityKey(); - return NotificationHelper.getFormatedName(identityKey); + return NotificationHelper.getFormatedName(info.getAuthor()); } String path = filePath.substring(1); diff --git a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java index 6b7dd1c4a113002fddf9ddb54411952470274572..2c4bb30b8bac1676da43f3908660c69f274b7c8d 100644 --- a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java +++ b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java @@ -30,6 +30,8 @@ import org.olat.basesecurity.BaseSecurity; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -40,7 +42,6 @@ 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.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentHelper; import org.olat.course.assessment.AssessmentManager; @@ -374,8 +375,8 @@ public class ConvertToGTACourseNode { VFSItem sourceItem = source.resolve(name); VFSItem targetItem = target.resolve(name); if(sourceItem.canMeta() == VFSConstants.YES && targetItem.canMeta() == VFSConstants.YES) { - MetaInfo metaSource = sourceItem.getMetaInfo(); - MetaInfo metaTarget = targetItem.getMetaInfo(); + VFSMetadata metaSource = sourceItem.getMetaInfo(); + VFSMetadata metaTarget = targetItem.getMetaInfo(); if(metaSource != null) { if(taskDef != null) { @@ -391,7 +392,7 @@ public class ConvertToGTACourseNode { if(metaTarget != null) { metaTarget.copyValues(metaSource); - metaTarget.write(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).updateMetadata(metaTarget); } } } diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxController.java b/src/main/java/org/olat/course/nodes/ta/DropboxController.java index fc0d26660039715b4148564a58501dc3478103e7..e838077b2d15bce45cd25757d991f319790e8a97 100644 --- a/src/main/java/org/olat/course/nodes/ta/DropboxController.java +++ b/src/main/java/org/olat/course/nodes/ta/DropboxController.java @@ -43,6 +43,8 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.commons.services.notifications.ui.ContextualSubscriptionController; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; @@ -74,7 +76,6 @@ import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.FullAccessWithQuotaCallback; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.auditing.UserNodeAuditManager; import org.olat.course.nodes.AssessableCourseNode; import org.olat.course.nodes.CourseNode; @@ -108,6 +109,8 @@ public class DropboxController extends BasicController { @Autowired private QuotaManager quotaManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; // Constructor for ProjectBrokerDropboxController protected DropboxController(UserRequest ureq, WindowControl wControl) { @@ -258,9 +261,9 @@ public class DropboxController extends BasicController { } if(fOut.canMeta() == VFSConstants.YES) { - MetaInfo info = fOut.getMetaInfo(); + VFSMetadata info = fOut.getMetaInfo(); info.setAuthor(ureq.getIdentity()); - info.write(); + vfsRepositoryService.updateMetadata(info); } if (success) { diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementListController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementListController.java index 93cac76e0fc1cb602131db6d59bf016d25976e52..ea530c0e69bd27d657035b26c90b98b45f89b9a0 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementListController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementListController.java @@ -289,7 +289,7 @@ public class CurriculumElementListController extends FormBasicController impleme rows.forEach(row -> { row.setParent(keyToRow.get(row.getParentKey())); if(row.getOlatResource() != null) { - VFSLeaf image = repositoryManager.getImage(row.getRepositoryEntryResourceable()); + VFSLeaf image = repositoryManager.getImage(row.getRepositoryEntryResourceable().getResourceableId(), row.getOlatResource()); if(image != null) { row.setThumbnailRelPath(mapperThumbnailKey.getUrl() + "/" + image.getName()); } diff --git a/src/main/java/org/olat/modules/docpool/manager/DocumentPoolNotificationsHandler.java b/src/main/java/org/olat/modules/docpool/manager/DocumentPoolNotificationsHandler.java index 47dbb987e959172af7383d576469f7a3fcf8cb94..6a05dbab37a665a0f35283ceed818cba732a6f46 100644 --- a/src/main/java/org/olat/modules/docpool/manager/DocumentPoolNotificationsHandler.java +++ b/src/main/java/org/olat/modules/docpool/manager/DocumentPoolNotificationsHandler.java @@ -36,6 +36,7 @@ import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.commons.services.notifications.SubscriptionInfo; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; import org.olat.core.commons.services.notifications.model.TitleItem; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.components.tree.TreeModel; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; @@ -48,7 +49,6 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.tree.TreeVisitor; import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.modules.docpool.DocumentPoolModule; import org.olat.modules.docpool.ui.DocumentPoolMainController; import org.olat.modules.taxonomy.Taxonomy; @@ -154,7 +154,7 @@ public class DocumentPoolNotificationsHandler implements NotificationsHandler { // skip this file, continue with next item in folder continue; } - MetaInfo metaInfo = infos.getMetaInfo(); + VFSMetadata metaInfo = infos.getMetaInfo(); String iconCssClass = null; if (metaInfo != null) { if (metaInfo.getTitle() != null) { diff --git a/src/main/java/org/olat/modules/fo/ui/MessageListController.java b/src/main/java/org/olat/modules/fo/ui/MessageListController.java index 17de0884c23ebbd53700bf118784ee383466f25f..96510f26fed76f24b6ec38e9cd36eec9cbbfae05 100644 --- a/src/main/java/org/olat/modules/fo/ui/MessageListController.java +++ b/src/main/java/org/olat/modules/fo/ui/MessageListController.java @@ -35,6 +35,8 @@ import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.mark.Mark; import org.olat.core.commons.services.mark.MarkResourceStat; import org.olat.core.commons.services.mark.MarkingService; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -80,7 +82,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; import org.olat.core.util.vfs.filters.VFSItemMetaFilter; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.FOCourseNode; import org.olat.modules.fo.Forum; import org.olat.modules.fo.ForumCallback; @@ -183,6 +184,8 @@ public class MessageListController extends BasicController implements GenericEve private PortfolioV2Module portfolioModule; @Autowired private ForumMediaHandler forumMediaHandler; + @Autowired + private VFSRepositoryService vfsRepositoryService; public MessageListController(UserRequest ureq, WindowControl wControl, Forum forum, ForumCallback foCallback) { @@ -438,7 +441,7 @@ public class MessageListController extends BasicController implements GenericEve } List<MarkResourceStat> statList = markingService.getMarkManager().getStats(forumOres, subPaths, getIdentity()); - Map<String,MarkResourceStat> stats = new HashMap<String,MarkResourceStat>(statList.size() * 2 + 1); + Map<String,MarkResourceStat> stats = new HashMap<>(statList.size() * 2 + 1); for(MarkResourceStat stat:statList) { stats.put(stat.getSubPath(), stat); } @@ -1491,14 +1494,12 @@ public class MessageListController extends BasicController implements GenericEve if (view != null) { List<VFSItem> attachments = view.getAttachments(); for (VFSItem vfsItem : attachments) { - MetaInfo meta = vfsItem.getMetaInfo(); - if (meta != null && meta.getUUID().equals(query[2])) { - if (meta.isThumbnailAvailable()) { - VFSLeaf thumb = meta.getThumbnail(200, 200, false); - if(thumb != null) { - // Positive lookup, send as response - return new VFSMediaResource(thumb); - } + VFSMetadata meta = vfsItem.getMetaInfo(); + if (meta instanceof VFSLeaf && meta.getUuid().equals(query[2])) { + VFSLeaf thumb = vfsRepositoryService.getThumbnail((VFSLeaf)vfsItem, meta, 200, 200, false); + if(thumb != null) { + // Positive lookup, send as response + return new VFSMediaResource(thumb); } break; } diff --git a/src/main/java/org/olat/modules/forms/ui/FileUploadListingController.java b/src/main/java/org/olat/modules/forms/ui/FileUploadListingController.java index a20f2fdd637291b52fd3b3fb625d6fd065be7248..ad206d8f1fbf7f4597a63f881d73f743e247d60f 100644 --- a/src/main/java/org/olat/modules/forms/ui/FileUploadListingController.java +++ b/src/main/java/org/olat/modules/forms/ui/FileUploadListingController.java @@ -23,6 +23,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; @@ -35,10 +36,8 @@ import org.olat.core.gui.media.ZippedDirectoryMediaResource; import org.olat.core.gui.util.CSSHelper; import org.olat.core.util.CodeHelper; import org.olat.core.util.Formatter; -import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaMapper; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.modules.forms.EvaluationFormManager; import org.olat.modules.forms.EvaluationFormResponse; import org.olat.modules.forms.EvaluationFormSession; @@ -61,6 +60,8 @@ public class FileUploadListingController extends BasicController { private final ResponseDataSource dataSource; private final ReportHelper reportHelper; + @Autowired + private VFSRepositoryService vfsRepositoryService; @Autowired private EvaluationFormManager evaluationFormManager; @@ -112,14 +113,10 @@ public class FileUploadListingController extends BasicController { filesize = Formatter.formatBytes((leaf).getSize()); mapperUri = registerCacheableMapper(ureq, "file-upload-" + CodeHelper.getRAMUniqueID() + "-" + leaf.getLastModified(), new VFSMediaMapper(leaf)); iconCss = CSSHelper.createFiletypeIconCssClassFor(leaf.getName()); - if (leaf.canMeta() == VFSConstants.YES) { - MetaInfo meta = leaf.getMetaInfo(); - if (meta != null && meta.isThumbnailAvailable()) { - VFSLeaf thumb = meta.getThumbnail(200, 200, false); - if (thumb != null) { - thumbUri = registerCacheableMapper(ureq, "file-upload-thumb" + CodeHelper.getRAMUniqueID() + "-" + leaf.getLastModified(), new VFSMediaMapper(thumb)); - } - } + + VFSLeaf thumb = vfsRepositoryService.getThumbnail(leaf, 200, 200, false); + if (thumb != null) { + thumbUri = registerCacheableMapper(ureq, "file-upload-thumb" + CodeHelper.getRAMUniqueID() + "-" + leaf.getLastModified(), new VFSMediaMapper(thumb)); } } return new FileUploadListingWrapper(legend.getColor(), legend.getName(), filename, filesize, mapperUri, iconCss, thumbUri); diff --git a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java index e422abc5adb9dbb5780a353ffc4fef6f80a7ca71..a7f9302c341d919640596c7f7d372118b9ff428a 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java @@ -25,6 +25,8 @@ import java.util.List; import java.util.Locale; import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -38,7 +40,6 @@ 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.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.modules.ceditor.InteractiveAddPageElementHandler; import org.olat.modules.ceditor.PageElementAddController; import org.olat.modules.ceditor.PageElementCategory; @@ -77,6 +78,8 @@ public class FileHandler extends AbstractMediaHandler implements InteractiveAddP private PortfolioFileStorage fileStorage; @Autowired private EPFrontendManager oldPortfolioManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; public FileHandler() { super(FILE_TYPE); @@ -117,8 +120,7 @@ public class FileHandler extends AbstractMediaHandler implements InteractiveAddP VFSContainer storageContainer = fileStorage.getMediaContainer(media); VFSItem item = storageContainer.resolve(media.getRootFilename()); if(item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - thumbnail = metaInfo.getThumbnail(size.getHeight(), size.getWidth(), true); + thumbnail = vfsRepositoryService.getThumbnail((VFSLeaf)item, size.getHeight(), size.getWidth(), true); } } @@ -135,7 +137,7 @@ public class FileHandler extends AbstractMediaHandler implements InteractiveAddP String title = null; String description = null; if (mediaObject instanceof VFSItem && ((VFSItem)mediaObject).canMeta() == VFSConstants.YES) { - MetaInfo meta = ((VFSItem)mediaObject).getMetaInfo(); + VFSMetadata meta = ((VFSItem)mediaObject).getMetaInfo(); title = meta.getTitle(); description = meta.getComment(); } diff --git a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java index a1dab3788b6f1fdca67af1035000a8ba59da0c1e..41343ff5d83266e876fb89381bb2e6caf18c0818 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java @@ -28,6 +28,8 @@ import java.util.Set; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -40,7 +42,6 @@ import org.olat.core.util.vfs.VFSConstants; 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.meta.MetaInfo; import org.olat.modules.ceditor.InteractiveAddPageElementHandler; import org.olat.modules.ceditor.PageElement; import org.olat.modules.ceditor.PageElementAddController; @@ -91,6 +92,8 @@ public class ImageHandler extends AbstractMediaHandler implements PageElementSto private MediaDAO mediaDao; @Autowired private PortfolioFileStorage fileStorage; + @Autowired + private VFSRepositoryService VFSRepositoryService; public ImageHandler() { super(IMAGE_TYPE); @@ -129,8 +132,7 @@ public class ImageHandler extends AbstractMediaHandler implements PageElementSto VFSContainer storageContainer = fileStorage.getMediaContainer(media); VFSItem item = storageContainer.resolve(media.getRootFilename()); if(item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - thumbnail = metaInfo.getThumbnail(size.getHeight(), size.getWidth(), true); + thumbnail = VFSRepositoryService.getThumbnail((VFSLeaf)item, size.getHeight(), size.getWidth(), true); } } @@ -147,7 +149,7 @@ public class ImageHandler extends AbstractMediaHandler implements PageElementSto String title = null; String description = null; if (mediaObject instanceof VFSLeaf && ((VFSLeaf)mediaObject).canMeta() == VFSConstants.YES) { - MetaInfo meta = ((VFSLeaf)mediaObject).getMetaInfo(); + VFSMetadata meta = ((VFSLeaf)mediaObject).getMetaInfo(); title = meta.getTitle(); description = meta.getComment(); } diff --git a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java index 4406a5ff87608fc407bd75ca639b43b78ed8cc61..ad794b85e74ef70dfb4b8d400a234ac55c3bdec2 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java @@ -27,6 +27,8 @@ import java.util.Locale; import java.util.Set; import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -39,7 +41,6 @@ import org.olat.core.util.vfs.VFSConstants; 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.meta.MetaInfo; import org.olat.modules.ceditor.InteractiveAddPageElementHandler; import org.olat.modules.ceditor.PageElementAddController; import org.olat.modules.ceditor.PageElementCategory; @@ -78,6 +79,8 @@ public class VideoHandler extends AbstractMediaHandler implements InteractiveAdd private MediaDAO mediaDao; @Autowired private PortfolioFileStorage fileStorage; + @Autowired + private VFSRepositoryService vfsRepositoryService; public VideoHandler() { super(VIDEO_TYPE); @@ -116,8 +119,7 @@ public class VideoHandler extends AbstractMediaHandler implements InteractiveAdd VFSContainer storageContainer = fileStorage.getMediaContainer(media); VFSItem item = storageContainer.resolve(media.getRootFilename()); if(item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = item.getMetaInfo(); - thumbnail = metaInfo.getThumbnail(size.getHeight(), size.getWidth(), true); + thumbnail = vfsRepositoryService.getThumbnail((VFSLeaf)item, size.getHeight(), size.getWidth(), true); } } @@ -134,7 +136,7 @@ public class VideoHandler extends AbstractMediaHandler implements InteractiveAdd String title = null; String description = null; if (mediaObject instanceof VFSLeaf && ((VFSLeaf)mediaObject).canMeta() == VFSConstants.YES) { - MetaInfo meta = ((VFSLeaf)mediaObject).getMetaInfo(); + VFSMetadata meta = ((VFSLeaf)mediaObject).getMetaInfo(); title = meta.getTitle(); description = meta.getComment(); } diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java index 7ef5d63cd84344900c62e53327ed7335af0317bc..804b33d04511d0fec0e65759c0bf9fc36a92da4b 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java @@ -26,11 +26,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; - import org.olat.core.commons.persistence.DBFactory; -import org.olat.core.commons.services.image.Size; -import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItem; @@ -72,10 +68,7 @@ import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; import org.olat.core.util.prefs.Preferences; import org.olat.core.util.resource.OresHelper; -import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.course.nodes.PortfolioCourseNode; import org.olat.modules.portfolio.Binder; import org.olat.modules.portfolio.BinderConfiguration; @@ -116,7 +109,6 @@ import org.springframework.beans.factory.annotation.Autowired; public class BinderListController extends FormBasicController implements Activateable2, TooledController, FlexiTableComponentDelegate { - private static final Size BACKGROUND_SIZE = new Size(400, 230, false); private int counter = 1; private Link newBinderLink; @@ -781,44 +773,6 @@ public class BinderListController extends FormBasicController MediaResource resource = new ExportBinderAsCPResource(row, ureq, getLocale()); ureq.getDispatchResult().setResultingMediaResource(resource); } - - public static class ImageMapper implements Mapper { - - private final BindersDataModel binderModel; - - public ImageMapper(BindersDataModel model) { - this.binderModel = model; - } - - @Override - public MediaResource handle(String relPath, HttpServletRequest request) { - String row = relPath; - if(row.startsWith("/")) { - row = row.substring(1, row.length()); - } - int index = row.indexOf('/'); - if(index > 0) { - row = row.substring(0, index); - Long key = Long.valueOf(row); - List<BinderRow> rows = binderModel.getObjects(); - for(BinderRow prow:rows) { - if(key.equals(prow.getKey())) { - VFSLeaf image = prow.getBackgroundImage(); - if(image.canMeta() == VFSConstants.YES) { - MetaInfo info = image.getMetaInfo(); - VFSLeaf thumbnail = info.getThumbnail(BACKGROUND_SIZE.getWidth(), BACKGROUND_SIZE.getHeight(), true); - if(thumbnail != null) { - image = thumbnail; - } - } - return new VFSMediaResource(image); - } - } - } - - return null; - } - } private static class BinderCssDelegate extends DefaultFlexiTableCssDelegate { @Override diff --git a/src/main/java/org/olat/modules/portfolio/ui/ImageMapper.java b/src/main/java/org/olat/modules/portfolio/ui/ImageMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..28b0f02918a52fe2186bd4316f1b3c6e003e78dd --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/ui/ImageMapper.java @@ -0,0 +1,78 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.portfolio.ui; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.dispatcher.mapper.Mapper; +import org.olat.core.gui.media.MediaResource; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.VFSMediaResource; +import org.olat.modules.portfolio.ui.model.BinderRow; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ImageMapper implements Mapper { + + private static final Size BACKGROUND_SIZE = new Size(400, 230, false); + + private final BindersDataModel binderModel; + private final VFSRepositoryService vfsRepositoryService; + + public ImageMapper(BindersDataModel model) { + this.binderModel = model; + vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + } + + @Override + public MediaResource handle(String relPath, HttpServletRequest request) { + String row = relPath; + if(row.startsWith("/")) { + row = row.substring(1, row.length()); + } + int index = row.indexOf('/'); + if(index > 0) { + row = row.substring(0, index); + Long key = Long.valueOf(row); + List<BinderRow> rows = binderModel.getObjects(); + for(BinderRow prow:rows) { + if(key.equals(prow.getKey())) { + VFSLeaf image = prow.getBackgroundImage(); + VFSLeaf thumbnail = vfsRepositoryService.getThumbnail(image, BACKGROUND_SIZE.getWidth(), BACKGROUND_SIZE.getHeight(), true); + if(thumbnail != null) { + image = thumbnail; + } + return new VFSMediaResource(image); + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/ui/LastBinderListController.java b/src/main/java/org/olat/modules/portfolio/ui/LastBinderListController.java index 7e14c694fb23d15f548843e32f34b73bbf3716d6..fe154519d5cd3443d9861f1819945e3aed84c2ea 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/LastBinderListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/LastBinderListController.java @@ -43,7 +43,6 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.util.vfs.VFSLeaf; import org.olat.modules.portfolio.PortfolioService; import org.olat.modules.portfolio.model.BinderStatistics; -import org.olat.modules.portfolio.ui.BinderListController.ImageMapper; import org.olat.modules.portfolio.ui.BindersDataModel.PortfolioCols; import org.olat.modules.portfolio.ui.event.OpenBinderEvent; import org.olat.modules.portfolio.ui.event.OpenMyBindersEvent; diff --git a/src/main/java/org/olat/modules/video/ui/VideoListingController.java b/src/main/java/org/olat/modules/video/ui/VideoListingController.java index 595cd3ac9a48630f77e00bf8b7e9bc179f915bea..ffc266d06782deca710ac63f703e53ccc7f5be46 100644 --- a/src/main/java/org/olat/modules/video/ui/VideoListingController.java +++ b/src/main/java/org/olat/modules/video/ui/VideoListingController.java @@ -47,14 +47,12 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.NotFoundMediaResource; -import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; -import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; import org.olat.fileresource.types.VideoFileResource; @@ -224,9 +222,9 @@ public class VideoListingController extends FormBasicController implements Activ int start = relPath.lastIndexOf("/"); if (start != -1) { relPath = relPath.substring(start+1); - long id = Long.parseLong(relPath); - OLATResourceable videoResource = OresHelper.createOLATResourceableInstance("RepositoryEntry", id); - VFSLeaf imageFile = repositoryManager.getImage(videoResource); + Long id = Long.valueOf(relPath); + RepositoryEntry entry = repositoryService.loadByKey(id); + VFSLeaf imageFile = repositoryManager.getImage(entry); return new VFSMediaResource(imageFile); } } diff --git a/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java b/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java index 73d6e9093f645950562cd4dc0534319449b466e4..ceebf3300c66d3a577f314a5acd0759c097307d2 100644 --- a/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java +++ b/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java @@ -37,6 +37,7 @@ import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.commons.services.commentAndRating.CommentAndRatingService; import org.olat.core.commons.services.image.Size; import org.olat.core.commons.services.notifications.NotificationsManager; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.components.form.flexible.elements.FileElement; import org.olat.core.gui.media.MediaResource; import org.olat.core.helpers.Settings; @@ -115,13 +116,15 @@ public class FeedManagerImpl extends FeedManager { @Autowired private QuotaManager quotaManager; @Autowired + private BaseSecurity securityManager; + @Autowired private FeedFileStorge feedFileStorage; @Autowired private ExternalFeedFetcher externalFeedFetcher; @Autowired private NotificationsManager notificationsManager; @Autowired - private BaseSecurity securityManager; + private VFSRepositoryService vfsRepositoryService; /** * spring only @@ -654,9 +657,8 @@ public class FeedManagerImpl extends FeedManager { VFSItem item =feedFileStorage.getOrCreateFeedMediaContainer(feed); item = item.resolve(fileName); if (thumbnailSize != null && thumbnailSize.getHeight() > 0 && thumbnailSize.getWidth() > 0 - && item.canMeta() == VFSConstants.YES) { - item = item.getMetaInfo().getThumbnail(thumbnailSize.getWidth(), - thumbnailSize.getHeight(), false); + && item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { + item = vfsRepositoryService.getThumbnail((VFSLeaf)item, thumbnailSize.getWidth(), thumbnailSize.getHeight(), false); } if (item instanceof VFSLeaf) { mediaResource = (VFSLeaf) item; diff --git a/src/main/java/org/olat/portfolio/model/artefacts/FileArtefactHandler.java b/src/main/java/org/olat/portfolio/model/artefacts/FileArtefactHandler.java index b95f438a70f30edd5cadd1548d8b0c2a3feb8584..abc61b39a51ff2a03e9eabfa9bee544373c535db 100644 --- a/src/main/java/org/olat/portfolio/model/artefacts/FileArtefactHandler.java +++ b/src/main/java/org/olat/portfolio/model/artefacts/FileArtefactHandler.java @@ -22,6 +22,7 @@ package org.olat.portfolio.model.artefacts; import org.apache.lucene.document.Document; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -32,7 +33,6 @@ import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.portfolio.EPAbstractHandler; @@ -69,7 +69,7 @@ public class FileArtefactHandler extends EPAbstractHandler<FileArtefact> { VFSItem fileSource = (VFSItem) source; ((FileArtefact) artefact).setFilename(fileSource.getName()); - MetaInfo meta = null; + VFSMetadata meta = null; if(fileSource.canMeta() == VFSConstants.YES) { meta = fileSource.getMetaInfo(); } @@ -90,7 +90,8 @@ public class FileArtefactHandler extends EPAbstractHandler<FileArtefact> { String finalBusinessPath = null; String sourceInfo = null; // used to rebuild businessPath and source for a file: - if (pathElements[1].equals("homes") && meta != null && pathElements[2].equals(meta.getAuthor())) { + String author = meta != null && meta.getAuthor() != null ? meta.getAuthor().getKey().toString() : null; + if (pathElements[1].equals("homes") && meta != null && pathElements[2].equals(author)) { // from users briefcase String lastParts = "/"; for (int i = 4; i < (pathElements.length - 1); i++) { @@ -103,19 +104,19 @@ public class FileArtefactHandler extends EPAbstractHandler<FileArtefact> { for (int i = 5; i < (pathElements.length - 1); i++) { lastParts = lastParts + pathElements[i] + "/"; } - BusinessGroup bGroup = CoreSpringFactory.getImpl(BusinessGroupService.class).loadBusinessGroup(new Long(pathElements[4])); + BusinessGroup bGroup = CoreSpringFactory.getImpl(BusinessGroupService.class).loadBusinessGroup(Long.valueOf(pathElements[4])); if (bGroup != null) { sourceInfo = bGroup.getName() + " -> " + lastParts + " -> " + fileSource.getName(); } finalBusinessPath = "[BusinessGroup:" + pathElements[4] + "][toolfolder:0][path=" + lastParts + fileSource.getName() + ":0]"; } else if (pathElements[4].equals("coursefolder")) { // the course folder - sourceInfo = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(new Long(pathElements[2])) + sourceInfo = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(Long.valueOf(pathElements[2])) + " -> " + fileSource.getName(); } else if (pathElements[1].equals("course") && pathElements[3].equals("foldernodes")) { // folders inside a course - sourceInfo = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(new Long(pathElements[2])) + sourceInfo = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(Long.valueOf(pathElements[2])) + " -> " + pathElements[4] + " -> " + fileSource.getName(); finalBusinessPath = "[RepositoryEntry:" + pathElements[2] + "][CourseNode:" + pathElements[4] + "]"; } diff --git a/src/main/java/org/olat/portfolio/ui/artefacts/view/details/FileArtefactDetailsController.java b/src/main/java/org/olat/portfolio/ui/artefacts/view/details/FileArtefactDetailsController.java index 94777c997cd9781a15776e4577de683656d72cc3..d0b672b3935be522ece0d09798b934fb04ca1501 100644 --- a/src/main/java/org/olat/portfolio/ui/artefacts/view/details/FileArtefactDetailsController.java +++ b/src/main/java/org/olat/portfolio/ui/artefacts/view/details/FileArtefactDetailsController.java @@ -19,7 +19,8 @@ */ package org.olat.portfolio.ui.artefacts.view.details; -import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.download.DownloadComponent; @@ -39,11 +40,11 @@ import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.artefacts.FileArtefact; import org.olat.portfolio.ui.artefacts.collect.EPCreateFileArtefactStepForm00; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -63,16 +64,19 @@ public class FileArtefactDetailsController extends BasicController { private DialogBoxController delDialog; private FileArtefact fArtefact; private Controller fileUploadCtrl; - private EPFrontendManager ePFMgr; private Link uploadLink; private CloseableCalloutWindowController calloutCtrl; private Panel viewPanel; + + @Autowired + private EPFrontendManager ePFMgr; + @Autowired + private VFSRepositoryService vfsRepositoryService; public FileArtefactDetailsController(UserRequest ureq, WindowControl wControl, AbstractArtefact artefact, boolean readOnlyMode) { super(ureq, wControl); this.readOnlyMode = readOnlyMode; fArtefact = (FileArtefact)artefact; - ePFMgr = (EPFrontendManager) CoreSpringFactory.getBean("epFrontendManager"); viewPanel = new Panel("empty"); initViewDependingOnFileExistance(ureq); @@ -96,18 +100,16 @@ public class FileArtefactDetailsController extends BasicController { vC.contextPut("filename", fArtefact.getFilename()); if(file.canMeta() == VFSConstants.YES) { - MetaInfo meta = file.getMetaInfo(); + VFSMetadata meta = file.getMetaInfo(); vC.contextPut("meta", meta); // show a preview thumbnail if possible - if (meta.isThumbnailAvailable()) { - VFSLeaf thumb = meta.getThumbnail(200, 200, false); + if(file instanceof VFSLeaf) { + VFSLeaf thumb = vfsRepositoryService.getThumbnail((VFSLeaf)file, meta, 200, 200, false); if(thumb != null) { mr = new VFSMediaResource(thumb); } if(mr != null) { - String thumbMapper = registerMapper(ureq, (relPath, request) -> { - return mr; - }); + String thumbMapper = registerMapper(ureq, (relPath, request) -> mr); vC.contextPut("thumbMapper", thumbMapper); } } diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index d29991f5099c968370318f821b0dcd10914ad79c..ac4e1a1dc544ea702e0209c49bd5a8cd27f2f7e4 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -74,6 +74,8 @@ 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.VFSManager; +import org.olat.course.PersistingCourseImpl; +import org.olat.fileresource.FileResourceManager; import org.olat.group.GroupLoggingAction; import org.olat.modules.taxonomy.TaxonomyLevel; import org.olat.repository.manager.RepositoryEntryDAO; @@ -166,8 +168,8 @@ public class RepositoryManager { } String sourceImageSuffix = FileUtils.getFileSuffix(srcFile.getName()); - VFSContainer repositoryHome = new LocalFolderImpl(new File(FolderConfig.getCanonicalRepositoryHome())); - VFSLeaf newImage = repositoryHome.createChildLeaf(target.getResourceableId() + "." + sourceImageSuffix); + VFSContainer targetMediaDir = this.getMediaDirectory(target.getOlatResource()); + VFSLeaf newImage = targetMediaDir.createChildLeaf(target.getResourceableId() + "." + sourceImageSuffix); if (newImage != null) { return VFSManager.copyContent(srcFile, newImage, false); } @@ -181,20 +183,37 @@ public class RepositoryManager { } } - public VFSLeaf getImage(OLATResourceable re) { - VFSContainer repositoryHome = new LocalFolderImpl(new File(FolderConfig.getCanonicalRepositoryHome())); - String imageName = re.getResourceableId() + ".jpg"; + public VFSLeaf getImage(RepositoryEntry re) { + return getImage(re.getKey(), re.getOlatResource()); + } + + public VFSLeaf getImage(Long repoEntryKey, OLATResource re) { + VFSContainer repositoryHome = getMediaDirectory(re); + + String imageName = repoEntryKey + ".jpg"; VFSItem image = repositoryHome.resolve(imageName); if(image instanceof VFSLeaf) { return (VFSLeaf)image; } - imageName = re.getResourceableId() + ".png"; + imageName = repoEntryKey + ".png"; image = repositoryHome.resolve(imageName); if(image instanceof VFSLeaf) { return (VFSLeaf)image; } return null; } + + private VFSContainer getMediaDirectory(OLATResource re) { + File fResourceFileroot; + if("CourseModule".equals(re.getResourceableTypeName())) { + fResourceFileroot = new File(FolderConfig.getCanonicalRoot(), PersistingCourseImpl.COURSE_ROOT_DIR_NAME); + fResourceFileroot = new File(fResourceFileroot, re.getResourceableId().toString()); + } else { + fResourceFileroot = FileResourceManager.getInstance().getFileResourceRoot(re); + } + File mediaHome = new File(fResourceFileroot, "media"); + return new LocalFolderImpl(mediaHome); + } public boolean setImage(VFSLeaf newImageFile, RepositoryEntry re) { VFSLeaf currentImage = getImage(re); @@ -211,9 +230,15 @@ public class RepositoryManager { if("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)) { targetExtension = ".jpg"; } - - VFSContainer repositoryHome = new LocalFolderImpl(new File(FolderConfig.getCanonicalRepositoryHome())); + + VFSContainer repositoryHome = getMediaDirectory(re.getOlatResource()); VFSLeaf repoImage = repositoryHome.createChildLeaf(re.getResourceableId() + targetExtension); + if(repoImage == null) { + VFSItem item = repositoryHome.resolve(re.getResourceableId() + targetExtension); + if(item instanceof VFSLeaf) { + repoImage = (VFSLeaf)item; + } + } if(targetExtension.equals(".png") || targetExtension.equals(".jpg")) { Size newImageSize = imageHelper.getSize(newImageFile, extension); @@ -226,7 +251,6 @@ public class RepositoryManager { return size != null; } - /** * Lookup repo entry by key. * @param the repository entry key (not the olatresourceable key) diff --git a/src/main/java/org/olat/repository/manager/CatalogManager.java b/src/main/java/org/olat/repository/manager/CatalogManager.java index 36bb6828e07157ec12ad0b28958c15d332689701..294146e9ee1a87c050b3d5a6e5fe5caffc7f5588 100644 --- a/src/main/java/org/olat/repository/manager/CatalogManager.java +++ b/src/main/java/org/olat/repository/manager/CatalogManager.java @@ -44,6 +44,7 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.commons.services.image.ImageService; import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLog; @@ -115,6 +116,8 @@ public class CatalogManager implements UserDataDeletable, InitializingBean { private RepositoryService repositoryService; @Autowired private OrganisationService organisationService; + @Autowired + private VFSRepositoryService vfsRepositoryService; /** @@ -748,7 +751,7 @@ public class CatalogManager implements UserDataDeletable, InitializingBean { VFSLeaf imgFile = getImage(entry); if (imgFile != null) { if(imgFile.canMeta() == VFSConstants.YES) { - imgFile.getMetaInfo().clearThumbnails(); + vfsRepositoryService.resetThumbnails(imgFile); } imgFile.delete(); } @@ -758,7 +761,7 @@ public class CatalogManager implements UserDataDeletable, InitializingBean { VFSLeaf currentImage = getImage(re); if(currentImage != null) { if(currentImage.canMeta() == VFSConstants.YES) { - currentImage.getMetaInfo().clearThumbnails(); + vfsRepositoryService.resetThumbnails(currentImage); } currentImage.delete(); } diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java index ecff11dbf904c29a2c84a111fe2b73dd6d38452c..1c34939a7023946aba37c98a5b61ee15b4f7d2e9 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java +++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java @@ -19,7 +19,6 @@ */ package org.olat.repository.manager; -import java.io.File; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -37,7 +36,6 @@ import org.olat.basesecurity.OrganisationDataDeletable; import org.olat.basesecurity.OrganisationRoles; import org.olat.basesecurity.manager.GroupDAO; import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.mark.MarkManager; @@ -59,7 +57,6 @@ import org.olat.core.util.mail.MailPackage; import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailerResult; import org.olat.core.util.resource.OresHelper; -import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; @@ -386,14 +383,15 @@ public class RepositoryServiceImpl implements RepositoryService, OrganisationDat @Override public VFSLeaf getIntroductionImage(RepositoryEntry re) { - VFSContainer repositoryHome = new LocalFolderImpl(new File(FolderConfig.getCanonicalRepositoryHome())); + RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(re); + VFSContainer mediaContainer = handler.getMediaContainer(re); String imageName = re.getResourceableId() + ".jpg"; - VFSItem image = repositoryHome.resolve(imageName); + VFSItem image = mediaContainer.resolve(imageName); if(image instanceof VFSLeaf) { return (VFSLeaf)image; } imageName = re.getResourceableId() + ".png"; - image = repositoryHome.resolve(imageName); + image = mediaContainer.resolve(imageName); if(image instanceof VFSLeaf) { return (VFSLeaf)image; } diff --git a/src/main/java/org/olat/repository/ui/CatalogEntryImageMapper.java b/src/main/java/org/olat/repository/ui/CatalogEntryImageMapper.java index 5f5f32dbeca00f9ec92068e6493c548516fc64e9..94655efbe41e8181bc04368dd2c6f0d9835fa16f 100644 --- a/src/main/java/org/olat/repository/ui/CatalogEntryImageMapper.java +++ b/src/main/java/org/olat/repository/ui/CatalogEntryImageMapper.java @@ -22,6 +22,7 @@ package org.olat.repository.ui; import javax.servlet.http.HttpServletRequest; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.NotFoundMediaResource; @@ -30,7 +31,6 @@ 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.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.repository.manager.CatalogManager; @@ -43,6 +43,7 @@ import org.olat.repository.manager.CatalogManager; public class CatalogEntryImageMapper implements Mapper { private CatalogManager catalogManager; + private VFSRepositoryService vfsRepositoryService; public CatalogEntryImageMapper() { catalogManager = CoreSpringFactory.getImpl(CatalogManager.class); @@ -60,8 +61,7 @@ public class CatalogEntryImageMapper implements Mapper { MediaResource resource = null; if(image instanceof VFSLeaf) { if(image.canMeta() == VFSConstants.YES) { - MetaInfo info = image.getMetaInfo(); - VFSLeaf thumbnail = info.getThumbnail(180, 180, true); + VFSLeaf thumbnail = vfsRepositoryService.getThumbnail((VFSLeaf)image, 180, 180, true); if(thumbnail != null) { resource = new VFSMediaResource(thumbnail); } diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryImageMapper.java b/src/main/java/org/olat/repository/ui/RepositoryEntryImageMapper.java index 64a1a4a0f795296e2983399d221c61243c0c4cec..f4042e6bfff51588765024fa98fe4d18f2a7c660 100644 --- a/src/main/java/org/olat/repository/ui/RepositoryEntryImageMapper.java +++ b/src/main/java/org/olat/repository/ui/RepositoryEntryImageMapper.java @@ -23,16 +23,16 @@ import java.io.File; import javax.servlet.http.HttpServletRequest; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.media.MediaResource; import org.olat.core.util.vfs.LocalFolderImpl; -import org.olat.core.util.vfs.VFSConstants; 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.VFSMediaResource; -import org.olat.core.util.vfs.meta.MetaInfo; /** * @@ -43,6 +43,12 @@ import org.olat.core.util.vfs.meta.MetaInfo; public class RepositoryEntryImageMapper implements Mapper { private VFSContainer rootContainer; + + private VFSRepositoryService vfsRepositoryService; + + public RepositoryEntryImageMapper() { + vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + } @Override public MediaResource handle(String relPath, HttpServletRequest request) { @@ -56,13 +62,10 @@ public class RepositoryEntryImageMapper implements Mapper { MediaResource resource = null; VFSItem image = rootContainer.resolve(relPath); if(image instanceof VFSLeaf) { - if(image.canMeta() == VFSConstants.YES) { - MetaInfo info = image.getMetaInfo(); - //121 is needed to fill the div - VFSLeaf thumbnail = info.getThumbnail(180, 120, true); - if(thumbnail != null) { - resource = new VFSMediaResource(thumbnail); - } + //121 is needed to fill the div + VFSLeaf thumbnail = vfsRepositoryService.getThumbnail((VFSLeaf)image, 180, 120, true); + if(thumbnail != null) { + resource = new VFSMediaResource(thumbnail); } if(resource == null) { diff --git a/src/main/java/org/olat/repository/ui/list/DefaultRepositoryEntryDataSource.java b/src/main/java/org/olat/repository/ui/list/DefaultRepositoryEntryDataSource.java index 24168b01b34371229690381730b2b4150a54abe6..50ecf8e618185385417c13cd56cc04cedd0bcca7 100644 --- a/src/main/java/org/olat/repository/ui/list/DefaultRepositoryEntryDataSource.java +++ b/src/main/java/org/olat/repository/ui/list/DefaultRepositoryEntryDataSource.java @@ -154,7 +154,7 @@ public class DefaultRepositoryEntryDataSource implements FlexiTableDataSourceDel for(RepositoryEntryMyView entry:repoEntries) { RepositoryEntryRow row = new RepositoryEntryRow(entry); - VFSLeaf image = repositoryManager.getImage(entry); + VFSLeaf image = repositoryManager.getImage(entry.getKey(), entry.getOlatResource()); if(image != null) { row.setThumbnailRelPath(uifactory.getMapperThumbnailUrl() + "/" + image.getName()); } diff --git a/src/main/java/org/olat/repository/ui/settings/LazyRepositoryEdusharingProvider.java b/src/main/java/org/olat/repository/ui/settings/LazyRepositoryEdusharingProvider.java index 98c162d2bbe0037eefa398b49df6cef92ec27012..3657d7af8207ccc0b0bd0a1467c1409d0f88bf1c 100644 --- a/src/main/java/org/olat/repository/ui/settings/LazyRepositoryEdusharingProvider.java +++ b/src/main/java/org/olat/repository/ui/settings/LazyRepositoryEdusharingProvider.java @@ -60,7 +60,7 @@ public class LazyRepositoryEdusharingProvider implements VFSEdusharingProvider { @Override public void setSubPath(VFSItem item) { - this.subPath = "file-meta-uuid-" + item.getMetaInfo().getUUID(); + this.subPath = "file-meta-uuid-" + item.getMetaInfo().getUuid(); } @Override diff --git a/src/main/java/org/olat/resource/OLATResourceManager.java b/src/main/java/org/olat/resource/OLATResourceManager.java index d8e8ee5e3c6df433908c6c11d32c858c5530ef9b..60d1dcaff687b8284a7c9753b2ca4c93b732310d 100644 --- a/src/main/java/org/olat/resource/OLATResourceManager.java +++ b/src/main/java/org/olat/resource/OLATResourceManager.java @@ -31,10 +31,10 @@ import java.util.List; import org.olat.core.commons.persistence.DB; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; -import org.olat.core.manager.BasicManager; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.CodeHelper; import org.olat.core.util.coordinate.CoordinatorManager; -import org.olat.core.util.coordinate.SyncerCallback; import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseModule; @@ -45,7 +45,9 @@ import org.olat.course.CourseModule; * @author Andreas Ch. Kapp * */ -public class OLATResourceManager extends BasicManager { +public class OLATResourceManager { + + private static final OLog log = Tracing.createLoggerFor(OLATResourceManager.class); private static OLATResourceManager INSTANCE; private DB dbInstance; @@ -154,20 +156,18 @@ public class OLATResourceManager extends BasicManager { } // Second there exists no resourcable => try to find and create(if no exists) in a synchronized block //o_clusterOK by:cg - ores = CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resourceable, new SyncerCallback<OLATResource>(){ - public OLATResource execute() { - logDebug("start synchronized-block in findOrPersistResourceable"); - OLATResource oresSync = findResourceable(resourceable); - // if not found, persist it. - if (oresSync == null ) { - if(CourseModule.ORES_TYPE_COURSE.equals(resourceable.getResourceableTypeName())) { - logInfo("OLATResourceManager - createOLATResourceInstance if not found: " + resourceable.getResourceableTypeName() + " " + resourceable.getResourceableId()); - } - oresSync = createOLATResourceInstance(resourceable); - saveOLATResource(oresSync); + ores = CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resourceable, () -> { + log.debug("start synchronized-block in findOrPersistResourceable"); + OLATResource oresSync = findResourceable(resourceable); + // if not found, persist it. + if (oresSync == null ) { + if(CourseModule.ORES_TYPE_COURSE.equals(resourceable.getResourceableTypeName())) { + log.info("OLATResourceManager - createOLATResourceInstance if not found: " + resourceable.getResourceableTypeName() + " " + resourceable.getResourceableId()); } - return oresSync; + oresSync = createOLATResourceInstance(resourceable); + saveOLATResource(oresSync); } + return oresSync; }); return ores; } @@ -207,7 +207,7 @@ public class OLATResourceManager extends BasicManager { .getResultList(); // if not found, it is an empty list - if (resources.size() == 0) { + if (resources.isEmpty()) { return null; } return resources.get(0); @@ -228,12 +228,9 @@ public class OLATResourceManager extends BasicManager { if(types == null || types.isEmpty()) return Collections.<OLATResource>emptyList(); String s = "select ori from org.olat.resource.OLATResourceImpl ori where ori.resName in (:restrictedType)"; - List<OLATResource> resources = dbInstance.getCurrentEntityManager() + return dbInstance.getCurrentEntityManager() .createQuery(s, OLATResource.class) .setParameter("restrictedType", types) .getResultList(); - return resources; - - } } \ No newline at end of file diff --git a/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java index 941c2876fb70a3c27e183e7df70c2f44d1bb71a9..23b5976e8421ea1e9a35af867452a8917f5f69ae 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java @@ -47,6 +47,8 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.id.Roles; @@ -61,7 +63,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.callbacks.ReadOnlyCallback; import org.olat.core.util.vfs.filters.SystemItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.core.util.vfs.version.Versionable; import org.olat.course.ICourse; import org.olat.course.config.CourseConfig; @@ -108,6 +109,8 @@ public class CourseResourceFolderWebService { private RepositoryManager repositoryManager; @Autowired private RepositoryService repositoryService; + @Autowired + private VFSRepositoryService vfsRepositoryService; /** * The version of the resources folders Web Service @@ -371,9 +374,9 @@ public class CourseResourceFolderWebService { } if(newFile.canMeta() == VFSConstants.YES ) { - MetaInfo infos = newFile.getMetaInfo(); + VFSMetadata infos = newFile.getMetaInfo(); infos.setAuthor(ureq.getIdentity()); - infos.write(); + vfsRepositoryService.updateMetadata(infos); } return Response.ok().build(); diff --git a/src/main/java/org/olat/search/service/document/file/FileDocument.java b/src/main/java/org/olat/search/service/document/file/FileDocument.java index 2b15cc9d34df78808349fab0217df1bf316a7049..6b81571bb43571c46b1f46c5408a5e2cdc8f2f97 100644 --- a/src/main/java/org/olat/search/service/document/file/FileDocument.java +++ b/src/main/java/org/olat/search/service/document/file/FileDocument.java @@ -29,11 +29,12 @@ import java.io.IOException; import java.util.Calendar; import java.util.Date; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.id.User; import org.olat.core.util.StringHelper; import org.olat.core.util.WebappHelper; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.search.model.OlatDocument; import org.olat.search.service.SearchResourceContext; import org.olat.search.service.SimpleDublinCoreMetadataFieldsProvider; @@ -47,11 +48,11 @@ public abstract class FileDocument extends OlatDocument { private static final long serialVersionUID = -8977326187286155071L; // Must correspond with LocalString_xx.properties // Do not use '_' because we want to seach for certain documenttype and lucene haev problems with '_' - public final static String TYPE = "type.file"; + public static final String TYPE = "type.file"; protected void init(SearchResourceContext leafResourceContext, VFSLeaf leaf) throws IOException,DocumentException,DocumentAccessException { // Load metadata for this file - MetaInfo meta = null; + VFSMetadata meta = null; if (leaf.canMeta() == VFSConstants.YES) { meta = leaf.getMetaInfo(); } @@ -131,7 +132,23 @@ public abstract class FileDocument extends OlatDocument { addMetadata(SimpleDublinCoreMetadataFieldsProvider.DC_SOURCE, meta.getSource()); addMetadata(SimpleDublinCoreMetadataFieldsProvider.DC_SOURCE, meta.getUrl()); // use creator and author as olat author - setAuthor((meta.getCreator() == null ? meta.getAuthor() : meta.getAuthor() + " " + meta.getCreator())); + StringBuilder authors = new StringBuilder(64); + if(meta.getAuthor() != null) { + User user = meta.getAuthor().getUser(); + if(StringHelper.containsNonWhitespace(user.getFirstName())) { + authors.append(user.getFirstName()); + } + if(StringHelper.containsNonWhitespace(user.getLastName())) { + if(authors.length() > 0) authors.append(" "); + authors.append(user.getLastName()); + } + } + + if(meta.getCreator() != null) { + if(authors.length() > 0) authors.append(" "); + authors.append(authors); + } + setAuthor(authors.toString()); addMetadata(SimpleDublinCoreMetadataFieldsProvider.DC_CREATOR, meta.getCreator()); } // Add file type @@ -140,8 +157,8 @@ public abstract class FileDocument extends OlatDocument { // License String licenseTypeKey = ""; - if (meta != null && StringHelper.containsNonWhitespace(meta.getLicenseTypeKey())) { - licenseTypeKey = meta.getLicenseTypeKey(); + if (meta != null && meta.getLicenseType() != null) { + licenseTypeKey = meta.getLicenseType().getKey().toString(); } setLicenseTypeKey(licenseTypeKey); } diff --git a/src/main/java/org/olat/search/service/document/file/FileDocumentFactory.java b/src/main/java/org/olat/search/service/document/file/FileDocumentFactory.java index aaa7bd1fa168b479cda269041506fb5d3b70b7ed..27ad1394caf3980a5d183093347de35490b55895 100644 --- a/src/main/java/org/olat/search/service/document/file/FileDocumentFactory.java +++ b/src/main/java/org/olat/search/service/document/file/FileDocumentFactory.java @@ -32,12 +32,12 @@ import org.apache.lucene.document.DateTools; import org.apache.lucene.document.Document; import org.apache.lucene.queryparser.classic.ParseException; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.vfs.LocalImpl; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.search.QueryException; import org.olat.search.SearchModule; import org.olat.search.SearchService; @@ -113,8 +113,8 @@ public class FileDocumentFactory { Date indexLastModification = DateTools.stringToDate(timestamp); Date docLastModificationDate = new Date(leaf.getLastModified()); if(leaf.canMeta() == VFSConstants.YES) { - MetaInfo metaInfo = leaf.getMetaInfo(); - Date metaDate = metaInfo.getMetaLastModified(); + VFSMetadata metaInfo = leaf.getMetaInfo(); + Date metaDate = metaInfo.getLastModified(); if(metaDate != null && metaDate.after(docLastModificationDate)) { docLastModificationDate = metaDate; } diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_13_3_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_13_3_0.java new file mode 100644 index 0000000000000000000000000000000000000000..faaf358461df16480712ae227e30ce9200ef707d --- /dev/null +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_13_3_0.java @@ -0,0 +1,208 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.upgrade; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.manager.VFSRepositoryServiceImpl; +import org.olat.core.util.StringHelper; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 4 janv. 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class OLATUpgrade_13_3_0 extends OLATUpgrade { + + private static final String VERSION = "OLAT_13.3.0"; + private static final String MOVE_REPO_IMAGES = "MOVE REPO IMAGES"; + private static final String MIGRATE_FILE_METADATA = "MIGRATE FILE METADATA"; + + @Autowired + private DB dbInstance; + @Autowired + private RepositoryService repositoryService; + @Autowired + private VFSRepositoryServiceImpl vfsRepositoryService; + + public OLATUpgrade_13_3_0() { + super(); + } + + @Override + public String getVersion() { + return VERSION; + } + + @Override + public boolean doPreSystemInitUpgrade(UpgradeManager upgradeManager) { + return false; + } + + @Override + public boolean doPostSystemInitUpgrade(UpgradeManager upgradeManager) { + UpgradeHistoryData uhd = upgradeManager.getUpgradesHistory(VERSION); + if (uhd == null) { + // has never been called, initialize + uhd = new UpgradeHistoryData(); + } else if (uhd.isInstallationComplete()) { + return false; + } + + boolean allOk = true; + allOk &= migrateRepositoryImages(upgradeManager, uhd); + allOk &= migrateMetadata(upgradeManager, uhd); + + uhd.setInstallationComplete(allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + if(allOk) { + log.audit("Finished OLATUpgrade_13_3_0 successfully!"); + } else { + log.audit("OLATUpgrade_13_3_0 not finished, try to restart OpenOLAT!"); + } + return allOk; + } + + /** + * Migrate the images of learn resources and courses. + * + * @param upgradeManager The upgrade manage + * @param uhd The history + * @return true if successful + */ + private boolean migrateRepositoryImages(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + boolean allOk = true; + if (!uhd.getBooleanDataValue(MOVE_REPO_IMAGES)) { + + try { + int counter = 0; + + File repositoryHome = new File(FolderConfig.getCanonicalRepositoryHome()); + File[] images = repositoryHome.listFiles(new ImageFilter()); + for(File image:images) { + String name = image.getName(); + int index = name.lastIndexOf('.'); + String resourceId = name.substring(0, index); + if(StringHelper.isLong(resourceId)) { + migrateRepositoryImage(image, Long.valueOf(resourceId)); + } + if(counter++ % 50 == 0) { + log.info("Images of lear resources moved: " + counter); + dbInstance.commitAndCloseSession(); + } + } + } catch (Exception e) { + log.error("", e); + allOk = false; + } + + uhd.setBooleanDataValue(MOVE_REPO_IMAGES, allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } + return allOk; + } + + private void migrateRepositoryImage(File image, Long resourceId) { + RepositoryEntry resource = repositoryService.loadByKey(resourceId);// yes, resource id is repository entry primary key + if(resource == null) { + deleteImage(image); + } else { + File home; + if("CourseModule".equals(resource.getOlatResource().getResourceableTypeName())) { + home = new File(FolderConfig.getCanonicalRoot(), "course"); + } else { + home = new File(FolderConfig.getCanonicalRepositoryHome()); + } + + try { + File resourceDir = new File(home, resource.getOlatResource().getResourceableId().toString()); + if(resourceDir.exists()) { + File mediaDir = new File(resourceDir, "media"); + if(!mediaDir.exists()) { + mediaDir.mkdir(); + } + + File movedImage = new File(mediaDir, image.getName()); + if(movedImage.exists()) { + deleteImage(image); + } else { + Files.move(image.toPath(), movedImage.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } else { + deleteImage(image); + } + } catch (IOException e) { + log.error("", e); + } + } + } + + private void deleteImage(File image) { + try { + Files.delete(image.toPath()); + } catch (IOException e) { + log.error("", e); + } + } + + /** + * Migrate the metadata + * + * @param upgradeManager The upgrade manager + * @param uhd The upgrade history + * @return true if successful + */ + private boolean migrateMetadata(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + boolean allOk = true; + if (!uhd.getBooleanDataValue(MIGRATE_FILE_METADATA)) { + + try { + //go through /bcroot/ + File canonicalRoot = new File(FolderConfig.getCanonicalRoot()); + vfsRepositoryService.migrateDirectories(canonicalRoot); + } catch (IOException e) { + log.error("", e); + allOk = false; + } + + uhd.setBooleanDataValue(MIGRATE_FILE_METADATA, allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } + return allOk; + } + + private static class ImageFilter implements FilenameFilter { + @Override + public boolean accept(File dir, String name) { + File file = new File(dir, name); + return file.isFile() && !file.isHidden(); + } + } +} diff --git a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml index 49c142d1e132e89fc6e93d67adc8f3545ab01bcf..46b174368dbacc87159b708ecf5b1d8167438776 100644 --- a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml @@ -176,6 +176,10 @@ <constructor-arg index="0" value="OLAT_13.2.0" /> <property name="alterDbStatements" value="alter_13_1_x_to_13_2_0.sql" /> </bean> + <bean id="database_upgrade_13_3_0" class="org.olat.upgrade.DatabaseUpgrade"> + <constructor-arg index="0" value="OLAT_13.3.0" /> + <property name="alterDbStatements" value="alter_13_2_x_to_13_3_0.sql" /> + </bean> </list> </property> </bean> diff --git a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml index 397770715be3cb0a030c63ac79f27abe9401b92e..9a0983fcf024d896526e4e2e443d96d7fafa733e 100644 --- a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml @@ -48,6 +48,7 @@ <bean id="upgrade_13_0_0_beta9" class="org.olat.upgrade.OLATUpgrade_13_0_0_beta9"/> <bean id="upgrade_13_1_0" class="org.olat.upgrade.OLATUpgrade_13_1_0"/> <bean id="upgrade_13_2_0" class="org.olat.upgrade.OLATUpgrade_13_2_0"/> + <bean id="upgrade_13_3_0" class="org.olat.upgrade.OLATUpgrade_13_3_0"/> </list> </property> </bean> diff --git a/src/main/java/org/olat/user/DisplayPortraitManager.java b/src/main/java/org/olat/user/DisplayPortraitManager.java index cc4194d1815cda9e408b4e6e25713492158d6184..8cfe896e4de3a39ff35672f23ff98b7c93122b55 100644 --- a/src/main/java/org/olat/user/DisplayPortraitManager.java +++ b/src/main/java/org/olat/user/DisplayPortraitManager.java @@ -37,6 +37,7 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.services.image.ImageService; import org.olat.core.commons.services.image.Size; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.media.FileMediaResource; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.ServletUtil; @@ -53,6 +54,7 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.user.manager.ManifestBuilder; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -94,6 +96,10 @@ public class DisplayPortraitManager implements UserDataDeletable, UserDataExport public static final int WIDTH_LOGO_BIG = HEIGHT_BIG * 4; // 4-8 kbytes (jpeg) public static final int WIDTH_LOGO_SMALL = HEIGHT_SMALL * 4; // 2-4 + + + @Autowired + private VFSRepositoryService vfsRepositoryService; public MediaResource getSmallPortraitResource(String username) { return getPortraitResource(username, PORTRAIT_SMALL_FILENAME); @@ -307,7 +313,7 @@ public class DisplayPortraitManager implements UserDataDeletable, UserDataExport VFSLeaf vfsPortrait = getLargestVFSPortrait(username); if(vfsPortrait.canMeta() == VFSConstants.YES) { - vfsPortrait.getMetaInfo().clearThumbnails(); + vfsRepositoryService.resetThumbnails(vfsPortrait); } } diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 3546993e17b37d88b2e72e3c26a999bc16f0c78c..c301f71b6d01ab9cd442af28439ce56d6bead39a 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -65,7 +65,7 @@ <class>org.olat.basesecurity.model.GrantImpl</class> <class>org.olat.basesecurity.model.GroupMembershipImpl</class> <class>org.olat.basesecurity.model.UserProperty</class> - <class>org.olat.basesecurity.model.IdentityLastLoginImpl</class><class>org.olat.basesecurity.model.AuthenticationHistoryImpl</class> + <class>org.olat.basesecurity.model.IdentityLastLoginImpl</class> <class>org.olat.basesecurity.model.AuthenticationHistoryImpl</class> <class>org.olat.basesecurity.model.OrganisationTypeImpl</class> <class>org.olat.basesecurity.model.OrganisationTypeToTypeImpl</class> @@ -92,6 +92,9 @@ <class>org.olat.core.commons.services.commentAndRating.model.UserRatingImpl</class> <class>org.olat.core.commons.services.commentAndRating.model.UserCommentImpl</class> <class>org.olat.core.commons.services.sms.model.MessageLogImpl</class> + <class>org.olat.core.commons.services.vfs.model.VFSMetadataImpl</class> + <class>org.olat.core.commons.services.vfs.model.VFSMetadataDownloadCount</class> + <class>org.olat.core.commons.services.vfs.model.VFSThumbnailMetadataImpl</class> <class>org.olat.course.assessment.model.AssessmentModeImpl</class> <class>org.olat.course.assessment.model.AssessmentModeToAreaImpl</class> <class>org.olat.course.assessment.model.AssessmentModeToGroupImpl</class> diff --git a/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..9e53a48280516c2c00ccf473bef12f57e94a6a13 --- /dev/null +++ b/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql @@ -0,0 +1,72 @@ +-- vfs metadata +create table o_vfs_metadata ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory bool default false, + f_lastmodified datetime not null, + f_size bigint default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails bool default false, + f_download_count bigint default 0, + f_comment text(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(16), + f_language varchar(16), + f_url text(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text mediumtext, + f_licensor text(4000), + f_locked_date timestamp, + f_locked bool default false, + f_m_path_keys varchar(1024), + fk_locked_identity bigint, + fk_license_type bigint, + fk_author bigint, + fk_parent bigint, + primary key (id) +); + +alter table o_vfs_metadata ENGINE = InnoDB; + +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys(100)); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path(255)); +create index f_m_filename_idx on o_vfs_metadata (f_filename(255)); + + +create table o_vfs_thumbnail ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_size bigint default 0 not null, + f_max_width bigint default 0 not null, + f_max_height bigint default 0 not null, + f_final_width bigint default 0 not null, + f_final_height bigint default 0 not null, + f_fill bool default false not null, + f_filename varchar(256) not null, + fk_metadata bigint not null, + primary key (id) +); + +alter table o_vfs_thumbnail ENGINE = InnoDB; + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); + + + + diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index f59d0bd5196189f23c45cc38b1c05b6960c5a35d..b70d5d51b38df7b38e20b28ff7fa9490a4253a2c 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1680,6 +1680,59 @@ create table if not exists o_qp_license ( primary key (id) ); +-- vfs metadata +create table o_vfs_metadata ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory bool default false, + f_lastmodified datetime not null, + f_size bigint default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails bool default false, + f_download_count bigint default 0, + f_comment text(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(16), + f_language varchar(16), + f_url text(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text mediumtext, + f_licensor text(4000), + f_locked_date timestamp, + f_locked bool default false, + f_m_path_keys varchar(1024), + fk_locked_identity bigint, + fk_license_type bigint, + fk_author bigint, + fk_parent bigint, + primary key (id) +); + +create table o_vfs_thumbnail ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_size bigint default 0 not null, + f_max_width bigint default 0 not null, + f_max_height bigint default 0 not null, + f_final_width bigint default 0 not null, + f_final_height bigint default 0 not null, + f_fill bool default false not null, + f_filename varchar(256) not null, + fk_metadata bigint not null, + primary key (id) +); -- portfolio create table o_pf_binder ( @@ -3042,6 +3095,8 @@ alter table o_qual_generator ENGINE = InnoDB; alter table o_qual_generator_config ENGINE = InnoDB; alter table o_qual_generator_to_org ENGINE = InnoDB; alter table o_qual_analysis_presentation ENGINE = InnoDB; +alter table o_vfs_metadata ENGINE = InnoDB; +alter table o_vfs_thumbnail ENGINE = InnoDB; alter table o_sms_message_log ENGINE = InnoDB; alter table o_feed ENGINE = InnoDB; alter table o_feed_item ENGINE = InnoDB; @@ -3531,6 +3586,17 @@ alter table o_eva_form_session add constraint eva_sess_to_form_idx foreign key ( alter table o_eva_form_response add constraint eva_resp_to_sess_idx foreign key (fk_session) references o_eva_form_session (id); create index idx_eva_resp_report_idx on o_eva_form_response (fk_session, e_responseidentifier, e_no_response); +-- vfs metadata +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys(100)); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path(255)); +create index f_m_filename_idx on o_vfs_metadata (f_filename(255)); + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); + -- quality management alter table o_qual_data_collection add constraint qual_dc_to_gen_idx foreign key (fk_generator) references o_qual_generator (id); create index idx_dc_status_idx on o_qual_data_collection (q_status); diff --git a/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..999ca3814b5ce1f71998d01b1265d5b38dcd3699 --- /dev/null +++ b/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql @@ -0,0 +1,69 @@ +create table o_vfs_metadata ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory number default 0, + f_lastmodified timestamp not null, + f_size number(20) default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails number default 0, + f_download_count number(20) default 0, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text CLOB, + f_licensor varchar(4000), + f_locked_date timestamp, + f_locked number default 0, + f_m_path_keys varchar(1024), + fk_locked_identity number(20), + fk_license_type number(20), + fk_author number(20), + fk_parent number(20), + primary key (id) +); + +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +create index idx_fmeta_to_author_idx on o_vfs_metadata (fk_locked_identity); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fmeta_to_lockid_idx on o_vfs_metadata (fk_author); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fmeta_to_lic_type_idx on o_vfs_metadata (fk_license_type); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index idx_fmeta_to_parent_idx on o_vfs_metadata (fk_parent); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path); +create index f_m_filename_idx on o_vfs_metadata (f_filename); + + +create table o_vfs_thumbnail ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_size number(20) default 0 not null, + f_max_width number(20) default 0 not null, + f_max_height number(20) default 0 not null, + f_final_width number(20) default 0 not null, + f_final_height number(20) default 0 not null, + f_fill number default 0 not null, + f_filename varchar(256) not null, + fk_metadata number(20) not null, + primary key (id) +); + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 560fa0cc9ed7fce1c39da149087c2e122866d87f..4824214ded791b0410144bd45d6a294a5a694a6f 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -1610,6 +1610,60 @@ create table o_qti_assessment_marks ( primary key (id) ); +-- vfs +create table o_vfs_metadata ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory number default 0, + f_lastmodified timestamp not null, + f_size number(20) default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails number default 0, + f_download_count number(20) default 0, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text CLOB, + f_licensor varchar(4000), + f_locked_date timestamp, + f_locked number default 0, + f_m_path_keys varchar(1024), + fk_locked_identity number(20), + fk_license_type number(20), + fk_author number(20), + fk_parent number(20), + primary key (id) +); + +create table o_vfs_thumbnail ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_size number(20) default 0 not null, + f_max_width number(20) default 0 not null, + f_max_height number(20) default 0 not null, + f_final_width number(20) default 0 not null, + f_final_height number(20) default 0 not null, + f_fill number default 0 not null, + f_filename varchar(256) not null, + fk_metadata number(20) not null, + primary key (id) +); + -- portfolio create table o_pf_binder ( id number(20) GENERATED ALWAYS AS IDENTITY, @@ -3558,6 +3612,22 @@ create index idx_qti_marks_to_centry_idx on o_qti_assessment_marks (fk_reference alter table o_qti_assessment_marks add constraint qti_marks_to_identity_idx foreign key (fk_identity) references o_bs_identity (id); create index idx_qti_marks_to_identity_idx on o_qti_assessment_marks (fk_identity); +-- vfs +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +create index idx_fmeta_to_author_idx on o_vfs_metadata (fk_locked_identity); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fmeta_to_lockid_idx on o_vfs_metadata (fk_author); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fmeta_to_lic_type_idx on o_vfs_metadata (fk_license_type); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index idx_fmeta_to_parent_idx on o_vfs_metadata (fk_parent); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path); +create index f_m_filename_idx on o_vfs_metadata (f_filename); + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + -- portfolio alter table o_pf_binder add constraint pf_binder_resource_idx foreign key (fk_olatresource_id) references o_olatresource (resource_id); create index idx_pf_binder_resource_idx on o_pf_binder (fk_olatresource_id); diff --git a/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..08ccac477dd9feabf2455492558181e5d5f374a4 --- /dev/null +++ b/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql @@ -0,0 +1,70 @@ +-- vfs metadata +create table o_vfs_metadata ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory bool default false, + f_lastmodified timestamp not null, + f_size bigint default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails bool default false, + f_download_count bigint default 0, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text text, + f_licensor varchar(4000), + f_locked_date timestamp, + f_locked bool default false, + f_m_path_keys varchar(1024), + fk_locked_identity bigint, + fk_license_type bigint, + fk_author bigint, + fk_parent bigint, + primary key (id) +); + +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +create index idx_fmeta_to_author_idx on o_vfs_metadata (fk_locked_identity); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fmeta_to_lockid_idx on o_vfs_metadata (fk_author); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fmeta_to_lic_type_idx on o_vfs_metadata (fk_license_type); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index idx_fmeta_to_parent_idx on o_vfs_metadata (fk_parent); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path); +create index f_m_filename_idx on o_vfs_metadata (f_filename); + + +create table o_vfs_thumbnail ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_size bigint default 0 not null, + f_max_width bigint default 0 not null, + f_max_height bigint default 0 not null, + f_final_width bigint default 0 not null, + f_final_height bigint default 0 not null, + f_fill bool default false not null, + f_filename varchar(256) not null, + fk_metadata bigint not null, + primary key (id) +); + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index 3352ab6ae2e8ac8d1b02cee3d425bcbc28f60bd1..f04b654639ab0c8a047c0fc88f2b659c9bb2e28e 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1573,6 +1573,60 @@ create table o_qti_assessment_marks ( primary key (id) ); +-- vfs metadata +create table o_vfs_metadata ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_uuid varchar(64) not null, + f_filename varchar(256) not null, + f_relative_path varchar(2048) not null, + f_directory bool default false, + f_lastmodified timestamp not null, + f_size bigint default 0, + f_uri varchar(2000) not null, + f_uri_protocol varchar(16) not null, + f_cannot_thumbnails bool default false, + f_download_count bigint default 0, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text text, + f_licensor varchar(4000), + f_locked_date timestamp, + f_locked bool default false, + f_m_path_keys varchar(1024), + fk_locked_identity bigint, + fk_license_type bigint, + fk_author bigint, + fk_parent bigint, + primary key (id) +); + +create table o_vfs_thumbnail ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_size bigint default 0 not null, + f_max_width bigint default 0 not null, + f_max_height bigint default 0 not null, + f_final_width bigint default 0 not null, + f_final_height bigint default 0 not null, + f_fill bool default false not null, + f_filename varchar(256) not null, + fk_metadata bigint not null, + primary key (id) +); + -- portfolio create table o_pf_binder ( id bigserial, @@ -3519,6 +3573,22 @@ create index idx_user_pfpage_idx on o_pf_page_user_infos (fk_identity_id); alter table o_pf_page_user_infos add constraint page_pfpage_idx foreign key (fk_page_id) references o_pf_page (id); create index idx_page_pfpage_idx on o_pf_page_user_infos (fk_page_id); +-- vfs metadata +alter table o_vfs_metadata add constraint fmeta_to_author_idx foreign key (fk_locked_identity) references o_bs_identity (id); +create index idx_fmeta_to_author_idx on o_vfs_metadata (fk_locked_identity); +alter table o_vfs_metadata add constraint fmeta_to_lockid_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fmeta_to_lockid_idx on o_vfs_metadata (fk_author); +alter table o_vfs_metadata add constraint fmeta_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fmeta_to_lic_type_idx on o_vfs_metadata (fk_license_type); +alter table o_vfs_metadata add constraint fmeta_to_parent_idx foreign key (fk_parent) references o_vfs_metadata (id); +create index idx_fmeta_to_parent_idx on o_vfs_metadata (fk_parent); +create index f_m_path_keys_idx on o_vfs_metadata (f_m_path_keys); +create index f_m_rel_path_idx on o_vfs_metadata (f_relative_path); +create index f_m_filename_idx on o_vfs_metadata (f_filename); + +alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + -- evaluation form alter table o_eva_form_survey add constraint eva_surv_to_surv_idx foreign key (fk_series_previous) references o_eva_form_survey (id); create unique index idx_eva_surv_ores_idx on o_eva_form_survey (e_resid, e_resname, e_sub_ident); diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java new file mode 100644 index 0000000000000000000000000000000000000000..27d55c988d59b3edf6280d34618641ce57b37510 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java @@ -0,0 +1,113 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.Date; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.manager.VFSMetadataDAO; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 11 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSMetadataDAOTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private VFSMetadataDAO vfsMetadataDao; + + @Test + public void createMetadata() { + String uuid = UUID.randomUUID().toString(); + String relativePath = "/bcroot/hello/world/"; + String filename = "image.jpg"; + String uri = "file:///Users/frentix/Documents/bcroot/hello/world/image.jpg"; + String uriProtocol = "file"; + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, relativePath, filename, new Date(), 10l, false, uri, uriProtocol, null); + dbInstance.commitAndCloseSession(); + + Assert.assertNotNull(metadata); + Assert.assertNotNull(metadata.getKey()); + Assert.assertNotNull(metadata.getCreationDate()); + Assert.assertNotNull(metadata.getLastModified()); + Assert.assertEquals(uuid, metadata.getUuid()); + Assert.assertEquals(relativePath, metadata.getRelativePath()); + Assert.assertEquals(filename, metadata.getFilename()); + Assert.assertFalse(metadata.isDirectory()); + Assert.assertEquals(uri, metadata.getUri()); + Assert.assertEquals(uriProtocol, metadata.getProtocol()); + } + + @Test + public void getMetadata_uuid() { + String uuid = UUID.randomUUID().toString(); + String relativePath = "/bcroot/hello/world/"; + String filename = "image.jpg"; + String uri = "file:///Users/frentix/Documents/bcroot/hello/world/image.jpg"; + String uriProtocol = "file"; + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, relativePath, filename, new Date(), 15l, false, uri, uriProtocol, null); + dbInstance.commitAndCloseSession(); + Assert.assertNotNull(metadata); + + VFSMetadata loadedMetadata = vfsMetadataDao.getMetadata(uuid); + Assert.assertEquals(metadata, loadedMetadata); + Assert.assertEquals(metadata.getKey(), loadedMetadata.getKey()); + Assert.assertEquals(uuid, metadata.getUuid()); + Assert.assertEquals(relativePath, metadata.getRelativePath()); + Assert.assertEquals(filename, metadata.getFilename()); + Assert.assertFalse(metadata.isDirectory()); + Assert.assertEquals(uri, metadata.getUri()); + Assert.assertEquals(uriProtocol, metadata.getProtocol()); + } + + @Test + public void getMetadata_path() { + String uuid = UUID.randomUUID().toString(); + String relativePath = "/bcroot/hello/world/"; + String filename = uuid + ".jpg"; + String uri = "file:///Users/frentix/Documents/bcroot/hello/world/image.jpg"; + String uriProtocol = "file"; + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, relativePath, filename, new Date(), 18l, false, uri, uriProtocol, null); + dbInstance.commitAndCloseSession(); + Assert.assertNotNull(metadata); + + VFSMetadata loadedMetadata = vfsMetadataDao.getMetadata(relativePath, filename, false); + Assert.assertEquals(metadata, loadedMetadata); + Assert.assertEquals(metadata.getKey(), loadedMetadata.getKey()); + Assert.assertEquals(uuid, metadata.getUuid()); + Assert.assertEquals(relativePath, metadata.getRelativePath()); + Assert.assertEquals(filename, metadata.getFilename()); + Assert.assertEquals(18l, metadata.getFileSize()); + Assert.assertFalse(metadata.isDirectory()); + Assert.assertEquals(uri, metadata.getUri()); + Assert.assertEquals(uriProtocol, metadata.getProtocol()); + } + +} diff --git a/src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceTest.java similarity index 63% rename from src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java rename to src/test/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceTest.java index f0e91d0745571e4427f18199848d467a3425aefc..8ecf0d1ad2ae02b34ce3f3d1d81fb830b88326f4 100644 --- a/src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceTest.java @@ -17,16 +17,15 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.commons.modules.bc.meta; +package org.olat.core.commons.services.vfs.manager; import static org.assertj.core.api.Assertions.assertThat; -import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; +import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -35,45 +34,58 @@ import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.license.manager.LicenseCleaner; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.FileUtils; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.VFSTest; -import org.olat.core.util.vfs.meta.MetaInfo; -import org.olat.core.util.vfs.meta.MetaInfoFactory; -import org.olat.core.util.vfs.meta.MetaInfoFileImpl; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; /** * - * Initial date: 05.03.2018<br> - * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * Initial date: 12 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class MetaInfoFactoryTest extends OlatTestCase { +public class VFSRepositoryServiceTest extends OlatTestCase { - private static final OLog log = Tracing.createLoggerFor(MetaInfoFactoryTest.class); - private static final String VFS_META_DIR = "/vfsmetatest"; + private static final OLog log = Tracing.createLoggerFor(VFSRepositoryServiceTest.class); + private static final String VFS_TEST_DIR = "/vfsrepotest"; @Autowired private DB dbInstance; @Autowired - private MetaInfoFactory metaInfoFactory; - @Autowired private LicenseService licenseService; @Autowired private LicenseCleaner licenseCleaner; + @Autowired + private VFSRepositoryService vfsRepositoryService; @Before public void cleanUp() { licenseCleaner.deleteAll(); } + @Test + public void getMetadataFor_file() { + VFSLeaf leaf = createFile(); + + // create metadata + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(leaf); + dbInstance.commitAndCloseSession(); + Assert.assertNotNull(metadata); + Assert.assertNotNull(metadata.getKey()); + Assert.assertNotNull(metadata.getCreationDate()); + Assert.assertNotNull(metadata.getLastModified()); + Assert.assertNotNull(metadata.getFileLastModified()); + Assert.assertEquals(leaf.getName(), metadata.getFilename()); + Assert.assertFalse(metadata.isDirectory()); + } + @Test public void shouldLoadExistingLicenseType() { String typeName = "name"; @@ -82,34 +94,35 @@ public class MetaInfoFactoryTest extends OlatTestCase { dbInstance.commitAndCloseSession(); String licensor = "licensor"; String name = licenseType.getName(); - File file = new File(""); - MetaInfo meta = new MetaInfoFileImpl(file); + + VFSLeaf file = createFile(); + VFSMetadata meta = vfsRepositoryService.getMetadataFor(file); meta.setLicenseTypeName(name); meta.setLicensor(licensor); - - License license = metaInfoFactory.getLicense(meta); + License license = vfsRepositoryService.getLicense(meta); assertThat(license.getLicensor()).isEqualTo(licensor); LicenseType loadedLicenseType = license.getLicenseType(); assertThat(loadedLicenseType).isEqualTo(licenseType); } - + @Test public void shouldCreateNonExistingLicenseType() { String typeName = "name"; LicenseType licenseType = licenseService.createLicenseType(typeName); licenseType = licenseService.saveLicenseType(licenseType); dbInstance.commitAndCloseSession(); + String licensor = "licensor"; String name = "new"; String text = "text"; - File file = new File(""); - MetaInfo meta = new MetaInfoFileImpl(file); + VFSLeaf file = createFile(); + VFSMetadata meta = vfsRepositoryService.getMetadataFor(file); + meta.setLicenseTypeName(name); meta.setLicensor(licensor); meta.setLicenseText(text); - - License license = metaInfoFactory.getLicense(meta); + License license = vfsRepositoryService.getLicense(meta); assertThat(license.getLicensor()).isEqualTo(licensor); LicenseType loadedLicenseType = license.getLicenseType(); @@ -123,36 +136,45 @@ public class MetaInfoFactoryTest extends OlatTestCase { @Test public void readWriteBinary() { String filename = UUID.randomUUID() + ".txt"; - VFSContainer testContainer = VFSManager.olatRootContainer(VFS_META_DIR, null); + VFSContainer testContainer = VFSManager.olatRootContainer(VFS_TEST_DIR, null); VFSLeaf leaf = testContainer.createChildLeaf(filename); Assert.assertEquals(VFSConstants.YES, leaf.canMeta()); - prepareFile(leaf); + copyTestTxt(leaf); - MetaInfo metaInfo = leaf.getMetaInfo(); + VFSMetadata metaInfo = leaf.getMetaInfo(); metaInfo.setComment("A little comment"); - metaInfo.write(); + vfsRepositoryService.updateMetadata(metaInfo); - byte[] binaryData = metaInfo.readBinary(); + byte[] binaryData = MetaInfoReader.toBinaries(metaInfo); Assert.assertNotNull(binaryData); Assert.assertTrue(binaryData.length > 0); String secondFilename = UUID.randomUUID() + ".txt"; VFSLeaf secondLeaf = testContainer.createChildLeaf(secondFilename); - prepareFile(secondLeaf); + copyTestTxt(secondLeaf); - MetaInfo secondMetaInfo = leaf.getMetaInfo(); - secondMetaInfo.writeBinary(binaryData); + VFSMetadata secondMetaInfo = leaf.getMetaInfo(); + vfsRepositoryService.copyBinaries(secondMetaInfo, binaryData); String comment = secondMetaInfo.getComment(); Assert.assertEquals("A little comment", comment); } - private void prepareFile(VFSLeaf file) { + private VFSLeaf createFile() { + String filename = UUID.randomUUID() + ".txt"; + VFSContainer testContainer = VFSManager.olatRootContainer(VFS_TEST_DIR, null); + VFSLeaf firstLeaf = testContainer.createChildLeaf(filename); + copyTestTxt(firstLeaf); + return firstLeaf; + } + + private int copyTestTxt(VFSLeaf file) { try(OutputStream out = file.getOutputStream(false); - InputStream in = VFSTest.class.getResourceAsStream("test.txt")) { - FileUtils.cpio(in, out, ""); - } catch(IOException e) { + InputStream in = VFSRepositoryServiceTest.class.getResourceAsStream("test.txt")) { + return IOUtils.copy(in, out); + } catch(Exception e) { log.error("", e); + return -1; } } } diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAOTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAOTest.java new file mode 100644 index 0000000000000000000000000000000000000000..afaf2c6814432a75c9f82265a3f37616b0a78d75 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSThumbnailDAOTest.java @@ -0,0 +1,161 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSThumbnailMetadata; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 14 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSThumbnailDAOTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private VFSMetadataDAO vfsMetadataDao; + @Autowired + private VFSThumbnailDAO vfsThumbnailDao; + + @Test + public void createMetadata() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".jpg"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._oo_th_", 1l, true, 200, 150, 120, 80); + dbInstance.commitAndCloseSession(); + + Assert.assertNotNull(thumbnail); + Assert.assertNotNull(thumbnail.getKey()); + Assert.assertNotNull(thumbnail.getCreationDate()); + Assert.assertNotNull(thumbnail.getLastModified()); + Assert.assertTrue(thumbnail.isFill()); + Assert.assertEquals(200, thumbnail.getMaxWidth()); + Assert.assertEquals(150, thumbnail.getMaxHeight()); + Assert.assertEquals(120, thumbnail.getFinalWidth()); + Assert.assertEquals(80, thumbnail.getFinalHeight()); + } + + @Test + public void loadByKey() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".jpg"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 200, 150, 120, 80); + dbInstance.commitAndCloseSession(); + + VFSThumbnailMetadata reloadedThumbnail = vfsThumbnailDao.loadByKey(thumbnail.getKey()); + + Assert.assertNotNull(reloadedThumbnail); + Assert.assertNotNull(reloadedThumbnail.getKey()); + Assert.assertNotNull(reloadedThumbnail.getCreationDate()); + Assert.assertNotNull(reloadedThumbnail.getLastModified()); + Assert.assertTrue(reloadedThumbnail.isFill()); + Assert.assertEquals(thumbnail, reloadedThumbnail); + Assert.assertEquals(metadata, reloadedThumbnail.getOwner()); + Assert.assertEquals("._ooth_", reloadedThumbnail.getFilename()); + Assert.assertEquals(200, reloadedThumbnail.getMaxWidth()); + Assert.assertEquals(150, reloadedThumbnail.getMaxHeight()); + Assert.assertEquals(120, reloadedThumbnail.getFinalWidth()); + Assert.assertEquals(80, reloadedThumbnail.getFinalHeight()); + } + + @Test + public void loadByMetadata() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".png"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 200, 150, 120, 80); + dbInstance.commitAndCloseSession(); + + List<VFSThumbnailMetadata> thumbnails = vfsThumbnailDao.loadByMetadata(metadata); + + Assert.assertNotNull(thumbnails); + Assert.assertEquals(1, thumbnails.size()); + Assert.assertEquals(thumbnail, thumbnails.get(0)); + } + + @Test + public void findThumbnail() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".jpg"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 200, 150, 120, 80); + dbInstance.commitAndCloseSession(); + + VFSThumbnailMetadata reloadedThumbnail = vfsThumbnailDao.findThumbnail("vfsrepo2test/world/", filename, true, 200, 150); + + Assert.assertNotNull(reloadedThumbnail); + Assert.assertNotNull(reloadedThumbnail.getKey()); + Assert.assertNotNull(reloadedThumbnail.getCreationDate()); + Assert.assertNotNull(reloadedThumbnail.getLastModified()); + Assert.assertEquals(thumbnail, reloadedThumbnail); + Assert.assertTrue(reloadedThumbnail.isFill()); + Assert.assertEquals(metadata, reloadedThumbnail.getOwner()); + Assert.assertEquals("._ooth_", reloadedThumbnail.getFilename()); + Assert.assertEquals(200, reloadedThumbnail.getMaxWidth()); + Assert.assertEquals(150, reloadedThumbnail.getMaxHeight()); + Assert.assertEquals(120, reloadedThumbnail.getFinalWidth()); + Assert.assertEquals(80, reloadedThumbnail.getFinalHeight()); + } + + @Test + public void findThumbnails() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".jpg"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 200, 150, 120, 80); + dbInstance.commitAndCloseSession(); + + List<VFSThumbnailMetadata> thumbnails = vfsThumbnailDao.findThumbnails("vfsrepo2test/world/", filename); + + Assert.assertNotNull(thumbnails); + Assert.assertEquals(1, thumbnails.size()); + Assert.assertEquals(thumbnail, thumbnails.get(0)); + } + + @Test + public void findThumbnail_byMetadata() { + String uuid = UUID.randomUUID().toString(); + String filename = uuid.concat(".jpg"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(uuid, "vfsrepo2test/world/", filename, new Date(), 1l, false, "file:///uri", "file", null); + VFSThumbnailMetadata thumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 200, 150, 120, 80); + VFSThumbnailMetadata largeThumbnail = vfsThumbnailDao.createThumbnailMetadata(metadata, "._ooth_", 1l, true, 400, 300, 120, 80); + dbInstance.commitAndCloseSession(); + + VFSThumbnailMetadata reloadedThumbnail = vfsThumbnailDao.findThumbnail(metadata, true, 200, 150); + + Assert.assertNotNull(reloadedThumbnail); + Assert.assertEquals(thumbnail, reloadedThumbnail); + Assert.assertNotEquals(largeThumbnail, reloadedThumbnail); + } +} diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSXStreamTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSXStreamTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a8190fa3d22313bd03b9b60ed2f7f9bd63350801 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSXStreamTest.java @@ -0,0 +1,57 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.logging.OLATRuntimeException; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.vfs.version.VersionsFileImpl; +import org.olat.test.OlatTestCase; + +/** + * + * Initial date: 13 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSXStreamTest extends OlatTestCase { + + private static final OLog log = Tracing.createLoggerFor(VFSXStreamTest.class); + + @Test + public void readOldVersions() throws IOException { + VersionsFileImpl versions = null; + try(InputStream in = VFSXStreamTest.class.getResourceAsStream("house.versions.jpg.xml")) { + versions = (VersionsFileImpl)VFSXStream.read(in); + + } catch(IOException | OLATRuntimeException e) { + log.error("", e); + throw e; + } + + Assert.assertNotNull(versions); + } + +} diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/house.versions.jpg.xml b/src/test/java/org/olat/core/commons/services/vfs/manager/house.versions.jpg.xml new file mode 100644 index 0000000000000000000000000000000000000000..1e505ffd21d6d7b6ab4f68b45047a7c681f991c8 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/house.versions.jpg.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<versions> + <versioned>true</versioned> + <author>kanu</author> + <creator>kanu</creator> + <revisionNr>3</revisionNr> + <comment>The old one</comment> + <revisions> + <revision> + <author>kanu</author> + <name>house.jpg</name> + <uuid>cf39a5d5-4180-41b4-b600-35d9a727cc5e</uuid> + <lastModified>1547659812000</lastModified> + <revisionNr>1</revisionNr> + <filename>fafb0367-4cbe-41b7-9457-56d69b85c7d3_house.jpg</filename> + <metadata class="metadata"> + <uuid>e3d63dc8595942b2801d0af9c1f6182a</uuid> + <authorIdentKey>720898</authorIdentKey> + <comment>A very cute house</comment> + <title>An house</title> + <publisher>Still me</publisher> + <creator>Me too</creator> + <source>Always me</source> + <city>Where I lived</city> + <pages>68</pages> + <language>French</language> + <url>https://blog.cyberiacafe.ch</url> + <pubMonth>12</pubMonth> + <pubYear>2018</pubYear> + <licenseTypeKey>10</licenseTypeKey> + <licenseTypeName>CC BY-NC-ND</licenseTypeName> + <licenseText>https://creativecommons.org/licenses/by-nc-nd/4.0/</licenseText> + <licensor>Me</licensor> + <downloadCount>2</downloadCount> + <locked>false</locked> + <originFile>/HotCoffee/olatdatas/openolat_110_postgresql/bcroot/homes/kanu/public/house.jpg</originFile> + <metaFile>/HotCoffee/olatdatas/openolat_110_postgresql/bcroot/.meta/homes/kanu/public/house.jpg.xml</metaFile> + <cannotGenerateThumbnail>false</cannotGenerateThumbnail> + <thumbnails/> + </metadata> + </revision> + <revision> + <author>kanu</author> + <comment>A pink one</comment> + <name>house.jpg</name> + <uuid>acba63ce-de13-4759-bf85-a26f1833eca1</uuid> + <lastModified>1552487917000</lastModified> + <revisionNr>2</revisionNr> + <filename>c4087cf5-0ed6-4ed8-a97c-1317c963a0a8_house.jpg</filename> + <metadata class="metadata"> + <uuid>e3d63dc8595942b2801d0af9c1f6182a</uuid> + <authorIdentKey>720898</authorIdentKey> + <comment></comment> + <licenseTypeKey>1</licenseTypeKey> + <licenseTypeName>no.license</licenseTypeName> + <downloadCount>2</downloadCount> + <locked>false</locked> + <originFile>/HotCoffee/olatdatas/openolat_110_postgresql/bcroot/homes/kanu/public/house.jpg</originFile> + <metaFile>/HotCoffee/olatdatas/openolat_110_postgresql/bcroot/.meta/homes/kanu/public/house.jpg.xml</metaFile> + <cannotGenerateThumbnail>false</cannotGenerateThumbnail> + <thumbnails/> + </metadata> + </revision> + </revisions> +</versions> \ No newline at end of file diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/test.txt b/src/test/java/org/olat/core/commons/services/vfs/manager/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ab2f8a4323abafb10abb68657d9d39f1a775057 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/test.txt @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/src/test/java/org/olat/core/util/vfs/VFSTest.java b/src/test/java/org/olat/core/util/vfs/VFSTest.java index f5df2a971834a891e748ccb98c7e86df957fc8dd..c1f37c1a3f0a2129dde792f59228d4df1063ea06 100644 --- a/src/test/java/org/olat/core/util/vfs/VFSTest.java +++ b/src/test/java/org/olat/core/util/vfs/VFSTest.java @@ -26,11 +26,13 @@ import java.util.UUID; import org.junit.Assert; import org.junit.Test; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; /** @@ -45,6 +47,9 @@ public class VFSTest extends OlatTestCase { private static final String VFS_TEST_DIR = "/vfstest"; + @Autowired + private VFSRepositoryService vfsRepositoryService; + /** * Test the copyFrom method (inclusive copy of metadata) */ @@ -56,10 +61,10 @@ public class VFSTest extends OlatTestCase { Assert.assertEquals(VFSConstants.YES, firstLeaf.canMeta()); prepareFile(firstLeaf); - MetaInfo metaInfo = firstLeaf.getMetaInfo(); + VFSMetadata metaInfo = firstLeaf.getMetaInfo(); metaInfo.setComment("A comment"); metaInfo.setCreator("Me"); - Assert.assertTrue(metaInfo.write()); + Assert.assertNotNull(vfsRepositoryService.updateMetadata(metaInfo)); VFSContainer targetContainer = VFSManager.olatRootContainer(VFS_TEST_DIR + "/vfstarger" + UUID.randomUUID(), null); Assert.assertEquals(VFSConstants.YES, targetContainer.canMeta()); @@ -71,7 +76,7 @@ public class VFSTest extends OlatTestCase { VFSLeaf copiedLeaf = (VFSLeaf)copiedItem; Assert.assertEquals(VFSConstants.YES, copiedLeaf.canMeta()); - MetaInfo copiedMetaInfo = copiedLeaf.getMetaInfo(); + VFSMetadata copiedMetaInfo = copiedLeaf.getMetaInfo(); Assert.assertEquals("A comment", copiedMetaInfo.getComment()); Assert.assertEquals("Me", copiedMetaInfo.getCreator()); } @@ -84,10 +89,10 @@ public class VFSTest extends OlatTestCase { Assert.assertEquals(VFSConstants.YES, firstLeaf.canMeta()); prepareFile(firstLeaf); - MetaInfo metaInfo = firstLeaf.getMetaInfo(); + VFSMetadata metaInfo = firstLeaf.getMetaInfo(); metaInfo.setComment("my old comment"); metaInfo.setCreator("Always Me"); - Assert.assertTrue(metaInfo.write()); + Assert.assertNotNull(vfsRepositoryService.updateMetadata(metaInfo)); String newName = UUID.randomUUID() + ".txt"; VFSStatus renamedStatus = firstLeaf.rename(newName); @@ -97,7 +102,7 @@ public class VFSTest extends OlatTestCase { Assert.assertTrue(renamedItem instanceof VFSLeaf); VFSLeaf renamedLeaf = (VFSLeaf)renamedItem; - MetaInfo renamedMetaInfo = renamedLeaf.getMetaInfo(); + VFSMetadata renamedMetaInfo = renamedLeaf.getMetaInfo(); Assert.assertEquals("my old comment", renamedMetaInfo.getComment()); Assert.assertEquals("Always Me", renamedMetaInfo.getCreator()); } diff --git a/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java index 746ba91333cbccb45b04813c57c5cc3240db8c73..e54b907d65ca157ffa9e125c9f19c2da11fa3f93 100644 --- a/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java +++ b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java @@ -40,6 +40,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; @@ -47,7 +49,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.SystemItemFilter; -import org.olat.core.util.vfs.meta.MetaInfo; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -71,6 +72,8 @@ public class VersionManagerTest extends OlatTestCase { private VersionsFileManager versionsManager; @Autowired private SimpleVersionConfig versioningConfigurator; + @Autowired + private VFSRepositoryService vfsRepositoryService; @Before public void setUp() throws Exception { @@ -118,10 +121,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test", null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -153,7 +153,7 @@ public class VersionManagerTest extends OlatTestCase { VFSRevision revision0 = revisions.get(0); //we don't set an author for the original file - assertEquals("-", revision0.getAuthor()); + assertNull(null, revision0.getAuthor()); VFSRevision revision1 = revisions.get(1); assertEquals(id2.getName(), revision1.getAuthor()); VFSRevision revision2 = revisions.get(2); @@ -175,10 +175,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -212,10 +209,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -239,10 +233,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -291,10 +282,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -355,10 +343,7 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = new ByteArrayInputStream("Hello original".getBytes()); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); @@ -424,19 +409,16 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); assertEquals(VFSConstants.YES, file.canMeta()); //set the author - MetaInfo metaInfo = file.getMetaInfo(); + VFSMetadata metaInfo = file.getMetaInfo(); metaInfo.setAuthor(id1); metaInfo.setCreator(id1.getName()); - metaInfo.write(); + metaInfo = vfsRepositoryService.updateMetadata(metaInfo); //save a first version -> id2 Versionable versionedFile1 = (Versionable)file; @@ -483,19 +465,16 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); assertEquals(VFSConstants.YES, file.canMeta()); //set the author - MetaInfo metaInfo = file.getMetaInfo(); + VFSMetadata metaInfo = file.getMetaInfo(); metaInfo.setAuthor(id1); metaInfo.setCreator(id1.getName()); - metaInfo.write(); + metaInfo = vfsRepositoryService.updateMetadata(metaInfo); //save a first version -> id2 Versionable versionedFile1 = (Versionable)file; @@ -550,19 +529,16 @@ public class VersionManagerTest extends OlatTestCase { VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); String filename = getRandomName(); VFSLeaf file = rootTest.createChildLeaf(filename); - OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); - int byteCopied = IOUtils.copy(in, out); - in.close(); + int byteCopied = copyTestTxt(file); assertFalse(byteCopied == 0); assertTrue(file instanceof Versionable); assertEquals(VFSConstants.YES, file.canMeta()); //set the author - MetaInfo metaInfo = file.getMetaInfo(); + VFSMetadata metaInfo = file.getMetaInfo(); metaInfo.setAuthor(id1); metaInfo.setCreator(id1.getName()); - metaInfo.write(); + metaInfo = vfsRepositoryService.updateMetadata(metaInfo); //save a first version of file A -> id2 Versionable versionedFile1 = (Versionable)file; @@ -618,6 +594,15 @@ public class VersionManagerTest extends OlatTestCase { assertEquals(id2.getName(), versions.getAuthor()); } + private int copyTestTxt(VFSLeaf file) { + try(OutputStream out = file.getOutputStream(false); + InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt")) { + return IOUtils.copy(in, out); + } catch(IOException e) { + return -1; + } + } + private String getRandomName() { return UUID.randomUUID().toString().replace("-", ""); } diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 6c76a725a30822e7253d2fb1f22cb2813ad2fb58..55285c10e93983e6b4f0e74d095eb6a0a21c1571 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -97,8 +97,11 @@ import org.junit.runners.Suite; org.olat.commons.coordinate.cluster.jms.JMSTest.class, org.olat.commons.coordinate.cluster.lock.LockTest.class, org.olat.commons.coordinate.CoordinatorTest.class, - org.olat.core.commons.modules.bc.meta.MetaInfoFactoryTest.class, org.olat.core.commons.services.csp.manager.CSPManagerTest.class, + org.olat.core.commons.services.vfs.manager.VFSMetadataDAOTest.class, + org.olat.core.commons.services.vfs.manager.VFSRepositoryServiceTest.class, + org.olat.core.commons.services.vfs.manager.VFSThumbnailDAOTest.class, + org.olat.core.commons.services.vfs.manager.VFSXStreamTest.class, org.olat.core.commons.services.help.ConfluenceHelperTest.class, org.olat.core.commons.services.help.spi.ConfluenceLinkSPITest.class, org.olat.core.commons.services.license.manager.LicenseTypeActivationDAOTest.class, diff --git a/src/test/java/org/olat/test/VFSJavaIOFile.java b/src/test/java/org/olat/test/VFSJavaIOFile.java index fe27d9a44db30e5ae09ab1b3ff547416ba46d186..771a98f66caf4c2899b8530a0e49b03b2dd94376 100644 --- a/src/test/java/org/olat/test/VFSJavaIOFile.java +++ b/src/test/java/org/olat/test/VFSJavaIOFile.java @@ -27,6 +27,7 @@ import java.io.OutputStream; import java.nio.file.Path; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.util.vfs.JavaIOItem; import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSContainer; @@ -34,7 +35,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSStatus; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.meta.MetaInfo; /** * An implementation of the VFSLEaf for a pure java.io.File with @@ -154,7 +154,7 @@ public class VFSJavaIOFile implements VFSLeaf, JavaIOItem { } @Override - public MetaInfo getMetaInfo() { + public VFSMetadata getMetaInfo() { return null; }