File: TemplateRuleSet.java

package info (click to toggle)
libxt-java 0.19991105-5
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,908 kB
  • ctags: 2,762
  • sloc: java: 12,823; makefile: 52; xml: 46
file content (132 lines) | stat: -rw-r--r-- 3,859 bytes parent folder | download | duplicates (2)
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;
  }
}