src/share/jaxws_classes/com/sun/xml/internal/ws/api/addressing/OutboundReferenceParameterHeader.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  63  *
  64  * @author Kohsuke Kawaguchi
  65  */
  66 final class OutboundReferenceParameterHeader extends AbstractHeaderImpl {
  67     private final XMLStreamBuffer infoset;
  68     private final String nsUri,localName;
  69 
  70     /**
  71      * The attributes on the header element.
  72      * Lazily parsed.
  73      * Null if not parsed yet.
  74      */
  75     private FinalArrayList<Attribute> attributes;
  76 
  77     OutboundReferenceParameterHeader(XMLStreamBuffer infoset, String nsUri, String localName) {
  78         this.infoset = infoset;
  79         this.nsUri = nsUri;
  80         this.localName = localName;
  81     }
  82 

  83     public @NotNull String getNamespaceURI() {
  84         return nsUri;
  85     }
  86 

  87     public @NotNull String getLocalPart() {
  88         return localName;
  89     }
  90 

  91     public String getAttribute(String nsUri, String localName) {
  92         if(attributes==null)
  93             parseAttributes();

  94         for(int i=attributes.size()-1; i>=0; i-- ) {
  95             Attribute a = attributes.get(i);
  96             if(a.localName.equals(localName) && a.nsUri.equals(nsUri))
  97                 return a.value;
  98         }

  99         return null;
 100     }
 101 
 102     /**
 103      * We don't really expect this to be used, but just to satisfy
 104      * the {@link Header} contract.
 105      *
 106      * So this is rather slow.
 107      */
 108     private void parseAttributes() {
 109         try {
 110             XMLStreamReader reader = readHeader();
 111             reader.nextTag();   // move to the first element, which is the header element
 112 
 113             attributes = new FinalArrayList<Attribute>();
 114             boolean refParamAttrWritten = false;
 115             for (int i = 0; i < reader.getAttributeCount(); i++) {
 116                 final String localName = reader.getAttributeLocalName(i);
 117                 final String namespaceURI = reader.getAttributeNamespace(i);
 118                 final String value = reader.getAttributeValue(i);
 119                 if(namespaceURI.equals(AddressingVersion.W3C.nsUri)&& localName.equals("IS_REFERENCE_PARAMETER"))
 120                     refParamAttrWritten = true;
 121                 attributes.add(new Attribute(namespaceURI,localName,value));

 122             }
 123             // we are adding one more attribute "wsa:IsReferenceParameter", if its not alrady there
 124             if(!refParamAttrWritten)
 125                 attributes.add(new Attribute(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE));

 126         } catch (XMLStreamException e) {
 127             throw new WebServiceException("Unable to read the attributes for {"+nsUri+"}"+localName+" header",e);
 128         }
 129     }
 130 

 131     public XMLStreamReader readHeader() throws XMLStreamException {
 132         return new StreamReaderDelegate(infoset.readAsXMLStreamReader()) {
 133             int state=0; /* 0:expecting root, 1:in root, 2:past root */

 134             public int next() throws XMLStreamException {
 135                 return check(super.next());
 136             }
 137 

 138             public int nextTag() throws XMLStreamException {
 139                 return check(super.nextTag());
 140             }
 141 
 142             private int check(int type) {
 143                 switch(state) {
 144                 case 0:
 145                     if(type==START_ELEMENT)
 146                         state=1;

 147                     break;
 148                 case 1:
 149                     state=2;



 150                 }
 151 
 152                 return type;
 153             }
 154 

 155             public int getAttributeCount() {
 156                 if(state==1)    return super.getAttributeCount()+1;
 157                 else            return super.getAttributeCount();



 158             }
 159 

 160             public String getAttributeLocalName(int index) {
 161                 if(state==1 && index==super.getAttributeCount())
 162                     return IS_REFERENCE_PARAMETER;
 163                 else
 164                     return super.getAttributeLocalName(index);
 165             }

 166 

 167             public String getAttributeNamespace(int index) {
 168                 if(state==1 && index==super.getAttributeCount())
 169                     return AddressingVersion.W3C.nsUri;
 170                 else

 171                     return super.getAttributeNamespace(index);
 172             }

 173 

 174             public String getAttributePrefix(int index) {
 175                 if(state==1 && index==super.getAttributeCount())
 176                     return "wsa";
 177                 else
 178                     return super.getAttributePrefix(index);
 179             }

 180 

 181             public String getAttributeType(int index) {
 182                 if(state==1 && index==super.getAttributeCount())
 183                     return "CDATA";
 184                 else
 185                     return super.getAttributeType(index);
 186             }

 187 

 188             public String getAttributeValue(int index) {
 189                 if(state==1 && index==super.getAttributeCount())
 190                     return TRUE_VALUE;
 191                 else
 192                     return super.getAttributeValue(index);
 193             }

 194 

 195             public QName getAttributeName(int index) {
 196                 if(state==1 && index==super.getAttributeCount())
 197                     return new QName(AddressingVersion.W3C.nsUri, IS_REFERENCE_PARAMETER, "wsa");
 198                 else
 199                     return super.getAttributeName(index);
 200             }

 201 

 202             public String getAttributeValue(String namespaceUri, String localName) {
 203                 if(state==1 && localName.equals(IS_REFERENCE_PARAMETER) && namespaceUri.equals(AddressingVersion.W3C.nsUri))
 204                     return TRUE_VALUE;
 205                 else
 206                     return super.getAttributeValue(namespaceUri, localName);
 207             }

 208         };
 209     }
 210 

 211     public void writeTo(XMLStreamWriter w) throws XMLStreamException {
 212         infoset.writeToXMLStreamWriter(new XMLStreamWriterFilter(w) {
 213             private boolean root=true;
 214             private boolean onRootEl = true;

 215             public void writeStartElement(String localName) throws XMLStreamException {
 216                 super.writeStartElement(localName);
 217                 writeAddedAttribute();
 218             }
 219 
 220             private void writeAddedAttribute() throws XMLStreamException {
 221                 if(!root) {
 222                     onRootEl = false;
 223                     return;
 224                 }
 225                 root=false;
 226                 writeNamespace("wsa",AddressingVersion.W3C.nsUri);
 227                 super.writeAttribute("wsa",AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE);
 228             }
 229 

 230             public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
 231                 super.writeStartElement(namespaceURI, localName);
 232                 writeAddedAttribute();
 233             }
 234 

 235             public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
 236                 //TODO: Verify with KK later
 237                 //check if prefix is declared before writing start element.
 238                 boolean prefixDeclared = isPrefixDeclared(prefix,namespaceURI);
 239                 super.writeStartElement(prefix, localName, namespaceURI);
 240                 if(!prefixDeclared && !prefix.equals(""))
 241                     super.writeNamespace(prefix,namespaceURI);

 242                 writeAddedAttribute();
 243             }

 244             public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException{
 245                 //TODO: Verify with KK later
 246                 if(isPrefixDeclared(prefix, namespaceURI)) {
 247                     //Dont write it again , as its already in NamespaceContext
 248                     return;
 249                 } else
 250                     super.writeNamespace(prefix,namespaceURI);
 251             }

 252 

 253             public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
 254                 //skip if its on root element and attribute is wsa;IsReferenceParameter, as we write it.
 255                 if(onRootEl && namespaceURI.equals(AddressingVersion.W3C.nsUri)
 256                             && localName.equals(IS_REFERENCE_PARAMETER))
 257                     return;
 258 
 259                 writer.writeAttribute(prefix, namespaceURI, localName, value);
 260             }
 261             public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
 262 
 263 


 264                 writer.writeAttribute(namespaceURI, localName, value);
 265             }
 266             private boolean isPrefixDeclared(String prefix, String namespaceURI ) {
 267                 return namespaceURI.equals(getNamespaceContext().getNamespaceURI(prefix));
 268             }
 269         },true);
 270     }
 271 

 272     public void writeTo(SOAPMessage saaj) throws SOAPException {
 273         //TODO: SAAJ returns null instead of throwing SOAPException,
 274         // when there is no SOAPHeader in the message,
 275         // which leads to NPE.
 276         try {
 277             SOAPHeader header = saaj.getSOAPHeader();
 278             if (header == null)
 279                 header = saaj.getSOAPPart().getEnvelope().addHeader();

 280             Element node = (Element)infoset.writeTo(header);
 281             node.setAttributeNS(AddressingVersion.W3C.nsUri,AddressingVersion.W3C.getPrefix()+":"+IS_REFERENCE_PARAMETER,TRUE_VALUE);
 282         } catch (XMLStreamBufferException e) {
 283             throw new SOAPException(e);
 284         }
 285     }
 286 

 287     public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
 288         class Filter extends XMLFilterImpl {
 289             Filter(ContentHandler ch) { setContentHandler(ch); }
 290             private int depth=0;

 291             public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
 292                 if(depth++==0) {
 293                     // add one more attribute
 294                     super.startPrefixMapping("wsa",AddressingVersion.W3C.nsUri);
 295 
 296                     //Add the attirbute wsa:IsReferenceParameter if not present already
 297                     if(atts.getIndex(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER) == -1) {
 298                         AttributesImpl atts2 = new AttributesImpl(atts);
 299                         atts2.addAttribute(
 300                                 AddressingVersion.W3C.nsUri,
 301                                 IS_REFERENCE_PARAMETER,
 302                                 "wsa:IsReferenceParameter",
 303                                 "CDATA",
 304                                 TRUE_VALUE);
 305                         atts = atts2;
 306                     }
 307                 }
 308 
 309                 super.startElement(uri, localName, qName, atts);
 310             }
 311 

 312             public void endElement(String uri, String localName, String qName) throws SAXException {
 313                 super.endElement(uri, localName, qName);
 314                 if(--depth==0)
 315                     super.endPrefixMapping("wsa");
 316             }
 317         }

 318 
 319         infoset.writeTo(new Filter(contentHandler),errorHandler);
 320     }
 321 
 322 
 323     /**
 324      * Keep the information about an attribute on the header element.
 325      */
 326     static final class Attribute {
 327         /**
 328          * Can be empty but never null.
 329          */
 330         final String nsUri;
 331         final String localName;
 332         final String value;
 333 
 334         public Attribute(String nsUri, String localName, String value) {
 335             this.nsUri = fixNull(nsUri);
 336             this.localName = localName;
 337             this.value = value;
 338         }
 339 
 340         /**
 341          * Convert null to "".
 342          */
 343         private static String fixNull(String s) {
 344             if(s==null) return "";
 345             else        return s;
 346         }
 347     }
 348 
 349     /**
 350      * We the performance paranoid people in the JAX-WS RI thinks
 351      * saving three bytes is worth while...
 352      */
 353     private static final String TRUE_VALUE = "1";
 354     private static final String IS_REFERENCE_PARAMETER = "IsReferenceParameter";
 355 }
   1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  63  *
  64  * @author Kohsuke Kawaguchi
  65  */
  66 final class OutboundReferenceParameterHeader extends AbstractHeaderImpl {
  67     private final XMLStreamBuffer infoset;
  68     private final String nsUri,localName;
  69 
  70     /**
  71      * The attributes on the header element.
  72      * Lazily parsed.
  73      * Null if not parsed yet.
  74      */
  75     private FinalArrayList<Attribute> attributes;
  76 
  77     OutboundReferenceParameterHeader(XMLStreamBuffer infoset, String nsUri, String localName) {
  78         this.infoset = infoset;
  79         this.nsUri = nsUri;
  80         this.localName = localName;
  81     }
  82 
  83     @Override
  84     public @NotNull String getNamespaceURI() {
  85         return nsUri;
  86     }
  87 
  88     @Override
  89     public @NotNull String getLocalPart() {
  90         return localName;
  91     }
  92 
  93     @Override
  94     public String getAttribute(String nsUri, String localName) {
  95         if(attributes==null) {
  96             parseAttributes();
  97         }
  98         for(int i=attributes.size()-1; i>=0; i-- ) {
  99             Attribute a = attributes.get(i);
 100             if (a.localName.equals(localName) && a.nsUri.equals(nsUri)) {
 101                 return a.value;
 102             }
 103         }
 104         return null;
 105     }
 106 
 107     /**
 108      * We don't really expect this to be used, but just to satisfy
 109      * the {@link Header} contract.
 110      *
 111      * So this is rather slow.
 112      */
 113     private void parseAttributes() {
 114         try {
 115             XMLStreamReader reader = readHeader();
 116             reader.nextTag();   // move to the first element, which is the header element
 117 
 118             attributes = new FinalArrayList<Attribute>();
 119             boolean refParamAttrWritten = false;
 120             for (int i = 0; i < reader.getAttributeCount(); i++) {
 121                 final String attrLocalName = reader.getAttributeLocalName(i);
 122                 final String namespaceURI = reader.getAttributeNamespace(i);
 123                 final String value = reader.getAttributeValue(i);
 124                 if (namespaceURI.equals(AddressingVersion.W3C.nsUri)&& attrLocalName.equals("IS_REFERENCE_PARAMETER")) {
 125                     refParamAttrWritten = true;
 126                 }
 127                 attributes.add(new Attribute(namespaceURI,attrLocalName,value));
 128             }
 129             // we are adding one more attribute "wsa:IsReferenceParameter", if its not alrady there
 130             if (!refParamAttrWritten) {
 131                 attributes.add(new Attribute(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE));
 132             }
 133         } catch (XMLStreamException e) {
 134             throw new WebServiceException("Unable to read the attributes for {"+nsUri+"}"+localName+" header",e);
 135         }
 136     }
 137 
 138     @Override
 139     public XMLStreamReader readHeader() throws XMLStreamException {
 140         return new StreamReaderDelegate(infoset.readAsXMLStreamReader()) {
 141             int state=0; /* 0:expecting root, 1:in root, 2:past root */
 142             @Override
 143             public int next() throws XMLStreamException {
 144                 return check(super.next());
 145             }
 146 
 147             @Override
 148             public int nextTag() throws XMLStreamException {
 149                 return check(super.nextTag());
 150             }
 151 
 152             private int check(int type) {
 153                 switch (state) {
 154                     case 0:
 155                         if (type == START_ELEMENT) {
 156                             state = 1;
 157                         }
 158                         break;
 159                     case 1:
 160                         state = 2;
 161                         break;
 162                     default:
 163                         break;
 164                 }
 165 
 166                 return type;
 167             }
 168 
 169             @Override
 170             public int getAttributeCount() {
 171                 if (state == 1) {
 172                     return super.getAttributeCount()+1;
 173                 } else {
 174                     return super.getAttributeCount();
 175                 }
 176             }
 177 
 178             @Override
 179             public String getAttributeLocalName(int index) {
 180                 if (state == 1 && index == super.getAttributeCount()) {
 181                     return IS_REFERENCE_PARAMETER;
 182                 } else {
 183                     return super.getAttributeLocalName(index);
 184                 }
 185             }
 186 
 187             @Override
 188             public String getAttributeNamespace(int index) {
 189                 if (state == 1 && index==super.getAttributeCount()) {
 190                     return AddressingVersion.W3C.nsUri;
 191                 }
 192                 else {
 193                     return super.getAttributeNamespace(index);
 194                 }
 195             }
 196 
 197             @Override
 198             public String getAttributePrefix(int index) {
 199                 if(state==1 && index==super.getAttributeCount()) {
 200                     return "wsa";
 201                 } else {
 202                     return super.getAttributePrefix(index);
 203                 }
 204             }
 205 
 206             @Override
 207             public String getAttributeType(int index) {
 208                 if(state==1 && index==super.getAttributeCount()) {
 209                     return "CDATA";
 210                 } else {
 211                     return super.getAttributeType(index);
 212                 }
 213             }
 214 
 215             @Override
 216             public String getAttributeValue(int index) {
 217                 if(state==1 && index==super.getAttributeCount()) {
 218                     return TRUE_VALUE;
 219                 } else {
 220                     return super.getAttributeValue(index);
 221                 }
 222             }
 223 
 224             @Override
 225             public QName getAttributeName(int index) {
 226                 if(state==1 && index==super.getAttributeCount()) {
 227                     return new QName(AddressingVersion.W3C.nsUri, IS_REFERENCE_PARAMETER, "wsa");
 228                 } else {
 229                     return super.getAttributeName(index);
 230                 }
 231             }
 232 
 233             @Override
 234             public String getAttributeValue(String namespaceUri, String localName) {
 235                 if(state==1 && localName.equals(IS_REFERENCE_PARAMETER) && namespaceUri.equals(AddressingVersion.W3C.nsUri)) {
 236                     return TRUE_VALUE;
 237                 } else {
 238                     return super.getAttributeValue(namespaceUri, localName);
 239                 }
 240             }
 241         };
 242     }
 243 
 244     @Override
 245     public void writeTo(XMLStreamWriter w) throws XMLStreamException {
 246         infoset.writeToXMLStreamWriter(new XMLStreamWriterFilter(w) {
 247             private boolean root=true;
 248             private boolean onRootEl = true;
 249             @Override
 250             public void writeStartElement(String localName) throws XMLStreamException {
 251                 super.writeStartElement(localName);
 252                 writeAddedAttribute();
 253             }
 254 
 255             private void writeAddedAttribute() throws XMLStreamException {
 256                 if(!root) {
 257                     onRootEl = false;
 258                     return;
 259                 }
 260                 root=false;
 261                 writeNamespace("wsa",AddressingVersion.W3C.nsUri);
 262                 super.writeAttribute("wsa",AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE);
 263             }
 264 
 265             @Override
 266             public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
 267                 super.writeStartElement(namespaceURI, localName);
 268                 writeAddedAttribute();
 269             }
 270 
 271             @Override
 272             public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
 273                 //TODO: Verify with KK later
 274                 //check if prefix is declared before writing start element.
 275                 boolean prefixDeclared = isPrefixDeclared(prefix,namespaceURI);
 276                 super.writeStartElement(prefix, localName, namespaceURI);
 277                 if (!prefixDeclared && !prefix.equals("")) {
 278                     super.writeNamespace(prefix,namespaceURI);
 279                 }
 280                 writeAddedAttribute();
 281             }
 282             @Override
 283             public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException{
 284                 if (!isPrefixDeclared(prefix, namespaceURI)) {




 285                     super.writeNamespace(prefix,namespaceURI);
 286                 }
 287             }
 288 
 289             @Override
 290             public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
 291                 //skip if its on root element and attribute is wsa;IsReferenceParameter, as we write it.
 292                 if(onRootEl && namespaceURI.equals(AddressingVersion.W3C.nsUri)
 293                             && localName.equals(IS_REFERENCE_PARAMETER)) {
 294                     return;
 295                 }
 296                 writer.writeAttribute(prefix, namespaceURI, localName, value);
 297             }


 298 
 299             @Override
 300             public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
 301                 writer.writeAttribute(namespaceURI, localName, value);
 302             }
 303             private boolean isPrefixDeclared(String prefix, String namespaceURI ) {
 304                 return namespaceURI.equals(getNamespaceContext().getNamespaceURI(prefix));
 305             }
 306         },true);
 307     }
 308 
 309     @Override
 310     public void writeTo(SOAPMessage saaj) throws SOAPException {
 311         //TODO: SAAJ returns null instead of throwing SOAPException,
 312         // when there is no SOAPHeader in the message,
 313         // which leads to NPE.
 314         try {
 315             SOAPHeader header = saaj.getSOAPHeader();
 316             if (header == null) {
 317                 header = saaj.getSOAPPart().getEnvelope().addHeader();
 318             }
 319             Element node = (Element)infoset.writeTo(header);
 320             node.setAttributeNS(AddressingVersion.W3C.nsUri,AddressingVersion.W3C.getPrefix()+":"+IS_REFERENCE_PARAMETER,TRUE_VALUE);
 321         } catch (XMLStreamBufferException e) {
 322             throw new SOAPException(e);
 323         }
 324     }
 325 
 326     @Override
 327     public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
 328         class Filter extends XMLFilterImpl {
 329             Filter(ContentHandler ch) { setContentHandler(ch); }
 330             private int depth=0;
 331             @Override
 332             public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
 333                 if(depth++==0) {
 334                     // add one more attribute
 335                     super.startPrefixMapping("wsa",AddressingVersion.W3C.nsUri);
 336 
 337                     //Add the attirbute wsa:IsReferenceParameter if not present already
 338                     if(atts.getIndex(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER) == -1) {
 339                         AttributesImpl atts2 = new AttributesImpl(atts);
 340                         atts2.addAttribute(
 341                                 AddressingVersion.W3C.nsUri,
 342                                 IS_REFERENCE_PARAMETER,
 343                                 "wsa:IsReferenceParameter",
 344                                 "CDATA",
 345                                 TRUE_VALUE);
 346                         atts = atts2;
 347                     }
 348                 }
 349 
 350                 super.startElement(uri, localName, qName, atts);
 351             }
 352 
 353             @Override
 354             public void endElement(String uri, String localName, String qName) throws SAXException {
 355                 super.endElement(uri, localName, qName);
 356                 if (--depth == 0) {
 357                     super.endPrefixMapping("wsa");
 358                 }
 359             }
 360         }
 361 
 362         infoset.writeTo(new Filter(contentHandler),errorHandler);
 363     }
 364 
 365 
 366     /**
 367      * Keep the information about an attribute on the header element.
 368      */
 369     static final class Attribute {
 370         /**
 371          * Can be empty but never null.
 372          */
 373         final String nsUri;
 374         final String localName;
 375         final String value;
 376 
 377         public Attribute(String nsUri, String localName, String value) {
 378             this.nsUri = fixNull(nsUri);
 379             this.localName = localName;
 380             this.value = value;
 381         }
 382 
 383         /**
 384          * Convert null to "".
 385          */
 386         private static String fixNull(String s) {
 387             return s == null ? "" : s;

 388         }
 389     }
 390 
 391     /**
 392      * We the performance paranoid people in the JAX-WS RI thinks
 393      * saving three bytes is worth while...
 394      */
 395     private static final String TRUE_VALUE = "1";
 396     private static final String IS_REFERENCE_PARAMETER = "IsReferenceParameter";
 397 }