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 FromAncestors extends Axis { 42 private boolean _self; 43 44 public FromAncestors(AbstractPattern parent, boolean self) 45 { 46 super(parent) 47 ; 48 _self = self; 49 50 if (parent == null) 51 throw new RuntimeException (); 52 } 53 61 public boolean match(Node node, ExprEnvironment env) 62 throws XPathException 63 { 64 if (node == null) 65 return false; 66 67 Node lastNode = lastDescendantNode(node); 68 69 if (! _self) 70 node = XmlUtil.getNext(node); 71 72 for (; 73 node != null && node != lastNode; 74 node = XmlUtil.getNext(node)) { 75 if (_parent.match(node, env)) 76 return true; 77 } 78 79 return false; 80 } 81 82 public boolean isAscending() 83 { 84 return false; 85 } 86 87 94 public Node firstNode(Node node, ExprEnvironment env) 95 { 96 if (_self) 97 return node; 98 else 99 return node.getParentNode(); 100 } 101 102 110 public Node nextNode(Node node, Node last) 111 { 112 return (node == null) ? null : node.getParentNode(); 113 } 114 115 119 public int position(Node node, Env env, AbstractPattern pattern) 120 throws XPathException 121 { 122 int index = env.getPositionIndex(); 123 124 Node lastNode = lastDescendantNode(node); 125 126 Node axis = _self ? node : XmlUtil.getNext(node); 127 128 for (; index >= 0; index--) { 129 for (; axis != lastNode && axis != null; axis = XmlUtil.getNext(axis)) { 130 if (_parent.match(axis, env)) 131 break; 132 } 133 134 if (index > 0) 135 axis = XmlUtil.getNext(axis); 136 } 137 138 if (axis == lastNode) 139 return 0; 140 141 Node next = XmlUtil.getNext(axis); 142 for (; next != lastNode; next = XmlUtil.getNext(next)) { 143 if (_parent.match(next, env)) { 144 env.setMorePositions(true); 145 break; 146 } 147 } 148 149 Node a1 = axis; 150 151 if (! _self && axis != null) 152 axis = axis.getParentNode(); 153 154 int count = 0; 155 for (; axis != null; axis = axis.getParentNode()) { 156 if (pattern.match(axis, env)) 157 count++; 158 159 if (node == axis) 160 break; 161 } 162 163 return count; 164 } 165 166 173 private Node lastDescendantNode(Node node) 174 { 175 Node last = node; 176 177 for (; 178 last != null && last.getNextSibling() == null; 179 last = last.getParentNode()) { 180 } 181 182 return last != null ? last.getNextSibling() : null; 183 } 184 185 188 public int count(Node node, Env env, AbstractPattern pattern) 189 { 190 throw new RuntimeException (); 191 } 192 193 public String toString() 194 { 195 return getPrefix() + (_self ? "ancestor-or-self::" : "ancestor::"); 196 } 197 } 198 | Popular Tags |