Search in sources :

Example 6 with ItemSessionController

use of uk.ac.ed.ph.jqtiplus.running.ItemSessionController in project openolat by klemens.

the class AssessmentItemDisplayController method createNewItemSessionStateAndController.

public ItemSessionController createNewItemSessionStateAndController(NotificationRecorder notificationRecorder) {
    /* Resolve the underlying JQTI+ object */
    final ItemProcessingMap itemProcessingMap = getItemProcessingMap();
    if (itemProcessingMap == null) {
        return null;
    }
    /* Create fresh state for session */
    final ItemSessionState itemSessionState = new ItemSessionState();
    /* Create config for ItemSessionController */
    final ItemSessionControllerSettings itemSessionControllerSettings = new ItemSessionControllerSettings();
    itemSessionControllerSettings.setTemplateProcessingLimit(computeTemplateProcessingLimit());
    itemSessionControllerSettings.setMaxAttempts(10);
    /* Create controller and wire up notification recorder */
    final ItemSessionController result = new ItemSessionController(qtiService.jqtiExtensionManager(), itemSessionControllerSettings, itemProcessingMap, itemSessionState);
    if (notificationRecorder != null) {
        result.addNotificationListener(notificationRecorder);
    }
    return result;
}
Also used : ItemSessionControllerSettings(uk.ac.ed.ph.jqtiplus.running.ItemSessionControllerSettings) ItemProcessingMap(uk.ac.ed.ph.jqtiplus.state.ItemProcessingMap) ItemSessionState(uk.ac.ed.ph.jqtiplus.state.ItemSessionState) ItemSessionController(uk.ac.ed.ph.jqtiplus.running.ItemSessionController)

Example 7 with ItemSessionController

use of uk.ac.ed.ph.jqtiplus.running.ItemSessionController in project openolat by klemens.

the class AssessmentTestDisplayController method resumeSession.

private TestSessionController resumeSession(UserRequest ureq) {
    Date requestTimestamp = ureq.getRequestTimestamp();
    final NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
    TestSessionController controller = createTestSessionController(notificationRecorder);
    if (!controller.getTestSessionState().isEnded() && !controller.getTestSessionState().isExited()) {
        controller.unsuspendTestSession(requestTimestamp);
        TestSessionState testSessionState = controller.getTestSessionState();
        TestPlanNodeKey currentItemKey = testSessionState.getCurrentItemKey();
        if (currentItemKey != null) {
            TestPlanNode currentItemNode = testSessionState.getTestPlan().getNode(currentItemKey);
            ItemProcessingContext itemProcessingContext = controller.getItemProcessingContext(currentItemNode);
            ItemSessionState itemSessionState = itemProcessingContext.getItemSessionState();
            if (itemProcessingContext instanceof ItemSessionController && itemSessionState.isSuspended()) {
                ItemSessionController itemSessionController = (ItemSessionController) itemProcessingContext;
                itemSessionController.unsuspendItemSession(requestTimestamp);
            }
        }
    }
    return controller;
}
Also used : TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) ItemSessionState(uk.ac.ed.ph.jqtiplus.state.ItemSessionState) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) TestSessionController(uk.ac.ed.ph.jqtiplus.running.TestSessionController) ItemSessionController(uk.ac.ed.ph.jqtiplus.running.ItemSessionController) Date(java.util.Date) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey) ItemProcessingContext(uk.ac.ed.ph.jqtiplus.running.ItemProcessingContext)

Example 8 with ItemSessionController

use of uk.ac.ed.ph.jqtiplus.running.ItemSessionController in project openolat by klemens.

the class AssessmentTestDisplayController method handleTemporaryResponse.

