1 46 package org.jaxen.expr; 47 48 import java.util.ArrayList ; 49 import java.util.Collections ; 50 import java.util.Iterator ; 51 import java.util.List ; 52 53 import org.jaxen.Context; 54 import org.jaxen.ContextSupport; 55 import org.jaxen.JaxenException; 56 import org.jaxen.UnresolvableException; 57 import org.jaxen.Navigator; 58 import org.jaxen.expr.iter.IterableAxis; 59 import org.jaxen.saxpath.Axis; 60 61 73 public class DefaultNameStep extends DefaultStep implements NameStep { 74 75 81 private String prefix; 82 83 87 private String localName; 88 89 90 private boolean matchesAnyName; 91 92 93 private boolean hasPrefix; 94 95 103 public DefaultNameStep(IterableAxis axis, 104 String prefix, 105 String localName, 106 PredicateSet predicateSet) { 107 super(axis, predicateSet); 108 109 this.prefix = prefix; 110 this.localName = localName; 111 this.matchesAnyName = "*".equals(localName); 112 this.hasPrefix = (this.prefix != null && this.prefix.length() > 0); 113 } 114 115 120 public String getPrefix() { 121 return this.prefix; 122 } 123 124 129 public String getLocalName() { 130 return this.localName; 131 } 132 133 138 public boolean isMatchesAnyName() { 139 return matchesAnyName; 140 } 141 142 147 public String getText() { 148 StringBuffer buf = new StringBuffer (64); 149 buf.append(getAxisName()).append("::"); 150 if (getPrefix() != null && getPrefix().length() > 0) { 151 buf.append(getPrefix()).append(':'); 152 } 153 return buf.append(getLocalName()).append(super.getText()).toString(); 154 } 155 156 161 public List evaluate(Context context) throws JaxenException { 162 163 List contextNodeSet = context.getNodeSet(); 164 int contextSize = contextNodeSet.size(); 165 if (contextSize == 0) { 167 return Collections.EMPTY_LIST; 168 } 169 ContextSupport support = context.getContextSupport(); 170 IterableAxis iterableAxis = getIterableAxis(); 171 boolean namedAccess = (!matchesAnyName && iterableAxis.supportsNamedAccess(support)); 172 173 if (contextSize == 1) { 175 Object contextNode = contextNodeSet.get(0); 176 if (namedAccess) { 177 String uri = null; 179 if (hasPrefix) { 180 uri = support.translateNamespacePrefixToUri(prefix); 181 if (uri == null) { 182 throw new UnresolvableException("XPath expression uses unbound namespace prefix " + prefix); 183 } 184 } 185 Iterator axisNodeIter = iterableAxis.namedAccessIterator( 186 contextNode, support, localName, prefix, uri); 187 if (axisNodeIter == null || axisNodeIter.hasNext() == false) { 188 return Collections.EMPTY_LIST; 189 } 190 191 List newNodeSet = new ArrayList (); 194 while (axisNodeIter.hasNext()) { 195 newNodeSet.add(axisNodeIter.next()); 196 } 197 198 return getPredicateSet().evaluatePredicates(newNodeSet, support); 200 201 } 202 else { 203 Iterator axisNodeIter = iterableAxis.iterator(contextNode, support); 205 if (axisNodeIter == null || axisNodeIter.hasNext() == false) { 206 return Collections.EMPTY_LIST; 207 } 208 209 List newNodeSet = new ArrayList (contextSize); 212 while (axisNodeIter.hasNext()) { 213 Object eachAxisNode = axisNodeIter.next(); 214 if (matches(eachAxisNode, support)) { 215 newNodeSet.add(eachAxisNode); 216 } 217 } 218 219 return getPredicateSet().evaluatePredicates(newNodeSet, support); 221 } 222 } 223 224 IdentitySet unique = new IdentitySet(); 226 List interimSet = new ArrayList (contextSize); 227 List newNodeSet = new ArrayList (contextSize); 228 229 if (namedAccess) { 230 String uri = null; 231 if (hasPrefix) { 232 uri = support.translateNamespacePrefixToUri(prefix); 233 if (uri == null) { 234 throw new UnresolvableException("XPath expression uses unbound namespace prefix " + prefix); 235 } 236 } 237 for (int i = 0; i < contextSize; ++i) { 238 Object eachContextNode = contextNodeSet.get(i); 239 240 Iterator axisNodeIter = iterableAxis.namedAccessIterator( 241 eachContextNode, support, localName, prefix, uri); 242 if (axisNodeIter == null || axisNodeIter.hasNext() == false) { 243 continue; 244 } 245 246 while (axisNodeIter.hasNext()) { 248 Object eachAxisNode = axisNodeIter.next(); 249 if (! unique.contains(eachAxisNode)) { 250 unique.add(eachAxisNode); 251 interimSet.add(eachAxisNode); 252 } 253 } 254 255 newNodeSet.addAll(getPredicateSet().evaluatePredicates(interimSet, support)); 257 interimSet.clear(); 258 } 259 260 } else { 261 for (int i = 0; i < contextSize; ++i) { 262 Object eachContextNode = contextNodeSet.get(i); 263 264 Iterator axisNodeIter = axisIterator(eachContextNode, support); 265 if (axisNodeIter == null || axisNodeIter.hasNext() == false) { 266 continue; 267 } 268 269 276 277 while (axisNodeIter.hasNext()) { 279 Object eachAxisNode = axisNodeIter.next(); 280 281 if (matches(eachAxisNode, support)) { 282 if (! unique.contains(eachAxisNode)) { 283 unique.add(eachAxisNode); 284 interimSet.add(eachAxisNode); 285 } 286 } 287 } 288 289 newNodeSet.addAll(getPredicateSet().evaluatePredicates(interimSet, support)); 291 interimSet.clear(); 292 } 293 } 294 295 return newNodeSet; 296 } 297 298 306 public boolean matches(Object node, ContextSupport contextSupport) throws JaxenException { 307 308 Navigator nav = contextSupport.getNavigator(); 309 String myUri = null; 310 String nodeName = null; 311 String nodeUri = null; 312 313 if (nav.isElement(node)) { 314 nodeName = nav.getElementName(node); 315 nodeUri = nav.getElementNamespaceUri(node); 316 } 317 else if (nav.isText(node)) { 318 return false; 319 } 320 else if (nav.isAttribute(node)) { 321 if (getAxis() != Axis.ATTRIBUTE) { 322 return false; 323 } 324 nodeName = nav.getAttributeName(node); 325 nodeUri = nav.getAttributeNamespaceUri(node); 326 327 } 328 else if (nav.isDocument(node)) { 329 return false; 330 } 331 else if (nav.isNamespace(node)) { 332 if (getAxis() != Axis.NAMESPACE) { 333 return false; 335 } 336 nodeName = nav.getNamespacePrefix(node); 337 } 338 else { 339 return false; 340 } 341 342 if (hasPrefix) { 343 myUri = contextSupport.translateNamespacePrefixToUri(this.prefix); 344 if (myUri == null) { 345 throw new UnresolvableException("Cannot resolve namespace prefix '"+this.prefix+"'"); 346 } 347 } 348 else if (matchesAnyName) { 349 return true; 350 } 351 352 if (hasNamespace(myUri) != hasNamespace(nodeUri)) { 355 return false; 356 } 357 358 if (matchesAnyName || nodeName.equals(getLocalName())) { 362 return matchesNamespaceURIs(myUri, nodeUri); 363 } 364 365 return false; 366 } 367 368 374 private boolean hasNamespace(String uri) { 375 return (uri != null && uri.length() > 0); 376 } 377 378 385 protected boolean matchesNamespaceURIs(String uri1, String uri2) { 386 if (uri1 == uri2) { 387 return true; 388 } 389 if (uri1 == null) { 390 return (uri2.length() == 0); 391 } 392 if (uri2 == null) { 393 return (uri1.length() == 0); 394 } 395 return uri1.equals(uri2); 396 } 397 398 403 public void accept(Visitor visitor) { 404 visitor.visit(this); 405 } 406 407 412 public String toString() { 413 return "[(DefaultNameStep): " + getPrefix() + ":" + getLocalName() + "[" + super.toString() + "]]"; 414 } 415 416 } 417 | Popular Tags |