Search in sources :

Example 21 with ItemContext

use of org.olat.ims.qti.container.ItemContext in project openolat by klemens.

the class IQComponentRenderer method buildForm.

/**
 * Render the QTI form
 * @param comp
 * @param translator
 * @param renderer
 * @return rendered form
 */
public StringOutput buildForm(IQComponent comp, Translator translator, Renderer renderer, URLBuilder ubu) {
    StringOutput sb = new StringOutput();
    Info info = comp.getAssessmentInstance().getNavigator().getInfo();
    AssessmentInstance ai = comp.getAssessmentInstance();
    int status = info.getStatus();
    int message = info.getMessage();
    boolean renderItems = info.isRenderItems();
    AssessmentContext act = ai.getAssessmentContext();
    // first treat messages and errors
    if (info.containsMessage()) {
        switch(message) {
            case QTIConstants.MESSAGE_ITEM_SUBMITTED:
                // item hints?
                if (info.isHint()) {
                    Hint el_hint = info.getCurrentOutput().getHint();
                    if (el_hint.getFeedbackstyle() == Hint.FEEDBACKSTYLE_INCREMENTAL) {
                        // increase the hint level so we know which hint to display
                        ItemContext itc = act.getCurrentSectionContext().getCurrentItemContext();
                        int nLevel = itc.getHintLevel() + 1;
                        int numofhints = el_hint.getChildCount();
                        if (nLevel > numofhints)
                            nLevel = numofhints;
                        itc.setHintLevel(nLevel);
                        // <!ELEMENT hint (qticomment? , hintmaterial+)>
                        displayFeedback(sb, (GenericQTIElement) el_hint.getChildAt(nLevel - 1), ai, translator.getLocale());
                    } else {
                        displayFeedback(sb, el_hint, ai, translator.getLocale());
                    }
                }
                // item solution?
                if (info.isSolution()) {
                    Solution el_solution = info.getCurrentOutput().getSolution();
                    displayFeedback(sb, el_solution, ai, translator.getLocale());
                }
                // item fb?
                renderFeedback(info, sb, ai, translator);
                if (!comp.getMenuDisplayConf().isEnabledMenu() && comp.getMenuDisplayConf().isItemPageSequence() && !info.isRenderItems()) {
                    // if item was submitted and sequence is pageSequence and menu not enabled and isRenderItems returns false show section info
                    SectionContext sc = ai.getAssessmentContext().getCurrentSectionContext();
                    displaySectionInfo(sb, sc, ai, comp, ubu, translator);
                }
                break;
            case QTIConstants.MESSAGE_SECTION_SUBMITTED:
                // SectionContext sc = act.getCurrentSectionContext();
                if (info.isFeedback()) {
                    Output outp = info.getCurrentOutput();
                    GenericQTIElement el_feedback = outp.getEl_response();
                    if (el_feedback != null) {
                        displayFeedback(sb, el_feedback, ai, translator.getLocale());
                    } else {
                        renderFeedback(info, sb, ai, translator);
                    }
                }
                if (!comp.getMenuDisplayConf().isEnabledMenu() && !comp.getMenuDisplayConf().isItemPageSequence()) {
                    SectionContext sc = ai.getAssessmentContext().getCurrentSectionContext();
                    displaySectionInfo(sb, sc, ai, comp, ubu, translator);
                }
                break;
            case QTIConstants.MESSAGE_ASSESSMENT_SUBMITTED:
                // provide assessment feedback if enabled and existing
                if (info.isFeedback()) {
                    Output outp = info.getCurrentOutput();
                    GenericQTIElement el_feedback = outp.getEl_response();
                    if (el_feedback != null)
                        displayFeedback(sb, el_feedback, ai, translator.getLocale());
                }
                break;
            case // for menu item navigator
            QTIConstants.MESSAGE_SECTION_INFODEMANDED:
                // provide some stats maybe
                SectionContext sc = ai.getAssessmentContext().getCurrentSectionContext();
                displaySectionInfo(sb, sc, ai, comp, ubu, translator);
                break;
            case // at the start of the test
            QTIConstants.MESSAGE_ASSESSMENT_INFODEMANDED:
                displayAssessmentInfo(sb, act, ai, comp, ubu, translator);
                break;
        }
    }
    if (renderItems) {
        boolean displayForm = true;
        // First check wether we need to render a form.
        // No form is needed if the current item has a matapplet object to be displayed.
        // Matapplets will send their response back directly.
        SectionContext sct = act.getCurrentSectionContext();
        ItemContext itc = null;
        if (sct != null && !ai.isSectionPage()) {
            itc = sct.getCurrentItemContext();
            if (itc != null) {
                Item item = itc.getQtiItem();
                if (item.getQTIIdent().startsWith("QTIEDIT:FLA:"))
                    displayForm = false;
            }
        }
        // do not display form with button in case no more item is open
        if (sct != null && ai.isSectionPage()) {
            displayForm = sct.getItemsOpenCount() > 0;
        }
        sb.append("<form action=\"");
        ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "sitse" });
        sb.append("\" id=\"ofo_iq_item\" method=\"post\">");
        String memoId = null;
        String memoTx = "";
        boolean memo = comp.provideMemoField();
        if (!ai.isSectionPage()) {
            if (itc != null) {
                displayItem(sb, renderer, ubu, itc, ai);
                if (memo) {
                    memoId = itc.getIdent();
                    memoTx = ai.getMemo(memoId);
                }
            }
        } else {
            if (sct != null && sct.getItemContextCount() != 0) {
                displayItems(sb, renderer, ubu, sct, ai);
                if (memo) {
                    memoId = sct.getIdent();
                    memoTx = ai.getMemo(memoId);
                }
            }
        }
        boolean isDefaultMemo = false;
        if (memo) {
            if (memoTx == null) {
                isDefaultMemo = true;
                memoTx = translator.translate("qti.memofield.text");
            }
        }
        sb.append("<div class=\"row\">");
        sb.append("<div class='o_button_group'>");
        sb.append("<input class=\"btn btn-primary\" type=\"submit\" name=\"olat_fosm\" value=\"");
        if (ai.isSectionPage())
            sb.append(StringEscapeUtils.escapeHtml(translator.translate("submitMultiAnswers")));
        else
            sb.append(StringEscapeUtils.escapeHtml(translator.translate("submitSingleAnswer")));
        sb.append("\"");
        if (!displayForm)
            sb.append(" style=\"display: none;\"");
        sb.append(" />").append("</div><div class='col-md-10'>");
        if (memo && memoId != null) {
            sb.append("<div class=\"o_qti_item_note_box\">");
            sb.append("<label class=\"control-label\" for=\"o_qti_item_note\">").append(translator.translate("qti.memofield")).append("</label>");
            sb.append("<textarea id=\"o_qti_item_note\" class=\"form-control\" rows=\"4\" spellcheck=\"false\" onchange=\"memo('");
            sb.append(memoId);
            sb.append("', this.value);\" onkeyup=\"resize(this);\" onmouseup=\"resize(this);\"");
            if (isDefaultMemo) {
                sb.append(" onfocus=\"clrMemo(this);\"");
            }
            sb.append(">").append(memoTx).append("</textarea>").append("</div>");
        }
        // end memo
        sb.append("</div>").append(// end row
        "</div>").append("</form>");
    }
    if (status == QTIConstants.ASSESSMENT_FINISHED) {
        if (info.isFeedback()) {
            Output outp = info.getCurrentOutput();
            GenericQTIElement el_feedback = outp.getEl_response();
            if (el_feedback != null) {
                displayFeedback(sb, el_feedback, ai, null);
            } else {
                renderFeedback(info, sb, ai, translator);
                // add the next button
                sb.append("<a class=\"btn btn-primary\" onclick=\"return o2cl()\" href=\"");
                ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "sitsec" });
                String title = translator.translate("next");
                sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(title) + "\">");
                sb.append("<span>").append(title).append("</span>");
                sb.append("</a>");
            }
        }
    }
    return sb;
}
Also used : SectionContext(org.olat.ims.qti.container.SectionContext) Hint(org.olat.ims.qti.container.qtielements.Hint) StringOutput(org.olat.core.gui.render.StringOutput) Info(org.olat.ims.qti.navigator.Info) Hint(org.olat.ims.qti.container.qtielements.Hint) AssessmentContext(org.olat.ims.qti.container.AssessmentContext) ItemContext(org.olat.ims.qti.container.ItemContext) Item(org.olat.ims.qti.container.qtielements.Item) StringOutput(org.olat.core.gui.render.StringOutput) Output(org.olat.ims.qti.container.Output) GenericQTIElement(org.olat.ims.qti.container.qtielements.GenericQTIElement) AssessmentInstance(org.olat.ims.qti.process.AssessmentInstance) Solution(org.olat.ims.qti.container.qtielements.Solution)

