/**
   * Parses a condition list in string format for a puzzle in the scene graph, and returns a list of
   * PuzzleConditions. Note that it is important that the nodes described have been declared before
   * the puzzle in the XML file.
   *
   * @param conditionListString The string to parse.
   * @param sceneGraph The scene graph in which to look for the target nodes.
   * @return A list of PuzzleConditions describing the conditions in the list.
   */
  @SuppressWarnings("unchecked")
  public static List<Puzzle.PuzzleCondition> parseConditionList(
      String conditionListString, SceneNode sceneGraph) {
    String[] conditions = conditionListString.replaceAll("\\s+", "").split(";");

    List<Puzzle.PuzzleCondition> conditionsList = new ArrayList<>();

    for (String conditionString : conditions) {
      String[] components = conditionString.split(",");

      Class typeClass = Boolean.class;

      int index = 0;
      if (components.length == 4) {
        try {
          typeClass = Class.forName("java.lang." + components[index++]);
        } catch (ClassNotFoundException e) {
          System.err.println("Error parsing condition list: " + e);
        }
      } else if (components.length != 3) {
        System.err.println(
            "Error reading condition string "
                + conditionString
                + ": a condition must have three components.");
        break;
      }

      Optional<SceneNode> targetObject = sceneGraph.nodeWithID(components[index++]);
      if (!targetObject.isPresent()) {
        System.err.println(
            "Error parsing condition list: could not find object with id " + components[index - 1]);
        break;
      }
      SceneNode sceneNode = targetObject.get();

      String getterName = components[index++];
      Supplier supplier;
      try {
        Method getter = sceneNode.getClass().getMethod(getterName);
        supplier =
            () -> {
              try {
                return getter.invoke(sceneNode);
              } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(
                    "Error retrieving property using getter " + getterName + ": " + e);
              }
            };
      } catch (NoSuchMethodException e) {
        System.err.println("Error parsing condition list: " + e);
        break;
      }

      Object desiredValue = ParserManager.convertFromString(components[index], typeClass);

      conditionsList.add(new Puzzle.PuzzleCondition(supplier, desiredValue, conditionString));
    }

    return conditionsList;
  }
Ejemplo n.º 2
0
  @Override
  public Object parse(final Element element) {
    // assert element.getName().equalsIgnoreCase("questestinterop");
    final Section section = new Section();

    // attributes
    section.setIdent(element.attribute("ident").getValue());
    section.setTitle(element.attribute("title").getValue());

    // elements

    // DURATION
    final QTIObject duration = (QTIObject) parserManager.parse(element.element("duration"));
    section.setDuration(duration);

    final List sectioncontrolsXML = element.elements("sectioncontrol");
    final List sectioncontrols = new ArrayList();
    for (final Iterator i = sectioncontrolsXML.iterator(); i.hasNext(); ) {
      sectioncontrols.add(parserManager.parse((Element) i.next()));
    }
    if (sectioncontrols.size() == 0) {
      sectioncontrols.add(new Control());
    }
    section.setSectioncontrols(sectioncontrols);

    // SELECTION ORDERING
    final SelectionOrdering selectionOrdering =
        (SelectionOrdering) parserManager.parse(element.element("selection_ordering"));
    if (selectionOrdering != null) {
      section.setSelection_ordering(selectionOrdering);
    } else {
      section.setSelection_ordering(new SelectionOrdering());
    }

    // SECTIONS
    final List sectionsXML = element.elements("section");
    final List sections = new ArrayList();
    for (final Iterator i = sectionsXML.iterator(); i.hasNext(); ) {
      sections.add(parserManager.parse((Element) i.next()));
    }
    section.setSections(sections);

    // ITEMS
    final List itemsXML = element.elements("item");
    final List items = new ArrayList();
    for (final Iterator i = itemsXML.iterator(); i.hasNext(); ) {
      items.add(parserManager.parse((Element) i.next()));
    }
    section.setItems(items);

    // OBJECTIVES
    final Element mattext = (Element) element.selectSingleNode("./objectives/material/mattext");
    if (mattext != null) {
      section.setObjectives(mattext.getTextTrim());
    }

    // FEEDBACKS
    final List feedbacksXML = element.elements("sectionfeedback");
    final List feedbacks = new ArrayList();
    for (final Iterator i = feedbacksXML.iterator(); i.hasNext(); ) {
      final QTIObject tmp = (QTIObject) parserManager.parse((Element) i.next());
      feedbacks.add(tmp);
    }
    section.setSectionfeedbacks(feedbacks);

    // OUTCOMES_PROCESSING
    // TODO: maybe we should use the OutcomesProcessing object and parser here? Same as on
    // assessment level?
    final QTIObject outcomes_processing =
        (QTIObject) parserManager.parse(element.element("outcomes_processing"));
    section.setOutcomes_processing(outcomes_processing);

    return section;
  }