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
|
package com.jclark.xsl.expr;
import com.jclark.xsl.om.*;
class FilterPattern extends PathPatternBase {
private PathPatternBase pattern;
private BooleanExpr predicate;
FilterPattern(PathPatternBase pattern, BooleanExpr predicate) {
this.pattern = pattern;
this.predicate = predicate;
}
class Context extends DelegateExprContext {
Node node;
int position = 0;
int lastPosition = 0;
Context(Node node, ExprContext context) {
super(context);
this.node = node;
}
public int getPosition() throws XSLException {
if (position != 0)
return position;
NodeIterator iter;
switch (node.getType()) {
case Node.ROOT:
position = 1;
return 1;
case Node.ATTRIBUTE:
iter = node.getParent().getAttributes();
break;
default:
iter = node.getParent().getChildren();
break;
}
position = 1;
for (;;) {
Node tem = iter.next();
if (tem.equals(node))
break;
if (pattern.matches(tem, origContext))
position++;
}
return position;
}
public int getLastPosition() throws XSLException {
if (lastPosition != 0)
return lastPosition;
NodeIterator iter;
switch (node.getType()) {
case Node.ROOT:
lastPosition = 1;
return 1;
case Node.ATTRIBUTE:
iter = node.getParent().getAttributes();
lastPosition = 0;
break;
default:
iter = node.getFollowingSiblings();
lastPosition = position;
break;
}
for (;;) {
Node tem = iter.next();
if (tem == null)
break;
if (pattern.matches(tem, origContext))
lastPosition++;
}
return lastPosition;
}
}
public boolean matches(Node node, ExprContext context) throws XSLException {
if (!pattern.matches(node, context))
return false;
return predicate.eval(node, new Context(node, context));
}
public int getDefaultPriority() {
return 1;
}
Name getMatchName() {
return pattern.getMatchName();
}
byte getMatchNodeType() {
return pattern.getMatchNodeType();
}
}
|