public boolean evaluateConstraint(TreeReference ref, IAnswerData data) { if (data == null) return true; TreeElement node = instance.resolveReference(ref); Constraint c = node.getConstraint(); if (c == null) return true; EvaluationContext ec = new EvaluationContext(exprEvalContext, ref); ec.isConstraint = true; ec.candidateValue = data; return c.constraint.eval(instance, ec); }
public String fillTemplateString( String template, TreeReference contextRef, Hashtable<String, ?> variables) { Hashtable args = new Hashtable(); int depth = 0; Vector outstandingArgs = Localizer.getArgs(template); while (outstandingArgs.size() > 0) { for (int i = 0; i < outstandingArgs.size(); i++) { String argName = (String) outstandingArgs.elementAt(i); if (!args.containsKey(argName)) { int ix = -1; try { ix = Integer.parseInt(argName); } catch (NumberFormatException nfe) { System.err.println("Warning: expect arguments to be numeric [" + argName + "]"); } if (ix < 0 || ix >= outputFragments.size()) continue; IConditionExpr expr = (IConditionExpr) outputFragments.elementAt(ix); EvaluationContext ec = new EvaluationContext(exprEvalContext, contextRef); ec.setVariables(variables); String value = expr.evalReadable(this.getInstance(), ec); args.put(argName, value); } } template = Localizer.processArguments(template, args); outstandingArgs = Localizer.getArgs(template); depth++; if (depth >= TEMPLATING_RECURSION_LIMIT) { throw new RuntimeException("Dependency cycle in <output>s; recursion limit exceeded!!"); } } return template; }
private void initEvalContext(EvaluationContext ec) { if (!ec.getFunctionHandlers().containsKey("jr:itext")) { final FormDef f = this; ec.addFunctionHandler( new IFunctionHandler() { public String getName() { return "jr:itext"; } public Object eval(Object[] args) { String textID = (String) args[0]; try { String text = f.getLocalizer().getText(textID); return text == null ? "[itext:" + textID + "]" : text; } catch (NoSuchElementException nsee) { return "[nolocale]"; } } public Vector getPrototypes() { Class[] proto = {String.class}; Vector v = new Vector(); v.addElement(proto); return v; } public boolean rawArgs() { return false; } public boolean realTime() { return false; } }); } /* function to reverse a select value into the display label for that choice in the question it came from * * arg 1: select value * arg 2: string xpath referring to origin question; must be absolute path * * this won't work at all if the original label needed to be processed/calculated in some way (<output>s, etc.) (is this even allowed?) * likely won't work with multi-media labels * _might_ work for itemsets, but probably not very well or at all; could potentially work better if we had some context info * DOES work with localization * * it's mainly intended for the simple case of reversing a question with compile-time-static fields, for use inside an <output> */ if (!ec.getFunctionHandlers().containsKey("jr:choice-name")) { final FormDef f = this; ec.addFunctionHandler( new IFunctionHandler() { public String getName() { return "jr:choice-name"; } public Object eval(Object[] args) { try { String value = (String) args[0]; String questionXpath = (String) args[1]; TreeReference ref = RestoreUtils.xfFact.ref(questionXpath); QuestionDef q = f.findQuestionByRef(ref, f); if (q == null || (q.getControlType() != Constants.CONTROL_SELECT_ONE && q.getControlType() != Constants.CONTROL_SELECT_MULTI)) { return ""; } Vector<SelectChoice> choices = q.getChoices(); for (SelectChoice ch : choices) { if (ch.getValue().equals(value)) { // this is really not ideal. we should hook into the existing code // (FormEntryPrompt) for pulling // display text for select choices. however, it's hard, because we don't really // have // any context to work with, and all the situations where that context would be // used // don't make sense for trying to reverse a select value back to a label in an // unrelated // expression String textID = ch.getTextID(); if (textID != null) { return f.getLocalizer().getText(textID); } else { return ch.getLabelInnerText(); } } } return ""; } catch (Exception e) { throw new WrappedException( "error in evaluation of xpath function [choice-name]", e); } } public Vector getPrototypes() { Class[] proto = {String.class, String.class}; Vector v = new Vector(); v.addElement(proto); return v; } public boolean rawArgs() { return false; } public boolean realTime() { return false; } }); } }