Class HeaderList

All Implemented Interfaces:
MessageHeaders, Serializable, Cloneable, Iterable<Header>, Collection<Header>, List<Header>, RandomAccess

public class HeaderList extends ArrayList<Header> implements MessageHeaders
A list of Headers on a Message.

This list can be modified to add headers from outside a Message, this is necessary since intermediate processing layers often need to put additional headers.

Following the SOAP convention, the order among headers are not significant. However, Codecs are expected to preserve the order of headers in the input message as much as possible.

MustUnderstand Processing

To perform SOAP mustUnderstang processing correctly, we need to keep track of headers that are understood and headers that are not. This is a collaborative process among Pipes, thus it's something a Pipe author needs to keep in mind.

Specifically, when a Pipe sees a header and processes it (that is, if it did enough computing with the header to claim that the header is understood), then it should mark the corresponding header as "understood". For example, when a pipe that handles JAX-WSA examins the <wsa:To> header, it can claim that it understood the header. But for example, if a pipe that does the signature verification checks <wsa:To> for a signature, that would not be considered as "understood".

There are two ways to mark a header as understood:

  1. Use one of the getXXX methods that take a boolean markAsUnderstood parameter. Most often, a Pipe knows it's going to understand a header as long as it's present, so this is the easiest and thus the preferred way. For example, if JAX-WSA looks for <wsa:To>, then it can set markAsUnderstand to true, to do the obtaining of a header and marking at the same time.
  2. Call understood(int). If under a rare circumstance, a pipe cannot determine whether it can understand it or not when you are fetching a header, then you can use this method afterward to mark it as understood.

Intuitively speaking, at the end of the day, if a header is not understood but Header.isIgnorable(SOAPVersion, java.util.Set) is false, a bad thing will happen. The actual implementation of the checking is more complicated, for that see ClientMUTube/ServerMUTube.

