1 17 package com.sun.org.apache.xml.internal.security.signature; 18 19 import java.io.IOException ; 20 import java.io.StringWriter ; 21 import java.io.Writer ; 22 import java.util.Arrays ; 23 import java.util.Set ; 24 25 import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; 26 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 27 import org.w3c.dom.Attr ; 28 import org.w3c.dom.Comment ; 29 import org.w3c.dom.Document ; 30 import org.w3c.dom.Element ; 31 import org.w3c.dom.NamedNodeMap ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.ProcessingInstruction ; 34 35 41 public class XMLSignatureInputDebugger { 42 43 44 45 46 private Set _xpathNodeSet; 47 48 private Set _inclusiveNamespaces; 49 50 51 private Document _doc = null; 52 53 54 private Writer _writer = null; 55 56 67 static final String HTMLPrefix = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" 68 + "<html>\n" 69 + "<head>\n" 70 + "<title>Caninical XML node set</title>\n" 71 + "<style type=\"text/css\">\n" 72 + "<!-- \n" 73 + ".INCLUDED { \n" 74 + " color: #000000; \n" 75 + " background-color: \n" 76 + " #FFFFFF; \n" 77 + " font-weight: bold; } \n" 78 + ".EXCLUDED { \n" 79 + " color: #666666; \n" 80 + " background-color: \n" 81 + " #999999; } \n" 82 + ".INCLUDEDINCLUSIVENAMESPACE { \n" 83 + " color: #0000FF; \n" 84 + " background-color: #FFFFFF; \n" 85 + " font-weight: bold; \n" 86 + " font-style: italic; } \n" 87 + ".EXCLUDEDINCLUSIVENAMESPACE { \n" 88 + " color: #0000FF; \n" 89 + " background-color: #999999; \n" 90 + " font-style: italic; } \n" 91 + "--> \n" 92 + "</style> \n" 93 + "</head>\n" 94 + "<body bgcolor=\"#999999\">\n" 95 + "<h1>Explanation of the output</h1>\n" 96 + "<p>The following text contains the nodeset of the given Reference before it is canonicalized. There exist four different styles to indicate how a given node is treated.</p>\n" 97 + "<ul>\n" 98 + "<li class=\"INCLUDED\">A node which is in the node set is labeled using the INCLUDED style.</li>\n" 99 + "<li class=\"EXCLUDED\">A node which is <em>NOT</em> in the node set is labeled EXCLUDED style.</li>\n" 100 + "<li class=\"INCLUDEDINCLUSIVENAMESPACE\">A namespace which is in the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n" 101 + "<li class=\"EXCLUDEDINCLUSIVENAMESPACE\">A namespace which is in NOT the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n" 102 + "</ul>\n" + "<h1>Output</h1>\n" + "<pre>\n"; 103 104 105 static final String HTMLSuffix = "</pre></body></html>"; 106 107 static final String HTMLExcludePrefix = "<span class=\"EXCLUDED\">"; 108 109 static final String HTMLExcludeSuffix = "</span>"; 110 111 static final String HTMLIncludePrefix = "<span class=\"INCLUDED\">"; 112 113 static final String HTMLIncludeSuffix = "</span>"; 114 115 static final String HTMLIncludedInclusiveNamespacePrefix = "<span class=\"INCLUDEDINCLUSIVENAMESPACE\">"; 116 117 static final String HTMLIncludedInclusiveNamespaceSuffix = "</span>"; 118 119 static final String HTMLExcludedInclusiveNamespacePrefix = "<span class=\"EXCLUDEDINCLUSIVENAMESPACE\">"; 120 121 static final String HTMLExcludedInclusiveNamespaceSuffix = "</span>"; 122 123 private static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1; 124 125 private static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0; 126 127 private static final int NODE_AFTER_DOCUMENT_ELEMENT = 1; 128 129 static final AttrCompare ATTR_COMPARE = new AttrCompare(); 130 131 private XMLSignatureInputDebugger() { 133 } 135 136 141 public XMLSignatureInputDebugger( 142 XMLSignatureInput xmlSignatureInput) { 143 144 if (!xmlSignatureInput.isNodeSet()) { 145 this._xpathNodeSet = null; 146 } else { 147 this._xpathNodeSet = xmlSignatureInput._inputNodeSet; 148 } 149 } 150 151 157 public XMLSignatureInputDebugger( 158 XMLSignatureInput xmlSignatureInput, Set inclusiveNamespace) { 159 160 this(xmlSignatureInput); 161 162 this._inclusiveNamespaces = inclusiveNamespace; 163 } 164 165 171 public String getHTMLRepresentation() throws XMLSignatureException { 172 173 if ((this._xpathNodeSet == null) || (this._xpathNodeSet.size() == 0)) { 174 return HTMLPrefix + "<blink>no node set, sorry</blink>" 175 + HTMLSuffix; 176 } 177 178 { 179 180 Node n = (Node ) this._xpathNodeSet.iterator().next(); 182 183 this._doc = XMLUtils.getOwnerDocument(n); 184 } 185 186 try { 187 this._writer = new StringWriter (); 188 189 this.canonicalizeXPathNodeSet(this._doc); 190 this._writer.close(); 191 192 return this._writer.toString(); 193 } catch (IOException ex) { 194 throw new XMLSignatureException("empty", ex); 195 } finally { 196 this._xpathNodeSet = null; 197 this._doc = null; 198 this._writer = null; 199 } 200 } 201 202 209 private void canonicalizeXPathNodeSet(Node currentNode) 210 throws XMLSignatureException, IOException { 211 212 int currentNodeType = currentNode.getNodeType(); 213 switch (currentNodeType) { 214 215 case Node.DOCUMENT_TYPE_NODE: 216 default: 217 break; 218 219 case Node.ENTITY_NODE: 220 case Node.NOTATION_NODE: 221 case Node.DOCUMENT_FRAGMENT_NODE: 222 case Node.ATTRIBUTE_NODE: 223 throw new XMLSignatureException("empty"); 224 case Node.DOCUMENT_NODE: 225 this._writer.write(HTMLPrefix); 226 227 for (Node currentChild = currentNode.getFirstChild(); currentChild != null; currentChild = currentChild 228 .getNextSibling()) { 229 this.canonicalizeXPathNodeSet(currentChild); 230 } 231 232 this._writer.write(HTMLSuffix); 233 break; 234 235 case Node.COMMENT_NODE: 236 if (this._xpathNodeSet.contains(currentNode)) { 237 this._writer.write(HTMLIncludePrefix); 238 } else { 239 this._writer.write(HTMLExcludePrefix); 240 } 241 242 int position = getPositionRelativeToDocumentElement(currentNode); 243 244 if (position == NODE_AFTER_DOCUMENT_ELEMENT) { 245 this._writer.write("\n"); 246 } 247 248 this.outputCommentToWriter((Comment ) currentNode); 249 250 if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { 251 this._writer.write("\n"); 252 } 253 254 if (this._xpathNodeSet.contains(currentNode)) { 255 this._writer.write(HTMLIncludeSuffix); 256 } else { 257 this._writer.write(HTMLExcludeSuffix); 258 } 259 break; 260 261 case Node.PROCESSING_INSTRUCTION_NODE: 262 if (this._xpathNodeSet.contains(currentNode)) { 263 this._writer.write(HTMLIncludePrefix); 264 } else { 265 this._writer.write(HTMLExcludePrefix); 266 } 267 268 position = getPositionRelativeToDocumentElement(currentNode); 269 270 if (position == NODE_AFTER_DOCUMENT_ELEMENT) { 271 this._writer.write("\n"); 272 } 273 274 this.outputPItoWriter((ProcessingInstruction ) currentNode); 275 276 if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { 277 this._writer.write("\n"); 278 } 279 280 if (this._xpathNodeSet.contains(currentNode)) { 281 this._writer.write(HTMLIncludeSuffix); 282 } else { 283 this._writer.write(HTMLExcludeSuffix); 284 } 285 break; 286 287 case Node.TEXT_NODE: 288 case Node.CDATA_SECTION_NODE: 289 if (this._xpathNodeSet.contains(currentNode)) { 290 this._writer.write(HTMLIncludePrefix); 291 } else { 292 this._writer.write(HTMLExcludePrefix); 293 } 294 295 outputTextToWriter(currentNode.getNodeValue()); 296 297 for (Node nextSibling = currentNode.getNextSibling(); (nextSibling != null) 298 && ((nextSibling.getNodeType() == Node.TEXT_NODE) || (nextSibling 299 .getNodeType() == Node.CDATA_SECTION_NODE)); nextSibling = nextSibling 300 .getNextSibling()) { 301 302 309 this.outputTextToWriter(nextSibling.getNodeValue()); 310 } 311 312 if (this._xpathNodeSet.contains(currentNode)) { 313 this._writer.write(HTMLIncludeSuffix); 314 } else { 315 this._writer.write(HTMLExcludeSuffix); 316 } 317 break; 318 319 case Node.ELEMENT_NODE: 320 Element currentElement = (Element ) currentNode; 321 322 if (this._xpathNodeSet.contains(currentNode)) { 323 this._writer.write(HTMLIncludePrefix); 324 } else { 325 this._writer.write(HTMLExcludePrefix); 326 } 327 328 this._writer.write("<"); 329 this._writer.write(currentElement.getTagName()); 330 331 if (this._xpathNodeSet.contains(currentNode)) { 332 this._writer.write(HTMLIncludeSuffix); 333 } else { 334 this._writer.write(HTMLExcludeSuffix); 335 } 336 337 NamedNodeMap attrs = currentElement.getAttributes(); 339 int attrsLength = attrs.getLength(); 340 Object attrs2[] = new Object [attrsLength]; 341 342 for (int i = 0; i < attrsLength; i++) { 343 attrs2[i] = attrs.item(i); 344 } 345 346 Arrays.sort(attrs2, ATTR_COMPARE); 347 Object attrs3[] = attrs2; 348 349 for (int i = 0; i < attrsLength; i++) { 350 Attr a = (Attr ) attrs3[i]; 351 boolean included = this._xpathNodeSet.contains(a); 352 boolean inclusive = this._inclusiveNamespaces.contains(a 353 .getName()); 354 355 if (included) { 356 if (inclusive) { 357 358 this._writer 360 .write(HTMLIncludedInclusiveNamespacePrefix); 361 } else { 362 363 this._writer.write(HTMLIncludePrefix); 365 } 366 } else { 367 if (inclusive) { 368 369 this._writer 371 .write(HTMLExcludedInclusiveNamespacePrefix); 372 } else { 373 374 this._writer.write(HTMLExcludePrefix); 376 } 377 } 378 379 this.outputAttrToWriter(a.getNodeName(), a.getNodeValue()); 380 381 if (included) { 382 if (inclusive) { 383 384 this._writer 386 .write(HTMLIncludedInclusiveNamespaceSuffix); 387 } else { 388 389 this._writer.write(HTMLIncludeSuffix); 391 } 392 } else { 393 if (inclusive) { 394 395 this._writer 397 .write(HTMLExcludedInclusiveNamespaceSuffix); 398 } else { 399 400 this._writer.write(HTMLExcludeSuffix); 402 } 403 } 404 } 405 406 if (this._xpathNodeSet.contains(currentNode)) { 407 this._writer.write(HTMLIncludePrefix); 408 } else { 409 this._writer.write(HTMLExcludePrefix); 410 } 411 412 this._writer.write(">"); 413 414 if (this._xpathNodeSet.contains(currentNode)) { 415 this._writer.write(HTMLIncludeSuffix); 416 } else { 417 this._writer.write(HTMLExcludeSuffix); 418 } 419 420 for (Node currentChild = currentNode.getFirstChild(); currentChild != null; currentChild = currentChild 422 .getNextSibling()) { 423 this.canonicalizeXPathNodeSet(currentChild); 424 } 425 426 if (this._xpathNodeSet.contains(currentNode)) { 427 this._writer.write(HTMLIncludePrefix); 428 } else { 429 this._writer.write(HTMLExcludePrefix); 430 } 431 432 this._writer.write("</"); 433 this._writer.write(currentElement.getTagName()); 434 this._writer.write(">"); 435 436 if (this._xpathNodeSet.contains(currentNode)) { 437 this._writer.write(HTMLIncludeSuffix); 438 } else { 439 this._writer.write(HTMLExcludeSuffix); 440 } 441 break; 442 } 443 } 444 445 458 private int getPositionRelativeToDocumentElement(Node currentNode) { 459 460 if (currentNode == null) { 461 return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; 462 } 463 464 Document doc = currentNode.getOwnerDocument(); 465 466 if (currentNode.getParentNode() != doc) { 467 return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; 468 } 469 470 Element documentElement = doc.getDocumentElement(); 471 472 if (documentElement == null) { 473 return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; 474 } 475 476 if (documentElement == currentNode) { 477 return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; 478 } 479 480 for (Node x = currentNode; x != null; x = x.getNextSibling()) { 481 if (x == documentElement) { 482 return NODE_BEFORE_DOCUMENT_ELEMENT; 483 } 484 } 485 486 return NODE_AFTER_DOCUMENT_ELEMENT; 487 } 488 489 507 private void outputAttrToWriter(String name, String value) 508 throws IOException { 509 510 this._writer.write(" "); 511 this._writer.write(name); 512 this._writer.write("=\""); 513 514 int length = value.length(); 515 516 for (int i = 0; i < length; i++) { 517 char c = value.charAt(i); 518 519 switch (c) { 520 521 case '&': 522 this._writer.write("&amp;"); 523 break; 524 525 case '<': 526 this._writer.write("&lt;"); 527 break; 528 529 case '"': 530 this._writer.write("&quot;"); 531 break; 532 533 case 0x09: this._writer.write("&#x9;"); 535 break; 536 537 case 0x0A: this._writer.write("&#xA;"); 539 break; 540 541 case 0x0D: this._writer.write("&#xD;"); 543 break; 544 545 default: 546 this._writer.write(c); 547 break; 548 } 549 } 550 551 this._writer.write("\""); 552 } 553 554 560 private void outputPItoWriter(ProcessingInstruction currentPI) 561 throws IOException { 562 563 if (currentPI == null) { 564 return; 565 } 566 567 this._writer.write("<?"); 568 569 String target = currentPI.getTarget(); 570 int length = target.length(); 571 572 for (int i = 0; i < length; i++) { 573 char c = target.charAt(i); 574 575 switch (c) { 576 577 case 0x0D: 578 this._writer.write("&#xD;"); 579 break; 580 581 case ' ': 582 this._writer.write("·"); 583 break; 584 585 case '\n': 586 this._writer.write("¶\n"); 587 break; 588 589 default: 590 this._writer.write(c); 591 break; 592 } 593 } 594 595 String data = currentPI.getData(); 596 597 length = data.length(); 598 599 if ((data != null) && (length > 0)) { 600 this._writer.write(" "); 601 602 for (int i = 0; i < length; i++) { 603 char c = data.charAt(i); 604 605 switch (c) { 606 607 case 0x0D: 608 this._writer.write("&#xD;"); 609 break; 610 611 default: 612 this._writer.write(c); 613 break; 614 } 615 } 616 } 617 618 this._writer.write("?>"); 619 } 620 621 627 private void outputCommentToWriter(Comment currentComment) 628 throws IOException { 629 630 if (currentComment == null) { 631 return; 632 } 633 634 this._writer.write("<!--"); 635 636 String data = currentComment.getData(); 637 int length = data.length(); 638 639 for (int i = 0; i < length; i++) { 640 char c = data.charAt(i); 641 642 switch (c) { 643 644 case 0x0D: 645 this._writer.write("&#xD;"); 646 break; 647 648 case ' ': 649 this._writer.write("·"); 650 break; 651 652 case '\n': 653 this._writer.write("¶\n"); 654 break; 655 656 default: 657 this._writer.write(c); 658 break; 659 } 660 } 661 662 this._writer.write("-->"); 663 } 664 665 671 private void outputTextToWriter(String text) throws IOException { 672 673 if (text == null) { 674 return; 675 } 676 677 int length = text.length(); 678 679 for (int i = 0; i < length; i++) { 680 char c = text.charAt(i); 681 682 switch (c) { 683 684 case '&': 685 this._writer.write("&amp;"); 686 break; 687 688 case '<': 689 this._writer.write("&lt;"); 690 break; 691 692 case '>': 693 this._writer.write("&gt;"); 694 break; 695 696 case 0xD: 697 this._writer.write("&#xD;"); 698 break; 699 700 case ' ': 701 this._writer.write("·"); 702 break; 703 704 case '\n': 705 this._writer.write("¶\n"); 706 break; 707 708 default: 709 this._writer.write(c); 710 break; 711 } 712 } 713 } 714 } | Popular Tags |