Пример #1
0
  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);
  }
Пример #2
0
  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;
  }
Пример #3
0
  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;
            }
          });
    }
  }