See Also:
  • Constructor Details

    • HeaderList

      public HeaderList(SOAPVersion soapVersion)
      Creates an empty HeaderList with the given soap version
    • HeaderList

      public HeaderList(HeaderList that)
      Copy constructor.
    • HeaderList

      public HeaderList(MessageHeaders that)
  • Method Details

    • size

      public int size()
      The total number of headers.
      Specified by:
      size in interface Collection<Header>
      Specified by:
      size in interface List<Header>
      Overrides:
      size in class ArrayList<Header>
    • hasHeaders

      public boolean hasHeaders()
      Specified by:
      hasHeaders in interface MessageHeaders
    • addAll

      @Deprecated public void addAll(Header... headers)
      Deprecated.
      throws UnsupportedOperationException from some HeaderList implementations - better iterate over items one by one
      Adds all the headers.
    • get

      public Header get(int index)
      Gets the Header at the specified index.

      This method does not mark the returned Header as understood.

      Specified by:
      get in interface List<Header>
      Overrides:
      get in class ArrayList<Header>
      See Also:
    • understood

      public void understood(int index)
      Marks the Header at the specified index as "understood".
    • isUnderstood

      public boolean isUnderstood(int index)
      Returns true if a Header at the given index was "understood".
    • understood

      @Deprecated public void understood(@NotNull Header header)
      Deprecated.
      By the definition of ArrayList, this operation requires O(n) search of the array, and thus inherently inefficient. Because of this, if you are developing a Pipe for a performance sensitive environment, do not use this method.
      Marks the specified Header as "understood".
      Specified by:
      understood in interface MessageHeaders
      Throws:
      IllegalArgumentException - if the given header is not contained in this header.
    • get

      @Nullable public Header get(@NotNull String nsUri, @NotNull String localName, boolean markAsUnderstood)
      Gets the first Header of the specified name.
      Specified by:
      get in interface MessageHeaders
      Parameters:
      markAsUnderstood - If this parameter is true, the returned header will be marked as "understood".
      Returns:
      null if not found.
    • get

      @Nullable public Header get(@NotNull QName name, boolean markAsUnderstood)
      Gets the first Header of the specified name.
      Specified by:
      get in interface MessageHeaders
      Parameters:
      markAsUnderstood - If this parameter is true, the returned header will be marked as "understood".
      Returns:
      null if not found.
    • getHeaders

      @NotNull public Iterator<Header> getHeaders(@NotNull String nsUri, @NotNull String localName, boolean markAsUnderstood)
      Gets all the Headers of the specified name, including duplicates (if any.)
      Specified by:
      getHeaders in interface MessageHeaders
      Parameters:
      markAsUnderstood - If this parameter is true, the returned headers will be marked as "understood" when they are returned from Iterator.next().
      Returns:
      empty iterator if not found.
    • getHeaders

      @NotNull public Iterator<Header> getHeaders(@NotNull QName headerName, boolean markAsUnderstood)
      Specified by:
      getHeaders in interface MessageHeaders
      See Also:
    • getHeaders

      @NotNull public Iterator<Header> getHeaders(@NotNull String nsUri, boolean markAsUnderstood)
      Gets an iteration of headers Header in the specified namespace, including duplicates (if any.)
      Specified by:
      getHeaders in interface MessageHeaders
      Parameters:
      markAsUnderstood - If this parameter is true, the returned headers will be marked as "understood" when they are returned from Iterator.next().
      Returns:
      empty iterator if not found.
    • getTo

      public String getTo(AddressingVersion av, SOAPVersion sv)
      Returns the value of WS-Addressing To header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate To headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing To header, anonymous URI if no header is present
      Throws:
      IllegalArgumentException - if either av or sv is null.
    • getAction

      public String getAction(@NotNull AddressingVersion av, @NotNull SOAPVersion sv)
      Returns the value of WS-Addressing Action header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate Action headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing Action header, null if no header is present
      Throws:
      IllegalArgumentException - if either av or sv is null.
    • getReplyTo

      public WSEndpointReference getReplyTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv)
      Returns the value of WS-Addressing ReplyTo header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate ReplyTo headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing ReplyTo header, null if no header is present
      Throws:
      IllegalArgumentException - if either av or sv is null.
    • getFaultTo

      public WSEndpointReference getFaultTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv)
      Returns the value of WS-Addressing FaultTo header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate FaultTo headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing FaultTo header, null if no header is present
      Throws:
      IllegalArgumentException - if either av or sv is null.
    • getMessageID

      public String getMessageID(@NotNull AddressingVersion av, @NotNull SOAPVersion sv)
      Returns the value of WS-Addressing MessageID header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate MessageID headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing MessageID header, null if no header is present
      Throws:
      jakarta.xml.ws.WebServiceException - if either av or sv is null.
    • getRelatesTo

      public String getRelatesTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv)
      Returns the value of WS-Addressing RelatesTo header. The version identifies the WS-Addressing version and the header returned is targeted at the current implicit role. Caches the value for subsequent invocation. Duplicate RelatesTo headers are detected earlier.
      Parameters:
      av - WS-Addressing version
      sv - SOAP version
      Returns:
      Value of WS-Addressing RelatesTo header, null if no header is present
      Throws:
      jakarta.xml.ws.WebServiceException - if either av or sv is null.
    • fillRequestAddressingHeaders

      public void fillRequestAddressingHeaders(Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action, boolean mustUnderstand)
      Creates a set of outbound WS-Addressing headers on the client with the specified Action Message Addressing Property value.

      This method needs to be invoked right after such a Message is created which is error prone but so far only MEX, RM and JAX-WS creates a request so this ugliness is acceptable. This method is also used to create protocol messages that are not associated with any WSBinding and WSDLPort.

      Parameters:
      packet - request packet
      av - WS-Addressing version
      sv - SOAP version
      oneway - Indicates if the message exchange pattern is oneway
      action - Action Message Addressing Property value
      mustUnderstand - to indicate if the addressing headers are set with mustUnderstand attribute
    • fillRequestAddressingHeaders

      public void fillRequestAddressingHeaders(Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action)
    • fillRequestAddressingHeaders

      public void fillRequestAddressingHeaders(WSDLPort wsdlPort, @NotNull WSBinding binding, Packet packet)
      Creates a set of outbound WS-Addressing headers on the client with the default Action Message Addressing Property value.

      This method needs to be invoked right after such a Message is created which is error prone but so far only MEX, RM and JAX-WS creates a request so this ugliness is acceptable. If more components are identified using this, then we may revisit this.

      This method is used if default Action Message Addressing Property is to be used. See fillRequestAddressingHeaders(Packet, com.sun.xml.ws.api.addressing.AddressingVersion, com.sun.xml.ws.api.SOAPVersion, boolean, String) if non-default Action is to be used, for example when creating a protocol message not associated with WSBinding and WSDLPort. This method uses SOAPAction as the Action unless set expplicitly in the wsdl.

      Parameters:
      wsdlPort - request WSDL port
      binding - request WSBinding
      packet - request packet
    • add

      public boolean add(Header header)
      Adds a new Header.

      Order doesn't matter in headers, so this method does not make any guarantee as to where the new header is inserted.

      Specified by:
      add in interface Collection<Header>
      Specified by:
      add in interface List<Header>
      Specified by:
      add in interface MessageHeaders
      Overrides:
      add in class ArrayList<Header>
      Returns:
      always true. Don't use the return value.
    • remove

      @Nullable public Header remove(@NotNull String nsUri, @NotNull String localName)
      Removes the first Header of the specified name.
      Specified by:
      remove in interface MessageHeaders
      Parameters:
      nsUri - namespace URI of the header to remove
      localName - local part of the FQN of the header to remove
      Returns:
      null if not found.
    • addOrReplace

      public boolean addOrReplace(Header header)
      Replaces an existing Header or adds a new Header.

      Order doesn't matter in headers, so this method does not make any guarantee as to where the new header is inserted.

      Specified by:
      addOrReplace in interface MessageHeaders
      Returns:
      always true. Don't use the return value.
    • replace

      public void replace(Header old, Header header)
      Specified by:
      replace in interface MessageHeaders
    • addInternal

      protected void addInternal(int index, Header header)
    • removeInternal

      protected Header removeInternal(int index)
    • remove

      @Nullable public Header remove(@NotNull QName name)
      Removes the first Header of the specified name.
      Specified by:
      remove in interface MessageHeaders
      Parameters:
      name - fully qualified name of the header to remove
      Returns:
      null if not found.
    • remove

      public Header remove(int index)
      Removes the first Header of the specified name.
      Specified by:
      remove in interface List<Header>
      Overrides:
      remove in class ArrayList<Header>
      Parameters:
      index - index of the header to remove
      Returns:
      removed header
    • remove

      public boolean remove(Object o)
      Removes a single instance of the specified element from this header list, if it is present. More formally, removes a header h such that (o==null ? h==null : o.equals(h)), if the header list contains one or more such headers. Returns true if the list contained the specified element (or equivalently, if the list changed as a result of the call).
      Specified by:
      remove in interface Collection<Header>
      Specified by:
      remove in interface List<Header>
      Overrides:
      remove in class ArrayList<Header>
      Parameters:
      o - element to be removed from this list, if present.
      Returns:
      true if the list contained the specified element.
      See Also:
    • remove

      public Header remove(Header h)
    • copy

      public static HeaderList copy(MessageHeaders original)
      Creates a copy. This handles null HeaderList correctly.
      Parameters:
      original - Can be null, in which case null will be returned.
    • copy

      public static HeaderList copy(HeaderList original)
      Creates a copy. This handles null HeaderList correctly.
      Parameters:
      original - Can be null, in which case null will be returned.
    • readResponseAddressingHeaders

      public void readResponseAddressingHeaders(WSDLPort wsdlPort, WSBinding binding)
    • understood

      public void understood(QName name)
      Specified by:
      understood in interface MessageHeaders
    • understood

      public void understood(String nsUri, String localName)
      Specified by:
      understood in interface MessageHeaders
    • getUnderstoodHeaders

      public Set<QName> getUnderstoodHeaders()
      Description copied from interface: MessageHeaders
      Return a Set of QNames of headers that have been explicitly marked as understood. If none have been marked, this method could return null
      Specified by:
      getUnderstoodHeaders in interface MessageHeaders
    • isUnderstood

      public boolean isUnderstood(Header header)
      Description copied from interface: MessageHeaders
      True if the header has been explicitly marked understood, false otherwise
      Specified by:
      isUnderstood in interface MessageHeaders
    • isUnderstood

      public boolean isUnderstood(String nsUri, String localName)
      Description copied from interface: MessageHeaders
      True if the header has been explicitly marked understood, false otherwise
      Specified by:
      isUnderstood in interface MessageHeaders
    • isUnderstood

      public boolean isUnderstood(QName name)
      Description copied from interface: MessageHeaders
      True if the header has been explicitly marked understood, false otherwise
      Specified by:
      isUnderstood in interface MessageHeaders
    • getNotUnderstoodHeaders

      public Set<QName> getNotUnderstoodHeaders(Set<String> roles, Set<QName> knownHeaders, WSBinding binding)
      Description copied from interface: MessageHeaders
      Returns a Set of QNames of headers that satisfy ALL the following conditions: (a) Have mustUnderstand = true (b) have NOT been explicitly marked as understood (c) If roles argument is non-null, the header has isIgnorable = false for the roles argument and SOAP version (d) If non-null binding is passed in, are NOT understood by the binding (e) If (d) is met, the header is NOT in the knownHeaders list passed in
      Specified by:
      getNotUnderstoodHeaders in interface MessageHeaders
    • setSoapVersion

      public void setSoapVersion(SOAPVersion soapVersion)
    • getHeaders

      public Iterator<Header> getHeaders()
      Specified by:
      getHeaders in interface MessageHeaders
    • asList

      public List<Header> asList()
      Description copied from interface: MessageHeaders
      Returns Header instances in a List.
      Specified by:
      asList in interface MessageHeaders
      Returns:
      List containing Header instances