예제 #1
0
  private void evaluateTriggerables(Vector tv, TreeReference anchorRef) {
    // add all cascaded triggerables to queue
    for (int i = 0; i < tv.size(); i++) {
      Triggerable t = (Triggerable) tv.elementAt(i);
      if (t.canCascade()) {
        for (int j = 0; j < t.getTargets().size(); j++) {
          TreeReference target = (TreeReference) t.getTargets().elementAt(j);
          Vector triggered = (Vector) triggerIndex.get(target);
          if (triggered != null) {
            for (int k = 0; k < triggered.size(); k++) {
              Triggerable u = (Triggerable) triggered.elementAt(k);
              if (!tv.contains(u)) tv.addElement(u);
            }
          }
        }
      }
    }

    // 'triggerables' is topologically-ordered by dependencies, so evaluate the triggerables in 'tv'
    // in the order they appear in 'triggerables'
    for (int i = 0; i < triggerables.size(); i++) {
      Triggerable t = (Triggerable) triggerables.elementAt(i);
      if (tv.contains(t)) {
        evaluateTriggerable(t, anchorRef);
      }
    }
  }
예제 #2
0
  /**
   * Add a Condition to the form's Collection.
   *
   * @param condition the condition to be set
   */
  public Triggerable addTriggerable(Triggerable t) {
    int existingIx = triggerables.indexOf(t);
    if (existingIx >= 0) {
      // one node may control access to many nodes; this means many nodes effectively have the same
      // condition
      // let's identify when conditions are the same, and store and calculate it only once

      // note, if the contextRef is unnecessarily deep, the condition will be evaluated more times
      // than needed
      // perhaps detect when 'identical' condition has a shorter contextRef, and use that one
      // instead?
      return (Triggerable) triggerables.elementAt(existingIx);
    } else {
      triggerables.addElement(t);
      triggerablesInOrder = false;

      Vector triggers = t.getTriggers();
      for (int i = 0; i < triggers.size(); i++) {
        TreeReference trigger = (TreeReference) triggers.elementAt(i);
        if (!triggerIndex.containsKey(trigger)) {
          triggerIndex.put(trigger, new Vector());
        }
        Vector triggered = (Vector) triggerIndex.get(trigger);
        if (!triggered.contains(t)) {
          triggered.addElement(t);
        }
      }

      return t;
    }
  }
예제 #3
0
 private void evaluateTriggerable(Triggerable t, TreeReference anchorRef) {
   TreeReference contextRef = t.contextRef.contextualize(anchorRef);
   Vector v = instance.expandReference(contextRef);
   for (int i = 0; i < v.size(); i++) {
     EvaluationContext ec = new EvaluationContext(exprEvalContext, (TreeReference) v.elementAt(i));
     t.apply(instance, ec, this);
   }
 }
예제 #4
0
  /** Walks the current set of conditions, and evaluates each of them with the current context. */
  private void initializeTriggerables(TreeReference rootRef) {
    TreeReference genericRoot = rootRef.genericize();

    Vector applicable = new Vector();
    for (int i = 0; i < triggerables.size(); i++) {
      Triggerable t = (Triggerable) triggerables.elementAt(i);
      for (int j = 0; j < t.getTargets().size(); j++) {
        TreeReference target = (TreeReference) t.getTargets().elementAt(j);
        if (genericRoot.isParentOf(target, false)) {
          applicable.addElement(t);
          break;
        }
      }
    }

    evaluateTriggerables(applicable, rootRef);
  }
예제 #5
0
  public void finalizeTriggerables() {
    //
    // DAGify the triggerables based on dependencies and sort them so that
    // trigbles come only after the trigbles they depend on
    //

    Vector partialOrdering = new Vector();
    for (int i = 0; i < triggerables.size(); i++) {
      Triggerable t = (Triggerable) triggerables.elementAt(i);
      Vector deps = new Vector();

      if (t.canCascade()) {
        for (int j = 0; j < t.getTargets().size(); j++) {
          TreeReference target = (TreeReference) t.getTargets().elementAt(j);
          Vector triggered = (Vector) triggerIndex.get(target);
          if (triggered != null) {
            for (int k = 0; k < triggered.size(); k++) {
              Triggerable u = (Triggerable) triggered.elementAt(k);
              if (!deps.contains(u)) deps.addElement(u);
            }
          }
        }
      }

      for (int j = 0; j < deps.size(); j++) {
        Triggerable u = (Triggerable) deps.elementAt(j);
        Triggerable[] edge = {t, u};
        partialOrdering.addElement(edge);
      }
    }

    Vector vertices = new Vector();
    for (int i = 0; i < triggerables.size(); i++) vertices.addElement(triggerables.elementAt(i));
    triggerables.removeAllElements();

    while (vertices.size() > 0) {
      // determine root nodes
      Vector roots = new Vector();
      for (int i = 0; i < vertices.size(); i++) {
        roots.addElement(vertices.elementAt(i));
      }
      for (int i = 0; i < partialOrdering.size(); i++) {
        Triggerable[] edge = (Triggerable[]) partialOrdering.elementAt(i);
        roots.removeElement(edge[1]);
      }

      // if no root nodes while graph still has nodes, graph has cycles
      if (roots.size() == 0) {
        throw new RuntimeException(
            "Cannot create partial ordering of triggerables due to dependency cycle. Why wasn't this caught during parsing?");
      }

      // remove root nodes and edges originating from them
      for (int i = 0; i < roots.size(); i++) {
        Triggerable root = (Triggerable) roots.elementAt(i);
        triggerables.addElement(root);
        vertices.removeElement(root);
      }
      for (int i = partialOrdering.size() - 1; i >= 0; i--) {
        Triggerable[] edge = (Triggerable[]) partialOrdering.elementAt(i);
        if (roots.contains(edge[0])) partialOrdering.removeElementAt(i);
      }
    }

    triggerablesInOrder = true;

    //
    // build the condition index for repeatable nodes
    //

    conditionRepeatTargetIndex = new Hashtable();
    for (int i = 0; i < triggerables.size(); i++) {
      Triggerable t = (Triggerable) triggerables.elementAt(i);
      if (t instanceof Condition) {
        Vector targets = t.getTargets();
        for (int j = 0; j < targets.size(); j++) {
          TreeReference target = (TreeReference) targets.elementAt(j);
          if (instance.getTemplate(target) != null) {
            conditionRepeatTargetIndex.put(target, (Condition) t);
          }
        }
      }
    }
  }