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
|
package com.jclark.xsl.expr;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import com.jclark.xsl.om.*;
public class PatternList {
private Hashtable nameRules = new Hashtable();
private Vector typeRules[] = new Vector[Node.N_TYPES];
private Vector anyNameRules = new Vector();
public PatternList() {
for (int i = 0; i < Node.N_TYPES; i++)
typeRules[i] = new Vector();
}
public Object get(Node node, ExprContext context) throws XSLException {
Vector v = getVector(node);
int len = v.size();
for (int i = 0; i < len; i += 2)
if (((PathPattern)v.elementAt(i)).matches(node, context))
return v.elementAt(i + 1);
return null;
}
private static class MatchEnumeration implements Enumeration {
private Enumeration possibleMatches;
private Node node;
private Object nextMatch;
private ExprContext context;
MatchEnumeration(Enumeration possibleMatches, Node node, ExprContext context) {
this.node = node;
this.possibleMatches = possibleMatches;
this.context = context;
setNextMatch();
}
public boolean hasMoreElements() {
return nextMatch != null;
}
public Object nextElement() {
Object tem = nextMatch;
setNextMatch();
return tem;
}
void setNextMatch() {
while (possibleMatches.hasMoreElements()) {
PathPattern pp = (PathPattern)possibleMatches.nextElement();
try {
if (pp.matches(node, context)) {
nextMatch = possibleMatches.nextElement();
return;
}
}
catch (XSLException e) { } // FIXME
possibleMatches.nextElement();
}
nextMatch = null;
}
}
public Enumeration getAll(Node node, ExprContext context) {
return new MatchEnumeration(getVector(node).elements(), node, context);
}
private Vector getVector(Node node) {
Name nodeName = node.getName();
if (nodeName != null) {
Vector rules = (Vector)nameRules.get(nodeName);
if (rules != null)
return rules;
}
return typeRules[node.getType()];
}
private static void append(Vector v, PathPattern pp, Object obj) {
v.addElement(pp);
v.addElement(obj);
}
public void add(PathPattern pp, Object obj) {
PathPatternBase ppb = (PathPatternBase)pp;
Name matchName = ppb.getMatchName();
if (matchName == null) {
byte matchNodeType = ppb.getMatchNodeType();
append(typeRules[matchNodeType], ppb, obj);
switch (matchNodeType) {
case Node.ELEMENT:
case Node.ATTRIBUTE:
case Node.PROCESSING_INSTRUCTION:
for (Enumeration enum = nameRules.elements(); enum.hasMoreElements();)
append((Vector)enum.nextElement(), ppb, obj);
append(anyNameRules, ppb, obj);
break;
}
}
else {
Vector v = (Vector)nameRules.get(matchName);
if (v == null) {
v = (Vector)anyNameRules.clone();
nameRules.put(matchName, v);
}
append(v, ppb, obj);
}
}
}
|