Skip to content
Snippets Groups Projects
Commit 15dec8c4 authored by srosse's avatar srosse
Browse files

OO-3643: stop assessment modes if course is closed or trashed

parent f81c8fbc
No related branches found
No related tags found
No related merge requests found
...@@ -22,6 +22,7 @@ package org.olat.course.assessment; ...@@ -22,6 +22,7 @@ package org.olat.course.assessment;
import java.util.Date; import java.util.Date;
import org.olat.course.assessment.AssessmentMode.Status; import org.olat.course.assessment.AssessmentMode.Status;
import org.olat.repository.RepositoryEntry;
/** /**
* *
...@@ -46,6 +47,9 @@ public interface AssessmentModeCoordinationService { ...@@ -46,6 +47,9 @@ public interface AssessmentModeCoordinationService {
*/ */
public boolean canStop(AssessmentMode assessmentMode); public boolean canStop(AssessmentMode assessmentMode);
public void processRepositoryEntryChangedStatus(RepositoryEntry entry);
public Status evaluateStatus(Date begin, int leadtime, Date end, int followup); public Status evaluateStatus(Date begin, int leadtime, Date end, int followup);
public AssessmentMode startAssessment(AssessmentMode assessmentMode); public AssessmentMode startAssessment(AssessmentMode assessmentMode);
......
...@@ -34,6 +34,7 @@ import org.olat.core.logging.OLog; ...@@ -34,6 +34,7 @@ import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing; import org.olat.core.logging.Tracing;
import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.event.GenericEventListener;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.CourseFactory; import org.olat.course.CourseFactory;
import org.olat.course.assessment.AssessmentMode; import org.olat.course.assessment.AssessmentMode;
import org.olat.course.assessment.AssessmentMode.Status; import org.olat.course.assessment.AssessmentMode.Status;
...@@ -45,7 +46,9 @@ import org.olat.course.assessment.model.CoordinatedAssessmentMode; ...@@ -45,7 +46,9 @@ import org.olat.course.assessment.model.CoordinatedAssessmentMode;
import org.olat.course.assessment.model.TransientAssessmentMode; import org.olat.course.assessment.model.TransientAssessmentMode;
import org.olat.group.ui.edit.BusinessGroupModifiedEvent; import org.olat.group.ui.edit.BusinessGroupModifiedEvent;
import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService; import org.olat.repository.manager.RepositoryEntryDAO;
import org.olat.repository.model.RepositoryEntryStatusChangedEvent;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -56,7 +59,7 @@ import org.springframework.stereotype.Service; ...@@ -56,7 +59,7 @@ import org.springframework.stereotype.Service;
* *
*/ */
@Service @Service
public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoordinationService, GenericEventListener { public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoordinationService, GenericEventListener, InitializingBean {
private static final OLog log = Tracing.createLoggerFor(AssessmentModeCoordinationServiceImpl.class); private static final OLog log = Tracing.createLoggerFor(AssessmentModeCoordinationServiceImpl.class);
...@@ -65,7 +68,7 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -65,7 +68,7 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
@Autowired @Autowired
private AssessmentModule assessmentModule; private AssessmentModule assessmentModule;
@Autowired @Autowired
private RepositoryService repositoryService; private RepositoryEntryDAO repositoryEntryDao;
@Autowired @Autowired
private CoordinatorManager coordinatorManager; private CoordinatorManager coordinatorManager;
@Autowired @Autowired
...@@ -146,6 +149,14 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -146,6 +149,14 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
} }
} }
@Override
public void afterPropertiesSet() throws Exception {
coordinatorManager.getCoordinator().getEventBus()
.registerFor(this, null, OresHelper.lookupType(RepositoryEntry.class));
}
@Override @Override
public void event(Event event) { public void event(Event event) {
if(event instanceof BusinessGroupModifiedEvent) { if(event instanceof BusinessGroupModifiedEvent) {
...@@ -158,6 +169,27 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -158,6 +169,27 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
} catch (Exception e) { } catch (Exception e) {
log.error("", e); log.error("", e);
} }
} else if(event instanceof RepositoryEntryStatusChangedEvent) {
RepositoryEntryStatusChangedEvent changedEvent = (RepositoryEntryStatusChangedEvent)event;
RepositoryEntry entry = repositoryEntryDao.loadByKey(changedEvent.getRepositoryEntryKey());
processRepositoryEntryChangedStatus(entry);
}
}
@Override
public void processRepositoryEntryChangedStatus(RepositoryEntry entry) {
if(entry != null && (entry.getAccess() == RepositoryEntry.DELETED || entry.getRepositoryEntryStatus().isClosed())) {
try {
List<AssessmentMode> modes = assessmentModeManager.getAssessmentModeFor(entry);
for(AssessmentMode mode:modes) {
if(mode.getStatus() == Status.assessment || mode.getStatus() == Status.followup) {
endAssessment(mode);
}
}
} catch (Exception e) {
log.error("", e);
dbInstance.rollbackAndCloseSession();
}
} }
} }
...@@ -341,8 +373,16 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -341,8 +373,16 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
return mode; return mode;
} }
private AssessmentMode endAssessment(AssessmentMode mode) {
mode = assessmentModeManager.getAssessmentModeById(mode.getKey());
Set<Long> assessedIdentityKeys = assessmentModeManager.getAssessedIdentityKeys(mode);
mode = ensureStatusOfMode(mode, Status.end);
sendEvent(AssessmentModeNotificationEvent.END, mode, assessedIdentityKeys);
return mode;
}
private void warmUpAssessment(AssessmentMode mode) { private void warmUpAssessment(AssessmentMode mode) {
RepositoryEntry entry = repositoryService.loadByKey(mode.getRepositoryEntry().getKey()); RepositoryEntry entry = repositoryEntryDao.loadByKey(mode.getRepositoryEntry().getKey());
CourseFactory.loadCourse(entry); CourseFactory.loadCourse(entry);
} }
} }
\ No newline at end of file
...@@ -50,6 +50,7 @@ import org.olat.core.logging.activity.OlatResourceableType; ...@@ -50,6 +50,7 @@ import org.olat.core.logging.activity.OlatResourceableType;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.CodeHelper; import org.olat.core.util.CodeHelper;
import org.olat.core.util.StringHelper; import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.mail.MailPackage; import org.olat.core.util.mail.MailPackage;
import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailTemplate;
import org.olat.core.util.mail.MailerResult; import org.olat.core.util.mail.MailerResult;
...@@ -59,6 +60,7 @@ import org.olat.core.util.vfs.VFSContainer; ...@@ -59,6 +60,7 @@ import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSManager;
import org.olat.course.assessment.AssessmentModeCoordinationService;
import org.olat.course.assessment.manager.AssessmentModeDAO; import org.olat.course.assessment.manager.AssessmentModeDAO;
import org.olat.course.assessment.manager.UserCourseInformationsManager; import org.olat.course.assessment.manager.UserCourseInformationsManager;
import org.olat.course.certificate.CertificatesManager; import org.olat.course.certificate.CertificatesManager;
...@@ -83,6 +85,7 @@ import org.olat.repository.handlers.RepositoryHandler; ...@@ -83,6 +85,7 @@ import org.olat.repository.handlers.RepositoryHandler;
import org.olat.repository.handlers.RepositoryHandlerFactory; import org.olat.repository.handlers.RepositoryHandlerFactory;
import org.olat.repository.model.RepositoryEntryLifecycle; import org.olat.repository.model.RepositoryEntryLifecycle;
import org.olat.repository.model.RepositoryEntryStatistics; import org.olat.repository.model.RepositoryEntryStatistics;
import org.olat.repository.model.RepositoryEntryStatusChangedEvent;
import org.olat.repository.model.RepositoryEntryToGroupRelation; import org.olat.repository.model.RepositoryEntryToGroupRelation;
import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams; import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams;
import org.olat.repository.model.SearchMyRepositoryEntryViewParams; import org.olat.repository.model.SearchMyRepositoryEntryViewParams;
...@@ -115,6 +118,8 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -115,6 +118,8 @@ public class RepositoryServiceImpl implements RepositoryService {
@Autowired @Autowired
private CatalogManager catalogManager; private CatalogManager catalogManager;
@Autowired @Autowired
private CoordinatorManager coordinatorManager;
@Autowired
private BaseSecurity securityManager; private BaseSecurity securityManager;
@Autowired @Autowired
private ACReservationDAO reservationDao; private ACReservationDAO reservationDao;
...@@ -145,6 +150,8 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -145,6 +150,8 @@ public class RepositoryServiceImpl implements RepositoryService {
@Autowired @Autowired
private AssessmentModeDAO assessmentModeDao; private AssessmentModeDAO assessmentModeDao;
@Autowired @Autowired
private AssessmentModeCoordinationService assessmentModeCoordinationService;
@Autowired
private AssessmentTestSessionDAO assessmentTestSessionDao; private AssessmentTestSessionDAO assessmentTestSessionDao;
@Autowired @Autowired
private PersistentTaskDAO persistentTaskDao; private PersistentTaskDAO persistentTaskDao;
...@@ -354,6 +361,7 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -354,6 +361,7 @@ public class RepositoryServiceImpl implements RepositoryService {
@Override @Override
public RepositoryEntry deleteSoftly(RepositoryEntry re, Identity deletedBy, boolean owners, boolean sendNotifications) { public RepositoryEntry deleteSoftly(RepositoryEntry re, Identity deletedBy, boolean owners, boolean sendNotifications) {
// start delete
RepositoryEntry reloadedRe = repositoryEntryDAO.loadForUpdate(re); RepositoryEntry reloadedRe = repositoryEntryDAO.loadForUpdate(re);
reloadedRe.setAccess(RepositoryEntry.DELETED); reloadedRe.setAccess(RepositoryEntry.DELETED);
if(reloadedRe.getDeletionDate() == null) { if(reloadedRe.getDeletionDate() == null) {
...@@ -363,7 +371,10 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -363,7 +371,10 @@ public class RepositoryServiceImpl implements RepositoryService {
} }
reloadedRe = dbInstance.getCurrentEntityManager().merge(reloadedRe); reloadedRe = dbInstance.getCurrentEntityManager().merge(reloadedRe);
List<Identity> ownerList = reToGroupDao.getMembers(reloadedRe, RepositoryEntryRelationType.defaultGroup, GroupRoles.owner.name()); List<Identity> ownerList = reToGroupDao.getMembers(reloadedRe, RepositoryEntryRelationType.defaultGroup, GroupRoles.owner.name());
dbInstance.commit(); dbInstance.commit();
// first stop assessment mode if needed
assessmentModeCoordinationService.processRepositoryEntryChangedStatus(reloadedRe);
//remove from catalog //remove from catalog
catalogManager.resourceableDeleted(reloadedRe); catalogManager.resourceableDeleted(reloadedRe);
//remove participant and coach //remove participant and coach
...@@ -384,6 +395,9 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -384,6 +395,9 @@ public class RepositoryServiceImpl implements RepositoryService {
if(sendNotifications && deletedBy != null) { if(sendNotifications && deletedBy != null) {
sendStatusChangedNotifications(ownerList, deletedBy, reloadedRe, RepositoryMailing.Type.deleteSoftEntry); sendStatusChangedNotifications(ownerList, deletedBy, reloadedRe, RepositoryMailing.Type.deleteSoftEntry);
} }
RepositoryEntryStatusChangedEvent statusChangedEvent = new RepositoryEntryStatusChangedEvent(reloadedRe.getKey());
coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(statusChangedEvent, OresHelper.clone(reloadedRe));
return reloadedRe; return reloadedRe;
} }
...@@ -516,6 +530,9 @@ public class RepositoryServiceImpl implements RepositoryService { ...@@ -516,6 +530,9 @@ public class RepositoryServiceImpl implements RepositoryService {
if(sendNotifications && closedBy != null) { if(sendNotifications && closedBy != null) {
sendStatusChangedNotifications(ownerList, closedBy, reloadedEntry, RepositoryMailing.Type.closeEntry); sendStatusChangedNotifications(ownerList, closedBy, reloadedEntry, RepositoryMailing.Type.closeEntry);
} }
RepositoryEntryStatusChangedEvent statusChangedEvent = new RepositoryEntryStatusChangedEvent(reloadedEntry.getKey());
coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(statusChangedEvent, OresHelper.clone(entry));
return reloadedEntry; return reloadedEntry;
} }
......
/**
* <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.model;
import org.olat.core.util.event.MultiUserEvent;
/**
*
* Initial date: 13 sept. 2018<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class RepositoryEntryStatusChangedEvent extends MultiUserEvent {
private static final long serialVersionUID = -8624039692057985920L;
public static final String STATUS_CHANGED = "repo.entry.status.changed";
private Long repositoryEntryKey;
public RepositoryEntryStatusChangedEvent(Long repositoryEntryKey) {
super(STATUS_CHANGED);
this.repositoryEntryKey = repositoryEntryKey;
}
public Long getRepositoryEntryKey() {
return repositoryEntryKey;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment