use of uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder in project OpenOLAT by OpenOLAT.
the class QTI21ItemBodyController method createNewItemSessionStateAndController.
private ItemSessionController createNewItemSessionStateAndController() {
/* Resolve the underlying JQTI+ object */
final ItemProcessingMap itemProcessingMap = new ItemProcessingInitializer(resolvedAssessmentItem, true).initialize();
/* Create fresh state for session */
final ItemSessionState itemSessionState = new ItemSessionState();
final ItemSessionControllerSettings itemSessionControllerSettings = new ItemSessionControllerSettings();
itemSessionControllerSettings.setTemplateProcessingLimit(25);
itemSessionControllerSettings.setMaxAttempts(10);
/* Create controller and wire up notification recorder */
final ItemSessionController sessionController = new ItemSessionController(qtiService.jqtiExtensionManager(), itemSessionControllerSettings, itemProcessingMap, itemSessionState);
sessionController.addNotificationListener(new NotificationRecorder(NotificationLevel.ERROR));
sessionController.initialize(new Date());
return sessionController;
}
use of uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder in project OpenOLAT by OpenOLAT.
the class AssessmentItemDisplayController method handleTemporaryResponses.
public void handleTemporaryResponses(UserRequest ureq, Map<Identifier, ResponseInput> stringResponseMap) {
/* Retrieve current JQTI state and set up JQTI controller */
NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
ItemSessionState itemSessionState = itemSessionController.getItemSessionState();
/* Make sure an attempt is allowed */
if (itemSessionState.isEnded()) {
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.RESPONSES_NOT_EXPECTED, null);
logError("RESPONSES_NOT_EXPECTED", null);
return;
}
/* Build response map in required format for JQTI+.
* NB: The following doesn't test for duplicate keys in the two maps. I'm not sure
* it's worth the effort.
*/
final Map<Identifier, ResponseData> responseDataMap = new HashMap<>();
final Map<Identifier, AssessmentResponse> assessmentResponseDataMap = new HashMap<>();
if (stringResponseMap != null) {
for (final Entry<Identifier, ResponseInput> stringResponseEntry : stringResponseMap.entrySet()) {
Identifier identifier = stringResponseEntry.getKey();
ResponseInput responseData = stringResponseEntry.getValue();
if (responseData instanceof StringInput) {
responseDataMap.put(identifier, new StringResponseData(((StringInput) responseData).getResponseData()));
}
}
}
final Date timestamp = ureq.getRequestTimestamp();
/* Attempt to bind responses */
boolean allResponsesValid = false;
boolean allResponsesBound = false;
try {
itemSessionController.bindResponses(timestamp, responseDataMap);
} catch (final QtiCandidateStateException e) {
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.RESPONSES_NOT_EXPECTED, null);
logError("RESPONSES_NOT_EXPECTED", e);
return;
} catch (final RuntimeException e) {
logError("", e);
return;
}
/* Record resulting attempt and event */
final CandidateItemEventType eventType = allResponsesBound ? (allResponsesValid ? CandidateItemEventType.ATTEMPT_VALID : CandidateItemEventType.RESPONSE_INVALID) : CandidateItemEventType.RESPONSE_BAD;
final CandidateEvent candidateEvent = qtiService.recordCandidateItemEvent(candidateSession, null, entry, eventType, itemSessionState, notificationRecorder);
candidateAuditLogger.logCandidateEvent(candidateEvent, assessmentResponseDataMap);
lastEvent = candidateEvent;
}
use of uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder in project OpenOLAT by OpenOLAT.
the class AssessmentItemDisplayController method enterSession.
private ItemSessionController enterSession(UserRequest ureq) /*, final UserTestSession candidateSession */
{
/* Set up listener to record any notifications */
final NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
/* Create fresh JQTI+ state Object and try to create controller */
itemSessionController = createNewItemSessionStateAndController(notificationRecorder);
if (itemSessionController == null) {
logError("Cannot create item session controller for:" + itemFileRef, null);
return null;
}
/* Try to Initialise JQTI+ state */
final ItemSessionState itemSessionState = itemSessionController.getItemSessionState();
try {
final Date timestamp = ureq.getRequestTimestamp();
itemSessionController.initialize(timestamp);
itemSessionController.performTemplateProcessing(timestamp);
itemSessionController.enterItem(timestamp);
} catch (final RuntimeException e) {
logError("", e);
return null;
}
/* Record and log entry event */
final CandidateEvent candidateEvent = qtiService.recordCandidateItemEvent(candidateSession, null, entry, CandidateItemEventType.ENTER, itemSessionState, notificationRecorder);
candidateAuditLogger.logCandidateEvent(candidateEvent);
lastEvent = candidateEvent;
/* Record current result state */
final AssessmentResult assessmentResult = computeAndRecordItemAssessmentResult(ureq);
/* Handle immediate end of session */
if (itemSessionState.isEnded()) {
qtiService.finishItemSession(candidateSession, assessmentResult, ureq.getRequestTimestamp());
}
return itemSessionController;
}
use of uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder in project OpenOLAT by OpenOLAT.
the class AssessmentItemDisplayController method endSession.
public void endSession(UserRequest ureq) {
NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
// final ItemSessionController itemSessionController = candidateDataService.createItemSessionController(mostRecentEvent, notificationRecorder);
ItemSessionState itemSessionState = itemSessionController.getItemSessionState();
if (itemSessionState.isEnded()) {
logError("END_SESSION_WHEN_ALREADY_ENDED", null);
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.END_SESSION_WHEN_ALREADY_ENDED, null);
return;
}
/* else if (!itemDeliverySettings.isAllowEnd()) {
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.END_SESSION_WHEN_INTERACTING_FORBIDDEN);
return null;
}*/
/* Update state */
final Date timestamp = ureq.getRequestTimestamp();
try {
itemSessionController.endItem(timestamp);
} catch (QtiCandidateStateException e) {
String msg = itemSessionState.isEnded() ? "END_SESSION_WHEN_ALREADY_ENDED" : "END_SESSION_WHEN_INTERACTING_FORBIDDEN";
logError(msg, e);
candidateAuditLogger.logAndThrowCandidateException(candidateSession, itemSessionState.isEnded() ? CandidateExceptionReason.END_SESSION_WHEN_ALREADY_ENDED : CandidateExceptionReason.END_SESSION_WHEN_INTERACTING_FORBIDDEN, null);
return;
} catch (final RuntimeException e) {
logError("", e);
// handleExplosion(e, candidateSession);
return;
}
/* Record current result state */
final AssessmentResult assessmentResult = computeAndRecordItemAssessmentResult(ureq);
/* Record and log event */
final CandidateEvent candidateEvent = qtiService.recordCandidateItemEvent(candidateSession, null, entry, CandidateItemEventType.END, itemSessionState, notificationRecorder);
candidateAuditLogger.logCandidateEvent(candidateEvent);
lastEvent = candidateEvent;
/* Close session */
qtiService.finishItemSession(candidateSession, assessmentResult, timestamp);
}
use of uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder in project OpenOLAT by OpenOLAT.
the class AssessmentTestDisplayController method processAdvanceTestPart.
private void processAdvanceTestPart(UserRequest ureq) {
/* Get current JQTI state and create JQTI controller */
NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
TestSessionState testSessionState = testSessionController.getTestSessionState();
/* Perform action */
final TestPlanNode nextTestPart;
final Date currentTimestamp = ureq.getRequestTimestamp();
try {
nextTestPart = testSessionController.enterNextAvailableTestPart(currentTimestamp);
} catch (final QtiCandidateStateException e) {
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.CANNOT_ADVANCE_TEST_PART, e);
logError("CANNOT_ADVANCE_TEST_PART", e);
return;
} catch (final RuntimeException e) {
candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.CANNOT_ADVANCE_TEST_PART, e);
logError("RuntimeException", e);
// handleExplosion(e, candidateSession);
return;
}
CandidateTestEventType eventType;
if (nextTestPart != null) {
/* Moved into next test part */
eventType = CandidateTestEventType.ADVANCE_TEST_PART;
} else {
/* No more test parts.
*
* For single part tests, we terminate the test completely now as the test feedback was shown with the testPart feedback.
* For multi-part tests, we shall keep the test open so that the test feedback can be viewed.
*/
if (testSessionState.getTestPlan().getTestPartNodes().size() == 1) {
eventType = CandidateTestEventType.EXIT_TEST;
testSessionController.exitTest(currentTimestamp);
candidateSession.setTerminationTime(currentTimestamp);
candidateSession = qtiService.updateAssessmentTestSession(candidateSession);
} else {
eventType = CandidateTestEventType.ADVANCE_TEST_PART;
}
}
boolean terminated = isTerminated();
/* Record current result state */
computeAndRecordTestAssessmentResult(currentTimestamp, testSessionState, terminated);
/* Record and log event */
final CandidateEvent candidateTestEvent = qtiService.recordCandidateTestEvent(candidateSession, testEntry, entry, eventType, testSessionState, notificationRecorder);
candidateAuditLogger.logCandidateEvent(candidateTestEvent);
this.lastEvent = candidateTestEvent;
if (terminated) {
qtiWorksCtrl.updateStatusAndResults(ureq);
doExitTest(ureq);
}
}
Aggregations