/** * Evaluates this expression and all its children. * * @param depth of this expression in expression tree (root's depth = 0) * @return result of evaluation * @see #evaluate(ProcessingContext) */ protected Value evaluate(final ProcessingContext context, final int depth) { Value result; final boolean thisIsValid = context.isSubjectValid() || isThisExpressionValid(context); if (thisIsValid) { /* Expression is valid, so evaluate it */ result = evaluateValidSelfAndChildren(context, depth); } else { /* Expression is not valid, so register a warning and return NULL */ context.fireRuntimeWarning( this, "Expression is not valid and will not be evaluated. Returning NULL instead"); result = NullValue.INSTANCE; } /* Log result of evaluation. */ if (logger.isTraceEnabled() || logger.isDebugEnabled()) { final String format = "{}{} -> {}({})"; final Object[] arguments = new Object[] { formatIndent(depth), getClass().getSimpleName(), result.getBaseType(), result }; if (!(getParent() instanceof Expression)) { logger.debug(format, arguments); } else { logger.trace(format, arguments); } } return result; }
/** Returns true if any subexpression is NULL; false otherwise. */ protected static boolean isAnyChildNull(final Value[] childValues) { for (final Value childValue : childValues) { if (childValue.isNull()) { return true; } } return false; }
@Override public boolean evaluate(final ItemProcessingContext context) throws TemplateProcessingInterrupt { final Value value = getExpression().evaluate(context); if (value.isNull() || !((BooleanValue) value).booleanValue()) { return false; } super.evaluate(context); return true; }
@Override public boolean validateResponse( final ItemSessionController itemSessionController, final Value responseValue) { /* Extract response values */ final Set<Identifier> responseHottextIdentifiers = new HashSet<Identifier>(); if (responseValue.isNull()) { /* (Empty response) */ } else if (responseValue.getCardinality().isList()) { /* (Container response) */ for (final SingleValue value : (ListValue) responseValue) { responseHottextIdentifiers.add(((IdentifierValue) value).identifierValue()); } } else { /* (Single response) */ responseHottextIdentifiers.add(((IdentifierValue) responseValue).identifierValue()); } /* Check the number of responses */ final int minChoices = getMinChoices(); final int maxChoices = getMaxChoices(); if (responseHottextIdentifiers.size() < minChoices) { return false; } if (maxChoices != 0 && responseHottextIdentifiers.size() > maxChoices) { return false; } /* Make sure each choice is a valid identifier */ final Set<Identifier> hottextIdentifiers = new HashSet<Identifier>(); final List<Hottext> hottexts = QueryUtils.search(Hottext.class, this); for (final Hottext hottext : hottexts) { hottextIdentifiers.add(hottext.getIdentifier()); } for (final Identifier responseHottextIdentifier : responseHottextIdentifiers) { if (!hottextIdentifiers.contains(responseHottextIdentifier)) { return false; } } return true; }
@Override public boolean validateResponse( final ItemSessionController itemSessionController, final Value responseValue) { /* Extract response values */ final Set<Identifier> responseChoiceIdentifiers = new HashSet<Identifier>(); if (responseValue.isNull()) { /* (Empty response) */ } else if (responseValue.getCardinality().isList()) { /* (Container response) */ for (final SingleValue hotspotChoiceIdentifier : (ListValue) responseValue) { responseChoiceIdentifiers.add( ((IdentifierValue) hotspotChoiceIdentifier).identifierValue()); } } else { /* (Single response - this won't actually happen) */ responseChoiceIdentifiers.add(((IdentifierValue) responseValue).identifierValue()); } /* Chheck min/max (if set) */ final Integer maxChoices = getMaxChoices(); final Integer minChoices = getMinChoices(); if (maxChoices != null && minChoices != null) { if (responseChoiceIdentifiers.size() < minChoices.intValue() || responseChoiceIdentifiers.size() > maxChoices.intValue()) { return false; } } /* Check that each identifier is valid */ final Set<Identifier> choiceIdentifiers = new HashSet<Identifier>(); for (final HotspotChoice choice : getHotspotChoices()) { choiceIdentifiers.add(choice.getIdentifier()); } for (final Identifier choiceIdentifier : responseChoiceIdentifiers) { if (!choiceIdentifiers.contains(choiceIdentifier)) { return false; } } return true; }
private String stringifyQtiValue(final Value value) { if (qtiWorksDeploymentSettings.isEnableMathAssessExtension() && GlueValueBinder.isMathsContentRecord(value)) { /* This is a special MathAssess "Maths Content" variable. In this case, we'll record * just the ASCIIMath input form or the Maxima form, if either are available. */ final RecordValue mathsValue = (RecordValue) value; final SingleValue asciiMathInput = mathsValue.get(MathAssessConstants.FIELD_CANDIDATE_INPUT_IDENTIFIER); if (asciiMathInput != null) { return "ASCIIMath[" + asciiMathInput.toQtiString() + "]"; } final SingleValue maximaForm = mathsValue.get(MathAssessConstants.FIELD_MAXIMA_IDENTIFIER); if (maximaForm != null) { return "Maxima[" + maximaForm.toQtiString() + "]"; } } /* Just convert to QTI string in the usual way */ return value.toQtiString(); }