private void handleTemporaryResponse(UserRequest ureq, Map<Identifier, ResponseInput> stringResponseMap) {
    NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
    TestSessionState testSessionState = testSessionController.getTestSessionState();
    TestPlanNodeKey currentItemKey = testSessionState.getCurrentItemKey();
    if (currentItemKey == null) {
        // 
        return;
    }
    String cmd = ureq.getParameter("tmpResponse");
    if (!qtiWorksCtrl.validateResponseIdentifierCommand(cmd, currentItemKey)) {
        // this is not the right node in the plan
        return;
    }
    final Date timestamp = ureq.getRequestTimestamp();
    final Map<Identifier, ResponseData> responseDataMap = new HashMap<>();
    if (stringResponseMap != null) {
        for (final Entry<Identifier, ResponseInput> responseEntry : stringResponseMap.entrySet()) {
            final Identifier identifier = responseEntry.getKey();
            final ResponseInput responseData = responseEntry.getValue();
            if (responseData instanceof StringInput) {
                responseDataMap.put(identifier, new StringResponseData(((StringInput) responseData).getResponseData()));
            }
        }
    }
    ParentPartItemRefs parentParts = getParentSection(currentItemKey);
    String assessmentItemIdentifier = currentItemKey.getIdentifier().toString();
    AssessmentItemSession itemSession = qtiService.getOrCreateAssessmentItemSession(candidateSession, parentParts, assessmentItemIdentifier);
    TestPlanNode currentItemRefNode = testSessionState.getTestPlan().getNode(currentItemKey);
    ItemSessionController itemSessionController = (ItemSessionController) testSessionController.getItemProcessingContext(currentItemRefNode);
    ItemSessionState itemSessionState = itemSessionController.getItemSessionState();
    List<Interaction> interactions = itemSessionController.getInteractions();
    Map<Identifier, Interaction> interactionMap = new HashMap<>();
    for (Interaction interaction : interactions) {
        interactionMap.put(interaction.getResponseIdentifier(), interaction);
    }
    Map<Identifier, AssessmentResponse> candidateResponseMap = qtiService.getAssessmentResponses(itemSession);
    for (Entry<Identifier, ResponseData> responseEntry : responseDataMap.entrySet()) {
        Identifier responseIdentifier = responseEntry.getKey();
        ResponseData responseData = responseEntry.getValue();
        AssessmentResponse candidateItemResponse;
        if (candidateResponseMap.containsKey(responseIdentifier)) {
            candidateItemResponse = candidateResponseMap.get(responseIdentifier);
        } else {
            candidateItemResponse = qtiService.createAssessmentResponse(candidateSession, itemSession, responseIdentifier.toString(), ResponseLegality.VALID, responseData.getType());
        }
        switch(responseData.getType()) {
            case STRING:
                {
                    List<String> data = ((StringResponseData) responseData).getResponseData();
                    String stringuifiedResponse = ResponseFormater.format(data);
                    candidateItemResponse.setStringuifiedResponse(stringuifiedResponse);
                    break;
                }
            default:
                throw new OLATRuntimeException("Unexpected switch case: " + responseData.getType());
        }
        candidateResponseMap.put(responseIdentifier, candidateItemResponse);
        itemSessionState.setRawResponseData(responseIdentifier, responseData);
        try {
            Interaction interaction = interactionMap.get(responseIdentifier);
            interaction.bindResponse(itemSessionController, responseData);
        } catch (final ResponseBindingException e) {
        // 
        }
    }
    /* Copy uncommitted responses over */
    for (final Entry<Identifier, Value> uncommittedResponseEntry : itemSessionState.getUncommittedResponseValues().entrySet()) {
        final Identifier identifier = uncommittedResponseEntry.getKey();
        final Value value = uncommittedResponseEntry.getValue();
        itemSessionState.setResponseValue(identifier, value);
    }
    /* Persist CandidateResponse entities */
    qtiService.recordTestAssessmentResponses(itemSession, candidateResponseMap.values());
    /* Record resulting event */
    final CandidateEvent candidateEvent = qtiService.recordCandidateTestEvent(candidateSession, testEntry, entry, CandidateTestEventType.ITEM_EVENT, null, currentItemKey, testSessionState, notificationRecorder);
    candidateAuditLogger.logCandidateEvent(candidateEvent, candidateResponseMap);
    /* Record current result state */
    AssessmentResult assessmentResult = computeTestAssessmentResult(timestamp, candidateSession);
    synchronized (this) {
        qtiService.recordTestAssessmentResult(candidateSession, testSessionState, assessmentResult, candidateAuditLogger);
    }
}
Also used : TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) HashMap(java.util.HashMap) ResponseBindingException(uk.ac.ed.ph.jqtiplus.exception.ResponseBindingException) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent) Identifier(uk.ac.ed.ph.jqtiplus.types.Identifier) StringResponseData(uk.ac.ed.ph.jqtiplus.types.StringResponseData) AssessmentItemSession(org.olat.ims.qti21.AssessmentItemSession) List(java.util.List) AssessmentResult(uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult) ParentPartItemRefs(org.olat.ims.qti21.model.ParentPartItemRefs) TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) Interaction(uk.ac.ed.ph.jqtiplus.node.item.interaction.Interaction) FileResponseData(uk.ac.ed.ph.jqtiplus.types.FileResponseData) StringResponseData(uk.ac.ed.ph.jqtiplus.types.StringResponseData) ResponseData(uk.ac.ed.ph.jqtiplus.types.ResponseData) ItemSessionState(uk.ac.ed.ph.jqtiplus.state.ItemSessionState) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) ItemSessionController(uk.ac.ed.ph.jqtiplus.running.ItemSessionController) AssessmentResponse(org.olat.ims.qti21.AssessmentResponse) Date(java.util.Date) StringInput(org.olat.ims.qti21.ui.ResponseInput.StringInput) OLATRuntimeException(org.olat.core.logging.OLATRuntimeException) Value(uk.ac.ed.ph.jqtiplus.value.Value) NumberValue(uk.ac.ed.ph.jqtiplus.value.NumberValue) FloatValue(uk.ac.ed.ph.jqtiplus.value.FloatValue) IntegerValue(uk.ac.ed.ph.jqtiplus.value.IntegerValue) BooleanValue(uk.ac.ed.ph.jqtiplus.value.BooleanValue) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)

