use of org.olat.ims.qti.editor.beecom.objects.Response in project OpenOLAT by OpenOLAT.
the class QTIEditorMainController method createChangeMessage.
/**
* helper method to create the change log message
*
* @return
*/
private String createChangeMessage() {
// FIXME:pb:break down into smaller pieces
final StringBuilder result = new StringBuilder();
if (isRestrictedEdit()) {
Visitor v = new Visitor() {
/*
* a history key is built as follows
* sectionkey+"/"+itemkey+"/"+questionkey+"/"+responsekey
*/
String sectionKey = null;
Map<String, String> itemMap = new HashMap<>();
public void visit(INode node) {
if (node instanceof AssessmentNode) {
AssessmentNode an = (AssessmentNode) node;
String key = "null/null/null/null";
if (history.containsKey(key)) {
// some assessment top level data changed
Memento mem = history.get(key);
result.append("---+ Changes in test " + formatVariable(startedWithTitle) + ":");
result.append(an.createChangeMessage(mem));
}
} else if (node instanceof SectionNode) {
SectionNode sn = (SectionNode) node;
String tmpKey = ((Section) sn.getUnderlyingQTIObject()).getIdent();
String key = tmpKey + "/null/null/null";
if (history.containsKey(key)) {
// some section only data changed
Memento mem = history.get(key);
result.append("\n---++ Section " + formatVariable(sn.getAltText()) + " changes:");
result.append(sn.createChangeMessage(mem));
}
} else if (node instanceof ItemNode) {
ItemNode in = (ItemNode) node;
SectionNode sn = (SectionNode) in.getParent();
String parentSectkey = ((Section) ((SectionNode) in.getParent()).getUnderlyingQTIObject()).getIdent();
Item item = (Item) in.getUnderlyingQTIObject();
Question question = item.getQuestion();
String itemKey = item.getIdent();
String prefixKey = "null/" + itemKey;
String questionIdent = question != null ? question.getQuestion().getId() : "null";
String key = prefixKey + "/" + questionIdent + "/null";
StringBuilder changeMessage = new StringBuilder();
boolean hasChanges = false;
if (!itemMap.containsKey(itemKey)) {
Memento questMem = null;
Memento respMem = null;
if (history.containsKey(key)) {
// question changed!
questMem = history.get(key);
hasChanges = true;
}
// if(!hasChanges){
// check if a response changed
// new prefix for responses
prefixKey += "/null/";
// list contains org.olat.ims.qti.editor.beecom.objects.Response
List<Response> responses = question != null ? question.getResponses() : null;
if (responses != null && responses.size() > 0) {
// check for changes in each response
for (Iterator<Response> iter = responses.iterator(); iter.hasNext(); ) {
Response resp = iter.next();
if (history.containsKey(prefixKey + resp.getIdent())) {
// this response changed!
Memento tmpMem = history.get(prefixKey + resp.getIdent());
if (respMem != null) {
respMem = respMem.getTimestamp() > tmpMem.getTimestamp() ? tmpMem : respMem;
} else {
hasChanges = true;
respMem = tmpMem;
}
}
}
}
// output message
if (hasChanges) {
Memento mem = null;
if (questMem != null && respMem != null) {
// use the earlier memento
mem = questMem.getTimestamp() > respMem.getTimestamp() ? respMem : questMem;
} else if (questMem != null) {
mem = questMem;
} else if (respMem != null) {
mem = respMem;
}
changeMessage.append(in.createChangeMessage(mem));
itemMap.put(itemKey, itemKey);
if (!parentSectkey.equals(sectionKey)) {
// either this item belongs to a new section or no section
// is active
result.append("\n---++ Section " + formatVariable(sn.getAltText()) + " changes:");
result.append("\n").append(changeMessage);
sectionKey = parentSectkey;
} else {
result.append("\n").append(changeMessage);
}
}
}
}
}
private String formatVariable(String var) {
if (StringHelper.containsNonWhitespace(var)) {
return var;
}
return "[no entry]";
}
};
TreeVisitor tv = new TreeVisitor(v, menuTreeModel.getRootNode(), false);
tv.visitAll();
}
/*
*
*/
return result.toString();
}
use of org.olat.ims.qti.editor.beecom.objects.Response in project OpenOLAT by OpenOLAT.
the class QTIEditHelper method fetchChoices.
/**
* Fetch choices.
* @param response_labels
* @return Map of choices.
*/
public static List<Response> fetchChoices(List response_labels) {
List<Response> choices = new ArrayList<Response>();
for (Iterator i = response_labels.iterator(); i.hasNext(); ) {
ChoiceResponse choice = new ChoiceResponse();
Element response_label = (Element) i.next();
choice.setIdent(response_label.attributeValue("ident"));
List materials = response_label.selectNodes(".//material");
Material content = new Material();
for (Iterator iter = materials.iterator(); iter.hasNext(); ) {
Element el_material = (Element) iter.next();
Material mat = (Material) parserManager.parse(el_material);
content.getElements().addAll(mat.getElements());
}
// assure material always has some content
if (content.getElements().size() == 0) {
content.getElements().add(new Mattext(""));
}
choice.setContent(content);
choices.add(choice);
}
return choices;
}
use of org.olat.ims.qti.editor.beecom.objects.Response in project OpenOLAT by OpenOLAT.
the class QTIEditHelper method getMediaReferences.
/**
* Retrieves all referenced media by thisItem if filterOut is false,
* or all referenced media by other items if filterOut is true.
* <p>
* Iterates over all sections, items, etc. </br>
* -> if filterOut is true gets all references except those for thisItem.
* -> if filterOut is false gets all references for thisItem.
*
* @param qtiDocument
* @param thisItem
* @param filterOut
* @return Returns empty set if no reference found.
*/
private static Set<String> getMediaReferences(QTIDocument qtiDocument, Item thisItem, boolean filterOut) {
HashSet<String> returnSet = new HashSet<String>();
// sections
List sectionList = qtiDocument.getAssessment().getSections();
Iterator sectionIterator = sectionList.iterator();
while (sectionIterator.hasNext()) {
// section
Section section = (Section) sectionIterator.next();
List itemList = section.getItems();
Iterator listIterator = itemList.iterator();
while (listIterator.hasNext()) {
// item
Item item = (Item) listIterator.next();
if ((filterOut && thisItem.getIdent().equals(item.getIdent())) || (!filterOut && !thisItem.getIdent().equals(item.getIdent()))) {
continue;
}
// question
Material material = item.getQuestion().getQuestion();
if (material != null) {
String htmlContent = material.renderAsHtmlForEditor();
// parse filenames
returnSet.addAll(getMediaFileNames(htmlContent));
}
// responses
List responseList = item.getQuestion().getResponses();
Iterator responseIterator = responseList.iterator();
while (responseIterator.hasNext()) {
Response response = (Response) responseIterator.next();
Material responseMat = response.getContent();
// parse filenames
if (responseMat != null) {
returnSet.addAll(getMediaFileNames(responseMat.renderAsHtmlForEditor()));
}
// response-level feedback
Material responseFeedbackMat = QTIEditHelper.getFeedbackOlatRespMaterial(item, response.getIdent());
if (responseFeedbackMat != null) {
returnSet.addAll(getMediaFileNames(responseFeedbackMat.renderAsHtmlForEditor()));
}
}
// feedback
Material masteryMat = QTIEditHelper.getFeedbackMasteryMaterial(item);
if (masteryMat != null) {
returnSet.addAll(getMediaFileNames(masteryMat.renderAsHtmlForEditor()));
}
Material failureMat = QTIEditHelper.getFeedbackFailMaterial(item);
if (failureMat != null) {
returnSet.addAll(getMediaFileNames(failureMat.renderAsHtmlForEditor()));
}
}
}
return returnSet;
}
use of org.olat.ims.qti.editor.beecom.objects.Response in project OpenOLAT by OpenOLAT.
the class QTI12To21Converter method convertFeedbackPerAnswers.
private void convertFeedbackPerAnswers(Item item, AssessmentItemBuilder itemBuilder, Map<String, Identifier> identToIdentifier) {
Question question = item.getQuestion();
List<ModalFeedbackBuilder> additionalFeedbacks = new ArrayList<>();
for (Response response : question.getResponses()) {
if (response instanceof ChoiceResponse) {
Material responseFeedbackMat = QTIEditHelper.getFeedbackOlatRespMaterial(item, response.getIdent());
if (responseFeedbackMat != null) {
String feedbackCondition = responseFeedbackMat.renderAsHtmlForEditor();
feedbackCondition = blockedHtml(feedbackCondition);
ModalFeedbackCondition condition = new ModalFeedbackCondition();
condition.setVariable(Variable.response);
condition.setOperator(Operator.equals);
condition.setValue(identToIdentifier.get(response.getIdent()).toString());
List<ModalFeedbackCondition> conditions = new ArrayList<>(1);
conditions.add(condition);
ModalFeedbackBuilder feedback = new ModalFeedbackBuilder(itemBuilder.getAssessmentItem(), ModalFeedbackType.additional);
feedback.setFeedbackConditions(conditions);
feedback.setText(feedbackCondition);
additionalFeedbacks.add(feedback);
}
}
}
itemBuilder.setAdditionalFeedbackBuilders(additionalFeedbacks);
}
use of org.olat.ims.qti.editor.beecom.objects.Response in project OpenOLAT by OpenOLAT.
the class QTI12To21Converter method convertMultipleChoice.
private AssessmentItemBuilder convertMultipleChoice(Item item) {
MultipleChoiceAssessmentItemBuilder itemBuilder = new MultipleChoiceAssessmentItemBuilder("Multiple choice", "New answer", qtiSerializer);
convertItemBasics(item, itemBuilder);
itemBuilder.clearMapping();
itemBuilder.clearSimpleChoices();
ChoiceInteraction interaction = itemBuilder.getChoiceInteraction();
Question question = item.getQuestion();
itemBuilder.setShuffle(question.isShuffle());
convertOrientation(question, itemBuilder);
boolean hasNegative = false;
List<Response> responses = question.getResponses();
for (Response response : responses) {
if (response.getPoints() < 0.0f) {
hasNegative = true;
}
}
boolean singleCorrect = question.isSingleCorrect();
Map<String, Identifier> identToIdentifier = new HashMap<>();
for (Response response : responses) {
String responseText = response.getContent().renderAsHtmlForEditor();
responseText = blockedHtml(responseText);
SimpleChoice newChoice;
if (StringHelper.isHtml(responseText)) {
newChoice = AssessmentItemFactory.createSimpleChoice(interaction, "", itemBuilder.getQuestionType().getPrefix());
htmlBuilder.appendHtml(newChoice, responseText);
} else {
newChoice = AssessmentItemFactory.createSimpleChoice(interaction, responseText, itemBuilder.getQuestionType().getPrefix());
}
itemBuilder.addSimpleChoice(newChoice);
identToIdentifier.put(response.getIdent(), newChoice.getIdentifier());
double score = response.getPoints();
if (singleCorrect) {
if (response.isCorrect()) {
itemBuilder.addCorrectAnswer(newChoice.getIdentifier());
}
if (score > 0.0f) {
itemBuilder.setMaxScore(score);
}
} else {
if ((hasNegative && response.getPoints() >= 0.0f) || (!hasNegative && response.getPoints() > 0.0f)) {
itemBuilder.addCorrectAnswer(newChoice.getIdentifier());
}
itemBuilder.setMapping(newChoice.getIdentifier(), score);
}
}
convertFeedbackPerAnswers(item, itemBuilder, identToIdentifier);
if (singleCorrect) {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.allCorrectAnswers);
} else {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.perAnswer);
if (question instanceof ChoiceQuestion) {
ChoiceQuestion choice = (ChoiceQuestion) question;
itemBuilder.setMinScore(new Double(choice.getMinValue()));
itemBuilder.setMaxScore(new Double(choice.getMaxValue()));
}
}
return itemBuilder;
}
Aggregations