Search in sources :

Example 1 with TestSessionState

use of uk.ac.ed.ph.jqtiplus.state.TestSessionState in project OpenOLAT by OpenOLAT.

the class AssessmentTestComponent method getCurrentTestPartNode.

public TestPlanNode getCurrentTestPartNode() {
    TestSessionState sessionState = getTestSessionController().getTestSessionState();
    TestPlanNodeKey testPlanNodeKey = sessionState.getCurrentTestPartKey();
    return sessionState.getTestPlan().getNode(testPlanNodeKey);
}
Also used : TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)

Example 2 with TestSessionState

use of uk.ac.ed.ph.jqtiplus.state.TestSessionState in project OpenOLAT by OpenOLAT.

the class AssessmentTreeComponentRenderer method renderTestEvent.

private void renderTestEvent(TestSessionController testSessionController, AssessmentRenderer renderer, StringOutput target, AssessmentTreeComponent component, URLBuilder ubu, Translator translator, RenderingRequest options) {
    CandidateSessionContext candidateSessionContext = component.getCandidateSessionContext();
    CandidateEvent candidateEvent = candidateSessionContext.getLastEvent();
    CandidateTestEventType testEventType = candidateEvent.getTestEventType();
    final TestSessionState testSessionState = testSessionController.getTestSessionState();
    if (!candidateSessionContext.isTerminated() && !testSessionState.isExited()) {
        if (testEventType == CandidateTestEventType.REVIEW_ITEM) {
            renderer.setReviewMode(true);
        } else if (testEventType == CandidateTestEventType.SOLUTION_ITEM) {
            renderer.setSolutionMode(true);
        }
        renderNavigation(renderer, target, component, ubu, translator, options);
    }
}
Also used : CandidateSessionContext(org.olat.ims.qti21.ui.CandidateSessionContext) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) CandidateTestEventType(org.olat.ims.qti21.model.audit.CandidateTestEventType) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent)

Example 3 with TestSessionState

use of uk.ac.ed.ph.jqtiplus.state.TestSessionState in project OpenOLAT by OpenOLAT.

the class QTI21ServiceImpl method reopenAssessmentTestSession.

/*
	@Override
	public AssessmentTestSession reopenAssessmentTestSession(AssessmentTestSession session, Identity actor) {
		// update test session on the database
		AssessmentTestSession reloadedSession = testSessionDao.loadByKey(session.getKey());

		//update the XMl test session state
		TestSessionState testSessionState = loadTestSessionState(reloadedSession);
		testSessionState.setEndTime(null);
		testSessionState.setExitTime(null);
		for(TestPartSessionState testPartSessionState:testSessionState.getTestPartSessionStates().values()) {
			testPartSessionState.setEndTime(null);
			testPartSessionState.setExitTime(null);
		}
		for(AssessmentSectionSessionState sessionState:testSessionState.getAssessmentSectionSessionStates().values()) {
			sessionState.setEndTime(null);
			sessionState.setExitTime(null);
		}
		
		TestPlanNodeKey lastEntryItemKey = null;
		ItemSessionState lastEntryItemSessionState = null;
		for(Map.Entry<TestPlanNodeKey, ItemSessionState> entry:testSessionState.getItemSessionStates().entrySet()) {
			ItemSessionState itemSessionState = entry.getValue();
			itemSessionState.setEndTime(null);
			itemSessionState.setExitTime(null);
			if(itemSessionState.getEntryTime() != null &&
					(lastEntryItemSessionState == null || itemSessionState.getEntryTime().after(lastEntryItemSessionState.getEntryTime()))) {
				lastEntryItemKey = entry.getKey();
				lastEntryItemSessionState = itemSessionState;
			}
		}
		
		if(lastEntryItemKey != null) {
			Date now = new Date();
			TestPlan plan = testSessionState.getTestPlan();
			TestPlanNodeKey currentTestPartKey = null;
			for(TestPlanNode currentNode = plan.getNode(lastEntryItemKey); currentNode != null; currentNode = currentNode.getParent()) {
				TestNodeType type = currentNode.getTestNodeType();
				TestPlanNodeKey currentNodeKey = currentNode.getKey();
				switch(type) {
					case TEST_PART: {
						currentTestPartKey = currentNodeKey;
						TestPartSessionState state = testSessionState.getTestPartSessionStates().get(currentNodeKey);
						if(state != null) {
							state.setDurationIntervalStartTime(now);
						}
						break;
					}
					case ASSESSMENT_SECTION: {
						AssessmentSectionSessionState sessionState = testSessionState.getAssessmentSectionSessionStates().get(currentNodeKey);
						if(sessionState != null) {
							sessionState.setDurationIntervalStartTime(now);
						}
						break;
					}
					case ASSESSMENT_ITEM_REF: {
						ItemSessionState itemState = testSessionState.getItemSessionStates().get(currentNodeKey);
						if(itemState != null) {
							itemState.setDurationIntervalStartTime(now);
						}
						break;
					}
					default: {
						//root doesn't match any session state
						break;
					}
				}
			}
			
			//if all the elements are started again, allow to reopen the test
			if(currentTestPartKey != null) {
				testSessionState.setCurrentTestPartKey(currentTestPartKey);
				testSessionState.setCurrentItemKey(lastEntryItemKey);
				storeTestSessionState(reloadedSession, testSessionState);
				
				reloadedSession.setFinishTime(null);
				reloadedSession.setTerminationTime(null);
				reloadedSession = testSessionDao.update(reloadedSession);
				
				AssessmentSessionAuditLogger candidateAuditLogger = getAssessmentSessionAuditLogger(session, false);
				candidateAuditLogger.logTestReopen(session, actor);
				
				RetrieveAssessmentTestSessionEvent event = new RetrieveAssessmentTestSessionEvent(session.getKey());
				OLATResourceable sessionOres = OresHelper.createOLATResourceableInstance(AssessmentTestSession.class, session.getKey());
				coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(event, sessionOres);
				return reloadedSession;
			}
		}
		return null;
	}*/