Example 22 with ItemContext

use of org.olat.ims.qti.container.ItemContext in project openolat by klemens.

the class IQComponentRenderer method buildMenu.

/**
 * Method buildMenu.
 *
 * @return DOCUMENT ME!
 */
private StringOutput buildMenu(IQComponent comp, Translator translator, Renderer r, URLBuilder ubu) {
    StringOutput sb = new StringOutput();
    AssessmentInstance ai = comp.getAssessmentInstance();
    AssessmentContext ac = ai.getAssessmentContext();
    boolean renderSectionTitlesOnly = comp.getMenuDisplayConf().isRenderSectionsOnly();
    sb.append("<div id=\"o_qti_menu\">");
    sb.append("<h4>");
    sb.append(StringHelper.escapeHtml(ac.getTitle()));
    sb.append("</h4>");
    sb.append("<table border=0 width=\"100%\">");
    // append assessment navigation
    Formatter formatter = Formatter.getInstance(translator.getLocale());
    int scnt = ac.getSectionContextCount();
    for (int i = 0; i < scnt; i++) {
        SectionContext sc = ac.getSectionContext(i);
        boolean clickable = (ai.isSectionPage() && sc.isOpen()) || (!ai.isSectionPage());
        clickable = clickable && !ai.isClosed();
        clickable = clickable && ai.isMenu();
        sb.append("<tr>");
        sb.append(addSectionLink(r, ubu, formatter, sc, i, clickable, ac.getCurrentSectionContextPos() == i, ai.isSectionPage()));
        sb.append("</tr>");
        if (!renderSectionTitlesOnly) {
            // not only sections, but render questions to
            int icnt = sc.getItemContextCount();
            for (int j = 0; j < icnt; j++) {
                ItemContext itc = sc.getItemContext(j);
                clickable = !ai.isSectionPage() && sc.isOpen() && itc.isOpen();
                clickable = clickable && !ai.isClosed();
                clickable = clickable && ai.isMenu();
                sb.append("<tr>");
                sb.append(addItemLink(r, ubu, formatter, ai, itc, i, j, clickable, (ac.getCurrentSectionContextPos() == i && sc.getCurrentItemContextPos() == j), !ai.isSurvey()));
                sb.append("</tr>");
            }
        }
    }
    sb.append("</table>");
    sb.append("</div>");
    return sb;
}
Also used : SectionContext(org.olat.ims.qti.container.SectionContext) AssessmentContext(org.olat.ims.qti.container.AssessmentContext) ItemContext(org.olat.ims.qti.container.ItemContext) Formatter(org.olat.core.util.Formatter) AssessmentInstance(org.olat.ims.qti.process.AssessmentInstance) StringOutput(org.olat.core.gui.render.StringOutput) Hint(org.olat.ims.qti.container.qtielements.Hint)

