1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
package com.jclark.xsl.tr;
import com.jclark.xsl.om.*;
import com.jclark.xsl.expr.PathPattern;
import com.jclark.xsl.expr.TopLevelPattern;
import com.jclark.xsl.expr.PatternList;
import com.jclark.xsl.expr.ExprContext;
import java.util.Vector;
import java.util.Enumeration;
class TemplateRuleSet {
private static class Rule {
final PathPattern pattern;
final Importance ruleImportance;
final Importance importImportance;
final Priority priority;
final Action action;
Rule(PathPattern pattern,
Importance ruleImportance,
Importance importImportance,
Priority priority,
Action action) {
this.ruleImportance = ruleImportance;
this.importImportance = importImportance;
if (priority == null)
this.priority = Priority.createDefault(pattern.getDefaultPriority());
else
this.priority = priority;
this.pattern = pattern;
this.action = action;
}
static boolean isBetter(Rule rule1, Rule rule2) {
int n = rule1.ruleImportance.compareTo(rule2.ruleImportance);
if (n == 0)
return rule1.priority.compareTo(rule2.priority) > 0;
// if n < 0, rule1.importance - rule2.importance < 0
// => rule1.importance < rule2.importance
// => false
return n > 0;
}
}
private Vector rules = new Vector();
private PatternList patternList = new PatternList();
private Action builtinAction;
TemplateRuleSet(Action builtinAction) {
this.builtinAction = builtinAction;
}
void compile() {
reverse(rules);
sortRulesVector(rules);
for (Enumeration iter = rules.elements(); iter.hasMoreElements();) {
Rule r = (Rule)iter.nextElement();
patternList.add(r.pattern, r);
}
}
private static void reverse(Vector v) {
int i = 0;
int j = v.size() - 1;
for (; i < j; i++, j--) {
Object tem = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(tem, j);
}
}
private static void sortRulesVector(Vector v) {
// Insertion sort
int sz = v.size();
for (int i = 1; i < sz; i++) {
Rule rule = (Rule)v.elementAt(i);
int j;
for (j = i; j > 0; j--) {
Rule tem = (Rule)v.elementAt(j - 1);
// Order best first.
// So stop when rule is worse or equal to tem
// => stop when not rule is better than tem.
if (!Rule.isBetter(rule, tem))
break;
v.setElementAt(tem, j);
}
v.setElementAt(rule, j);
}
}
void add(TopLevelPattern pattern,
Importance ruleImportance,
Importance importImportance,
Priority priority,
Action action) {
PathPattern[] alternatives = pattern.getAlternatives();
for (int i = 0; i < alternatives.length; i++)
rules.addElement(new Rule(alternatives[i],
ruleImportance,
importImportance,
priority,
action));
}
Action getAction(Node node, ExprContext context) throws XSLException {
Rule r = (Rule)patternList.get(node, context);
if (r == null)
return builtinAction;
return r.action;
}
Action getImportAction(Node node, ExprContext context, int importLevel) throws XSLException {
Enumeration rules = patternList.getAll(node, context);
Rule r = (Rule)rules.nextElement();
Importance minImportance = r.importImportance;
Importance limImportance = r.ruleImportance;
int currentLevel = 0;
while (rules.hasMoreElements()) {
r = (Rule)rules.nextElement();
if (r.ruleImportance.compareTo(limImportance) >= 0)
break;
if (r.ruleImportance.compareTo(minImportance) >= 0) {
if (currentLevel == importLevel)
return r.action;
currentLevel++;
minImportance = r.importImportance;
limImportance = r.ruleImportance;
}
}
return builtinAction;
}
}
|