Package org.olat.ims.qti.process.elements

Source Code of org.olat.ims.qti.process.elements.QTI_respcondition

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.ims.qti.process.elements;

import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;
import org.olat.ims.qti.container.ItemContext;
import org.olat.ims.qti.container.Output;
import org.olat.ims.qti.container.Variable;
import org.olat.ims.qti.container.Variables;
import org.olat.ims.qti.container.qtielements.Hint;
import org.olat.ims.qti.container.qtielements.Solution;
import org.olat.ims.qti.process.QTIHelper;

/**
*
*/
public class QTI_respcondition {

  /**
   * Response Condition
   *
   * ims qti 1.2.1 respcondition
   * <!ELEMENT respcondition (qticomment? , conditionvar , setvar* , displayfeedback*)>
   * <!ELEMENT conditionvar (not | and | or | unanswered | other | varequal | varlt | varlte |
   *      vargt | vargte | varsubset | varinside | varsubstring | durequal | durlt | durlte | durgt | durgte)+>
   *
   * <!ELEMENT setvar (#PCDATA)>
   * <!ATTLIST setvar  %I_VarName; action     (Set | Add | Subtract | Multiply | Divide )  'Set' >
   * mit I_VarName = varname CDATA  'SCORE'
   * <setvar action="Set" varname="SCORE">10</setvar>
   *
   * <!ELEMENT displayfeedback (#PCDATA)>
   * <!ATTLIST displayfeedback  feedbacktype  (Response | Solution | Hint )  'Response'
                          %I_LinkRefId; >
   * mit I_LinkRefId = linkrefid CDATA  #REQUIRED"
   * e.g. <displayfeedback feedbacktype = "Solution" linkrefid = "CorrectSoln"/>
   *
   * ??? should be ? ? <conditionvar><or>...</or><varequal>...</varequal></conditionvar> does not make sense
   * but   <conditionvar> 
          <varequal respident = "Word-1">KITTENS</varequal> 
          <varequal respident = "Word-2">HATS</varequal>
        </conditionvar> makes sense, so treat members of conditionvar as children of an "and" element
   * @param node_respcond
   */
  public boolean process(Element el_respcond, ItemContext itc, EvalContext ect) {
    // 1. evaluate conditionvar
    // 2. if true, set variables
    //    and setCurrentDisplayFeedback (TODO: assuming there is only one displayfeedback in a respcondition)
    Variables vars;
    Element el_condVar = (Element) el_respcond.selectSingleNode("conditionvar");
    String respcondtitle = el_respcond.attributeValue("title");
    QTI_and qtiAnd = QTIHelper.getQTI_and();
    boolean fulfilled = qtiAnd.eval(el_condVar, itc, ect);
    // continue to set variables and display feedback if question was answered correctly
    if (fulfilled) {
      vars = itc.getVariables();
      List setvars = el_respcond.selectNodes("setvar");
      for (Iterator iter = setvars.iterator(); iter.hasNext();) {
        Element element = (Element) iter.next();
        String action = element.attributeValue("action");
        String varName = element.attributeValue("varname");
        if (varName == null) varName = "SCORE";
        varName.trim();
        String varVal = element.getText();
        Variable var = vars.getVariable(varName);
        if (var == null) throw new RuntimeException("var "+varName+" is in setvar, but was not declared ");
        if (action.equals("Set")) {
          var.setValue(varVal);
        } else {
          // we are doing Integer or float arithmetic
          // Add | Subtract | Multiply | Divide
          if (action.equals("Add")) {
            var.add(varVal);
          } else if (action.equals("Subtract")) {
            var.subtract(varVal);
          } else if (action.equals("Multiply")) {
            var.multiply(varVal);
          } else if (action.equals("Divide")) {
            var.divide(varVal);
          }
        }
      }
      // set displayfeedback
      //<displayfeedback feedbacktype = "Response" linkrefid = "Correct"/>
      //<!ATTLIST displayfeedback  feedbacktype  (Response | Solution | Hint )  'Response' %I_LinkRefId; >
      Output output = itc.getOutput();
      List fbs = el_respcond.selectNodes("displayfeedback");
      for (Iterator it_fbs = fbs.iterator(); it_fbs.hasNext();) {
        Element el_dispfb = (Element) it_fbs.next();
        String linkRefId = el_dispfb.attributeValue("linkrefid"); // must exist (dtd)
        String feedbacktype = el_dispfb.attributeValue("feedbacktype"); // must exist (dtd)
        Element el_resolved =
          (Element) itc.getEl_item().selectSingleNode(".//itemfeedback[@ident='" + linkRefId + "']");
        if (el_resolved == null) continue;
        if (feedbacktype.equals("Response")) {
          // additional (olat) rule:
          // we want to render the original answer again in the simple case where the respcondition was generated
          // by the olat export and contains only one varequal.
          /*
           
              <response_label ident = "2">
                 <flow_mat>
                <material>
                    <mattext texttype="text/html">...</mattext>
                </material>
                        </flow_mat>
                    </response_label>
            ...
         
             <respcondition title="_olat_resp_feedback" continue="Yes">
              <conditionvar>
                <varequal respident="Frage6549" case="Yes">2</varequal>
              </conditionvar>
                    <displayfeedback linkrefid="2"/>
            </respcondition>
           
            In this case, it is possible (and wished) to trace the feedback back to the answer which triggered this feedback.
            Such a respcondition is identified by the title which is exactly "_olat_resp_feedback".
           
           
           */
          Element el_chosenanswer = null;
          if (respcondtitle != null && respcondtitle.equals("_olat_resp_feedback")) {
            Element el_vareq = (Element) el_respcond.selectSingleNode(".//varequal");
            String answerident = el_vareq.getText();
            el_chosenanswer = (Element) itc.getEl_item().selectSingleNode(".//response_label[@ident='" + answerident + "']//material");
          }
          output.addItem_El_response(el_chosenanswer,el_resolved); // give the whole itemfeedback to render
        } else if (feedbacktype.equals("Solution")) {
          Element el_solution = (Element) el_resolved.selectSingleNode(".//solution");
          if (el_solution != null) output.setSolution(new Solution(el_solution));
        } else if (feedbacktype.equals("Hint")) {
          //<!ENTITY % I_FeedbackStyle " feedbackstyle  (Complete | Incremental | Multilevel | Proprietary )  'Complete'">
          Element el_hint = (Element) el_resolved.selectSingleNode(".//hint");
          output.setHint(new Hint(el_hint));
        }
      }
    }
    return fulfilled;

  }


}
TOP

Related Classes of org.olat.ims.qti.process.elements.QTI_respcondition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.