Example 23 with ItemContext

use of org.olat.ims.qti.container.ItemContext in project openolat by klemens.

the class IQManager method persistResults.

/**
 * Create the QTIResults on the database for a given assessments,
 * self-assessment or survey. These database entries can be used for
 * statistical downloads.
 *
 * @param ai
 * @param resId
 * @param resDetail
 * @param ureq
 */
public void persistResults(AssessmentInstance ai) {
    AssessmentContext ac = ai.getAssessmentContext();
    QTIResultSet qtiResultSet = new QTIResultSet();
    qtiResultSet.setLastModified(new Date(System.currentTimeMillis()));
    qtiResultSet.setOlatResource(ai.getCallingResId());
    qtiResultSet.setOlatResourceDetail(ai.getCallingResDetail());
    qtiResultSet.setRepositoryRef(ai.getRepositoryEntryKey());
    qtiResultSet.setIdentity(ai.getAssessedIdentity());
    qtiResultSet.setQtiType(ai.getType());
    qtiResultSet.setAssessmentID(ai.getAssessID());
    qtiResultSet.setDuration(new Long(ai.getAssessmentContext().getDuration()));
    if (ai.isSurvey()) {
        qtiResultSet.setScore(0);
        qtiResultSet.setIsPassed(true);
    } else {
        qtiResultSet.setScore(ac.getScore());
        qtiResultSet.setIsPassed(ac.isPassed());
    }
    dbInstance.getCurrentEntityManager().persist(qtiResultSet);
    // Loop over all sections in this assessment
    int sccnt = ac.getSectionContextCount();
    for (int i = 0; i < sccnt; i++) {
        // Loop over all items in this section
        SectionContext sc = ac.getSectionContext(i);
        int iccnt = sc.getItemContextCount();
        for (int j = 0; j < iccnt; j++) {
            ItemContext ic = sc.getItemContext(j);
            // Create new result item for this item
            QTIResult qtiResult = new QTIResult();
            qtiResult.setResultSet(qtiResultSet);
            qtiResult.setItemIdent(ic.getIdent());
            qtiResult.setDuration(new Long(ic.getTimeSpent()));
            if (ai.isSurvey())
                qtiResult.setScore(0);
            else
                qtiResult.setScore(ic.getScore());
            qtiResult.setTstamp(new Date(ic.getLatestAnswerTime()));
            qtiResult.setLastModified(new Date(System.currentTimeMillis()));
            qtiResult.setIp(ai.getRemoteAddr());
            // Get user answers for this item
            StringBuilder sb = new StringBuilder();
            if (ic.getItemInput() == null) {
            } else {
                ItemInput inp = ic.getItemInput();
                if (inp.isEmpty()) {
                    sb.append("[]");
                } else {
                    Map<String, List<String>> im = inp.getInputMap();
                    // Create answer block
                    Set<String> keys = im.keySet();
                    Iterator<String> iter = keys.iterator();
                    while (iter.hasNext()) {
                        String ident = iter.next();
                        // response_lid ident
                        sb.append(ident);
                        sb.append("[");
                        List<String> answers = inp.getAsList(ident);
                        for (int y = 0; y < answers.size(); y++) {
                            sb.append("[");
                            String answer = answers.get(y);
                            // answer is referenced to response_label ident, if
                            // render_choice
                            // answer is userinput, if render_fib
                            answer = quoteSpecialQTIResultCharacters(answer);
                            sb.append(answer);
                            sb.append("]");
                        }
                        sb.append("]");
                    }
                }
            }
            qtiResult.setAnswer(sb.toString());
            // Persist result data in database
            dbInstance.getCurrentEntityManager().persist(qtiResult);
        }
    }
}
Also used : SectionContext(org.olat.ims.qti.container.SectionContext) QTIResult(org.olat.ims.qti.QTIResult) HttpItemInput(org.olat.ims.qti.container.HttpItemInput) ItemInput(org.olat.ims.qti.container.ItemInput) Date(java.util.Date) QTIResultSet(org.olat.ims.qti.QTIResultSet) AssessmentContext(org.olat.ims.qti.container.AssessmentContext) ItemContext(org.olat.ims.qti.container.ItemContext) List(java.util.List) ArrayList(java.util.ArrayList)