Example 9 with ItemSessionController

use of uk.ac.ed.ph.jqtiplus.running.ItemSessionController in project openolat by klemens.

the class AssessmentTestDisplayController method suspendAssessmentTest.

/**
 * It suspend the current item
 * @return
 */
private boolean suspendAssessmentTest(Date requestTimestamp) {
    if (!deliveryOptions.isEnableSuspend() || testSessionController == null || testSessionController.getTestSessionState() == null || testSessionController.getTestSessionState().isEnded() || testSessionController.getTestSessionState().isExited() || testSessionController.getTestSessionState().isSuspended()) {
        return false;
    }
    testSessionController.touchDurations(currentRequestTimestamp);
    testSessionController.suspendTestSession(requestTimestamp);
    TestSessionState testSessionState = testSessionController.getTestSessionState();
    TestPlanNodeKey currentItemKey = testSessionState.getCurrentItemKey();
    if (currentItemKey == null) {
        return false;
    }
    TestPlanNode currentItemNode = testSessionState.getTestPlan().getNode(currentItemKey);
    ItemProcessingContext itemProcessingContext = testSessionController.getItemProcessingContext(currentItemNode);
    ItemSessionState itemSessionState = itemProcessingContext.getItemSessionState();
    if (itemProcessingContext instanceof ItemSessionController && !itemSessionState.isEnded() && !itemSessionState.isExited() && itemSessionState.isOpen() && !itemSessionState.isSuspended()) {
        ItemSessionController itemSessionController = (ItemSessionController) itemProcessingContext;
        itemSessionController.suspendItemSession(requestTimestamp);
        computeAndRecordTestAssessmentResult(requestTimestamp, testSessionState, false);
        NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
        final CandidateEvent candidateEvent = qtiService.recordCandidateTestEvent(candidateSession, testEntry, entry, CandidateTestEventType.SUSPEND, null, null, testSessionState, notificationRecorder);
        candidateAuditLogger.logCandidateEvent(candidateEvent);
        this.lastEvent = candidateEvent;
        return true;
    }
    return false;
}
Also used : TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) ItemSessionState(uk.ac.ed.ph.jqtiplus.state.ItemSessionState) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) ItemSessionController(uk.ac.ed.ph.jqtiplus.running.ItemSessionController) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey) ItemProcessingContext(uk.ac.ed.ph.jqtiplus.running.ItemProcessingContext) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent)

Example 10 with ItemSessionController

use of uk.ac.ed.ph.jqtiplus.running.ItemSessionController in project openolat by klemens.

the class SingleChoiceAssessmentItemBuilderTest method createSingleAssessmentItem_allCorrectAnswers.

