1 57 58 package com.sun.org.apache.xerces.internal.impl.xs.identity; 59 60 import com.sun.org.apache.xerces.internal.impl.Constants; 61 import com.sun.org.apache.xerces.internal.impl.xpath.XPath; 62 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 63 import com.sun.org.apache.xerces.internal.util.IntStack; 64 import com.sun.org.apache.xerces.internal.xni.QName; 65 import com.sun.org.apache.xerces.internal.xni.XMLAttributes; 66 import com.sun.org.apache.xerces.internal.xs.AttributePSVI; 67 68 69 76 public class XPathMatcher { 77 78 82 84 85 protected static final boolean DEBUG_ALL = false; 86 87 88 protected static final boolean DEBUG_METHODS = false || DEBUG_ALL; 89 90 91 protected static final boolean DEBUG_METHODS2 = false || DEBUG_METHODS || DEBUG_ALL; 92 93 94 protected static final boolean DEBUG_METHODS3 = false || DEBUG_METHODS || DEBUG_ALL; 95 96 97 protected static final boolean DEBUG_MATCH = false || DEBUG_ALL; 98 99 100 protected static final boolean DEBUG_STACK = false || DEBUG_ALL; 101 102 103 protected static final boolean DEBUG_ANY = DEBUG_METHODS || 104 DEBUG_METHODS2 || 105 DEBUG_METHODS3 || 106 DEBUG_MATCH || 107 DEBUG_STACK; 108 109 protected static final int MATCHED = 1; 113 protected static final int MATCHED_ATTRIBUTE = 3; 115 protected static final int MATCHED_DESCENDANT = 5; 117 protected static final int MATCHED_DESCENDANT_PREVIOUS = 13; 119 120 124 125 private XPath.LocationPath[] fLocationPaths; 126 127 128 private int[] fMatched; 129 130 131 protected Object fMatchedString; 132 133 134 private IntStack[] fStepIndexes; 135 136 137 private int[] fCurrentStep; 138 139 143 private int [] fNoMatchDepth; 144 145 final QName fQName = new QName(); 146 147 XSTypeDefinition fCurrMatchedType = null; 148 152 158 public XPathMatcher(XPath xpath) { 159 fLocationPaths = xpath.getLocationPaths(); 160 fStepIndexes = new IntStack[fLocationPaths.length]; 161 for(int i=0; i<fStepIndexes.length; i++) fStepIndexes[i] = new IntStack(); 162 fCurrentStep = new int[fLocationPaths.length]; 163 fNoMatchDepth = new int[fLocationPaths.length]; 164 fMatched = new int[fLocationPaths.length]; 165 } 167 171 175 public boolean isMatched() { 176 for (int i=0; i < fLocationPaths.length; i++) 178 if (((fMatched[i] & MATCHED) == MATCHED) 179 && ((fMatched[i] & MATCHED_DESCENDANT_PREVIOUS) != MATCHED_DESCENDANT_PREVIOUS) 180 && ((fNoMatchDepth[i] == 0) 181 || ((fMatched[i] & MATCHED_DESCENDANT) == MATCHED_DESCENDANT))) 182 return true; 183 184 return false; 185 } 187 191 protected void handleContent(XSTypeDefinition type, boolean nillable, Object value) { 194 } 195 196 201 protected void matched(Object actualValue, boolean isNil) { 202 if (DEBUG_METHODS3) { 203 System.out.println(toString()+"#matched(\""+actualValue+"\")"); 204 } 205 } 207 211 217 public void startDocumentFragment(){ 218 if (DEBUG_METHODS) { 219 System.out.println(toString()+"#startDocumentFragment("+ 220 ")"); 221 } 222 223 fMatchedString = null; 225 for(int i = 0; i < fLocationPaths.length; i++) { 226 fStepIndexes[i].clear(); 227 fCurrentStep[i] = 0; 228 fNoMatchDepth[i] = 0; 229 fMatched[i] = 0; 230 } 231 232 233 } 235 246 public void startElement(QName element, XMLAttributes attributes){ 247 if (DEBUG_METHODS2) { 248 System.out.println(toString()+"#startElement("+ 249 "element={"+element+"},"+ 250 "attributes=..."+attributes+ 251 ")"); 252 } 253 254 for(int i = 0; i < fLocationPaths.length; i++) { 255 int startStep = fCurrentStep[i]; 257 fStepIndexes[i].push(startStep); 258 259 if ((fMatched[i] & MATCHED_DESCENDANT) == MATCHED || fNoMatchDepth[i] > 0) { 261 fNoMatchDepth[i]++; 262 continue; 263 } 264 if((fMatched[i] & MATCHED_DESCENDANT) == MATCHED_DESCENDANT) { 265 fMatched[i] = MATCHED_DESCENDANT_PREVIOUS; 266 } 267 268 if (DEBUG_STACK) { 269 System.out.println(toString()+": "+fStepIndexes[i]); 270 } 271 272 XPath.Step[] steps = fLocationPaths[i].steps; 274 while (fCurrentStep[i] < steps.length && 275 steps[fCurrentStep[i]].axis.type == XPath.Axis.SELF) { 276 if (DEBUG_MATCH) { 277 XPath.Step step = steps[fCurrentStep[i]]; 278 System.out.println(toString()+" [SELF] MATCHED!"); 279 } 280 fCurrentStep[i]++; 281 } 282 if (fCurrentStep[i] == steps.length) { 283 if (DEBUG_MATCH) { 284 System.out.println(toString()+" XPath MATCHED!"); 285 } 286 fMatched[i] = MATCHED; 287 continue; 288 } 289 290 int descendantStep = fCurrentStep[i]; 295 while(fCurrentStep[i] < steps.length && steps[fCurrentStep[i]].axis.type == XPath.Axis.DESCENDANT) { 296 if (DEBUG_MATCH) { 297 XPath.Step step = steps[fCurrentStep[i]]; 298 System.out.println(toString()+" [DESCENDANT] MATCHED!"); 299 } 300 fCurrentStep[i]++; 301 } 302 boolean sawDescendant = fCurrentStep[i] > descendantStep; 303 if (fCurrentStep[i] == steps.length) { 304 if (DEBUG_MATCH) { 305 System.out.println(toString()+" XPath DIDN'T MATCH!"); 306 } 307 fNoMatchDepth[i]++; 308 if (DEBUG_MATCH) { 309 System.out.println(toString()+" [CHILD] after NO MATCH"); 310 } 311 continue; 312 } 313 314 if ((fCurrentStep[i] == startStep || fCurrentStep[i] > descendantStep) && 316 steps[fCurrentStep[i]].axis.type == XPath.Axis.CHILD) { 317 XPath.Step step = steps[fCurrentStep[i]]; 318 XPath.NodeTest nodeTest = step.nodeTest; 319 if (DEBUG_MATCH) { 320 System.out.println(toString()+" [CHILD] before"); 321 } 322 if (nodeTest.type == XPath.NodeTest.QNAME) { 323 if (!nodeTest.name.equals(element)) { 324 if(fCurrentStep[i] > descendantStep) { 325 fCurrentStep[i] = descendantStep; 326 continue; 327 } 328 fNoMatchDepth[i]++; 329 if (DEBUG_MATCH) { 330 System.out.println(toString()+" [CHILD] after NO MATCH"); 331 } 332 continue; 333 } 334 } 335 fCurrentStep[i]++; 336 if (DEBUG_MATCH) { 337 System.out.println(toString()+" [CHILD] after MATCHED!"); 338 } 339 } 340 if (fCurrentStep[i] == steps.length) { 341 if(sawDescendant) { 342 fCurrentStep[i] = descendantStep; 343 fMatched[i] = MATCHED_DESCENDANT; 344 } else { 345 fMatched[i] = MATCHED; 346 } 347 continue; 348 } 349 350 if (fCurrentStep[i] < steps.length && 352 steps[fCurrentStep[i]].axis.type == XPath.Axis.ATTRIBUTE) { 353 if (DEBUG_MATCH) { 354 System.out.println(toString()+" [ATTRIBUTE] before"); 355 } 356 int attrCount = attributes.getLength(); 357 if (attrCount > 0) { 358 XPath.NodeTest nodeTest = steps[fCurrentStep[i]].nodeTest; 359 360 for (int aIndex = 0; aIndex < attrCount; aIndex++) { 361 attributes.getName(aIndex, fQName); 362 if (nodeTest.type != XPath.NodeTest.QNAME || 363 nodeTest.name.equals(fQName)) { 364 fCurrentStep[i]++; 365 if (fCurrentStep[i] == steps.length) { 366 fMatched[i] = MATCHED_ATTRIBUTE; 367 int j=0; 368 for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++); 369 if(j==i) { 370 AttributePSVI attrPSVI = (AttributePSVI)attributes.getAugmentations(aIndex).getItem(Constants.ATTRIBUTE_PSVI); 371 fMatchedString = attrPSVI.getActualNormalizedValue(); 372 fCurrMatchedType = attrPSVI.getTypeDefinition(); 373 matched(fMatchedString, false); 374 } 375 } 376 break; 377 } 378 } 379 } 380 if ((fMatched[i] & MATCHED) != MATCHED) { 381 if(fCurrentStep[i] > descendantStep) { 382 fCurrentStep[i] = descendantStep; 383 continue; 384 } 385 fNoMatchDepth[i]++; 386 if (DEBUG_MATCH) { 387 System.out.println(toString()+" [ATTRIBUTE] after"); 388 } 389 continue; 390 } 391 if (DEBUG_MATCH) { 392 System.out.println(toString()+" [ATTRIBUTE] after MATCHED!"); 393 } 394 } 395 } 396 397 } 398 400 414 public void endElement(QName element, XSTypeDefinition type, boolean nillable, Object value ) { 415 if (DEBUG_METHODS2) { 416 System.out.println(toString()+"#endElement("+ 417 "element={"+element+"},"+ 418 ")"); 419 } 420 for(int i = 0; i<fLocationPaths.length; i++) { 421 fCurrentStep[i] = fStepIndexes[i].pop(); 423 424 if (fNoMatchDepth[i] > 0) { 426 fNoMatchDepth[i]--; 427 } 428 429 else { 431 int j=0; 432 for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++); 433 if ((j<i) || (fMatched[j] == 0) || 434 ((fMatched[j] & MATCHED_ATTRIBUTE) == MATCHED_ATTRIBUTE)) { 435 continue; 436 } 437 handleContent(type, nillable, value); 442 fMatched[i] = 0; 443 } 444 445 if (DEBUG_STACK) { 446 System.out.println(toString()+": "+fStepIndexes[i]); 447 } 448 } 449 450 } 452 456 457 public String toString() { 458 461 StringBuffer str = new StringBuffer (); 462 String s = super.toString(); 463 int index2 = s.lastIndexOf('.'); 464 if (index2 != -1) { 465 s = s.substring(index2 + 1); 466 } 467 str.append(s); 468 for(int i =0;i<fLocationPaths.length; i++) { 469 str.append('['); 470 XPath.Step[] steps = fLocationPaths[i].steps; 471 for (int j = 0; j < steps.length; j++) { 472 if (j == fCurrentStep[i]) { 473 str.append('^'); 474 } 475 str.append(steps[j].toString()); 476 if (j < steps.length - 1) { 477 str.append('/'); 478 } 479 } 480 if (fCurrentStep[i] == steps.length) { 481 str.append('^'); 482 } 483 str.append(']'); 484 str.append(','); 485 } 486 return str.toString(); 487 } 489 493 494 private String normalize(String s) { 495 StringBuffer str = new StringBuffer (); 496 int length = s.length(); 497 for (int i = 0; i < length; i++) { 498 char c = s.charAt(i); 499 switch (c) { 500 case '\n': { 501 str.append("\\n"); 502 break; 503 } 504 default: { 505 str.append(c); 506 } 507 } 508 } 509 return str.toString(); 510 } 512 public XSTypeDefinition getCurrentMatchedType(){ 513 return fCurrMatchedType; 514 } 515 516 520 528 529 564 565 } | Popular Tags |