From 613bcaf36a93a658ad4c73decf2c3f96e638396e Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Fri, 9 May 2014 08:48:17 +0200 Subject: [PATCH] OO-990: authoring details and settings --- .../java/org/olat/core/util/PathUtils.java | 38 ++ .../course/nodes/AbstractFeedCourseNode.java | 22 +- .../org/olat/course/nodes/CPCourseNode.java | 14 +- .../olat/course/nodes/IQSELFCourseNode.java | 12 +- .../olat/course/nodes/IQSURVCourseNode.java | 17 +- .../olat/course/nodes/IQTESTCourseNode.java | 14 +- .../course/nodes/PortfolioCourseNode.java | 7 +- .../olat/course/nodes/ScormCourseNode.java | 20 +- .../org/olat/course/nodes/WikiCourseNode.java | 12 +- .../course/nodes/wiki/WikiEditController.java | 36 +- .../olat/course/run/RunMainController.java | 3 +- .../types/AnimationFileResource.java | 7 +- .../fileresource/types/CourseResource.java | 70 ---- .../fileresource/types/DocFileResource.java | 7 +- .../fileresource/types/FeedFileResource.java | 7 +- .../olat/fileresource/types/FileResource.java | 31 +- .../fileresource/types/GlossaryResource.java | 8 +- .../fileresource/types/ImageFileResource.java | 7 +- .../fileresource/types/ImsCPFileResource.java | 5 +- .../fileresource/types/MovieFileResource.java | 7 +- .../fileresource/types/PdfFileResource.java | 7 +- .../types/PowerpointFileResource.java | 7 +- .../types/ScormCPFileResource.java | 5 +- .../types/SharedFolderFileResource.java | 5 +- .../fileresource/types/SoundFileResource.java | 7 +- .../olat/fileresource/types/WikiResource.java | 5 +- .../fileresource/types/XlsFileResource.java | 7 +- .../qti/fileresource/SurveyFileResource.java | 5 +- .../qti/fileresource/TestFileResource.java | 5 +- .../repository/RepositoryEntryAuthorView.java | 2 + .../RepositoryEntryImportExport.java | 16 +- ...SearchAuthorRepositoryEntryViewParams.java | 32 +- .../repository/_spring/repositoryContext.xml | 2 +- .../ReferencableEntriesSearchController.java | 2 +- .../repository/handlers/CourseHandler.java | 70 +++- .../handlers/RepositoryHandlerFactory.java | 24 +- .../RepositoryEntryAuthorViewQueries.java | 24 ++ .../model/RepositoryEntryAuthorViewImpl.java | 8 +- .../ui/author/AuthorListController.java | 10 +- .../ui/author/AuthorSearchController.java | 127 ++---- .../author/AuthoringEditEntryController.java | 2 +- .../AuthoringEntryDetailsController.java | 391 ++++++++++++++++-- .../author/CopyRepositoryEntryController.java | 13 +- .../ImportRepositoryEntryController.java | 2 +- .../author/OverviewAuthoringController.java | 12 +- .../repository/ui/author/SearchEvent.java | 25 +- .../database/mysql/alter_9_4_0_to_10_0_0.sql | 1 + .../database/mysql/setupDatabase.sql | 1 + .../postgresql/alter_9_4_0_to_10_0_0.sql | 1 + .../services/webdav/WebDAVExternalTest.java | 19 + 50 files changed, 740 insertions(+), 441 deletions(-) create mode 100644 src/main/java/org/olat/core/util/PathUtils.java delete mode 100644 src/main/java/org/olat/fileresource/types/CourseResource.java diff --git a/src/main/java/org/olat/core/util/PathUtils.java b/src/main/java/org/olat/core/util/PathUtils.java new file mode 100644 index 00000000000..eb7b67f08e8 --- /dev/null +++ b/src/main/java/org/olat/core/util/PathUtils.java @@ -0,0 +1,38 @@ +package org.olat.core.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * + * Initial date: 08.05.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class PathUtils { + + public static Path visit(File file, String filename, FileVisitor<Path> visitor) + throws IOException { + if(!StringHelper.containsNonWhitespace(filename)) { + filename = file.getName(); + } + + Path fPath = null; + if(file.isDirectory()) { + fPath = file.toPath(); + } else if(filename != null && filename.toLowerCase().endsWith(".zip")) { + fPath = FileSystems.newFileSystem(file.toPath(), null).getPath("/"); + } else { + fPath = file.toPath(); + } + if(fPath != null) { + Files.walkFileTree(fPath, visitor); + } + return fPath; + } + +} diff --git a/src/main/java/org/olat/course/nodes/AbstractFeedCourseNode.java b/src/main/java/org/olat/course/nodes/AbstractFeedCourseNode.java index d336c793cd6..ee15f1b6eb4 100644 --- a/src/main/java/org/olat/course/nodes/AbstractFeedCourseNode.java +++ b/src/main/java/org/olat/course/nodes/AbstractFeedCourseNode.java @@ -20,17 +20,11 @@ package org.olat.course.nodes; import java.io.File; -import java.util.Date; import java.util.Locale; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; -import org.olat.core.id.OLATResourceable; -import org.olat.core.util.Formatter; -import org.olat.core.util.vfs.LocalFolderImpl; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSLeaf; import org.olat.course.ICourse; import org.olat.course.condition.Condition; import org.olat.course.condition.interpreter.ConditionInterpreter; @@ -243,18 +237,20 @@ public abstract class AbstractFeedCourseNode extends GenericCourseNode { } public void importNode(RepositoryHandler handler, File importDirectory, Identity owner, Locale locale) { - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if (rie.anyExportedPropertiesAvailable()) { + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - FeedNodeEditController.setReference(re, getModuleConfiguration()); + FeedNodeEditController.setReference(re, getModuleConfiguration()); + } } /** * @see org.olat.course.nodes.GenericCourseNode#archiveNodeData(java.util.Locale, * org.olat.course.ICourse, java.io.File, java.lang.String) - */ - public void archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset, String type) { + *//* + @Override + public boolean archiveNodeData(Locale locale, ICourse course, ArchiveOptions options, ZipOutputStream exportStream, String charset) { VFSContainer exportContainer = new LocalFolderImpl(exportDirectory); VFSContainer exportDir = (VFSContainer) exportContainer.resolve(type); if (exportDir == null) { @@ -273,5 +269,5 @@ public abstract class AbstractFeedCourseNode extends GenericCourseNode { } // FIXME:FG:6.3 Archive user comments as soon as implemented. } - } + }*/ } diff --git a/src/main/java/org/olat/course/nodes/CPCourseNode.java b/src/main/java/org/olat/course/nodes/CPCourseNode.java index 3c71dc66b66..8b31557fd95 100644 --- a/src/main/java/org/olat/course/nodes/CPCourseNode.java +++ b/src/main/java/org/olat/course/nodes/CPCourseNode.java @@ -291,13 +291,13 @@ public class CPCourseNode extends AbstractAccessableCourseNode { @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(ImsCPFileResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), - locale, rie.importGetExportedFile(), null); - CPEditController.setCPReference(re, getModuleConfiguration()); + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(ImsCPFileResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + locale, rie.importGetExportedFile(), null); + CPEditController.setCPReference(re, getModuleConfiguration()); + } } @Override diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java index ced23c6c525..33f76df1fef 100644 --- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java @@ -246,13 +246,13 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(TestFileResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(TestFileResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - IQEditController.setIQReference(re, getModuleConfiguration()); + IQEditController.setIQReference(re, getModuleConfiguration()); + } } @Override diff --git a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java index 7e74a3f7704..eab9b1cb8e3 100644 --- a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java @@ -271,10 +271,7 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT } } - /** - * @see org.olat.course.nodes.GenericCourseNode#exportNode(java.io.File, - * org.olat.course.ICourse) - */ + @Override public void exportNode(File exportDirectory, ICourse course) { String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY); if (repositorySoftKey == null) return; // nothing to export @@ -293,13 +290,13 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(SurveyFileResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(SurveyFileResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - IQEditController.setIQReference(re, getModuleConfiguration()); + IQEditController.setIQReference(re, getModuleConfiguration()); + } } @Override diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java index 88f580666f8..60f8f5dc122 100644 --- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java @@ -68,7 +68,7 @@ import org.olat.ims.qti.QTIResultSet; import org.olat.ims.qti.export.QTIExportFormatter; import org.olat.ims.qti.export.QTIExportFormatterCSVType1; import org.olat.ims.qti.export.QTIExportManager; -import org.olat.ims.qti.fileresource.SurveyFileResource; +import org.olat.ims.qti.fileresource.TestFileResource; import org.olat.ims.qti.process.AssessmentInstance; import org.olat.ims.qti.statistics.QTIStatisticResourceResult; import org.olat.ims.qti.statistics.QTIStatisticSearchParams; @@ -470,13 +470,13 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements As @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(SurveyFileResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(TestFileResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - IQEditController.setIQReference(re, getModuleConfiguration()); + IQEditController.setIQReference(re, getModuleConfiguration()); + } } /** diff --git a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java index ac11b59849f..9f6c478dc71 100644 --- a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java +++ b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java @@ -94,7 +94,7 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements ModuleConfiguration config = getModuleConfiguration(); if (isNewNode) { MSCourseNode.initDefaultConfig(config); - config.setConfigurationVersion(CURRENT_CONFIG_VERSION); + config.setConfigurationVersion(CURRENT_CONFIG_VERSION); } if (config.getConfigurationVersion() < 2) { if(config.get(PortfolioCourseNodeConfiguration.REPO_SOFT_KEY) == null) { @@ -105,7 +105,7 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements config.set(PortfolioCourseNodeConfiguration.REPO_SOFT_KEY, re.getSoftkey()); } } - config.setConfigurationVersion(2); + config.setConfigurationVersion(2); } } @@ -421,8 +421,7 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); if (rie.anyExportedPropertiesAvailable()) { RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(EPTemplateMapResource.TYPE_NAME); RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), diff --git a/src/main/java/org/olat/course/nodes/ScormCourseNode.java b/src/main/java/org/olat/course/nodes/ScormCourseNode.java index 8c2e2b39f4b..c29715d6f7d 100644 --- a/src/main/java/org/olat/course/nodes/ScormCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ScormCourseNode.java @@ -326,13 +326,13 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Ass @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(ScormCPFileResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(ScormCPFileResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - ScormEditController.setScormCPReference(re, getModuleConfiguration()); + ScormEditController.setScormCPReference(re, getModuleConfiguration()); + } } @Override @@ -353,18 +353,14 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Ass return true; } - /** - * @see org.olat.course.nodes.CourseNode#createInstanceForCopy() - */ + @Override public CourseNode createInstanceForCopy() { CourseNode copyInstance = super.createInstanceForCopy(); CPEditController.removeCPReference(copyInstance.getModuleConfiguration()); return copyInstance; } - /** - * @see org.olat.course.nodes.AssessableCourseNode#getUserScoreEvaluation(org.olat.course.run.userview.UserCourseEnvironment) - */ + @Override public ScoreEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnvironment) { // read score from properties save score, passed and attempts information AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); diff --git a/src/main/java/org/olat/course/nodes/WikiCourseNode.java b/src/main/java/org/olat/course/nodes/WikiCourseNode.java index fbc71010327..64186e18bab 100644 --- a/src/main/java/org/olat/course/nodes/WikiCourseNode.java +++ b/src/main/java/org/olat/course/nodes/WikiCourseNode.java @@ -209,13 +209,13 @@ public class WikiCourseNode extends AbstractAccessableCourseNode { @Override public void importNode(File importDirectory, ICourse course, Identity owner, Locale locale) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(WikiResource.TYPE_NAME); - - File importSubdir = new File(importDirectory, getIdent()); - RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importSubdir); - RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), + RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent()); + if(rie.anyExportedPropertiesAvailable()) { + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(WikiResource.TYPE_NAME); + RepositoryEntry re = handler.importResource(owner, rie.getDisplayName(), rie.getDescription(), locale, rie.importGetExportedFile(), null); - WikiEditController.setWikiRepoReference(re, getModuleConfiguration()); + WikiEditController.setWikiRepoReference(re, getModuleConfiguration()); + } } @Override diff --git a/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java b/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java index 85b3b04ebc4..4847a5ab2d5 100644 --- a/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java +++ b/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java @@ -25,11 +25,8 @@ package org.olat.course.nodes.wiki; -import java.util.List; - import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; @@ -41,13 +38,8 @@ import org.olat.core.gui.control.ControllerEventListener; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; -import org.olat.core.gui.control.generic.dtabs.DTab; -import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.tabbable.ActivateableTabbableDefaultController; import org.olat.core.id.Identity; -import org.olat.core.id.OLATResourceable; -import org.olat.core.id.context.BusinessControlFactory; -import org.olat.core.id.context.ContextEntry; import org.olat.core.logging.AssertException; import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentHelper; @@ -68,8 +60,6 @@ import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.controllers.ReferencableEntriesSearchController; import org.olat.repository.controllers.RepositoryDetailsController; -import org.olat.repository.handlers.RepositoryHandler; -import org.olat.repository.handlers.RepositoryHandlerFactory; /** * Description: <BR/>Edit controller for single page course nodes <P/> Initial @@ -212,32 +202,8 @@ public class WikiEditController extends ActivateableTabbableDefaultController im // do nothing return; } - RepositoryHandler typeToEdit = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry); - // Open editor in new tab - OLATResourceable ores = repositoryEntry.getOlatResource(); - DTabs dts = Windows.getWindows(ureq).getWindow(ureq).getDTabs(); - DTab dt = dts.getDTab(ores); - if (dt == null) { - // does not yet exist -> create and add - //fxdiff BAKS-7 Resume function - dt = dts.createDTab(ores, repositoryEntry, repositoryEntry.getDisplayname()); - if (dt == null){ - //null means DTabs are full -> warning is shown - return; - } - //user activity logger is set by course factory - Controller editorController = typeToEdit.createLaunchController(repositoryEntry, ureq, dt.getWindowControl()); - if(editorController == null){ - //editor could not be created -> warning is shown - return; - } - dt.setController(editorController); - dts.addDTab(ureq, dt); - } - List<ContextEntry> entries = BusinessControlFactory.getInstance().createCEListFromResourceType(RepositoryDetailsController.ACTIVATE_EDITOR); - dts.activate(ureq, dt, entries); + RepositoryDetailsController.doEdit(ureq, repositoryEntry); } - } /** diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index 489d758554f..311c882206b 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -140,7 +140,6 @@ import org.olat.repository.RepositoryEntryStatus; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; import org.olat.repository.controllers.EntryChangedEvent; -import org.olat.repository.controllers.RepositoryDetailsController; import org.olat.repository.ui.list.RepositoryEntryDetailsController; import org.olat.repository.ui.list.RepositoryEntryRow; import org.olat.resource.OLATResource; @@ -1385,7 +1384,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene } catch (OLATSecurityException e) { //the wrong link to the wrong person } - } else if("Editor".equalsIgnoreCase(type) || RepositoryDetailsController.ACTIVATE_EDITOR.equalsIgnoreCase(type)) { + } else if("Editor".equalsIgnoreCase(type) || "activateEditor".equalsIgnoreCase(type)) { // Nothing to do if already in editor. Can happen when editor is // triggered externally, e.g. from the details page while user has // the editor already open diff --git a/src/main/java/org/olat/fileresource/types/AnimationFileResource.java b/src/main/java/org/olat/fileresource/types/AnimationFileResource.java index 82b0ba15b63..f7599b6bf1e 100644 --- a/src/main/java/org/olat/fileresource/types/AnimationFileResource.java +++ b/src/main/java/org/olat/fileresource/types/AnimationFileResource.java @@ -39,10 +39,9 @@ public class AnimationFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.ANIM"; - /** - * Default constructor. - */ - public AnimationFileResource() { super.setTypeName(TYPE_NAME); } + public AnimationFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/CourseResource.java b/src/main/java/org/olat/fileresource/types/CourseResource.java deleted file mode 100644 index 963f980874e..00000000000 --- a/src/main/java/org/olat/fileresource/types/CourseResource.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.olat.fileresource.types; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileVisitResult; -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.repository.RepositoryEntryImportExport; -import org.olat.repository.RepositoryEntryImportExport.RepositoryEntryImport; - -public class CourseResource extends FileResource { - - private static final OLog log = Tracing.createLoggerFor(CourseResource.class); - - public static final String TYPE_NAME = "CourseModule"; - public static final String EDITOR_XML = "editortreemodel.xml"; - - public CourseResource() { - setTypeName(TYPE_NAME); - } - - public static ResourceEvaluation evaluate(File file, String filename) { - ResourceEvaluation eval = new ResourceEvaluation(); - try { - IndexFileFilter visitor = new IndexFileFilter(); - Path fPath = visit(file, filename, visitor); - - if(visitor.isValid()) { - Path repoXml = fPath.resolve("export/repo.xml"); - if(repoXml != null) { - eval.setValid(true); - - RepositoryEntryImport re = RepositoryEntryImportExport.getConfiguration(repoXml); - if(re != null) { - eval.setDisplayname(re.getDisplayname()); - eval.setDescription(re.getDescription()); - } - } - } - eval.setValid(visitor.isValid()); - } catch (IOException e) { - log.error("", e); - } - return eval; - } - - private static class IndexFileFilter extends SimpleFileVisitor<Path> { - private boolean editorFile; - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - - String filename = file.getFileName().toString(); - if(EDITOR_XML.equals(filename)) { - editorFile = true; - } - return editorFile ? FileVisitResult.TERMINATE : FileVisitResult.CONTINUE; - } - - public boolean isValid() { - return editorFile; - } - } - -} diff --git a/src/main/java/org/olat/fileresource/types/DocFileResource.java b/src/main/java/org/olat/fileresource/types/DocFileResource.java index 8e974170835..9120b3cb462 100644 --- a/src/main/java/org/olat/fileresource/types/DocFileResource.java +++ b/src/main/java/org/olat/fileresource/types/DocFileResource.java @@ -39,10 +39,9 @@ public class DocFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.DOC"; - /** - * Standard constructor. - */ - public DocFileResource() { super.setTypeName(TYPE_NAME); } + public DocFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/FeedFileResource.java b/src/main/java/org/olat/fileresource/types/FeedFileResource.java index 22d751e1643..74234de258d 100644 --- a/src/main/java/org/olat/fileresource/types/FeedFileResource.java +++ b/src/main/java/org/olat/fileresource/types/FeedFileResource.java @@ -29,6 +29,7 @@ import java.util.List; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; @@ -50,11 +51,11 @@ public abstract class FeedFileResource extends FileResource { private static final OLog log = Tracing.createLoggerFor(FeedFileResource.class); public FeedFileResource(String type) { - super.setTypeName(type); + super(type); } public FeedFileResource(File root, File resourceFolder, String type) { - super.setTypeName(type); + super(type); // After unziping the uploaded folder, I would like to copy it to the // appropriate location right away (and not on the next read). So, I put the // code here. Note that this constructor is also called on copying a @@ -84,7 +85,7 @@ public abstract class FeedFileResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { IndexFileFilter visitor = new IndexFileFilter(); - Path fPath = visit(file, filename, visitor); + Path fPath = PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { Path feedXml = fPath.resolve(FeedManager.FEED_FILE_NAME); diff --git a/src/main/java/org/olat/fileresource/types/FileResource.java b/src/main/java/org/olat/fileresource/types/FileResource.java index 43f8cdf87e5..6b597238912 100644 --- a/src/main/java/org/olat/fileresource/types/FileResource.java +++ b/src/main/java/org/olat/fileresource/types/FileResource.java @@ -29,7 +29,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; -import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.PathMatcher; @@ -57,7 +56,7 @@ public class FileResource implements OLATResourceable { * Generic file resource type identifier. */ public static final String GENERIC_TYPE_NAME = "FileResource.FILE"; - private String typeName; + private final String typeName; private Long typeId; public FileResource() { @@ -70,14 +69,6 @@ public class FileResource implements OLATResourceable { typeId = new Long(CodeHelper.getForeverUniqueID()); } - /** - * User by subtypes to set appropriate ResourceableTypeName - * @param newTypeName - */ - protected void setTypeName(String newTypeName) { - typeName = newTypeName; - } - /** * Only used internally when switching subtypes. * @param newId @@ -100,25 +91,7 @@ public class FileResource implements OLATResourceable { return typeId; } - protected static Path visit(File file, String filename, FileVisitor<Path> visitor) - throws IOException { - if(!StringHelper.containsNonWhitespace(filename)) { - filename = file.getName(); - } - - Path fPath = null; - if(file.isDirectory()) { - fPath = file.toPath(); - } else if(filename != null && filename.toLowerCase().endsWith(".zip")) { - fPath = FileSystems.newFileSystem(file.toPath(), null).getPath("/"); - } else { - fPath = file.toPath(); - } - if(fPath != null) { - Files.walkFileTree(fPath, visitor); - } - return fPath; - } + /** * This method open a new FileSystem for zip diff --git a/src/main/java/org/olat/fileresource/types/GlossaryResource.java b/src/main/java/org/olat/fileresource/types/GlossaryResource.java index 371105483fe..4af7d53aae9 100644 --- a/src/main/java/org/olat/fileresource/types/GlossaryResource.java +++ b/src/main/java/org/olat/fileresource/types/GlossaryResource.java @@ -35,6 +35,7 @@ import java.nio.file.attribute.BasicFileAttributes; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; /** * Description:<br> @@ -62,11 +63,8 @@ public class GlossaryResource extends FileResource { } }; - /** - * Constructor - */ public GlossaryResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** @@ -91,7 +89,7 @@ public class GlossaryResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { GlossaryFileFilter visitor = new GlossaryFileFilter(); - visit(file, filename, visitor); + PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { eval.setValid(true); } diff --git a/src/main/java/org/olat/fileresource/types/ImageFileResource.java b/src/main/java/org/olat/fileresource/types/ImageFileResource.java index 7918e481529..6303beea540 100644 --- a/src/main/java/org/olat/fileresource/types/ImageFileResource.java +++ b/src/main/java/org/olat/fileresource/types/ImageFileResource.java @@ -39,10 +39,9 @@ public class ImageFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.IMAGE"; - /** - * Standard constructor. - */ - public ImageFileResource() { super.setTypeName(TYPE_NAME); } + public ImageFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java b/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java index 365a19eba42..46a6e79e1f5 100644 --- a/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java +++ b/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java @@ -41,6 +41,7 @@ import org.dom4j.Element; import org.dom4j.XPath; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.ims.resources.IMSLoader; /** @@ -59,7 +60,7 @@ public class ImsCPFileResource extends FileResource { public static final String TYPE_NAME = "FileResource.IMSCP"; public ImsCPFileResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** @@ -83,7 +84,7 @@ public class ImsCPFileResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { ImsManifestFileFilter visitor = new ImsManifestFileFilter(); - Path fPath = visit(file, filename, visitor); + Path fPath = PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { Path manifestPath = fPath.resolve(IMS_MANIFEST); Document doc = IMSLoader.loadIMSDocument(manifestPath); diff --git a/src/main/java/org/olat/fileresource/types/MovieFileResource.java b/src/main/java/org/olat/fileresource/types/MovieFileResource.java index b14775bf5d6..63096b31094 100644 --- a/src/main/java/org/olat/fileresource/types/MovieFileResource.java +++ b/src/main/java/org/olat/fileresource/types/MovieFileResource.java @@ -39,10 +39,9 @@ public class MovieFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.MOVIE"; - /** - * Standard constructor. - */ - public MovieFileResource() { super.setTypeName(TYPE_NAME); } + public MovieFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/PdfFileResource.java b/src/main/java/org/olat/fileresource/types/PdfFileResource.java index 5996e9d8602..0e95f74ef04 100644 --- a/src/main/java/org/olat/fileresource/types/PdfFileResource.java +++ b/src/main/java/org/olat/fileresource/types/PdfFileResource.java @@ -39,10 +39,9 @@ public class PdfFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.PDF"; - /** - * Standard constructor. - */ - public PdfFileResource() { super.setTypeName(TYPE_NAME); } + public PdfFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/PowerpointFileResource.java b/src/main/java/org/olat/fileresource/types/PowerpointFileResource.java index 20e7bd5af90..b54cac04bd5 100644 --- a/src/main/java/org/olat/fileresource/types/PowerpointFileResource.java +++ b/src/main/java/org/olat/fileresource/types/PowerpointFileResource.java @@ -39,10 +39,9 @@ public class PowerpointFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.PPT"; - /** - * Standard constructor. - */ - public PowerpointFileResource() { super.setTypeName(TYPE_NAME); } + public PowerpointFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java b/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java index d058af54668..fc9c3294fd6 100644 --- a/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java +++ b/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java @@ -45,6 +45,7 @@ import org.dom4j.Namespace; import org.dom4j.XPath; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.ims.resources.IMSLoader; /** @@ -64,7 +65,7 @@ public class ScormCPFileResource extends FileResource { public ScormCPFileResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** @@ -83,7 +84,7 @@ public class ScormCPFileResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { ImsManifestFileFilter visitor = new ImsManifestFileFilter(); - Path fPath = visit(file, filename, visitor); + Path fPath = PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { Path manifestPath = fPath.resolve(IMS_MANIFEST); Document doc = IMSLoader.loadIMSDocument(manifestPath); diff --git a/src/main/java/org/olat/fileresource/types/SharedFolderFileResource.java b/src/main/java/org/olat/fileresource/types/SharedFolderFileResource.java index a6d7fa3e0aa..fe438a29191 100644 --- a/src/main/java/org/olat/fileresource/types/SharedFolderFileResource.java +++ b/src/main/java/org/olat/fileresource/types/SharedFolderFileResource.java @@ -44,11 +44,8 @@ public class SharedFolderFileResource extends FileResource { */ public static final String RESOURCE_NAME = "-"; - /** - * Standard constructor. - */ public SharedFolderFileResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** diff --git a/src/main/java/org/olat/fileresource/types/SoundFileResource.java b/src/main/java/org/olat/fileresource/types/SoundFileResource.java index ab599804e0c..81ba484ae04 100644 --- a/src/main/java/org/olat/fileresource/types/SoundFileResource.java +++ b/src/main/java/org/olat/fileresource/types/SoundFileResource.java @@ -39,10 +39,9 @@ public class SoundFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.SOUND"; - /** - * Standard constructor. - */ - public SoundFileResource() { super.setTypeName(TYPE_NAME); } + public SoundFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/fileresource/types/WikiResource.java b/src/main/java/org/olat/fileresource/types/WikiResource.java index b5a0b3d72de..645c50bd120 100644 --- a/src/main/java/org/olat/fileresource/types/WikiResource.java +++ b/src/main/java/org/olat/fileresource/types/WikiResource.java @@ -34,6 +34,7 @@ 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.modules.wiki.WikiManager; import org.olat.modules.wiki.WikiPage; @@ -53,14 +54,14 @@ public class WikiResource extends FileResource { public static final String INDEX_PROPNAME = WikiManager.generatePageId(WikiPage.WIKI_INDEX_PAGE) + "." + WikiManager.WIKI_PROPERTIES_SUFFIX; public WikiResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } public static ResourceEvaluation validate(File file, String filename) { ResourceEvaluation eval = new ResourceEvaluation(); try { IndexFileFilter visitor = new IndexFileFilter(); - visit(file, filename, visitor); + PathUtils.visit(file, filename, visitor); eval.setValid(visitor.isValid()); } catch (IOException e) { log.error("", e); diff --git a/src/main/java/org/olat/fileresource/types/XlsFileResource.java b/src/main/java/org/olat/fileresource/types/XlsFileResource.java index a9497e72004..d2065a30bcf 100644 --- a/src/main/java/org/olat/fileresource/types/XlsFileResource.java +++ b/src/main/java/org/olat/fileresource/types/XlsFileResource.java @@ -39,10 +39,9 @@ public class XlsFileResource extends FileResource { */ public static final String TYPE_NAME = "FileResource.XLS"; - /** - * Standard constructor. - */ - public XlsFileResource() { super.setTypeName(TYPE_NAME); } + public XlsFileResource() { + super(TYPE_NAME); + } /** * @param f diff --git a/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java b/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java index 643ba661be9..143bf5098da 100644 --- a/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java +++ b/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java @@ -40,6 +40,7 @@ import org.dom4j.Attribute; import org.olat.core.CoreSpringFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; @@ -67,7 +68,7 @@ public class SurveyFileResource extends FileResource { public static final String TYPE_NAME = "FileResource.SURVEY"; public SurveyFileResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** @@ -91,7 +92,7 @@ public class SurveyFileResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { QTIFileFilter visitor = new QTIFileFilter(); - Path fPath = visit(file, filename, visitor); + Path fPath = PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { Path qtiPath = fPath.resolve(QTI_FILE); Document doc = QTIHelper.getDocument(qtiPath); diff --git a/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java b/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java index 44b70a4f5e5..f4ab27f13fd 100644 --- a/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java +++ b/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java @@ -40,6 +40,7 @@ import org.dom4j.Element; import org.olat.core.CoreSpringFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.PathUtils; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; @@ -66,7 +67,7 @@ public class TestFileResource extends FileResource { public static final String TYPE_NAME = "FileResource.TEST"; public TestFileResource() { - super.setTypeName(TYPE_NAME); + super(TYPE_NAME); } /** @@ -91,7 +92,7 @@ public class TestFileResource extends FileResource { ResourceEvaluation eval = new ResourceEvaluation(); try { QTIFileFilter visitor = new QTIFileFilter(); - Path fPath = visit(file, filename, visitor); + Path fPath = PathUtils.visit(file, filename, visitor); if(visitor.isValid()) { Path qtiPath = fPath.resolve(QTI_FILE); Document doc = QTIHelper.getDocument(qtiPath); diff --git a/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java b/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java index 89e9f2d25f0..a7fe36a1c0c 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java +++ b/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java @@ -35,6 +35,8 @@ public interface RepositoryEntryAuthorView extends OLATResourceable, RepositoryE public Date getCreationDate(); + public String getSoftkey(); + public String getExternalId(); public String getExternalRef(); diff --git a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java index 598786d103b..cb0bc19f4ae 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java +++ b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java @@ -86,8 +86,12 @@ public class RepositoryEntryImportExport { * * @param baseDirecotry */ - public RepositoryEntryImportExport(File baseDirecotry) { - this.baseDirectory = baseDirecotry; + public RepositoryEntryImportExport(File baseDirectory) { + this.baseDirectory = baseDirectory; + } + + public RepositoryEntryImportExport(File baseDirectory, String subDir) { + this.baseDirectory = new File(baseDirectory, subDir); } public boolean anyExportedPropertiesAvailable() { @@ -160,8 +164,12 @@ public class RepositoryEntryImportExport { private void loadConfiguration() { try { File inputFile = new File(baseDirectory, PROPERTIES_FILE); - XStream xstream = getXStream(); - repositoryProperties = (RepositoryEntryImport)xstream.fromXML(inputFile); + if(inputFile.exists()) { + XStream xstream = getXStream(); + repositoryProperties = (RepositoryEntryImport)xstream.fromXML(inputFile); + } else { + repositoryProperties = new RepositoryEntryImport(); + } propertiesLoaded = true; } catch (Exception ce) { throw new OLATRuntimeException("Error importing repository entry properties.", ce); diff --git a/src/main/java/org/olat/repository/SearchAuthorRepositoryEntryViewParams.java b/src/main/java/org/olat/repository/SearchAuthorRepositoryEntryViewParams.java index 72cee09e16f..59cd269a7c8 100644 --- a/src/main/java/org/olat/repository/SearchAuthorRepositoryEntryViewParams.java +++ b/src/main/java/org/olat/repository/SearchAuthorRepositoryEntryViewParams.java @@ -32,11 +32,15 @@ import org.olat.core.id.Roles; * */ public class SearchAuthorRepositoryEntryViewParams { - private Identity identity; - private Roles roles; + private final Identity identity; + private final Roles roles; private Boolean marked; + private String idAndRefs; + private String author; + private String displayname; + private OrderBy orderBy; private List<Filter> filters; private List<String> resourceTypes; @@ -47,6 +51,30 @@ public class SearchAuthorRepositoryEntryViewParams { this.roles = roles; } + public String getIdAndRefs() { + return idAndRefs; + } + + public void setIdAndRefs(String idAndRefs) { + this.idAndRefs = idAndRefs; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getDisplayname() { + return displayname; + } + + public void setDisplayname(String displayname) { + this.displayname = displayname; + } + public List<Long> getRepoEntryKeys() { return repoEntryKeys; } diff --git a/src/main/java/org/olat/repository/_spring/repositoryContext.xml b/src/main/java/org/olat/repository/_spring/repositoryContext.xml index d53f1f7a161..c288bbaf94b 100644 --- a/src/main/java/org/olat/repository/_spring/repositoryContext.xml +++ b/src/main/java/org/olat/repository/_spring/repositoryContext.xml @@ -8,7 +8,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - <context:component-scan base-package="org.olat.repository.manager" /> + <context:component-scan base-package="org.olat.repository.manager,org.olat.repository.handlers" /> <bean id="repositoryModule" class="org.olat.repository.RepositoryModule" depends-on="userModule"> <property name="groupModule" ref="businessGroupModule"/> diff --git a/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java b/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java index 121234a0a9d..caab020a21b 100644 --- a/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java +++ b/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java @@ -338,7 +338,7 @@ public class ReferencableEntriesSearchController extends BasicController { StringBuilder sb = new StringBuilder(translate("error.launch")); sb.append(": No launcher for repository entry: "); sb.append(repositoryEntry.getKey()); - throw new OLATRuntimeException(RepositoryDetailsController.class, sb.toString(), null); + throw new OLATRuntimeException(ReferencableEntriesSearchController.class, sb.toString(), null); } // do skip the increment launch counter, this is only a preview! removeAsListenerAndDispose(previewCtr); diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java index 35118fa25ba..6ada2e2c49f 100644 --- a/src/main/java/org/olat/repository/handlers/CourseHandler.java +++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java @@ -26,6 +26,11 @@ package org.olat.repository.handlers; import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -53,6 +58,7 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.CodeHelper; import org.olat.core.util.FileUtils; import org.olat.core.util.Formatter; +import org.olat.core.util.PathUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; @@ -85,7 +91,6 @@ import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.groupsandrights.PersistingCourseGroupManager; import org.olat.course.nodes.CourseNode; import org.olat.course.tree.CourseEditorTreeNode; -import org.olat.fileresource.types.CourseResource; import org.olat.fileresource.types.GlossaryResource; import org.olat.fileresource.types.ResourceEvaluation; import org.olat.fileresource.types.SharedFolderFileResource; @@ -94,6 +99,7 @@ import org.olat.modules.glossary.GlossaryManager; import org.olat.modules.sharedfolder.SharedFolderManager; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryImportExport; +import org.olat.repository.RepositoryEntryImportExport.RepositoryEntryImport; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; @@ -121,17 +127,9 @@ import de.tuchemnitz.wizard.workflows.coursecreation.steps.CcStep00; * */ public class CourseHandler implements RepositoryHandler { - - private static final OLog log = Tracing.createLoggerFor(CourseHandler.class); - /** - * Command to add (i.e. import) a course. - */ - public static final String PROCESS_IMPORT = "add"; - /** - * Command to create a new course. - */ - public static final String PROCESS_CREATENEW = "new"; + public static final String EDITOR_XML = "editortreemodel.xml"; + private static final OLog log = Tracing.createLoggerFor(CourseHandler.class); private static final List<String> supportedTypes = Collections.singletonList(CourseModule.getCourseTypeName()); @@ -182,7 +180,28 @@ public class CourseHandler implements RepositoryHandler { @Override public ResourceEvaluation acceptImport(File file, String filename) { - return CourseResource.evaluate(file, filename); + ResourceEvaluation eval = new ResourceEvaluation(); + try { + IndexFileFilter visitor = new IndexFileFilter(); + Path fPath = PathUtils.visit(file, filename, visitor); + + if(visitor.isValid()) { + Path repoXml = fPath.resolve("export/repo.xml"); + if(repoXml != null) { + eval.setValid(true); + + RepositoryEntryImport re = RepositoryEntryImportExport.getConfiguration(repoXml); + if(re != null) { + eval.setDisplayname(re.getDisplayname()); + eval.setDescription(re.getDescription()); + } + } + } + eval.setValid(visitor.isValid()); + } catch (IOException e) { + log.error("", e); + } + return eval; } @Override @@ -212,8 +231,12 @@ public class CourseHandler implements RepositoryHandler { //import references importReferences((CourseEditorTreeNode)course.getEditorTreeModel().getRootNode(), course, initialAuthor); - importSharedFolder(course, initialAuthor); - importGlossary(course, initialAuthor); + if(course.getCourseConfig().hasCustomSharedFolder()) { + importSharedFolder(course, initialAuthor); + } + if(course.getCourseConfig().hasGlossary()) { + importGlossary(course, initialAuthor); + } // create group management / import groups cgm = course.getCourseEnvironment().getCourseGroupManager(); @@ -562,4 +585,23 @@ public class CourseHandler implements RepositoryHandler { public WizardCloseResourceController createCloseResourceController(UserRequest ureq, WindowControl wControl, RepositoryEntry repositoryEntry) { return new WizardCloseCourseController(ureq, wControl, repositoryEntry); } + + private static class IndexFileFilter extends SimpleFileVisitor<Path> { + private boolean editorFile; + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + + String filename = file.getFileName().toString(); + if(EDITOR_XML.equals(filename)) { + editorFile = true; + } + return editorFile ? FileVisitResult.TERMINATE : FileVisitResult.CONTINUE; + } + + public boolean isValid() { + return editorFile; + } + } } diff --git a/src/main/java/org/olat/repository/handlers/RepositoryHandlerFactory.java b/src/main/java/org/olat/repository/handlers/RepositoryHandlerFactory.java index 102a98dfea3..95773cdb594 100644 --- a/src/main/java/org/olat/repository/handlers/RepositoryHandlerFactory.java +++ b/src/main/java/org/olat/repository/handlers/RepositoryHandlerFactory.java @@ -29,9 +29,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.olat.core.CoreSpringFactory; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; import org.olat.repository.RepositoryEntry; +import org.springframework.stereotype.Service; /** * Initial Date: Apr 6, 2004 @@ -41,21 +43,12 @@ import org.olat.repository.RepositoryEntry; * Comment: * */ +@Service public class RepositoryHandlerFactory { - private static RepositoryHandlerFactory INSTANCE; private static Map<String, RepositoryHandler> handlerMap; - - /** - * - */ - private RepositoryHandlerFactory() { - // singleton - } - static { - INSTANCE = new RepositoryHandlerFactory(); - handlerMap = new HashMap<String, RepositoryHandler>(10); + handlerMap = new HashMap<String, RepositoryHandler>(21); registerHandler(new WebDocumentHandler()); registerHandler(new ImsCPHandler()); @@ -75,10 +68,9 @@ public class RepositoryHandlerFactory { } } - /** - * @return Singleton. - */ - public static RepositoryHandlerFactory getInstance() { return INSTANCE; } + public static RepositoryHandlerFactory getInstance() { + return CoreSpringFactory.getImpl(RepositoryHandlerFactory.class); + } /** * Get the repository handler for this repository entry. @@ -104,7 +96,7 @@ public class RepositoryHandlerFactory { * Get a set of types this factory supports. * @return Set of supported types. */ - public static Set<String> getSupportedTypes() { + public Set<String> getSupportedTypes() { return handlerMap.keySet(); } } diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java index 7395895cc20..f4dcd533b4b 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java @@ -29,6 +29,7 @@ import org.olat.core.commons.persistence.DB; 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.repository.RepositoryEntryAuthorView; import org.olat.repository.SearchAuthorRepositoryEntryViewParams; import org.springframework.beans.factory.annotation.Autowired; @@ -106,6 +107,23 @@ public class RepositoryEntryAuthorViewQueries { if(params.getMarked() != null) { sb.append(" and v.markKey ").append(params.getMarked().booleanValue() ? " is not null " : " is null "); } + Long id = null; + String refs = null; + if(StringHelper.containsNonWhitespace(params.getIdAndRefs())) { + refs = params.getIdAndRefs(); + if(StringHelper.isLong(refs)) { + try { + id = Long.parseLong(refs); + } catch (NumberFormatException e) { + // + } + } + sb.append(" and (v.externalId=:ref or v.externalRef=:ref or v.softkey=:ref"); + if(id != null) { + sb.append(" or v.key=:vKey)"); + } + sb.append(")"); + } TypedQuery<T> dbQuery = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), type); @@ -118,6 +136,12 @@ public class RepositoryEntryAuthorViewQueries { if(params.isLifecycleFilterDefined()) { dbQuery.setParameter("now", new Date()); } + if(id != null) { + dbQuery.setParameter("vKey", id); + } + if(refs != null) { + dbQuery.setParameter("ref", refs); + } dbQuery.setParameter("identityKey", identity.getKey()); return dbQuery; } diff --git a/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java b/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java index 8704b350ad5..8d2ab0e543a 100644 --- a/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java +++ b/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java @@ -73,6 +73,8 @@ public class RepositoryEntryAuthorViewImpl implements RepositoryEntryAuthorView @Column(name="re_authors", nullable=false, insertable=false, updatable=false) private String authors; + @Column(name="re_softkey", nullable=false, insertable=false, updatable=false) + private String softkey; @Column(name="re_external_id", nullable=false, insertable=false, updatable=false) private String externalId; @Column(name="re_external_ref", nullable=false, insertable=false, updatable=false) @@ -147,7 +149,11 @@ public class RepositoryEntryAuthorViewImpl implements RepositoryEntryAuthorView public String getDescription() { return description; } - + + public String getSoftkey() { + return softkey; + } + @Override public String getExternalId() { return externalId; diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java index cb5c7154bc3..307828bb3f8 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.List; import org.olat.NewControllerFactory; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.mark.Mark; import org.olat.core.commons.services.mark.MarkManager; import org.olat.core.gui.UserRequest; @@ -56,6 +55,7 @@ import org.olat.core.util.resource.OresHelper; import org.olat.repository.RepositoryManager; import org.olat.repository.SearchAuthorRepositoryEntryViewParams; import org.olat.repository.ui.author.AuthoringEntryDataModel.Cols; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -69,17 +69,18 @@ public class AuthorListController extends FormBasicController implements Activat private AuthoringEntryDataModel model; private AuthoringEntryDataSource dataSource; private final SearchAuthorRepositoryEntryViewParams searchParams; - private final MarkManager markManager; private final TooledStackedPanel stackPanel; private AuthorSearchController searchCtrl; private AuthoringEntryDetailsController detailsCtrl; + @Autowired + private MarkManager markManager; + public AuthorListController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, SearchAuthorRepositoryEntryViewParams searchParams) { super(ureq, wControl, "repoentry_table"); setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator())); - markManager = CoreSpringFactory.getImpl(MarkManager.class); this.stackPanel = stackPanel; this.searchParams = searchParams; @@ -196,6 +197,9 @@ public class AuthorListController extends FormBasicController implements Activat searchParams.setResourceTypes(null); } + searchParams.setIdAndRefs(se.getId()); + searchParams.setAuthor(se.getAuthor()); + searchParams.setDisplayname(se.getDisplayname()); tableEl.reset(); } diff --git a/src/main/java/org/olat/repository/ui/author/AuthorSearchController.java b/src/main/java/org/olat/repository/ui/author/AuthorSearchController.java index 55e9e404e60..b0d26f450a9 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthorSearchController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthorSearchController.java @@ -1,10 +1,27 @@ - +/** + * <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.repository.ui.author; import java.util.ArrayList; import java.util.List; -import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -19,29 +36,11 @@ import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.util.StringHelper; import org.olat.core.util.Util; -import org.olat.course.CourseModule; -import org.olat.fileresource.types.AnimationFileResource; -import org.olat.fileresource.types.BlogFileResource; -import org.olat.fileresource.types.DocFileResource; -import org.olat.fileresource.types.FileResource; -import org.olat.fileresource.types.GlossaryResource; -import org.olat.fileresource.types.ImageFileResource; -import org.olat.fileresource.types.ImsCPFileResource; -import org.olat.fileresource.types.MovieFileResource; -import org.olat.fileresource.types.PdfFileResource; -import org.olat.fileresource.types.PodcastFileResource; -import org.olat.fileresource.types.PowerpointFileResource; -import org.olat.fileresource.types.ScormCPFileResource; -import org.olat.fileresource.types.SharedFolderFileResource; -import org.olat.fileresource.types.SoundFileResource; -import org.olat.fileresource.types.WikiResource; -import org.olat.fileresource.types.XlsFileResource; -import org.olat.ims.qti.fileresource.SurveyFileResource; -import org.olat.ims.qti.fileresource.TestFileResource; -import org.olat.portfolio.EPTemplateMapResource; import org.olat.repository.RepositoryManager; -import org.olat.repository.RepositoryModule; +import org.olat.repository.handlers.RepositoryHandlerFactory; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -55,20 +54,19 @@ public class AuthorSearchController extends FormBasicController{ private TextElement displayName; private TextElement author; private TextElement description; - private TextElement externalId; - private TextElement externalRef; private SingleSelection types; private FormLink searchButton; private String[] limitTypes; private boolean isAdmin; - private final boolean managedEnabled; + + @Autowired + private RepositoryHandlerFactory repositoryHandlerFactory; public AuthorSearchController(UserRequest ureq, WindowControl wControl, boolean isAdmin, Form form) { super(ureq, wControl, LAYOUT_CUSTOM, "search", form); setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator())); this.isAdmin = isAdmin; - managedEnabled = CoreSpringFactory.getImpl(RepositoryModule.class).isManagedRepositoryEntries(); initForm(ureq); } @@ -81,9 +79,6 @@ public class AuthorSearchController extends FormBasicController{ displayName = uifactory.addTextElement("cif_displayname", "cif.displayname", 255, "", leftContainer); displayName.setElementCssClass("o_sel_repo_search_displayname"); displayName.setFocus(true); - - author = uifactory.addTextElement("cif_author", "cif.author", 255, "", formLayout); - author.setElementCssClass("o_sel_repo_search_author"); description = uifactory.addTextElement("cif_description", "cif.description", 255, "", leftContainer); description.setElementCssClass("o_sel_repo_search_description"); @@ -92,24 +87,18 @@ public class AuthorSearchController extends FormBasicController{ String[] typeKeys = typeList.toArray(new String[typeList.size()]); String[] typeValues = getTranslatedResources(typeList); types = uifactory.addDropdownSingleselect("cif.type", "cif.type", leftContainer, typeKeys, typeValues, null); - - + FormLayoutContainer rightContainer = FormLayoutContainer.createDefaultFormLayout("right_1", getTranslator()); rightContainer.setRootForm(mainForm); formLayout.add(rightContainer); + author = uifactory.addTextElement("cif_author", "cif.author", 255, "", rightContainer); + author.setElementCssClass("o_sel_repo_search_author"); + id = uifactory.addTextElement("cif_id", "cif.id", 12, "", rightContainer); id.setElementCssClass("o_sel_repo_search_id"); id.setVisible(isAdmin); id.setRegexMatchCheck("\\d*", "search.id.format"); - - externalId = uifactory.addTextElement("cif_extid", "cif.externalid", 128, "", rightContainer); - externalId.setElementCssClass("o_sel_repo_search_external_id"); - externalId.setVisible(managedEnabled); - - externalRef = uifactory.addTextElement("cif_extref", "cif.externalref", 128, "", rightContainer); - externalRef.setElementCssClass("o_sel_repo_search_external_ref"); - externalRef.setVisible(managedEnabled); FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator()); formLayout.add(buttonLayout); @@ -120,30 +109,12 @@ public class AuthorSearchController extends FormBasicController{ protected void doDispose() { // } - - /** - * @return Is ID field available? - */ - public boolean hasId() { - return (id != null && !id.isEmpty()); - } /** * @return Return value of ID field. */ - public Long getId() { - if (!hasId()) { - return null; - } - return new Long(id.getValue()); - } - - public String getExternalId() { - return externalId.getValue(); - } - - public String getExternalRef() { - return externalRef.getValue(); + public String getId() { + return id.getValue(); } /** @@ -181,8 +152,7 @@ public class AuthorSearchController extends FormBasicController{ @Override protected boolean validateFormLogic(UserRequest ureq) { - if (displayName.isEmpty() && author.isEmpty() && description.isEmpty() && (id != null && id.isEmpty()) - && externalId.isEmpty() && externalRef.isEmpty()) { + if (displayName.isEmpty() && author.isEmpty() && description.isEmpty() && (id != null && id.isEmpty())) { showWarning("cif.error.allempty", null); return false; } @@ -211,8 +181,6 @@ public class AuthorSearchController extends FormBasicController{ e.setId(getId()); e.setAuthor(getAuthor()); e.setDisplayname(getDisplayName()); - e.setExternalId(getExternalId()); - e.setExternalRef(getExternalRef()); e.setType(getRestrictedType()); fireEvent(ureq, e); } @@ -220,34 +188,21 @@ public class AuthorSearchController extends FormBasicController{ private String[] getTranslatedResources(List<String> resources) { List<String> l = new ArrayList<String>(); for(String key: resources){ - l.add(translate(key)); + if(StringHelper.containsNonWhitespace(key)) { + l.add(translate(key)); + } else { + l.add(""); + } } return l.toArray(new String[0]); } private List<String> getResources() { List<String> resources = new ArrayList<String>(); - resources.add(CourseModule.getCourseTypeName()); - resources.add(ImsCPFileResource.TYPE_NAME); - resources.add(ScormCPFileResource.TYPE_NAME); - resources.add(WikiResource.TYPE_NAME); - resources.add(PodcastFileResource.TYPE_NAME); - resources.add(BlogFileResource.TYPE_NAME); - resources.add(TestFileResource.TYPE_NAME); - resources.add(SurveyFileResource.TYPE_NAME); - resources.add(EPTemplateMapResource.TYPE_NAME); - resources.add(SharedFolderFileResource.TYPE_NAME); - resources.add(GlossaryResource.TYPE_NAME); - resources.add(PdfFileResource.TYPE_NAME); - resources.add(XlsFileResource.TYPE_NAME); - resources.add(PowerpointFileResource.TYPE_NAME); - resources.add(DocFileResource.TYPE_NAME); - resources.add(AnimationFileResource.TYPE_NAME); - resources.add(ImageFileResource.TYPE_NAME); - resources.add(SoundFileResource.TYPE_NAME); - resources.add(MovieFileResource.TYPE_NAME); - resources.add(FileResource.GENERIC_TYPE_NAME); + resources.add(""); + for(String type:repositoryHandlerFactory.getSupportedTypes()) { + resources.add(type); + } return resources; } - } \ No newline at end of file diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEditEntryController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEditEntryController.java index db1aa1a3e52..93aeb3440ba 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthoringEditEntryController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthoringEditEntryController.java @@ -56,7 +56,7 @@ public class AuthoringEditEntryController extends BasicController { private final RepositoryEditDescriptionController descriptionCtrl; private RepositoryEntry entry; - private final RepositoryService repositoryService; + private RepositoryService repositoryService; public AuthoringEditEntryController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, AuthoringEntryRow row) { diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java index e8cf676c8d3..94548d0ad2a 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java @@ -23,9 +23,10 @@ import java.util.ArrayList; import java.util.List; import org.olat.NewControllerFactory; +import org.olat.basesecurity.GroupRoles; import org.olat.catalog.CatalogEntry; import org.olat.catalog.CatalogManager; -import org.olat.core.CoreSpringFactory; +import org.olat.catalog.ui.CatalogEntryAddController; import org.olat.core.commons.services.commentAndRating.CommentAndRatingDefaultSecurityCallback; import org.olat.core.commons.services.commentAndRating.CommentAndRatingSecurityCallback; import org.olat.core.commons.services.commentAndRating.ui.UserCommentsController; @@ -47,30 +48,51 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; +import org.olat.core.gui.media.MediaResource; +import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.Roles; +import org.olat.core.logging.OLATSecurityException; import org.olat.core.util.Formatter; 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.filter.FilterFactory; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSContainerMapper; import org.olat.core.util.vfs.VFSLeaf; +import org.olat.course.CorruptedCourseException; +import org.olat.course.CourseModule; +import org.olat.course.run.RunMainController; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryEntryManagedFlag; +import org.olat.repository.RepositoryManager; +import org.olat.repository.RepositoryModule; import org.olat.repository.RepositoryService; import org.olat.repository.RepositoyUIFactory; +import org.olat.repository.controllers.EntryChangedEvent; +import org.olat.repository.controllers.RepositoryMembersController; +import org.olat.repository.controllers.WizardCloseResourceController; import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.handlers.RepositoryHandlerFactory; import org.olat.repository.ui.PriceMethod; +import org.olat.resource.OLATResource; import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessResult; import org.olat.resource.accesscontrol.model.AccessMethod; import org.olat.resource.accesscontrol.model.OfferAccess; import org.olat.resource.accesscontrol.model.Price; +import org.olat.resource.accesscontrol.ui.OrdersAdminController; import org.olat.resource.accesscontrol.ui.PriceFormat; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -81,50 +103,173 @@ import org.olat.resource.accesscontrol.ui.PriceFormat; public class AuthoringEntryDetailsController extends FormBasicController { private FormLink markLink, startLink; + private Link editLink; + private Link downloadLink, downloadCompatLink, bookmarkLink, catalogLink; + private Link launchLink, editSettingsLink, membersLink, copyLink, deleteLink, closeLink, orderLink; private CloseableModalController cmc; + private WizardCloseResourceController wc; + private OrdersAdminController ordersCtlr; + private Controller catalogAdddController; private UserCommentsController commentsCtrl; + private DialogBoxController deleteDialogCtrl; private AuthoringEditEntryController editCtrl; + private RepositoryMembersController membersEditController; private final TooledStackedPanel stackPanel; + private boolean corrupted; private final RepositoryEntry entry; private final AuthoringEntryRow row; - private final ACService acService; - private final MarkManager markManager; - private final CatalogManager catalogManager; - private final RepositoryService repositoryService; - private final BusinessGroupService businessGroupService; + @Autowired + private ACService acService; + @Autowired + private MarkManager markManager; + @Autowired + private UserManager userManager; + @Autowired + private CatalogManager catalogManager; + @Autowired + private RepositoryManager repositoryManager; + @Autowired + private RepositoryModule repositoryModule; + @Autowired + private RepositoryService repositoryService; + @Autowired + private BusinessGroupService businessGroupService; + @Autowired + private RepositoryHandlerFactory repositoryHandlerFactory; private String baseUrl; + private final boolean isOwner; + private final boolean isAuthor; + private final boolean isOlatAdmin; + private final boolean isGuestOnly; + private LockResult lockResult; public AuthoringEntryDetailsController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, AuthoringEntryRow row) { super(ureq, wControl, "details"); - setTranslator(Util.createPackageTranslator(RepositoryService.class, getLocale(), getTranslator())); - acService = CoreSpringFactory.getImpl(ACService.class); - markManager = CoreSpringFactory.getImpl(MarkManager.class); - catalogManager = CoreSpringFactory.getImpl(CatalogManager.class); - repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); - businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); - this.stackPanel = stackPanel; this.row = row; entry = repositoryService.loadByKey(row.getKey()); + Identity identity = getIdentity(); + Roles roles = ureq.getUserSession().getRoles(); + isOlatAdmin = roles.isOLATAdmin(); + boolean isInstitutionalResourceManager = !roles.isGuestOnly() + && RepositoryManager.getInstance().isInstitutionalRessourceManagerFor(identity, roles, entry); + isOwner = isOlatAdmin || repositoryService.hasRole(ureq.getIdentity(), entry, GroupRoles.owner.name()) + | isInstitutionalResourceManager; + isAuthor = isOlatAdmin || roles.isAuthor() | isInstitutionalResourceManager; + isGuestOnly = roles.isGuestOnly(); + initForm(ureq); if(stackPanel != null) { String displayName = row.getDisplayname(); stackPanel.pushController(displayName, this); + initToolbar(ureq); + } + } + + + private void initToolbar(UserRequest ureq) { + // init handler details + RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(entry); + + launchLink = LinkFactory.createToolLink("launch", translate("details.launch"), this, "o_sel_repo_launch"); + launchLink.setEnabled(checkIsRepositoryEntryLaunchable(ureq) && !corrupted); + stackPanel.addTool(launchLink, false); + + if (!isGuestOnly) { + boolean canDownload = entry.getCanDownload() && handler.supportsDownload(entry); + // disable download for courses if not author or owner + if (entry.getOlatResource().getResourceableTypeName().equals(CourseModule.getCourseTypeName()) && !(isOwner || isAuthor)) { + canDownload = false; + } + // always enable download for owners + if (isOwner && handler.supportsDownload(entry)) { + canDownload = true; + } + + downloadLink = LinkFactory.createToolLink("download", translate("details.download"), this, "o_sel_repo_download"); + downloadLink.setEnabled(canDownload && !corrupted); + downloadCompatLink = LinkFactory.createToolLink("downloadcompat", translate("details.download.compatible"), this, "o_sel_repo_download_backward"); + downloadCompatLink.setEnabled(canDownload && !corrupted + && "CourseModule".equals(entry.getOlatResource().getResourceableTypeName())); + + boolean marked = markManager.isMarked(entry, getIdentity(), null); + String css = marked ? Mark.MARK_CSS_LARGE : Mark.MARK_ADD_CSS_LARGE; + bookmarkLink = LinkFactory.createToolLink("downloadcompat", translate("details.bookmark"), this, css); + bookmarkLink.setEnabled(!corrupted); + + stackPanel.addTool(downloadLink, false); + stackPanel.addTool(downloadCompatLink, false); + stackPanel.addTool(bookmarkLink, false); + } + + if (isAuthor || isOwner) { + if (isOwner) { + editLink = LinkFactory.createToolLink("edit", translate("details.openeditor"), this, "o_sel_repo_edit_descritpion"); + boolean editManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.editcontent); + editLink.setEnabled(handler.supportsEdit(entry) && !corrupted && !editManaged); + stackPanel.addTool(editLink, false); + + editSettingsLink = LinkFactory.createToolLink("editdesc", translate("details.chprop"), this, "o_sel_repor_edit_properties"); + editSettingsLink.setEnabled(!corrupted); + stackPanel.addTool(editLink, false); + + if(repositoryModule.isCatalogEnabled()) { + catalogLink = LinkFactory.createToolLink("cat", translate("details.catadd"), this, "o_sel_repo_add_to_catalog"); + catalogLink.setEnabled(!corrupted && (entry.getAccess() >= RepositoryEntry.ACC_USERS || entry.isMembersOnly())); + stackPanel.addTool(catalogLink, false); + } + + boolean closeManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.close); + if ((OresHelper.isOfType(entry.getOlatResource(), CourseModule.class)) + && !closeManaged + && (!RepositoryManager.getInstance().createRepositoryEntryStatus(entry.getStatusCode()).isClosed())) { + + closeLink = LinkFactory.createToolLink("close", translate("details.close.ressoure"), this, "o_sel_repo_close_resource"); + closeLink.setEnabled(!corrupted); + stackPanel.addTool(closeLink, false); + } + } + + if(isAuthor) { + copyLink = LinkFactory.createToolLink("close", translate("details.copy"), this, "o_sel_repo_copy"); + boolean copyManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.copy); + copyLink.setEnabled((isOwner || entry.getCanCopy()) && !corrupted && !copyManaged); + stackPanel.addTool(copyLink, false); + } - editLink = LinkFactory.createToolLink("edit", "Edit", this); - stackPanel.addTool(editLink, false); + if (isOwner) { + deleteLink = LinkFactory.createToolLink("delete", translate("details.delete"), this, "o_sel_repo_delete"); + boolean deleteManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.delete); + deleteLink.setEnabled(!corrupted && !deleteManaged); + + membersLink = LinkFactory.createToolLink("close", translate("details.copy"), this, "o_sel_repo_members"); + membersLink.setEnabled(!corrupted); + + orderLink = LinkFactory.createToolLink("order", translate("details.orders"), this, "o_sel_repo_booking"); + boolean booking = acService.isResourceAccessControled(entry.getOlatResource(), null); + orderLink.setEnabled(!corrupted && booking); + } + } + } + + private boolean checkIsRepositoryEntryLaunchable(UserRequest ureq) { + RepositoryHandler type = repositoryHandlerFactory.getRepositoryHandler(entry); + if (repositoryManager.isAllowedToLaunch(ureq, entry) || + (type.supportsLaunch(entry) && ureq.getUserSession().getRoles().isOLATAdmin())) { + return true; } + return false; } private void setText(String text, String key, FormLayoutContainer layoutCont) { @@ -261,23 +406,91 @@ public class AuthoringEntryDetailsController extends FormBasicController { } else if(cmc == source) { cleanUp(); + } else if (source == wc) { + if (event == Event.CANCELLED_EVENT) { + cmc.deactivate(); + } else if (event == Event.DONE_EVENT) { + cmc.deactivate(); + updateView(ureq); + fireEvent(ureq, Event.CHANGED_EVENT); + } + } else if (source == editCtrl) { + if (event == Event.CHANGED_EVENT || event == Event.DONE_EVENT) { + // RepositoryEntry changed + + updateView(ureq); + } else if (event == Event.CANCELLED_EVENT) { + + } + cleanUp(); + } else if (source == deleteDialogCtrl){ + if (DialogBoxUIFactory.isYesEvent(event)){ + deleteRepositoryEntry(ureq, getWindowControl()); + } + } else if (source == catalogAdddController) { + // finish modal dialog and reload categories list controller + cmc.deactivate(); + updateCategoriesTableC(ureq); } super.event(ureq, source, event); } + + private void updateView(UserRequest ureq) { + + } + + private void updateCategoriesTableC(UserRequest ureq) { + + } @Override public void event(UserRequest ureq, Component source, Event event) { - if(editLink == source) { + if (downloadLink == source) { + doDownload(ureq, false); + } else if (downloadCompatLink == source) { + doDownload(ureq, true); + } else if (launchLink == source) { + launch(ureq); + } else if (editLink == source) { doEdit(ureq); + } else if (editSettingsLink == source) { + doEditSettings(ureq); + } else if (catalogLink == source) { + if(repositoryModule.isCatalogEnabled()) { + doAddCatalog(ureq); + } + } else if (bookmarkLink == source) { + String css = doMark() ? Mark.MARK_CSS_LARGE : Mark.MARK_ADD_CSS_LARGE; + bookmarkLink.setElementCssClass(css); + } else if (membersLink == source) { // membership + doOpenMembers(ureq); + } else if (orderLink == source) { + doOrders(ureq); + } else if (closeLink == source) { + doCloseResource(ureq); + } else if (deleteLink == source) { // delete + if (!isOwner) throw new OLATSecurityException("Trying to delete, but not allowed: user = " + ureq.getIdentity()); + doDelete(ureq); } super.event(ureq, source, event); } private void cleanUp() { + removeAsListenerAndDispose(catalogAdddController); + removeAsListenerAndDispose(membersEditController); + removeAsListenerAndDispose(deleteDialogCtrl); removeAsListenerAndDispose(commentsCtrl); + removeAsListenerAndDispose(ordersCtlr); + removeAsListenerAndDispose(editCtrl); removeAsListenerAndDispose(cmc); + removeAsListenerAndDispose(wc); + catalogAdddController = null; + deleteDialogCtrl = null; commentsCtrl = null; + ordersCtlr = null; + editCtrl = null; cmc = null; + wc = null; } @Override @@ -294,7 +507,7 @@ public class AuthoringEntryDetailsController extends FormBasicController { } else if("comments".equals(cmd)) { doOpenComments(ureq); } else if("start".equals(cmd)) { - doStart(ureq); + launch(ureq); } else if("group".equals(cmd)) { Long groupKey = (Long)link.getUserObject(); doOpenGroup(ureq, groupKey); @@ -302,19 +515,93 @@ public class AuthoringEntryDetailsController extends FormBasicController { } super.formInnerEvent(ureq, source, event); } + + private void doCloseResource(UserRequest ureq) { + RepositoryHandler repoHandler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(entry); + + removeAsListenerAndDispose(wc); + wc = repoHandler.createCloseResourceController(ureq, getWindowControl(), entry); + listenTo(wc); + + wc.startWorkflow(); + + removeAsListenerAndDispose(cmc); + cmc = new CloseableModalController(getWindowControl(), translate("close"), wc.getInitialComponent()); + listenTo(cmc); + + cmc.activate(); + } - public void doEdit(UserRequest ureq) { - removeAsListenerAndDispose(editCtrl); + private void doDelete(UserRequest ureq) { + //show how many users are currently using this resource - editCtrl = new AuthoringEditEntryController(ureq, getWindowControl(), stackPanel, row); - listenTo(editCtrl); + String dialogTitle = translate("del.header", entry.getDisplayname()); + OLATResourceable courseRunOres = OresHelper.createOLATResourceableInstance(RunMainController.ORES_TYPE_COURSE_RUN, entry.getOlatResource().getResourceableId()); + int cnt = CoordinatorManager.getInstance().getCoordinator().getEventBus().getListeningIdentityCntFor(courseRunOres); + + String dialogText = translate(corrupted ? "del.confirm.corrupted" : "del.confirm", String.valueOf(cnt)); + deleteDialogCtrl = activateYesNoDialog(ureq, dialogTitle, dialogText, deleteDialogCtrl); } - private void doStart(UserRequest ureq) { - String businessPath = "[RepositoryEntry:" + entry.getKey() + "]"; + private void doDownload(UserRequest ureq, boolean backwardsCompatible) { + RepositoryHandler typeToDownload = RepositoryHandlerFactory.getInstance().getRepositoryHandler(entry); + if (typeToDownload == null) { + StringBuilder sb = new StringBuilder(translate("error.download")); + sb.append(": No download handler for repository entry: ") + .append(entry.getKey()); + showError(sb.toString()); + return; + } + OLATResource ores = entry.getOlatResource(); + if (ores == null) { + showError("error.download"); + return; + } + + boolean isAlreadyLocked = typeToDownload.isLocked(ores); + try { + lockResult = typeToDownload.acquireLock(ores, ureq.getIdentity()); + if(lockResult == null || (lockResult !=null && lockResult.isSuccess() && !isAlreadyLocked)) { + MediaResource mr = typeToDownload.getAsMediaResource(ores, backwardsCompatible); + if(mr!=null) { + repositoryService.incrementDownloadCounter(entry); + ureq.getDispatchResult().setResultingMediaResource(mr); + } else { + showError("error.export"); + fireEvent(ureq, Event.FAILED_EVENT); + } + } else if(lockResult !=null && lockResult.isSuccess() && isAlreadyLocked) { + String fullName = userManager.getUserDisplayName(lockResult.getOwner()); + showInfo("warning.course.alreadylocked.bySameUser", fullName); + lockResult = null; //invalid lock, it was already locked + } else { + String fullName = userManager.getUserDisplayName(lockResult.getOwner()); + showInfo("warning.course.alreadylocked", fullName); + } + } finally { + if((lockResult!=null && lockResult.isSuccess() && !isAlreadyLocked)) { + typeToDownload.releaseLock(lockResult); + lockResult = null; + } + } + } + + private void doEdit(UserRequest ureq) { + String businessPath = "[RepositoryEntry:" + entry.getKey() + "][Editor:0]"; NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); } + /** + * Open the editor for all repository entry metadata, access control... + * @param ureq + */ + private void doEditSettings(UserRequest ureq) { + removeAsListenerAndDispose(editCtrl); + + editCtrl = new AuthoringEditEntryController(ureq, getWindowControl(), stackPanel, row); + listenTo(editCtrl); + } + private void doOpenCategory(UserRequest ureq, Long categoryKey) { String businessPath = "[CatalogEntry:" + categoryKey + "]"; NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); @@ -348,4 +635,62 @@ public class AuthoringEntryDetailsController extends FormBasicController { listenTo(cmc); cmc.activate(); } + + private void doOpenMembers(UserRequest ureq) { + if (!isOwner) throw new OLATSecurityException("Trying to access groupmanagement, but not allowed: user = " + getIdentity()); + if(membersEditController != null) return; + + membersEditController = new RepositoryMembersController(ureq, getWindowControl(), entry); + listenTo(membersEditController); + CloseableModalController cmc = new CloseableModalController(getWindowControl(), translate("close"), + membersEditController.getInitialComponent(), true, translate("details.members")); + listenTo(cmc); + cmc.activate(); + } + + private void doOrders(UserRequest ureq) { + if(ordersCtlr != null) return; + + ordersCtlr = new OrdersAdminController(ureq, getWindowControl(), entry.getOlatResource()); + listenTo(ordersCtlr); + + removeAsListenerAndDispose(cmc); + CloseableModalController cmc = new CloseableModalController(getWindowControl(), translate("close"), ordersCtlr.getInitialComponent()); + listenTo(cmc); + + cmc.activate(); + } + + private void launch(UserRequest ureq) { + try { + String businessPath = "[RepositoryEntry:" + entry.getKey() + "]"; + NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); + } catch (CorruptedCourseException e) { + logError("", e); + } + } + + /** + * Internal helper to initiate the add to catalog workflow + * @param ureq + */ + private void doAddCatalog(UserRequest ureq) { + if(catalogAdddController != null) return; + + catalogAdddController = new CatalogEntryAddController(ureq, getWindowControl(), entry, true, false); + listenTo(catalogAdddController); + cmc = new CloseableModalController(getWindowControl(), "close", + catalogAdddController.getInitialComponent(), true, translate("details.catadd")); + listenTo(cmc); + cmc.activate(); + } + + private void deleteRepositoryEntry(UserRequest ureq, WindowControl wControl) { + if (RepositoryManager.getInstance().deleteRepositoryEntryWithAllData( ureq, wControl, entry) ) { + fireEvent(ureq, new EntryChangedEvent(entry, EntryChangedEvent.DELETED)); + showInfo("info.entry.deleted"); + } else { + showInfo("info.could.not.delete.entry"); + } + } } diff --git a/src/main/java/org/olat/repository/ui/author/CopyRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/CopyRepositoryEntryController.java index 45fc9613b19..4220e35da62 100644 --- a/src/main/java/org/olat/repository/ui/author/CopyRepositoryEntryController.java +++ b/src/main/java/org/olat/repository/ui/author/CopyRepositoryEntryController.java @@ -19,7 +19,6 @@ */ package org.olat.repository.ui.author; -import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.RichTextElement; @@ -42,6 +41,7 @@ import org.olat.repository.handlers.RepositoryHandlerFactory; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -57,17 +57,16 @@ public class CopyRepositoryEntryController extends FormBasicController { private RepositoryEntry copyEntry; private final RepositoryEntry sourceEntry; - private final RepositoryService repositoryService; - private final OLATResourceManager resourceManager; + @Autowired + private RepositoryService repositoryService; + @Autowired + private OLATResourceManager resourceManager; public CopyRepositoryEntryController(UserRequest ureq, WindowControl wControl, RepositoryEntry sourceEntry) { super(ureq, wControl); setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator())); this.sourceEntry = sourceEntry; - - resourceManager = OLATResourceManager.getInstance(); - repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); - + initForm(ureq); } diff --git a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java index ce2322e72ce..17eaae11ecf 100644 --- a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java +++ b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java @@ -177,7 +177,7 @@ public class ImportRepositoryEntryController extends FormBasicController { File uploadedFile = uploadFileEl.getUploadFile(); String uploadedFilename = uploadFileEl.getUploadFileName(); - for(String type:RepositoryHandlerFactory.getSupportedTypes()) { + for(String type:RepositoryHandlerFactory.getInstance().getSupportedTypes()) { RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(type); ResourceEvaluation eval = handler.acceptImport(uploadedFile, uploadedFilename); if(eval != null && eval.isValid()) { diff --git a/src/main/java/org/olat/repository/ui/author/OverviewAuthoringController.java b/src/main/java/org/olat/repository/ui/author/OverviewAuthoringController.java index b3dd71bed69..1eb446860ba 100644 --- a/src/main/java/org/olat/repository/ui/author/OverviewAuthoringController.java +++ b/src/main/java/org/olat/repository/ui/author/OverviewAuthoringController.java @@ -55,6 +55,7 @@ import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.handlers.RepositoryHandlerFactory; import org.olat.user.UserManager; import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -79,8 +80,11 @@ public class OverviewAuthoringController extends BasicController implements Acti private Dropdown createDropdown; private Link importLink; - private final UserManager userManager; - + @Autowired + private UserManager userManager; + @Autowired + private RepositoryHandlerFactory repositoryHandlerFactory; + public OverviewAuthoringController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator())); @@ -95,11 +99,11 @@ public class OverviewAuthoringController extends BasicController implements Acti importLink = LinkFactory.createLink("cmd.import.ressource", getTranslator(), this); importLink.setDomReplacementWrapperRequired(false); - Set<String> types = RepositoryHandlerFactory.getSupportedTypes(); + Set<String> types = repositoryHandlerFactory.getSupportedTypes(); createDropdown = new Dropdown("cmd.create.ressource", "cmd.create.ressource", false, getTranslator()); for(String type:types) { - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(type); + RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(type); if(handler != null && handler.isCreate()) { addCreateLink(handler, createDropdown); } diff --git a/src/main/java/org/olat/repository/ui/author/SearchEvent.java b/src/main/java/org/olat/repository/ui/author/SearchEvent.java index 24341f6d28c..ad8a9818eb2 100644 --- a/src/main/java/org/olat/repository/ui/author/SearchEvent.java +++ b/src/main/java/org/olat/repository/ui/author/SearchEvent.java @@ -32,11 +32,9 @@ public class SearchEvent extends Event implements StateEntry { private static final long serialVersionUID = -1222660688926846838L; - private Long id; + private String id; private String displayname; private String author; - private String externalId; - private String externalRef; private String type; public SearchEvent() { @@ -44,11 +42,11 @@ public class SearchEvent extends Event implements StateEntry { } - public Long getId() { + public String getId() { return id; } - public void setId(Long id) { + public void setId(String id) { this.id = id; } @@ -68,22 +66,6 @@ public class SearchEvent extends Event implements StateEntry { this.author = author; } - public String getExternalId() { - return externalId; - } - - public void setExternalId(String externalId) { - this.externalId = externalId; - } - - public String getExternalRef() { - return externalRef; - } - - public void setExternalRef(String externalRef) { - this.externalRef = externalRef; - } - public String getType() { return type; } @@ -92,7 +74,6 @@ public class SearchEvent extends Event implements StateEntry { this.type = type; } - @Override public SearchEvent clone() { SearchEvent clone = new SearchEvent(); diff --git a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql index c600566c3d9..9ed46f1f368 100644 --- a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql +++ b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql @@ -341,6 +341,7 @@ create view o_repositoryentry_author_v as ( re.lastmodified as re_lastmodified, re.displayname as re_displayname, re.description as re_description, + re.softkey as re_softkey, re.external_id as re_external_id, re.external_ref as re_external_ref, re.initialauthor as re_author, diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index d759103287c..922c672b572 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1506,6 +1506,7 @@ create view o_repositoryentry_author_v as ( re.lastmodified as re_lastmodified, re.displayname as re_displayname, re.description as re_description, + re.softkey as re_softkey, re.external_id as re_external_id, re.external_ref as re_external_ref, re.initialauthor as re_author, diff --git a/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql b/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql index 8e41d9b40aa..9be9a3379db 100644 --- a/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql +++ b/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql @@ -347,6 +347,7 @@ create view o_repositoryentry_author_v as ( re.lastmodified as re_lastmodified, re.displayname as re_displayname, re.description as re_description, + re.softkey as re_softkey, re.external_id as re_external_id, re.external_ref as re_external_ref, re.initialauthor as re_author, diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java index 3d58e120ed8..31a028c22cc 100644 --- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java +++ b/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java @@ -1,3 +1,22 @@ +/** + * <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.webdav; import java.io.IOException; -- GitLab