@Test
public void createSingleAssessmentItem_allCorrectAnswers() throws IOException {
    QtiSerializer qtiSerializer = new QtiSerializer(new JqtiExtensionManager());
    SingleChoiceAssessmentItemBuilder itemBuilder = new SingleChoiceAssessmentItemBuilder("Single choice", "Single choice", qtiSerializer);
    itemBuilder.setQuestion("<p>Hello</p>");
    ChoiceInteraction interaction = itemBuilder.getChoiceInteraction();
    SimpleChoice choice1 = AssessmentItemFactory.createSimpleChoice(interaction, "One", "sc");
    SimpleChoice choice2 = AssessmentItemFactory.createSimpleChoice(interaction, "Two", "sc");
    SimpleChoice choice3 = AssessmentItemFactory.createSimpleChoice(interaction, "Three", "sc");
    List<SimpleChoice> choiceList = new ArrayList<>();
    choiceList.add(choice1);
    choiceList.add(choice2);
    choiceList.add(choice3);
    itemBuilder.setSimpleChoices(choiceList);
    itemBuilder.setCorrectAnswer(choice2.getIdentifier());
    itemBuilder.setMaxScore(3.0d);
    itemBuilder.setScoreEvaluationMode(ScoreEvaluation.allCorrectAnswers);
    itemBuilder.build();
    File itemFile = new File(WebappHelper.getTmpDir(), "scAssessmentItem" + UUID.randomUUID() + ".xml");
    try (FileOutputStream out = new FileOutputStream(itemFile)) {
        qtiSerializer.serializeJqtiObject(itemBuilder.getAssessmentItem(), out);
    } catch (Exception e) {
        log.error("", e);
    }
    {
        // correct answers
        Map<Identifier, ResponseData> responseMap = new HashMap<>();
        Identifier responseIdentifier = itemBuilder.getInteraction().getResponseIdentifier();
        responseMap.put(responseIdentifier, new StringResponseData(choice2.getIdentifier().toString()));
        ItemSessionController itemSessionController = RunningItemHelper.run(itemFile, responseMap);
        Value score = itemSessionController.getItemSessionState().getOutcomeValue(QTI21Constants.SCORE_IDENTIFIER);
        Assert.assertEquals(new FloatValue(3.0d), score);
    }
    {
        // wrong answer
        Map<Identifier, ResponseData> responseMap = new HashMap<>();
        Identifier responseIdentifier = itemBuilder.getInteraction().getResponseIdentifier();
        responseMap.put(responseIdentifier, new StringResponseData(choice3.getIdentifier().toString()));
        ItemSessionController itemSessionController = RunningItemHelper.run(itemFile, responseMap);
        Value score = itemSessionController.getItemSessionState().getOutcomeValue(QTI21Constants.SCORE_IDENTIFIER);
        Assert.assertEquals(new FloatValue(0.0d), score);
    }
    FileUtils.deleteDirsAndFiles(itemFile.toPath());
}
Also used : SimpleChoice(uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.SimpleChoice) SingleChoiceAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder) ArrayList(java.util.ArrayList) ItemSessionController(uk.ac.ed.ph.jqtiplus.running.ItemSessionController) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) Identifier(uk.ac.ed.ph.jqtiplus.types.Identifier) JqtiExtensionManager(uk.ac.ed.ph.jqtiplus.JqtiExtensionManager) StringResponseData(uk.ac.ed.ph.jqtiplus.types.StringResponseData) QtiSerializer(uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer) FileOutputStream(java.io.FileOutputStream) FloatValue(uk.ac.ed.ph.jqtiplus.value.FloatValue) Value(uk.ac.ed.ph.jqtiplus.value.Value) ChoiceInteraction(uk.ac.ed.ph.jqtiplus.node.item.interaction.ChoiceInteraction) FloatValue(uk.ac.ed.ph.jqtiplus.value.FloatValue) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Aggregations

ItemSessionController (uk.ac.ed.ph.jqtiplus.running.ItemSessionController)26 ItemSessionState (uk.ac.ed.ph.jqtiplus.state.ItemSessionState)20 Date (java.util.Date)12 NotificationRecorder (uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder)10 HashMap (java.util.HashMap)8 ItemProcessingContext (uk.ac.ed.ph.jqtiplus.running.ItemProcessingContext)8 ItemSessionControllerSettings (uk.ac.ed.ph.jqtiplus.running.ItemSessionControllerSettings)8 ItemProcessingMap (uk.ac.ed.ph.jqtiplus.state.ItemProcessingMap)8 Identifier (uk.ac.ed.ph.jqtiplus.types.Identifier)8 StringResponseData (uk.ac.ed.ph.jqtiplus.types.StringResponseData)8 FloatValue (uk.ac.ed.ph.jqtiplus.value.FloatValue)8 Value (uk.ac.ed.ph.jqtiplus.value.Value)8 File (java.io.File)6 FileOutputStream (java.io.FileOutputStream)6 IOException (java.io.IOException)6 URISyntaxException (java.net.URISyntaxException)6 Map (java.util.Map)6 Test (org.junit.Test)6 CandidateEvent (org.olat.ims.qti21.model.audit.CandidateEvent)6 JqtiExtensionManager (uk.ac.ed.ph.jqtiplus.JqtiExtensionManager)6