From a72b103bdbc1646a227b0c696ac3f25c1807112e Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Fri, 8 Jul 2016 17:11:56 +0200 Subject: [PATCH] OO-2057: copy / import / export binder template --- .../modules/portfolio/PortfolioService.java | 6 + .../handler/BinderTemplateHandler.java | 96 ++++++++++++--- .../handler/BinderTemplateMediaResource.java | 113 ++++++++++++++++++ .../handler/BinderTemplateResource.java | 64 +++++++++- .../portfolio/handler/BinderXStream.java | 40 ++++--- .../modules/portfolio/manager/BinderDAO.java | 20 ++++ .../manager/PortfolioServiceImpl.java | 42 +++++++ .../ui/_i18n/LocalStrings_de.properties | 1 + .../ui/_i18n/LocalStrings_en.properties | 1 + .../RepositoryEntryImportExport.java | 36 ++++++ .../handlers/RepositoryHandler.java | 2 +- 11 files changed, 384 insertions(+), 37 deletions(-) create mode 100644 src/main/java/org/olat/modules/portfolio/handler/BinderTemplateMediaResource.java diff --git a/src/main/java/org/olat/modules/portfolio/PortfolioService.java b/src/main/java/org/olat/modules/portfolio/PortfolioService.java index f69d1ef6ec2..49ffc766d29 100644 --- a/src/main/java/org/olat/modules/portfolio/PortfolioService.java +++ b/src/main/java/org/olat/modules/portfolio/PortfolioService.java @@ -54,6 +54,12 @@ public interface PortfolioService { public Binder updateBinder(Binder binder); + public Binder copyBinder(Binder transientBinder, RepositoryEntry templateEntry); + + public Binder importBinder(Binder transientBinder, RepositoryEntry templateEntry, File image); + + public boolean deleteBinderTemplate(Binder binder, RepositoryEntry templateEntry); + /** * Add a new section at the end of the sections list of the specified binder. * diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java index c6a524ccc21..3ea96c6914d 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java @@ -19,12 +19,12 @@ */ package org.olat.modules.portfolio.handler; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.util.Locale; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.stack.TooledStackedPanel; @@ -33,19 +33,23 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.layout.MainLayoutController; import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.gui.media.MediaResource; -import org.olat.core.gui.media.StreamedMediaResource; +import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; import org.olat.core.logging.AssertException; 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.Util; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.LockResult; import org.olat.core.util.vfs.VFSContainer; import org.olat.course.assessment.AssessmentMode; import org.olat.course.assessment.manager.UserCourseInformationsManager; import org.olat.fileresource.FileResourceManager; +import org.olat.fileresource.types.FileResource; import org.olat.fileresource.types.ResourceEvaluation; import org.olat.modules.portfolio.Binder; import org.olat.modules.portfolio.BinderConfiguration; @@ -57,8 +61,10 @@ import org.olat.modules.portfolio.ui.BinderController; import org.olat.modules.portfolio.ui.BinderPickerController; import org.olat.modules.portfolio.ui.BinderRuntimeController; import org.olat.modules.portfolio.ui.PortfolioAssessmentDetailsController; +import org.olat.modules.portfolio.ui.PortfolioHomeController; import org.olat.repository.ErrorList; import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryEntryImportExport; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; import org.olat.repository.handlers.EditionSupport; @@ -66,6 +72,7 @@ import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.model.RepositoryEntrySecurity; import org.olat.repository.ui.RepositoryEntryRuntimeController.RuntimeControllerCreator; import org.olat.resource.OLATResource; +import org.olat.resource.references.ReferenceManager; /** * @@ -80,7 +87,7 @@ import org.olat.resource.OLATResource; public class BinderTemplateHandler implements RepositoryHandler { private static final OLog log = Tracing.createLoggerFor(BinderTemplateHandler.class); - + @Override public boolean isCreate() { return CoreSpringFactory.getImpl(PortfolioV2Module.class).isEnabled(); @@ -109,18 +116,56 @@ public class BinderTemplateHandler implements RepositoryHandler { @Override public ResourceEvaluation acceptImport(File file, String filename) { - return new ResourceEvaluation(false); + return BinderTemplateResource.evaluate(file, filename); } @Override public RepositoryEntry importResource(Identity initialAuthor, String initialAuthorAlt, String displayname, String description, boolean withReferences, Locale locale, File file, String filename) { - return null; + + RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); + PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); + try { + //create resource + OLATResource resource = portfolioService.createBinderTemplateResource(); + OlatRootFolderImpl fResourceRootContainer = FileResourceManager.getInstance().getFileResourceRootImpl(resource); + File fResourceFileroot = fResourceRootContainer.getBasefile(); + File zipRoot = new File(fResourceFileroot, FileResourceManager.ZIPDIR); + FileResource.copyResource(file, filename, zipRoot); + + //create repository entry + RepositoryEntry re = repositoryService.create(initialAuthor, initialAuthorAlt, "", displayname, description, resource, RepositoryEntry.ACC_OWNERS); + + //import binder + File binderFile = new File(zipRoot, BinderTemplateResource.BINDER_XML); + Binder transientBinder = BinderXStream.fromPath(binderFile.toPath()); + + File posterImage = null; + if(StringHelper.containsNonWhitespace(transientBinder.getImagePath())) { + posterImage = new File(zipRoot, transientBinder.getImagePath()); + } + portfolioService.importBinder(transientBinder, re, posterImage); + + RepositoryEntryImportExport rei = new RepositoryEntryImportExport(re, zipRoot); + if(rei.anyExportedPropertiesAvailable()) { + re = rei.importContent(re, fResourceRootContainer.createChildContainer("media")); + } + //delete the imported files + FileUtils.deleteDirsAndFiles(zipRoot, true, true); + return re; + } catch (IOException e) { + log.error("", e); + return null; + } } @Override public RepositoryEntry copy(Identity author, RepositoryEntry source, RepositoryEntry target) { - return null; + PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); + Binder templateSource = portfolioService.getBinderByResource(source.getOlatResource()); + Binder transientCopy = BinderXStream.copy(templateSource); + portfolioService.copyBinder(transientCopy, target); + return target; } @Override @@ -146,12 +191,32 @@ public class BinderTemplateHandler implements RepositoryHandler { @Override public boolean readyToDelete(RepositoryEntry entry, Identity identity, Roles roles, Locale locale, ErrorList errors) { - return false; + PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); + Binder template = portfolioService.getBinderByResource(entry.getOlatResource()); + if(portfolioService.isTemplateInUse(template, null, null)) { + Translator translator = Util.createPackageTranslator(PortfolioHomeController.class, locale); + errors.setError(translator.translate("warning.template.in.use", + new String[] { template.getTitle(), entry.getDisplayname() })); + return false; + } + + String referencesSummary = CoreSpringFactory.getImpl(ReferenceManager.class) + .getReferencesToSummary(entry.getOlatResource(), locale); + if (referencesSummary != null) { + Translator translator = Util.createPackageTranslator(RepositoryManager.class, locale); + errors.setError(translator.translate("details.delete.error.references", + new String[] { referencesSummary, entry.getDisplayname() })); + return false; + } + + return true; } @Override public boolean cleanupOnDelete(RepositoryEntry entry, OLATResourceable res) { - return false; + PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); + Binder template = portfolioService.getBinderByResource(entry.getOlatResource()); + return portfolioService.deleteBinderTemplate(template, entry); } /** @@ -160,17 +225,10 @@ public class BinderTemplateHandler implements RepositoryHandler { */ @Override public MediaResource getAsMediaResource(OLATResourceable res, boolean backwardsCompatible) { - RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntry(res, true); - PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); - Binder template = portfolioService.getBinderByResource(re.getOlatResource()); - - try { - byte[] bytes = BinderXStream.toBytes(template); - return new StreamedMediaResource(new ByteArrayInputStream(bytes), "binder.zip", "application/zip", new Long(bytes.length), null); - } catch (IOException e) { - log.error("", e); - return null; - } + RepositoryEntry templateEntry = RepositoryManager.getInstance().lookupRepositoryEntry(res, true); + Binder template = CoreSpringFactory.getImpl(PortfolioService.class) + .getBinderByResource(templateEntry.getOlatResource()); + return new BinderTemplateMediaResource(template, templateEntry); } @Override diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateMediaResource.java b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateMediaResource.java new file mode 100644 index 00000000000..63e0efcaba8 --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateMediaResource.java @@ -0,0 +1,113 @@ +package org.olat.modules.portfolio.handler; + +import java.io.File; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.io.FileUtils; +import org.olat.core.CoreSpringFactory; +import org.olat.core.gui.media.MediaResource; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.StringHelper; +import org.olat.core.util.io.ShieldOutputStream; +import org.olat.fileresource.FileResourceManager; +import org.olat.modules.portfolio.Binder; +import org.olat.modules.portfolio.BinderRef; +import org.olat.modules.portfolio.PortfolioService; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryEntryImportExport; +import org.olat.resource.OLATResource; + +/** + * + * Initial date: 08.07.2016<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class BinderTemplateMediaResource implements MediaResource { + + private static final OLog log = Tracing.createLoggerFor(BinderTemplateMediaResource.class); + + private final BinderRef template; + private final RepositoryEntry templateEntry; + + public BinderTemplateMediaResource(BinderRef template, RepositoryEntry templateEntry) { + this.template = template; + this.templateEntry = templateEntry; + } + + @Override + public boolean acceptRanges() { + return false; + } + + @Override + public String getContentType() { + return "application/zip"; + } + + @Override + public Long getSize() { + return null; + } + + @Override + public InputStream getInputStream() { + return null; + } + + @Override + public Long getLastModified() { + return null; + } + + @Override + public void release() { + // + } + + @Override + public void prepare(HttpServletResponse hres) { + try { + hres.setCharacterEncoding("UTF-8"); + } catch (Exception e) { + log.error("", e); + } + + try(ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) { + PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); + Binder loadedTemplate = portfolioService.getBinderByKey(template.getKey()); + String label = loadedTemplate.getTitle(); + String secureLabel = StringHelper.transformDisplayNameToFileSystemName(label); + + String file = secureLabel + ".zip"; + hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + StringHelper.urlEncodeUTF8(file)); + hres.setHeader("Content-Description", StringHelper.urlEncodeUTF8(label)); + + zout.setLevel(9); + zout.putNextEntry(new ZipEntry("binder.xml")); + BinderXStream.toStream(loadedTemplate, zout); + zout.closeEntry(); + + if(StringHelper.containsNonWhitespace(loadedTemplate.getImagePath())) { + File posterImage = portfolioService.getPosterImageFile(loadedTemplate); + if(posterImage.exists()) { + zout.putNextEntry(new ZipEntry(loadedTemplate.getImagePath())); + FileUtils.copyFile(posterImage, new ShieldOutputStream(zout)); + zout.closeEntry(); + } + } + + OLATResource resource = templateEntry.getOlatResource(); + File baseContainer= FileResourceManager.getInstance().getFileResource(resource); + RepositoryEntryImportExport importExport = new RepositoryEntryImportExport(templateEntry, baseContainer); + importExport.exportDoExportProperties(zout); + } catch (Exception e) { + log.error("", e); + } + } +} diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java index f5737b0303a..7eb16f26d0d 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java +++ b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java @@ -20,8 +20,20 @@ package org.olat.modules.portfolio.handler; 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.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.fileresource.types.FileResource; +import org.olat.fileresource.types.ResourceEvaluation; +import org.olat.repository.RepositoryEntryImportExport; +import org.olat.repository.RepositoryEntryImportExport.RepositoryEntryImport; /** * @@ -33,7 +45,10 @@ import org.olat.fileresource.types.FileResource; */ public class BinderTemplateResource extends FileResource { + private static final OLog log = Tracing.createLoggerFor(BinderTemplateResource.class); + public static final String TYPE_NAME = "BinderTemplate"; + public static final String BINDER_XML = "binder.xml"; /** * @param f @@ -42,8 +57,53 @@ public class BinderTemplateResource extends FileResource { public static boolean validate(File f) { if(f.isDirectory()) { //unzip directory - return new File(f, "map.xml").exists(); + return new File(f, BINDER_XML).exists(); + } + return f.getName().toLowerCase().endsWith(BINDER_XML); + } + + public static ResourceEvaluation evaluate(File file, String filename) { + ResourceEvaluation eval = new ResourceEvaluation(); + try { + BinderFileFilter visitor = new BinderFileFilter(); + Path fPath = PathUtils.visit(file, filename, visitor); + + if(visitor.isValid()) { + eval.setValid(true); + Path repoXml = fPath.resolve(RepositoryEntryImportExport.PROPERTIES_FILE); + if(Files.exists(repoXml)) { + RepositoryEntryImport re = RepositoryEntryImportExport.getConfiguration(repoXml); + if(re != null) { + eval.setDisplayname(re.getDisplayname()); + eval.setDescription(re.getDescription()); + } + } + } else { + eval.setValid(false); + } + } catch (IOException e) { + log.error("", e); + eval.setValid(false); + } + return eval; + } + + private static class BinderFileFilter extends SimpleFileVisitor<Path> { + private boolean binderFile; + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + + String filename = file.getFileName().toString(); + if(BINDER_XML.equals(filename)) { + binderFile = true; + } + return binderFile ? FileVisitResult.TERMINATE : FileVisitResult.CONTINUE; + } + + public boolean isValid() { + return binderFile; } - return f.getName().toLowerCase().endsWith("map.xml"); } } diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderXStream.java b/src/main/java/org/olat/modules/portfolio/handler/BinderXStream.java index f2dd5a97752..77e4e6f4562 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/BinderXStream.java +++ b/src/main/java/org/olat/modules/portfolio/handler/BinderXStream.java @@ -1,12 +1,14 @@ package org.olat.modules.portfolio.handler; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.zip.ZipEntry; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.zip.ZipOutputStream; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.io.ShieldOutputStream; import org.olat.core.util.xml.XStreamHelper; import org.olat.modules.portfolio.Binder; @@ -24,21 +26,29 @@ public class BinderXStream { private static final XStream myStream = XStreamHelper.createXStreamInstanceForDBObjects(); - public static final byte[] toBytes(Binder binder) + + public static final Binder copy(Binder binder) { + String stringuified = myStream.toXML(binder); + Binder copiedBinder = (Binder)myStream.fromXML(stringuified); + return copiedBinder; + } + + public static final Binder fromPath(Path path) + throws IOException { + try(InputStream inStream = Files.newInputStream(path)) { + return (Binder)myStream.fromXML(inStream); + } catch (Exception e) { + log.error("Cannot import this map: " + path, e); + return null; + } + } + + public static final void toStream(Binder binder, ZipOutputStream zout) throws IOException { - try(ByteArrayOutputStream out = new ByteArrayOutputStream(); - ZipOutputStream zipOut = new ZipOutputStream(out);) { - //prepare a zip - - zipOut.putNextEntry(new ZipEntry("binder.xml")); - myStream.toXML(binder, zipOut); - zipOut.closeEntry(); - zipOut.close(); - - return out.toByteArray(); - } catch (IOException e) { + try { + myStream.toXML(binder, new ShieldOutputStream(zout)); + } catch (Exception e) { log.error("Cannot export this map: " + binder, e); - return null; } } diff --git a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java index 36c0ce0c9e4..a5b0d13b4d0 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java +++ b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java @@ -197,6 +197,26 @@ public class BinderDAO { .getResultList(); } + public void detachBinderTemplate() { + //unlink entry + //unlink template + } + + public int deleteBinderTemplate(Binder binder) { + String sectionQ = "delete from pfsection section where section.binder.key=:binderKey"; + int sections = dbInstance.getCurrentEntityManager() + .createQuery(sectionQ) + .setParameter("binderKey", binder.getKey()) + .executeUpdate(); + + String binderQ = "delete from pfbinder binder where binder.key=:binderKey"; + int binders = dbInstance.getCurrentEntityManager() + .createQuery(binderQ) + .setParameter("binderKey", binder.getKey()) + .executeUpdate(); + return sections + binders; + } + /** * The same type of query is user for the categories * @param owner diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java index cf7dab3614e..2ae11cd9d86 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java @@ -162,6 +162,45 @@ public class PortfolioServiceImpl implements PortfolioService { return binderDao.updateBinder(binder); } + @Override + public Binder copyBinder(Binder transientBinder, RepositoryEntry entry) { + String imagePath = null; + if(StringHelper.containsNonWhitespace(transientBinder.getImagePath())) { + File bcroot = portfolioFileStorage.getRootDirectory(); + File image = new File(bcroot, transientBinder.getImagePath()); + if(image.exists()) { + imagePath = addPosterImageForBinder(image, image.getName()); + } + } + return internalCopyTransientBinder(transientBinder, entry, imagePath); + } + + @Override + public Binder importBinder(Binder transientBinder, RepositoryEntry templateEntry, File image) { + String imagePath = null; + if(StringHelper.containsNonWhitespace(transientBinder.getImagePath())) { + imagePath = addPosterImageForBinder(image, image.getName()); + } + return internalCopyTransientBinder(transientBinder, templateEntry, imagePath); + } + + private Binder internalCopyTransientBinder(Binder transientBinder, RepositoryEntry entry, String imagePath) { + Binder binder = binderDao.createAndPersist(transientBinder.getTitle(), transientBinder.getSummary(), imagePath, entry); + //copy sections + for(Section transientSection:((BinderImpl)transientBinder).getSections()) { + binderDao.createSection(transientSection.getTitle(), transientSection.getDescription(), + transientSection.getBeginDate(), transientSection.getEndDate(), binder); + } + return binder; + } + + @Override + public boolean deleteBinderTemplate(Binder binder, RepositoryEntry templateEntry) { + binderDao.detachBinderTemplate(); + int deletedRows = binderDao.deleteBinderTemplate(binder); + return deletedRows > 0; + } + @Override public void appendNewSection(String title, String description, Date begin, Date end, BinderRef binder) { Binder reloadedBinder = binderDao.loadByKey(binder.getKey()); @@ -458,6 +497,9 @@ public class PortfolioServiceImpl implements PortfolioService { @Override public String addPosterImageForBinder(File file, String filename) { File dir = portfolioFileStorage.generateBinderSubDirectory(); + if(!StringHelper.containsNonWhitespace(filename)) { + filename = file.getName(); + } File destinationFile = new File(dir, filename); String renamedFile = FileUtils.rename(destinationFile); if(renamedFile != null) { diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties index 3c88b5a94c3..52e0c8fae67 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties @@ -185,3 +185,4 @@ timeline.switch.on=Timeline timeline.switch.off=Timeline warning.binder.synched=Die Portfolio Mappe wurde mit seiner Vorlage synchroniziert. warning.portfolio.not.found=Die Portfolio Mappe konnte nicht gefunden werden. Sie wurde wahrscheinlich gel\u00F6scht. +warning.template.in.use=Die Vorlage konnte nicht gelöscht werden weil einige Benutzer es nutzt. diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties index 4814d2030ee..00006d2665e 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties @@ -184,4 +184,5 @@ title=Title timeline.switch.on=Timeline timeline.switch.off=Timeline warning.binder.synched=The binder is synchronized with its template. +warning.template.in.use=The template cannot deleted because some users use it. warning.portfolio.not.found=The portfolio cannot be found, probably deleted in the mean time diff --git a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java index 423e326a164..b1ae92d834a 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java +++ b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java @@ -34,6 +34,8 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; @@ -46,6 +48,7 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.io.HttpServletResponseOutputStream; +import org.olat.core.util.io.ShieldOutputStream; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; @@ -153,6 +156,39 @@ public class RepositoryEntryImportExport { FileUtils.closeSafely(fOut); } } + + public void exportDoExportProperties(ZipOutputStream zout) throws IOException { + RepositoryEntryImport imp = new RepositoryEntryImport(re); + RepositoryManager rm = RepositoryManager.getInstance(); + VFSLeaf image = rm.getImage(re); + if(image != null) { + imp.setImageName(image.getName()); + zout.putNextEntry(new ZipEntry(image.getName())); + try(InputStream inImage=image.getInputStream()) { + FileUtils.copy(inImage, new ShieldOutputStream(zout)); + } catch(Exception e) { + log.error("", e); + } + zout.closeEntry(); + } + + RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); + VFSLeaf movie = repositoryService.getIntroductionMovie(re); + if(movie != null) { + imp.setMovieName(movie.getName()); + zout.putNextEntry(new ZipEntry(movie.getName())); + try(InputStream inMovie=movie.getInputStream()) { + FileUtils.copy(inMovie, new ShieldOutputStream(zout)); + } catch(Exception e) { + log.error("", e); + } + zout.closeEntry(); + } + + zout.putNextEntry(new ZipEntry(PROPERTIES_FILE)); + getXStream().toXML(imp, new ShieldOutputStream(zout)); + zout.closeEntry(); + } /** * Export a repository entry referenced by a course node to the given export directory. diff --git a/src/main/java/org/olat/repository/handlers/RepositoryHandler.java b/src/main/java/org/olat/repository/handlers/RepositoryHandler.java index 1d4427f91b4..e4c1779091c 100644 --- a/src/main/java/org/olat/repository/handlers/RepositoryHandler.java +++ b/src/main/java/org/olat/repository/handlers/RepositoryHandler.java @@ -106,7 +106,7 @@ public interface RepositoryHandler { * * @param source * @param target - * @return + * @return The target repository entry */ public RepositoryEntry copy(Identity author, RepositoryEntry source, RepositoryEntry target); -- GitLab