1 28 29 package com.caucho.xpath.pattern; 30 31 import com.caucho.xpath.Env; 32 import com.caucho.xpath.Expr; 33 import com.caucho.xpath.ExprEnvironment; 34 import com.caucho.xpath.XPathException; 35 36 import org.w3c.dom.Node ; 37 38 42 public class FilterPattern extends AbstractPattern { 43 private Expr _expr; 44 45 private AbstractPattern _position; 46 47 public FilterPattern(AbstractPattern parent, Expr expr) 48 { 49 super(parent); 50 51 _expr = expr; 52 53 if (parent == null) 54 throw new RuntimeException (); 55 } 56 57 public String getNodeName() 58 { 59 return _parent.getNodeName(); 60 } 61 62 65 public Expr getExpr() 66 { 67 return _expr; 68 } 69 70 79 96 public boolean match(Node node, ExprEnvironment env) 97 throws XPathException 98 { 99 if (! _parent.match(node, env)) 100 return false; 101 102 int envPosition = env.getContextPosition(); 104 105 if (envPosition > 0) { 106 if (_expr.isBoolean()) { 107 return _expr.evalBoolean(node, env); 108 } 109 else if (_expr.isNumber()) { 110 double test = _expr.evalNumber(node, env); 111 112 return (envPosition == (int) test); 113 } 114 else { 115 Object value = _expr.evalObject(node, env); 116 117 if (value instanceof Number ) 118 return (envPosition == ((Number ) value).intValue()); 119 120 return Expr.toBoolean(value); 121 } 122 } 123 124 if (! (env instanceof Env)) 126 throw new RuntimeException (String.valueOf(env)); 127 128 Env globalEnv = (Env) env; 129 boolean oldMorePositions = globalEnv.setMorePositions(true); 130 int oldIndex = globalEnv.setPositionIndex(0); 131 try { 132 for (int i = 0; globalEnv.hasMorePositions(); i++) { 133 globalEnv.setPositionIndex(i); 134 globalEnv.setMorePositions(false); 135 136 if (_expr.isNumber()) { 137 double test = _expr.evalNumber(node, env); 138 double position = _parent.position(node, globalEnv, 139 _parent.copyPosition()); 140 141 if (position == test) 142 return true; 143 } 144 else if (_expr.isBoolean()) { 145 if (_expr.evalBoolean(node, env)) 146 return true; 147 } 148 else { 149 Object value = _expr.evalObject(node, env); 150 151 if (value instanceof Number ) { 152 double test = ((Number ) value).doubleValue(); 153 double position = _parent.position(node, globalEnv, 154 _parent.copyPosition()); 155 156 if (position == test) 157 return true; 158 } 159 else if (Expr.toBoolean(value)) 160 return true; 161 } 162 } 163 164 return false; 165 } finally { 166 globalEnv.setPositionIndex(oldIndex); 167 globalEnv.setMorePositions(oldMorePositions); 168 } 169 } 170 171 180 public NodeIterator createNodeIterator(Node node, ExprEnvironment env, 181 AbstractPattern match) 182 throws XPathException 183 { 184 NodeIterator parentIter; 185 parentIter = _parent.createNodeIterator(node, env, _parent.copyPosition()); 186 187 return new FilterIterator(parentIter, _expr, env, node); 188 } 189 190 public AbstractPattern copyPosition() 191 { 192 return null; 193 } 194 195 public String toString() 196 { 197 return (_parent.toString() + "[" + _expr + "]"); 198 } 199 } 200 | Popular Tags |