1 28 29 package com.caucho.xpath.pattern; 30 31 import com.caucho.xml.XmlUtil; 32 import com.caucho.xpath.Env; 33 import com.caucho.xpath.ExprEnvironment; 34 import com.caucho.xpath.XPathException; 35 36 import org.w3c.dom.Node ; 37 38 41 public class FromPrevious extends Axis { 42 public FromPrevious(AbstractPattern parent) 43 { 44 super(parent); 45 46 if (parent == null) 47 throw new RuntimeException (); 48 } 49 50 53 public boolean match(Node node, ExprEnvironment env) 54 throws XPathException 55 { 56 if (node == null) 57 return false; 58 59 return getAxisContext(node, env, node) != null; 60 } 61 62 65 public boolean isAscending() 66 { 67 return false; 68 } 69 70 75 public int position(Node node, Env env, AbstractPattern pattern) 76 throws XPathException 77 { 78 int index = env.getPositionIndex(); 79 80 boolean hasMatch = true; 81 Node axis = XmlUtil.getNext(node); 82 83 for (; axis != null; axis = XmlUtil.getNext(axis)) { 84 if (hasMatch && _parent.match(axis, env)) { 85 boolean hasParent = false; 86 for (Node ptr = node.getParentNode(); 87 ptr != null; 88 ptr = ptr.getParentNode()) { 89 if (ptr == axis) { 90 hasParent = true; 91 break; 92 } 93 } 94 95 if (! hasParent && --index < 0) { 96 hasMatch = false; 97 break; 98 } 99 } 100 101 if (! hasMatch && pattern.match(axis, env)) 102 hasMatch = true; 103 } 104 105 int count = 1; 106 Node ptr; 107 for (ptr = axis; 108 ptr != null && ptr.getNextSibling() == null; 109 ptr = ptr.getParentNode()) { 110 } 111 112 for (ptr = XmlUtil.getPrevious(axis); 113 ptr != null && ptr != node; 114 ptr = XmlUtil.getPrevious(ptr)) { 115 if (pattern.match(ptr, env)) { 116 boolean hasParent = false; 117 for (Node n = node; n != null; n = n.getParentNode()) { 118 if (n == ptr) { 119 hasParent = true; 120 break; 121 } 122 } 123 124 if (! hasParent) 125 count++; 126 } 127 } 128 129 for (; axis != null; axis = XmlUtil.getNext(axis)) { 130 if (_parent.match(axis, env)) { 131 env.setMorePositions(true); 132 break; 133 } 134 } 135 136 return count; 137 } 138 139 144 public int count(Node node, Env env, AbstractPattern pattern) 145 throws XPathException 146 { 147 int index = env.getPositionIndex(); 148 149 Node axis = getAxisContext(node, env, node); 150 for (; index > 0; index--) 151 axis = getAxisContext(axis, env, node); 152 153 if (getAxisContext(axis, env, node) != null) 154 env.setMorePositions(true); 155 156 int count = 0; 157 for (Node ptr = axis; 158 ptr != null; 159 ptr = XmlUtil.getPrevious(ptr)) { 160 if (pattern.match(ptr, env) && ! isDescendant(ptr, axis)) 161 count++; 162 } 163 164 return count; 165 } 166 167 170 public boolean isUnique() 171 { 172 if (_parent == null) 173 return true; 174 else 175 return _parent.isSingleSelect(); 176 } 177 178 185 public Node firstNode(Node node, ExprEnvironment env) 186 { 187 return XmlUtil.getPrevious(node); 188 } 189 190 198 public Node nextNode(Node node, Node lastNode) 199 { 200 loop: 201 while (node != null) { 202 node = XmlUtil.getPrevious(node); 203 204 for (Node ptr = lastNode; ptr != null; ptr = ptr.getParentNode()) { 205 if (ptr == node) 206 continue loop; 207 } 208 209 return node; 210 } 211 212 return null; 213 } 214 215 222 public Node lastNode(Node node) 223 { 224 return node; 225 } 226 227 231 private Node getAxisContext(Node axis, ExprEnvironment env, Node node) 232 throws XPathException 233 { 234 if (axis == null) 235 return null; 236 237 while ((axis = XmlUtil.getNext(axis)) != null) { 238 if (! isDescendant(axis, node) && _parent.match(axis, env)) 239 return axis; 240 } 241 242 return null; 243 } 244 245 private boolean isDescendant(Node descendant, Node node) 246 { 247 for (; 248 descendant != node && descendant != null; 249 descendant = descendant.getParentNode()) { 250 } 251 252 return descendant != null; 253 } 254 255 public String toString() 256 { 257 return getPrefix() + "preceding::"; 258 } 259 } 260 261 | Popular Tags |