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

OO-1349: react quickly to the participants added to a group during an exam

parent f04ba10c
No related branches found
No related tags found
No related merge requests found
...@@ -19,20 +19,30 @@ ...@@ -19,20 +19,30 @@
*/ */
package org.olat.course.assessment.manager; package org.olat.course.assessment.manager;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.olat.basesecurity.IdentityRef;
import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DB;
import org.olat.core.gui.control.Event;
import org.olat.core.logging.OLog;
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.course.assessment.AssessmentMode; import org.olat.course.assessment.AssessmentMode;
import org.olat.course.assessment.AssessmentMode.Status; import org.olat.course.assessment.AssessmentMode.Status;
import org.olat.course.assessment.AssessmentModeCoordinationService; import org.olat.course.assessment.AssessmentModeCoordinationService;
import org.olat.course.assessment.AssessmentModeNotificationEvent; import org.olat.course.assessment.AssessmentModeNotificationEvent;
import org.olat.course.assessment.AssessmentModule; import org.olat.course.assessment.AssessmentModule;
import org.olat.course.assessment.model.AssessmentModeImpl; import org.olat.course.assessment.model.AssessmentModeImpl;
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.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -43,7 +53,9 @@ import org.springframework.stereotype.Service; ...@@ -43,7 +53,9 @@ import org.springframework.stereotype.Service;
* *
*/ */
@Service @Service
public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoordinationService { public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoordinationService, GenericEventListener {
private static final OLog log = Tracing.createLoggerFor(AssessmentModeCoordinationServiceImpl.class);
@Autowired @Autowired
private DB dbInstance; private DB dbInstance;
...@@ -54,12 +66,36 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -54,12 +66,36 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
@Autowired @Autowired
private AssessmentModeManagerImpl assessmentModeManager; private AssessmentModeManagerImpl assessmentModeManager;
protected void beat() { private Map<Long,CoordinatedAssessmentMode> coordinatedModes = new ConcurrentHashMap<>();
protected synchronized void beat() {
if(assessmentModule.isAssessmentModeEnabled()) { if(assessmentModule.isAssessmentModeEnabled()) {
Date now = now(); Date now = now();
List<Long> currentModeKeys = new ArrayList<>();
List<AssessmentMode> currentModes = assessmentModeManager.getAssessmentModes(now); List<AssessmentMode> currentModes = assessmentModeManager.getAssessmentModes(now);
for(AssessmentMode currentMode:currentModes) { for(AssessmentMode currentMode:currentModes) {
sendEvent(currentMode, now, false); try {
sendEvent(currentMode, now, false);
currentModeKeys.add(currentMode.getKey());
} catch (Exception e) {
log.error("", e);
}
}
//remove coordinated mode
List<Long> coordinatedModeKeys = new ArrayList<>(coordinatedModes.keySet());
for(Long coordinatedModeKey:coordinatedModeKeys) {
if(!currentModeKeys.contains(coordinatedModeKey)) {
CoordinatedAssessmentMode decoordinatedMode = coordinatedModes.remove(coordinatedModeKey);
if(decoordinatedMode != null) {
coordinatorManager.getCoordinator().getEventBus()
.deregisterFor(this, decoordinatedMode.getListenerRes());
}
}
}
if(coordinatedModes.size() > 250) {
log.error("Seem to be a leak of coordinated modes");
} }
} }
} }
...@@ -80,6 +116,69 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -80,6 +116,69 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
return sendEvent(mode, now(), true); return sendEvent(mode, now(), true);
} }
private void manageListenersOfCoordinatedMode(AssessmentMode mode) {
try {
Status status = mode.getStatus();
if(status == Status.leadtime || status == Status.assessment || status == Status.followup) {
//add listeners
CoordinatedAssessmentMode coordinateMode = coordinatedModes.get(mode.getKey());
if(coordinateMode == null) {
coordinateMode = new CoordinatedAssessmentMode(mode);
coordinatedModes.put(mode.getKey(), coordinateMode);
}
coordinatorManager.getCoordinator().getEventBus()
.registerFor(this, null, coordinateMode.getListenerRes());
} else if(coordinatedModes.containsKey(mode.getKey())) {
CoordinatedAssessmentMode decoordinateMode = coordinatedModes.remove(mode.getKey());
if(decoordinateMode != null) {
coordinatorManager.getCoordinator().getEventBus()
.deregisterFor(this, decoordinateMode.getListenerRes());
}
}
} catch (Exception e) {
log.error("", e);
}
}
@Override
public void event(Event event) {
if(event instanceof BusinessGroupModifiedEvent) {
try {
BusinessGroupModifiedEvent mod = (BusinessGroupModifiedEvent)event;
if(BusinessGroupModifiedEvent.IDENTITY_ADDED_EVENT.equals(mod.getCommand())) {
Long identityKey = mod.getAffectedIdentityKey();
sendEventAfterMembershipChange(identityKey);
}
} catch (Exception e) {
log.error("", e);
}
}
}
private void sendEventAfterMembershipChange(final Long identityKey) {
List<AssessmentMode> modes = assessmentModeManager.getAssessmentModeFor(new IdentityRef() {
@Override
public Long getKey() {
return identityKey;
}
});
for(AssessmentMode mode:modes) {
Status status = mode.getStatus();
if(status == Status.leadtime ) {
sendEvent(AssessmentModeNotificationEvent.LEADTIME, mode,
assessmentModeManager.getAssessedIdentityKeys(mode));
} else if(status == Status.assessment) {
sendEvent(AssessmentModeNotificationEvent.START_ASSESSMENT, mode,
assessmentModeManager.getAssessedIdentityKeys(mode));
} else if(status == Status.followup) {
sendEvent(AssessmentModeNotificationEvent.END, mode,
assessmentModeManager.getAssessedIdentityKeys(mode));
}
}
}
@Override
public Status evaluateStatus(Date begin, int leadtime, Date end, int followup) { public Status evaluateStatus(Date begin, int leadtime, Date end, int followup) {
Status status; Status status;
Date now = now(); Date now = now();
...@@ -157,6 +256,7 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor ...@@ -157,6 +256,7 @@ public class AssessmentModeCoordinationServiceImpl implements AssessmentModeCoor
assessmentModeManager.getAssessedIdentityKeys(mode)); assessmentModeManager.getAssessedIdentityKeys(mode));
} }
} }
manageListenersOfCoordinatedMode(mode);
return mode; return mode;
} }
......
/**
* <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.course.assessment.model;
import org.olat.core.id.OLATResourceable;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.assessment.AssessmentMode;
/**
*
* Initial date: 06.02.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class CoordinatedAssessmentMode {
private final Long key;
private AssessmentMode assessmentMode;
private final OLATResourceable listenerRes;
public CoordinatedAssessmentMode(AssessmentMode assessmentMode) {
key = assessmentMode.getKey();
this.assessmentMode = assessmentMode;
this.listenerRes = OresHelper.clone(assessmentMode.getRepositoryEntry());
}
public Long getKey() {
return key;
}
public OLATResourceable getListenerRes() {
return listenerRes;
}
public AssessmentMode getAssessmentMode() {
return assessmentMode;
}
public void setAssessmentMode(AssessmentMode assessmentMode) {
this.assessmentMode = assessmentMode;
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof CoordinatedAssessmentMode) {
CoordinatedAssessmentMode m = (CoordinatedAssessmentMode)obj;
return key != null && key.equals(m.getKey());
}
return false;
}
}
\ No newline at end of file
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