70 * <h3>MustUnderstand Processing</h3> 71 * <p> 72 * To perform SOAP mustUnderstang processing correctly, we need to keep 73 * track of headers that are understood and headers that are not. 74 * This is a collaborative process among {@link Pipe}s, thus it's something 75 * a {@link Pipe} author needs to keep in mind. 76 * 77 * <p> 78 * Specifically, when a {@link Pipe} sees a header and processes it 79 * (that is, if it did enough computing with the header to claim that 80 * the header is understood), then it should mark the corresponding 81 * header as "understood". For example, when a pipe that handles JAX-WSA 82 * examins the <wsa:To> header, it can claim that it understood the header. 83 * But for example, if a pipe that does the signature verification checks 84 * <wsa:To> for a signature, that would not be considered as "understood". 85 * 86 * <p> 87 * There are two ways to mark a header as understood: 88 * 89 * <ol> 90 * <li>Use one of the <tt>getXXX</tt> methods that take a 91 * boolean <tt>markAsUnderstood</tt> parameter. 92 * Most often, a {@link Pipe} knows it's going to understand a header 93 * as long as it's present, so this is the easiest and thus the preferred way. 94 * 95 * For example, if JAX-WSA looks for <wsa:To>, then it can set 96 * <tt>markAsUnderstand</tt> to true, to do the obtaining of a header 97 * and marking at the same time. 98 * 99 * <li>Call {@link #understood(int)}. 100 * If under a rare circumstance, a pipe cannot determine whether 101 * it can understand it or not when you are fetching a header, then 102 * you can use this method afterward to mark it as understood. 103 * </ol> 104 * 105 * <p> 106 * Intuitively speaking, at the end of the day, if a header is not 107 * understood but {@link Header#isIgnorable(SOAPVersion, java.util.Set)} is false, a bad thing 108 * will happen. The actual implementation of the checking is more complicated, 109 * for that see {@link ClientMUTube}/{@link ServerMUTube}. 110 * 111 * @see Message#getHeaders() 112 */ 113 public class HeaderList extends ArrayList<Header> implements MessageHeaders { 114 115 private static final long serialVersionUID = -6358045781349627237L; 116 /** 472 } 473 474 private void fetch() { 475 while (idx < size()) { 476 Header h = get(idx++); 477 if (h.getNamespaceURI().equals(nsUri)) { 478 next = h; 479 break; 480 } 481 } 482 } 483 484 @Override 485 public void remove() { 486 throw new UnsupportedOperationException(); 487 } 488 }; 489 } 490 491 /** 492 * Returns the value of WS-Addressing <code>To</code> header. The <code>version</code> 493 * identifies the WS-Addressing version and the header returned is targeted at 494 * the current implicit role. Caches the value for subsequent invocation. 495 * Duplicate <code>To</code> headers are detected earlier. 496 * 497 * @param av WS-Addressing version 498 * @param sv SOAP version 499 * @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null. 500 * @return Value of WS-Addressing To header, anonymous URI if no header is present 501 */ 502 public String getTo(AddressingVersion av, SOAPVersion sv) { 503 return AddressingUtils.getTo(this, av, sv); 504 } 505 506 /** 507 * Returns the value of WS-Addressing <code>Action</code> header. The <code>version</code> 508 * identifies the WS-Addressing version and the header returned is targeted at 509 * the current implicit role. Caches the value for subsequent invocation. 510 * Duplicate <code>Action</code> headers are detected earlier. 511 * 512 * @param av WS-Addressing version 513 * @param sv SOAP version 514 * @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null. 515 * @return Value of WS-Addressing Action header, null if no header is present 516 */ 517 public String getAction(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 518 return AddressingUtils.getAction(this, av, sv); 519 } 520 521 /** 522 * Returns the value of WS-Addressing <code>ReplyTo</code> header. The <code>version</code> 523 * identifies the WS-Addressing version and the header returned is targeted at 524 * the current implicit role. Caches the value for subsequent invocation. 525 * Duplicate <code>ReplyTo</code> headers are detected earlier. 526 * 527 * @param av WS-Addressing version 528 * @param sv SOAP version 529 * @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null. 530 * @return Value of WS-Addressing ReplyTo header, null if no header is present 531 */ 532 public WSEndpointReference getReplyTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 533 return AddressingUtils.getReplyTo(this, av, sv); 534 } 535 536 /** 537 * Returns the value of WS-Addressing <code>FaultTo</code> header. The <code>version</code> 538 * identifies the WS-Addressing version and the header returned is targeted at 539 * the current implicit role. Caches the value for subsequent invocation. 540 * Duplicate <code>FaultTo</code> headers are detected earlier. 541 * 542 * @param av WS-Addressing version 543 * @param sv SOAP version 544 * @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null. 545 * @return Value of WS-Addressing FaultTo header, null if no header is present 546 */ 547 public WSEndpointReference getFaultTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 548 return AddressingUtils.getFaultTo(this, av, sv); 549 } 550 551 /** 552 * Returns the value of WS-Addressing <code>MessageID</code> header. The <code>version</code> 553 * identifies the WS-Addressing version and the header returned is targeted at 554 * the current implicit role. Caches the value for subsequent invocation. 555 * Duplicate <code>MessageID</code> headers are detected earlier. 556 * 557 * @param av WS-Addressing version 558 * @param sv SOAP version 559 * @throws WebServiceException if either <code>av</code> or <code>sv</code> is null. 560 * @return Value of WS-Addressing MessageID header, null if no header is present 561 */ 562 public String getMessageID(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 563 return AddressingUtils.getMessageID(this, av, sv); 564 } 565 566 /** 567 * Returns the value of WS-Addressing <code>RelatesTo</code> header. The <code>version</code> 568 * identifies the WS-Addressing version and the header returned is targeted at 569 * the current implicit role. Caches the value for subsequent invocation. 570 * Duplicate <code>RelatesTo</code> headers are detected earlier. 571 * 572 * @param av WS-Addressing version 573 * @param sv SOAP version 574 * @throws WebServiceException if either <code>av</code> or <code>sv</code> is null. 575 * @return Value of WS-Addressing RelatesTo header, null if no header is present 576 */ 577 public String getRelatesTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 578 return AddressingUtils.getRelatesTo(this, av, sv); 579 } 580 581 /** 582 * Creates a set of outbound WS-Addressing headers on the client with the 583 * specified Action Message Addressing Property value. 584 * <p><p> 585 * This method needs to be invoked right after such a Message is 586 * created which is error prone but so far only MEX, RM and JAX-WS 587 * creates a request so this ugliness is acceptable. This method is also used 588 * to create protocol messages that are not associated with any {@link WSBinding} 589 * and {@link WSDLPort}. 590 * 591 * @param packet request packet 592 * @param av WS-Addressing version 593 * @param sv SOAP version 594 * @param oneway Indicates if the message exchange pattern is oneway 786 } 787 } 788 } else if (moreUnderstoodBits != null && moreUnderstoodBits.cardinality() > 0) { 789 index -= 32; 790 moreUnderstoodBits.clear(index); 791 for (int i = moreUnderstoodBits.nextSetBit(index); i >= 1; i = moreUnderstoodBits.nextSetBit(i + 1)) { 792 moreUnderstoodBits.set(i - 1); 793 moreUnderstoodBits.clear(i); 794 } 795 } 796 797 // remove bit set if the new size will be < 33 => we fit all bits into int 798 if (size() - 1 <= 33 && moreUnderstoodBits != null) { 799 moreUnderstoodBits = null; 800 } 801 } 802 803 /** 804 * Removes a single instance of the specified element from this 805 * header list, if it is present. More formally, 806 * removes a header <tt>h</tt> such that <tt>(o==null ? h==null : 807 * o.equals(h))</tt>, if the header list contains one or more such 808 * headers. Returns <tt>true</tt> if the list contained the 809 * specified element (or equivalently, if the list changed as a 810 * result of the call).<p> 811 * 812 * @param o element to be removed from this list, if present. 813 * @return <tt>true</tt> if the list contained the specified element. 814 * @see #remove(javax.xml.namespace.QName) 815 */ 816 @Override 817 public boolean remove(Object o) { 818 if (o != null) { 819 for (int index = 0; index < this.size(); index++) { 820 if (o.equals(this.get(index))) { 821 remove(index); 822 return true; 823 } 824 } 825 } 826 827 return false; 828 } 829 830 public Header remove(Header h) { 831 if (remove((Object) h)) { 832 return h; 833 } else { | 70 * <h3>MustUnderstand Processing</h3> 71 * <p> 72 * To perform SOAP mustUnderstang processing correctly, we need to keep 73 * track of headers that are understood and headers that are not. 74 * This is a collaborative process among {@link Pipe}s, thus it's something 75 * a {@link Pipe} author needs to keep in mind. 76 * 77 * <p> 78 * Specifically, when a {@link Pipe} sees a header and processes it 79 * (that is, if it did enough computing with the header to claim that 80 * the header is understood), then it should mark the corresponding 81 * header as "understood". For example, when a pipe that handles JAX-WSA 82 * examins the <wsa:To> header, it can claim that it understood the header. 83 * But for example, if a pipe that does the signature verification checks 84 * <wsa:To> for a signature, that would not be considered as "understood". 85 * 86 * <p> 87 * There are two ways to mark a header as understood: 88 * 89 * <ol> 90 * <li>Use one of the {@code getXXX} methods that take a 91 * boolean {@code markAsUnderstood} parameter. 92 * Most often, a {@link Pipe} knows it's going to understand a header 93 * as long as it's present, so this is the easiest and thus the preferred way. 94 * 95 * For example, if JAX-WSA looks for <wsa:To>, then it can set 96 * {@code markAsUnderstand} to true, to do the obtaining of a header 97 * and marking at the same time. 98 * 99 * <li>Call {@link #understood(int)}. 100 * If under a rare circumstance, a pipe cannot determine whether 101 * it can understand it or not when you are fetching a header, then 102 * you can use this method afterward to mark it as understood. 103 * </ol> 104 * 105 * <p> 106 * Intuitively speaking, at the end of the day, if a header is not 107 * understood but {@link Header#isIgnorable(SOAPVersion, java.util.Set)} is false, a bad thing 108 * will happen. The actual implementation of the checking is more complicated, 109 * for that see {@link ClientMUTube}/{@link ServerMUTube}. 110 * 111 * @see Message#getHeaders() 112 */ 113 public class HeaderList extends ArrayList<Header> implements MessageHeaders { 114 115 private static final long serialVersionUID = -6358045781349627237L; 116 /** 472 } 473 474 private void fetch() { 475 while (idx < size()) { 476 Header h = get(idx++); 477 if (h.getNamespaceURI().equals(nsUri)) { 478 next = h; 479 break; 480 } 481 } 482 } 483 484 @Override 485 public void remove() { 486 throw new UnsupportedOperationException(); 487 } 488 }; 489 } 490 491 /** 492 * Returns the value of WS-Addressing {@code To} header. The {@code version} 493 * identifies the WS-Addressing version and the header returned is targeted at 494 * the current implicit role. Caches the value for subsequent invocation. 495 * Duplicate {@code To} headers are detected earlier. 496 * 497 * @param av WS-Addressing version 498 * @param sv SOAP version 499 * @throws IllegalArgumentException if either {@code av} or {@code sv} is null. 500 * @return Value of WS-Addressing To header, anonymous URI if no header is present 501 */ 502 public String getTo(AddressingVersion av, SOAPVersion sv) { 503 return AddressingUtils.getTo(this, av, sv); 504 } 505 506 /** 507 * Returns the value of WS-Addressing {@code Action} header. The {@code version} 508 * identifies the WS-Addressing version and the header returned is targeted at 509 * the current implicit role. Caches the value for subsequent invocation. 510 * Duplicate {@code Action} headers are detected earlier. 511 * 512 * @param av WS-Addressing version 513 * @param sv SOAP version 514 * @throws IllegalArgumentException if either {@code av} or {@code sv} is null. 515 * @return Value of WS-Addressing Action header, null if no header is present 516 */ 517 public String getAction(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 518 return AddressingUtils.getAction(this, av, sv); 519 } 520 521 /** 522 * Returns the value of WS-Addressing {@code ReplyTo} header. The {@code version} 523 * identifies the WS-Addressing version and the header returned is targeted at 524 * the current implicit role. Caches the value for subsequent invocation. 525 * Duplicate {@code ReplyTo} headers are detected earlier. 526 * 527 * @param av WS-Addressing version 528 * @param sv SOAP version 529 * @throws IllegalArgumentException if either {@code av} or {@code sv} is null. 530 * @return Value of WS-Addressing ReplyTo header, null if no header is present 531 */ 532 public WSEndpointReference getReplyTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 533 return AddressingUtils.getReplyTo(this, av, sv); 534 } 535 536 /** 537 * Returns the value of WS-Addressing {@code FaultTo} header. The {@code version} 538 * identifies the WS-Addressing version and the header returned is targeted at 539 * the current implicit role. Caches the value for subsequent invocation. 540 * Duplicate {@code FaultTo} headers are detected earlier. 541 * 542 * @param av WS-Addressing version 543 * @param sv SOAP version 544 * @throws IllegalArgumentException if either {@code av} or {@code sv} is null. 545 * @return Value of WS-Addressing FaultTo header, null if no header is present 546 */ 547 public WSEndpointReference getFaultTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 548 return AddressingUtils.getFaultTo(this, av, sv); 549 } 550 551 /** 552 * Returns the value of WS-Addressing {@code MessageID} header. The {@code version} 553 * identifies the WS-Addressing version and the header returned is targeted at 554 * the current implicit role. Caches the value for subsequent invocation. 555 * Duplicate {@code MessageID} headers are detected earlier. 556 * 557 * @param av WS-Addressing version 558 * @param sv SOAP version 559 * @throws WebServiceException if either {@code av} or {@code sv} is null. 560 * @return Value of WS-Addressing MessageID header, null if no header is present 561 */ 562 public String getMessageID(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 563 return AddressingUtils.getMessageID(this, av, sv); 564 } 565 566 /** 567 * Returns the value of WS-Addressing {@code RelatesTo} header. The {@code version} 568 * identifies the WS-Addressing version and the header returned is targeted at 569 * the current implicit role. Caches the value for subsequent invocation. 570 * Duplicate {@code RelatesTo} headers are detected earlier. 571 * 572 * @param av WS-Addressing version 573 * @param sv SOAP version 574 * @throws WebServiceException if either {@code av} or {@code sv} is null. 575 * @return Value of WS-Addressing RelatesTo header, null if no header is present 576 */ 577 public String getRelatesTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) { 578 return AddressingUtils.getRelatesTo(this, av, sv); 579 } 580 581 /** 582 * Creates a set of outbound WS-Addressing headers on the client with the 583 * specified Action Message Addressing Property value. 584 * <p><p> 585 * This method needs to be invoked right after such a Message is 586 * created which is error prone but so far only MEX, RM and JAX-WS 587 * creates a request so this ugliness is acceptable. This method is also used 588 * to create protocol messages that are not associated with any {@link WSBinding} 589 * and {@link WSDLPort}. 590 * 591 * @param packet request packet 592 * @param av WS-Addressing version 593 * @param sv SOAP version 594 * @param oneway Indicates if the message exchange pattern is oneway 786 } 787 } 788 } else if (moreUnderstoodBits != null && moreUnderstoodBits.cardinality() > 0) { 789 index -= 32; 790 moreUnderstoodBits.clear(index); 791 for (int i = moreUnderstoodBits.nextSetBit(index); i >= 1; i = moreUnderstoodBits.nextSetBit(i + 1)) { 792 moreUnderstoodBits.set(i - 1); 793 moreUnderstoodBits.clear(i); 794 } 795 } 796 797 // remove bit set if the new size will be < 33 => we fit all bits into int 798 if (size() - 1 <= 33 && moreUnderstoodBits != null) { 799 moreUnderstoodBits = null; 800 } 801 } 802 803 /** 804 * Removes a single instance of the specified element from this 805 * header list, if it is present. More formally, 806 * removes a header {@code h} such that 807 * {@code (o==null ? h==null : o.equals(h))}, 808 * if the header list contains one or more such 809 * headers. Returns {@code true} if the list contained the 810 * specified element (or equivalently, if the list changed as a 811 * result of the call).<p> 812 * 813 * @param o element to be removed from this list, if present. 814 * @return {@code true} if the list contained the specified element. 815 * @see #remove(javax.xml.namespace.QName) 816 */ 817 @Override 818 public boolean remove(Object o) { 819 if (o != null) { 820 for (int index = 0; index < this.size(); index++) { 821 if (o.equals(this.get(index))) { 822 remove(index); 823 return true; 824 } 825 } 826 } 827 828 return false; 829 } 830 831 public Header remove(Header h) { 832 if (remove((Object) h)) { 833 return h; 834 } else { |