Example 24 with ItemContext

use of org.olat.ims.qti.container.ItemContext in project openolat by klemens.

the class CourseAssessmentWebService method importTestItems.

private void importTestItems(ICourse course, String nodeKey, Identity identity, AssessableResultsVO resultsVO) {
    try {
        IQManager iqManager = CoreSpringFactory.getImpl(IQManager.class);
        // load the course and the course node
        CourseNode courseNode = getParentNode(course, nodeKey);
        ModuleConfiguration modConfig = courseNode.getModuleConfiguration();
        // check if the result set is already saved
        QTIResultSet set = iqManager.getLastResultSet(identity, course.getResourceableId(), courseNode.getIdent());
        if (set == null) {
            String resourcePathInfo = course.getResourceableId() + File.separator + courseNode.getIdent();
            // The use of these classes AssessmentInstance, AssessmentContext and
            // Navigator
            // allow the use of the persistence mechanism of OLAT without
            // duplicating the code.
            // The consequence is that we must loop on section and items and set the
            // navigator on
            // the right position before submitting the inputs.
            AssessmentInstance ai = AssessmentFactory.createAssessmentInstance(identity, "", modConfig, false, course.getResourceableId(), courseNode.getIdent(), resourcePathInfo, null);
            Navigator navigator = ai.getNavigator();
            navigator.startAssessment();
            // The type of the navigator depends on the setting of the course node
            boolean perItem = (navigator instanceof MenuItemNavigator);
            Map<String, ItemInput> datas = convertToHttpItemInput(resultsVO.getResults());
            AssessmentContext ac = ai.getAssessmentContext();
            int sectioncnt = ac.getSectionContextCount();
            // loop on the sections
            for (int i = 0; i < sectioncnt; i++) {
                SectionContext sc = ac.getSectionContext(i);
                navigator.goToSection(i);
                ItemsInput iips = new ItemsInput();
                int itemcnt = sc.getItemContextCount();
                // loop on the items
                for (int j = 0; j < itemcnt; j++) {
                    ItemContext it = sc.getItemContext(j);
                    if (datas.containsKey(it.getIdent())) {
                        if (perItem) {
                            // save the datas on a per item base
                            navigator.goToItem(i, j);
                            // the navigator can give informations on its current status
                            Info info = navigator.getInfo();
                            if (info.containsError()) {
                            // some items cannot processed twice
                            } else {
                                iips.addItemInput(datas.get(it.getIdent()));
                                navigator.submitItems(iips);
                                iips = new ItemsInput();
                            }
                        } else {
                            // put for a section
                            iips.addItemInput(datas.get(it.getIdent()));
                        }
                    }
                }
                if (!perItem) {
                    // save the inputs of the section. In a section based navigation,
                    // we must saved the inputs of the whole section at once
                    navigator.submitItems(iips);
                }
            }
            navigator.submitAssessment();
            // persist the QTIResultSet (o_qtiresultset and o_qtiresult) on the
            // database
            // TODO iqManager.persistResults(ai, course.getResourceableId(),
            // courseNode.getIdent(), identity, "127.0.0.1");
            // write the reporting file on the file system
            // The path is <olatdata> / resreporting / <username> / Assessment /
            // <assessId>.xml
            // TODO Document docResReporting = iqManager.getResultsReporting(ai,
            // identity, Locale.getDefault());
            // TODO FilePersister.createResultsReporting(docResReporting, identity,
            // ai.getFormattedType(), ai.getAssessID());
            // prepare all instances needed to save the score at the course node
            // level
            CourseEnvironment cenv = course.getCourseEnvironment();
            IdentityEnvironment identEnv = new IdentityEnvironment();
            identEnv.setIdentity(identity);
            UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(identEnv, cenv);
            // update scoring overview for the user in the current course
            Float score = ac.getScore();
            Boolean passed = ac.isPassed();
            // perhaps don't pass this key directly
            ScoreEvaluation sceval = new ScoreEvaluation(score, passed, passed, new Long(nodeKey));
            AssessableCourseNode acn = (AssessableCourseNode) courseNode;
            // assessment nodes are assessable
            boolean incrementUserAttempts = true;
            acn.updateUserScoreEvaluation(sceval, userCourseEnv, identity, incrementUserAttempts, Role.coach);
        } else {
            log.error("Result set already saved");
        }
    } catch (Exception e) {
        log.error("", e);
    }
}
Also used : SectionContext(org.olat.ims.qti.container.SectionContext) ScoreEvaluation(org.olat.course.run.scoring.ScoreEvaluation) HttpItemInput(org.olat.ims.qti.container.HttpItemInput) ItemInput(org.olat.ims.qti.container.ItemInput) ItemsInput(org.olat.ims.qti.container.ItemsInput) AssessableCourseNode(org.olat.course.nodes.AssessableCourseNode) AssessmentInstance(org.olat.ims.qti.process.AssessmentInstance) CourseNode(org.olat.course.nodes.CourseNode) AssessableCourseNode(org.olat.course.nodes.AssessableCourseNode) IQTESTCourseNode(org.olat.course.nodes.IQTESTCourseNode) IdentityEnvironment(org.olat.core.id.IdentityEnvironment) IQManager(org.olat.modules.iq.IQManager) ModuleConfiguration(org.olat.modules.ModuleConfiguration) UserCourseEnvironment(org.olat.course.run.userview.UserCourseEnvironment) CourseEnvironment(org.olat.course.run.environment.CourseEnvironment) UserCourseEnvironment(org.olat.course.run.userview.UserCourseEnvironment) Navigator(org.olat.ims.qti.navigator.Navigator) MenuItemNavigator(org.olat.ims.qti.navigator.MenuItemNavigator) Info(org.olat.ims.qti.navigator.Info) WebApplicationException(javax.ws.rs.WebApplicationException) QTIResultSet(org.olat.ims.qti.QTIResultSet) MenuItemNavigator(org.olat.ims.qti.navigator.MenuItemNavigator) AssessmentContext(org.olat.ims.qti.container.AssessmentContext) ItemContext(org.olat.ims.qti.container.ItemContext) UserCourseEnvironmentImpl(org.olat.course.run.userview.UserCourseEnvironmentImpl)