@Override
public AssessmentTestSession reopenAssessmentTestSession(AssessmentTestSession session, Identity actor) {
    AssessmentTestSession reloadedSession = testSessionDao.loadByKey(session.getKey());
    // update the XMl test session state
    TestSessionState testSessionState = loadTestSessionState(reloadedSession);
    testSessionState.setEndTime(null);
    testSessionState.setExitTime(null);
    TestPlanNodeKey lastEntryItemKey = null;
    ItemSessionState lastEntryItemSessionState = null;
    for (Map.Entry<TestPlanNodeKey, ItemSessionState> entry : testSessionState.getItemSessionStates().entrySet()) {
        ItemSessionState itemSessionState = entry.getValue();
        if (itemSessionState.getEntryTime() != null && (lastEntryItemSessionState == null || itemSessionState.getEntryTime().after(lastEntryItemSessionState.getEntryTime()))) {
            lastEntryItemKey = entry.getKey();
            lastEntryItemSessionState = itemSessionState;
        }
    }
    if (lastEntryItemKey != null) {
        TestPlan plan = testSessionState.getTestPlan();
        TestPlanNode lastItem = plan.getNode(lastEntryItemKey);
        TestPlanNodeKey partKey = reopenTestPart(lastItem, testSessionState);
        resumeItem(lastEntryItemKey, testSessionState);
        // if all the elements are started again, allow to reopen the test
        if (partKey != null) {
            testSessionState.setCurrentTestPartKey(partKey);
            testSessionState.setCurrentItemKey(lastEntryItemKey);
            storeTestSessionState(reloadedSession, testSessionState);
            reloadedSession.setFinishTime(null);
            reloadedSession.setTerminationTime(null);
            reloadedSession = testSessionDao.update(reloadedSession);
            AssessmentSessionAuditLogger candidateAuditLogger = getAssessmentSessionAuditLogger(session, false);
            candidateAuditLogger.logTestReopen(session, actor);
            RetrieveAssessmentTestSessionEvent event = new RetrieveAssessmentTestSessionEvent(session.getKey());
            OLATResourceable sessionOres = OresHelper.createOLATResourceableInstance(AssessmentTestSession.class, session.getKey());
            coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(event, sessionOres);
            return reloadedSession;
        }
    }
    return null;
}
Also used : TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) AssessmentTestSession(org.olat.ims.qti21.AssessmentTestSession) InMemoryAssessmentTestSession(org.olat.ims.qti21.model.InMemoryAssessmentTestSession) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) TestPlan(uk.ac.ed.ph.jqtiplus.state.TestPlan) OLATResourceable(org.olat.core.id.OLATResourceable) ItemSessionState(uk.ac.ed.ph.jqtiplus.state.ItemSessionState) AssessmentSessionAuditLogger(org.olat.ims.qti21.AssessmentSessionAuditLogger) RetrieveAssessmentTestSessionEvent(org.olat.ims.qti21.ui.event.RetrieveAssessmentTestSessionEvent) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)

Example 4 with TestSessionState

