use of org.olat.ims.qti.navigator.Info in project OpenOLAT by OpenOLAT.
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);
}
}
use of org.olat.ims.qti.navigator.Info in project OpenOLAT by OpenOLAT.
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;
}
use of org.olat.ims.qti.navigator.Info 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;
}
use of org.olat.ims.qti.navigator.Info 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);
}
}
Aggregations