Example 25 with ItemContext

use of org.olat.ims.qti.container.ItemContext in project openolat by klemens.

the class DefaultNavigator method submitAssessment.

/**
 * @see org.olat.qti.process.Navigator#submitAssessment()
 */
public final void submitAssessment() {
    Output pendingOutput = null;
    boolean pendingFeedback = getInfo().isFeedback();
    boolean alreadyClosed = getAssessmentInstance().isClosed();
    if (pendingFeedback && getAssessmentInstance().getAssessmentContext().getCurrentSectionContext() != null) {
        ItemContext itc = getAssessmentInstance().getAssessmentContext().getCurrentSectionContext().getCurrentItemContext();
        pendingOutput = itc.getOutput();
    }
    getAssessmentInstance().stop();
    if (!getAssessmentInstance().isPreview() && !alreadyClosed) {
        CoreSpringFactory.getImpl(IQManager.class).persistResults(getAssessmentInstance());
    }
    AssessmentContext ac = getAssessmentContext();
    info.clear();
    if (ac.isFeedbackavailable()) {
        Output outp = ac.getOutput();
        getInfo().setCurrentOutput(outp);
        getInfo().setFeedback(true);
    } else if (pendingFeedback) {
        getInfo().setCurrentOutput(pendingOutput);
        getInfo().setFeedback(true);
    }
    // info.clear();
    info.setMessage(QTIConstants.MESSAGE_ASSESSMENT_SUBMITTED);
    info.setStatus(QTIConstants.ASSESSMENT_FINISHED);
    info.setRenderItems(false);
    if (delegate != null && !getAssessmentInstance().isPreview() && !alreadyClosed) {
        delegate.submitAssessment(assessmentInstance);
    }
    getAssessmentInstance().cleanUp();
}
Also used : ItemContext(org.olat.ims.qti.container.ItemContext) IQManager(org.olat.modules.iq.IQManager) AssessmentContext(org.olat.ims.qti.container.AssessmentContext) Output(org.olat.ims.qti.container.Output)

Aggregations

ItemContext (org.olat.ims.qti.container.ItemContext)28 AssessmentContext (org.olat.ims.qti.container.AssessmentContext)20 SectionContext (org.olat.ims.qti.container.SectionContext)20 ItemInput (org.olat.ims.qti.container.ItemInput)10 Output (org.olat.ims.qti.container.Output)8 AssessmentInstance (org.olat.ims.qti.process.AssessmentInstance)6 Date (java.util.Date)4 List (java.util.List)4 StringOutput (org.olat.core.gui.render.StringOutput)4 QTIResultSet (org.olat.ims.qti.QTIResultSet)4 HttpItemInput (org.olat.ims.qti.container.HttpItemInput)4 Hint (org.olat.ims.qti.container.qtielements.Hint)4 Info (org.olat.ims.qti.navigator.Info)4 IQManager (org.olat.modules.iq.IQManager)4 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Iterator (java.util.Iterator)2 Set (java.util.Set)2 WebApplicationException (javax.ws.rs.WebApplicationException)2