use of uk.ac.ed.ph.jqtiplus.state.TestSessionState 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);
    }
}
Also used : TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) QtiCandidateStateException(uk.ac.ed.ph.jqtiplus.exception.QtiCandidateStateException) OLATRuntimeException(org.olat.core.logging.OLATRuntimeException) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) CandidateTestEventType(org.olat.ims.qti21.model.audit.CandidateTestEventType) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) Date(java.util.Date) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent)

Example 5 with TestSessionState

use of uk.ac.ed.ph.jqtiplus.state.TestSessionState in project OpenOLAT by OpenOLAT.

the class AssessmentTestDisplayController method enterSession.

// private CandidateSession enterCandidateSession(final CandidateSession candidateSession)
private TestSessionController enterSession(UserRequest ureq) {
    /* Set up listener to record any notifications */
    final NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
    /* Create fresh JQTI+ state & controller for it */
    testSessionController = createNewTestSessionStateAndController(notificationRecorder);
    if (testSessionController == null) {
        return null;
    }
    /* Initialise test state and enter test */
    final TestSessionState testSessionState = testSessionController.getTestSessionState();
    final Date timestamp = ureq.getRequestTimestamp();
    try {
        testSessionController.initialize(timestamp);
        final int testPartCount = testSessionController.enterTest(timestamp);
        if (testPartCount == 1) {
            /* If there is only testPart, then enter this (if possible).
                 * (Note that this may cause the test to exit immediately if there is a failed
                 * preCondition on this part.)
                 */
            testSessionController.enterNextAvailableTestPart(timestamp);
        } else {
        /* Don't enter first testPart yet - we shall tell candidate that
                 * there are multiple parts and let them enter manually.
                 */
        }
    } catch (final RuntimeException e) {
        logError("", e);
        return null;
    }
    /* Record and log event */
    final CandidateEvent candidateEvent = qtiService.recordCandidateTestEvent(candidateSession, testEntry, entry, CandidateTestEventType.ENTER_TEST, testSessionState, notificationRecorder);
    candidateAuditLogger.logCandidateEvent(candidateEvent);
    this.lastEvent = candidateEvent;
    boolean ended = testSessionState.isEnded();
    /* Record current result state */
    final AssessmentResult assessmentResult = computeAndRecordTestAssessmentResult(timestamp, testSessionState, ended);
    /* Handle immediate end of test session */
    if (ended) {
        candidateSession = qtiService.finishTestSession(candidateSession, testSessionState, assessmentResult, timestamp, getDigitalSignatureOptions(), getIdentity());
    } else {
        TestPart currentTestPart = testSessionController.getCurrentTestPart();
        if (currentTestPart != null && currentTestPart.getNavigationMode() == NavigationMode.NONLINEAR) {
            // go to the first assessment item
            if (testSessionController.hasFollowingNonLinearItem()) {
                testSessionController.selectFollowingItemNonLinear(currentRequestTimestamp);
            }
        }
    }
    return testSessionController;
}
Also used : OLATRuntimeException(org.olat.core.logging.OLATRuntimeException) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) TestPart(uk.ac.ed.ph.jqtiplus.node.test.TestPart) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) AssessmentResult(uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult) Date(java.util.Date) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent)

Aggregations

TestSessionState (uk.ac.ed.ph.jqtiplus.state.TestSessionState)78 TestPlanNodeKey (uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)42 CandidateEvent (org.olat.ims.qti21.model.audit.CandidateEvent)34 TestPlanNode (uk.ac.ed.ph.jqtiplus.state.TestPlanNode)32 NotificationRecorder (uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder)30 Date (java.util.Date)24 ItemSessionState (uk.ac.ed.ph.jqtiplus.state.ItemSessionState)24 AssessmentTestSession (org.olat.ims.qti21.AssessmentTestSession)19 OLATRuntimeException (org.olat.core.logging.OLATRuntimeException)18 AssessmentItemSession (org.olat.ims.qti21.AssessmentItemSession)18 HashMap (java.util.HashMap)15 QtiCandidateStateException (uk.ac.ed.ph.jqtiplus.exception.QtiCandidateStateException)13 AssessmentResult (uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult)12 TestSessionController (uk.ac.ed.ph.jqtiplus.running.TestSessionController)12 ArrayList (java.util.ArrayList)10 CandidateTestEventType (org.olat.ims.qti21.model.audit.CandidateTestEventType)10 AssessmentItemRef (uk.ac.ed.ph.jqtiplus.node.test.AssessmentItemRef)10 Identity (org.olat.core.id.Identity)9 File (java.io.File)8 ParentPartItemRefs (org.olat.ims.qti21.model.ParentPartItemRefs)8