diff --git a/src/main/java/org/olat/commons/calendar/CalendarWebDAVProvider.java b/src/main/java/org/olat/commons/calendar/CalendarWebDAVProvider.java deleted file mode 100644 index 70e06196f974a587c3189d285f12a18919d7d7dd..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/commons/calendar/CalendarWebDAVProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ - -package org.olat.commons.calendar; - -import java.io.File; - -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.services.webdav.WebDAVProvider; -import org.olat.core.id.IdentityEnvironment; -import org.olat.core.util.vfs.LocalFileImpl; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VirtualContainer; -import org.olat.core.util.vfs.callbacks.ReadOnlyCallback; - -public class CalendarWebDAVProvider implements WebDAVProvider { - - private static final String MOUNT_POINT = "calendars"; - - @Override - public boolean hasAccess(IdentityEnvironment identityEnv) { - return identityEnv != null; - } - - @Override - public VFSContainer getContainer(IdentityEnvironment identityEnv) { - VirtualContainer calendars = new VirtualContainer("calendars"); - calendars.setLocalSecurityCallback(new ReadOnlyCallback()); - // get private calendar - CalendarManager calendarManager = CoreSpringFactory.getImpl(CalendarManager.class); - File fPersonalCalendar = calendarManager.getCalendarICalFile(CalendarManager.TYPE_USER, identityEnv.getIdentity().getName()); - calendars.addItem(new LocalFileImpl(fPersonalCalendar)); - return calendars; - } - - @Override - public String getMountPoint() { - return MOUNT_POINT; - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/MergeSource.java b/src/main/java/org/olat/core/util/vfs/MergeSource.java index 10eedc406b42bdc64792bc03fb348eb4246ef037..d57476827fdf8b692996d0547468f4734416c9fa 100644 --- a/src/main/java/org/olat/core/util/vfs/MergeSource.java +++ b/src/main/java/org/olat/core/util/vfs/MergeSource.java @@ -134,6 +134,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#getParent() */ + @Override public VFSContainer getParentContainer() { return parentContainer; } @@ -141,6 +142,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#setParentContainer(org.olat.core.util.vfs.VFSContainer) */ + @Override public void setParentContainer(VFSContainer parentContainer) { this.parentContainer = parentContainer; } @@ -148,6 +150,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSContainer#getItems() */ + @Override public List<VFSItem> getItems() { return getItems(null); } @@ -155,6 +158,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSContainer#getItems(org.olat.core.util.vfs.filters.VFSItemFilter) */ + @Override public List<VFSItem> getItems(VFSItemFilter filter) { // remember: security callback and parent was already set during add to this MergeSource // and refreshed on any setSecurityCallback() so no need to handle the quota of children here. @@ -183,6 +187,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#canCopyTo() */ + @Override public VFSStatus canWrite() { if (rootWriteContainer == null) return VFSConstants.NO; return rootWriteContainer.canWrite(); @@ -191,6 +196,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSContainer#createChildContainer(java.lang.String) */ + @Override public VFSContainer createChildContainer(String name) { if (canWrite() != VFSConstants.YES) return null; VFSContainer newContainer = rootWriteContainer.createChildContainer(name); @@ -201,6 +207,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSContainer#createChildLeaf(java.lang.String) */ + @Override public VFSLeaf createChildLeaf(String name) { if (canWrite() != VFSConstants.YES) return null; return rootWriteContainer.createChildLeaf(name); @@ -209,6 +216,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSContainer#copyFrom(org.olat.core.util.vfs.VFSItem) */ + @Override public VFSStatus copyFrom(VFSItem source) { if (canWrite() != VFSConstants.YES) throw new AssertException("Cannot create child container in merge source if not writable."); return rootWriteContainer.copyFrom(source); @@ -217,15 +225,29 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#resolveFile(java.lang.String) */ + @Override public VFSItem resolve(String path) { path = VFSManager.sanitizePath(path); if (path.equals("/")) return this; String childName = VFSManager.extractChild(path); - VFSItem vfsItem = null; + String nextPath = path.substring(childName.length() + 1); + // simple case + for (VFSContainer container:mergedContainers) { + if (container.getName().equals(childName)) { + VFSItem vfsItem = container.resolve(nextPath); + // set default filter on resolved file if it is a container + if (vfsItem != null && vfsItem instanceof VFSContainer) { + VFSContainer resolvedContainer = (VFSContainer) vfsItem; + resolvedContainer.setDefaultItemFilter(defaultFilter); + } + return vfsItem; + } + } + + // check delegates for (VFSContainer container:mergedContainers) { - String nextPath = path.substring(childName.length() + 1); - // fxdiff FXOLAT-176 a namedContainer doesn't match with its own getName()! -> work with delegate + // A namedContainer doesn't match with its own getName()! -> work with delegate boolean nameMatch = container.getName().equals(childName); if (container instanceof NamedContainerImpl && !nameMatch) { // Special case: sometimes the path refers to the named containers @@ -245,7 +267,7 @@ public class MergeSource extends AbstractVirtualContainer { nameMatch = name.equals(childName); } if (nameMatch) { - vfsItem = container.resolve(nextPath); + VFSItem vfsItem = container.resolve(nextPath); // set default filter on resolved file if it is a container if (vfsItem != null && vfsItem instanceof VFSContainer) { VFSContainer resolvedContainer = (VFSContainer) vfsItem; @@ -256,11 +278,11 @@ public class MergeSource extends AbstractVirtualContainer { } for (VFSContainer container : mergedContainersChildren) { - // fxdiff FXOLAT-176 a namedContainer doesn't match with its own getName()! -> work with delegate + // A namedContainer doesn't match with its own getName()! -> work with delegate if (container instanceof NamedContainerImpl) { container = ((NamedContainerImpl) container).getDelegate(); } - vfsItem = container.resolve(path); + VFSItem vfsItem = container.resolve(path); if (vfsItem != null) { // set default filter on resolved file if it is a container if (vfsItem instanceof VFSContainer) { @@ -276,6 +298,7 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#getLocalSecurityCallback() */ + @Override public VFSSecurityCallback getLocalSecurityCallback() { return securityCallback; } @@ -283,10 +306,12 @@ public class MergeSource extends AbstractVirtualContainer { /** * @see org.olat.core.util.vfs.VFSItem#setLocalSecurityCallback(org.olat.core.util.vfs.callbacks.VFSSecurityCallback) */ + @Override public void setLocalSecurityCallback(VFSSecurityCallback secCallback) { securityCallback = secCallback; } + @Override public boolean isSame(VFSItem vfsItem) { if (rootWriteContainer == null) { // Unwriteable merge source (e.g. users private folder), compare on object identity diff --git a/src/main/java/org/olat/core/util/vfs/callbacks/FullAccessWithLazyQuotaCallback.java b/src/main/java/org/olat/core/util/vfs/callbacks/FullAccessWithLazyQuotaCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..64cb697e66923d5cf52d7681a656415129077526 --- /dev/null +++ b/src/main/java/org/olat/core/util/vfs/callbacks/FullAccessWithLazyQuotaCallback.java @@ -0,0 +1,60 @@ +/** + * <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.util.vfs.callbacks; + +import org.olat.admin.quota.QuotaConstants; +import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.util.vfs.Quota; +import org.olat.core.util.vfs.QuotaManager; + +/** + * + * Initial date: 14 févr. 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class FullAccessWithLazyQuotaCallback extends FullAccessWithQuotaCallback { + + private final String folderPath; + + public FullAccessWithLazyQuotaCallback(String folderPath) { + super(null); + this.folderPath = folderPath; + } + + public FullAccessWithLazyQuotaCallback(String folderPath, SubscriptionContext subscriptionContext) { + super(null, subscriptionContext); + this.folderPath = folderPath; + } + + @Override + public Quota getQuota() { + if(super.getQuota() == null) { + QuotaManager qm = QuotaManager.getInstance(); + Quota q = qm.getCustomQuota(folderPath); + if (q == null) { + Quota defQuota = qm.getDefaultQuota(QuotaConstants.IDENTIFIER_DEFAULT_GROUPS); + q = QuotaManager.getInstance().createQuota(folderPath, defQuota.getQuotaKB(), defQuota.getUlLimitKB()); + } + super.setQuota(q); + } + return super.getQuota(); + } +} diff --git a/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java b/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java index b328f248d33a5a190b7bddbba9f846f56446e8f4..6ca18689d6153b7ec4f7042b9e8b625ffbc9503a 100644 --- a/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java +++ b/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java @@ -66,6 +66,7 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { Map<String, VFSContainer> terms = null; VirtualContainer noTermContainer = null; + VirtualContainer finishedContainer = new VirtualContainer("finished"); boolean useTerms = webDAVModule.isTermsFoldersEnabled(); if (useTerms) { @@ -77,18 +78,18 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { UniqueNames container = new UniqueNames(); List<RepositoryEntry> editorEntries = repositoryManager.queryByOwner(getIdentity(), "CourseModule"); - appendCourses(editorEntries, true, containers, useTerms, terms, noTermContainer, prependReference, container); + appendCourses(editorEntries, true, containers, useTerms, terms, noTermContainer, finishedContainer, prependReference, container); //add courses as participant and coaches if(webDAVModule.isEnableLearnersParticipatingCourses()) { List<RepositoryEntry> entries = repositoryManager.getLearningResourcesAsParticipantAndCoach(getIdentity(), "CourseModule"); - appendCourses(entries, false, containers, useTerms, terms, noTermContainer, prependReference, container); + appendCourses(entries, false, containers, useTerms, terms, noTermContainer, finishedContainer, prependReference, container); } //add bookmarked courses if(webDAVModule.isEnableLearnersBookmarksCourse()) { List<RepositoryEntry> bookmarkedEntries = repositoryManager.getLearningResourcesAsBookmark(getIdentity(), identityEnv.getRoles(), "CourseModule", 0, -1); - appendCourses(bookmarkedEntries, false, containers, useTerms, terms, noTermContainer, prependReference, container); + appendCourses(bookmarkedEntries, false, containers, useTerms, terms, noTermContainer, finishedContainer, prependReference, container); } if (useTerms) { @@ -97,12 +98,16 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { addContainerToList(noTermContainer, containers); } } + + if(finishedContainer.getItems().size() > 0) { + addContainerToList(finishedContainer, containers); + } return containers; } private void appendCourses(List<RepositoryEntry> courseEntries, boolean editor, List<VFSContainer> containers, - boolean useTerms, Map<String, VFSContainer> terms, VirtualContainer noTermContainer, + boolean useTerms, Map<String, VFSContainer> terms, VirtualContainer noTermContainer, VirtualContainer finishedContainer, boolean prependReference, UniqueNames container) { // Add all found repo entries to merge source @@ -118,7 +123,11 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { } String courseTitle = RequestUtil.normalizeFilename(displayName); - if (useTerms) { + if(re.getRepositoryEntryStatus().isClosed()) { + String name = container.getFinishedUniqueName(courseTitle); + NamedContainerImpl cfContainer = new CoursefolderWebDAVNamedContainer(name, re, editor ? null : identityEnv); + finishedContainer.getItems().add(cfContainer); + } else if (useTerms) { RepositoryEntryLifecycle lc = re.getLifecycle(); if (lc != null && !lc.isPrivateCycle()) { // when a semester term info is found, add it to corresponding term folder @@ -157,6 +166,7 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { private final Set<RepositoryEntry> duplicates = new HashSet<>(); private final Set<String> containers = new HashSet<>(); private final Set<String> noTermContainer = new HashSet<>(); + private final Set<String> finishedContainer = new HashSet<>(); private final Map<String,Set<String>> termContainers = new HashMap<>(); public boolean isDuplicate(RepositoryEntry re) { @@ -184,6 +194,10 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { return getUniqueName(courseTitle, noTermContainer); } + private String getFinishedUniqueName(String courseTitle) { + return getUniqueName(courseTitle, finishedContainer); + } + private String getContainersUniqueName(String courseTitle) { return getUniqueName(courseTitle, containers); } diff --git a/src/main/java/org/olat/course/PersistingCourseImpl.java b/src/main/java/org/olat/course/PersistingCourseImpl.java index 33bd5dfc5787c89b4982ae0f9758b2c3a3ffe601..01b34af8ec32d5a92a4156dc4f5225a54ae597c6 100644 --- a/src/main/java/org/olat/course/PersistingCourseImpl.java +++ b/src/main/java/org/olat/course/PersistingCourseImpl.java @@ -28,7 +28,6 @@ package org.olat.course; import java.io.File; import java.io.Serializable; -import org.olat.admin.quota.QuotaConstants; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.commons.persistence.DBFactory; @@ -42,11 +41,10 @@ import org.olat.core.util.FileUtils; import org.olat.core.util.nodes.INode; import org.olat.core.util.tree.TreeVisitor; import org.olat.core.util.tree.Visitor; -import org.olat.core.util.vfs.Quota; -import org.olat.core.util.vfs.QuotaManager; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.callbacks.FullAccessWithLazyQuotaCallback; import org.olat.core.util.vfs.callbacks.FullAccessWithQuotaCallback; import org.olat.core.util.vfs.version.Versionable; import org.olat.core.util.vfs.version.VersionsFileManager; @@ -249,13 +247,7 @@ public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializ "could not create course's coursefolder path:" + fCourseFolder.getAbsolutePath(), null); } - QuotaManager qm = QuotaManager.getInstance(); - Quota q = qm.getCustomQuota(isolatedCourseFolder.getRelPath()); - if (q == null){ - Quota defQuota = qm.getDefaultQuota(QuotaConstants.IDENTIFIER_DEFAULT_COURSE); - q = qm.createQuota(isolatedCourseFolder.getRelPath(), defQuota.getQuotaKB(), defQuota.getUlLimitKB()); - } - FullAccessWithQuotaCallback secCallback = new FullAccessWithQuotaCallback(q); + FullAccessWithQuotaCallback secCallback = new FullAccessWithLazyQuotaCallback(isolatedCourseFolder.getRelPath()); isolatedCourseFolder.setLocalSecurityCallback(secCallback); return isolatedCourseFolder; } diff --git a/src/main/java/org/olat/group/GroupfoldersWebDAVMergeSource.java b/src/main/java/org/olat/group/GroupfoldersWebDAVMergeSource.java index 0c65a25fc13c5cd51ac6f4e405997ec9a42ad650..d0e4179b3fb5ff832525b85b5d7513c20833f3a3 100644 --- a/src/main/java/org/olat/group/GroupfoldersWebDAVMergeSource.java +++ b/src/main/java/org/olat/group/GroupfoldersWebDAVMergeSource.java @@ -24,7 +24,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.olat.admin.quota.QuotaConstants; import org.olat.collaboration.CollaborationManager; import org.olat.collaboration.CollaborationTools; import org.olat.core.CoreSpringFactory; @@ -34,10 +33,8 @@ import org.olat.core.commons.services.webdav.manager.WebDAVMergeSource; import org.olat.core.commons.services.webdav.servlets.RequestUtil; import org.olat.core.id.Identity; import org.olat.core.util.vfs.NamedContainerImpl; -import org.olat.core.util.vfs.Quota; -import org.olat.core.util.vfs.QuotaManager; import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.callbacks.FullAccessWithQuotaCallback; +import org.olat.core.util.vfs.callbacks.FullAccessWithLazyQuotaCallback; import org.olat.core.util.vfs.callbacks.ReadOnlyCallback; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.group.model.SearchBusinessGroupParams; @@ -144,28 +141,4 @@ class GroupfoldersWebDAVMergeSource extends WebDAVMergeSource { grpContainer.setLocalSecurityCallback(secCallback); return grpContainer; } - - private static class FullAccessWithLazyQuotaCallback extends FullAccessWithQuotaCallback { - - private final String folderPath; - - public FullAccessWithLazyQuotaCallback(String folderPath, SubscriptionContext sc) { - super(null, sc); - this.folderPath = folderPath; - } - - @Override - public Quota getQuota() { - if(super.getQuota() == null) { - QuotaManager qm = QuotaManager.getInstance(); - Quota q = qm.getCustomQuota(folderPath); - if (q == null) { - Quota defQuota = qm.getDefaultQuota(QuotaConstants.IDENTIFIER_DEFAULT_GROUPS); - q = QuotaManager.getInstance().createQuota(folderPath, defQuota.getQuotaKB(), defQuota.getUlLimitKB()); - } - super.setQuota(q); - } - return super.getQuota(); - } - } }