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); } } }
/** * 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; } }
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); } }
/** 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); }
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); } } } } }