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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     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
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.api.addressing;
    28 import com.sun.istack.internal.FinalArrayList;
    29 import com.sun.istack.internal.NotNull;
    30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
    31 import com.sun.xml.internal.stream.buffer.XMLStreamBufferException;
    32 import com.sun.xml.internal.ws.api.message.Header;
    33 import com.sun.xml.internal.ws.message.AbstractHeaderImpl;
    34 import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter;
    35 import org.w3c.dom.Element;
    36 import org.xml.sax.Attributes;
    37 import org.xml.sax.ContentHandler;
    38 import org.xml.sax.ErrorHandler;
    39 import org.xml.sax.SAXException;
    40 import org.xml.sax.helpers.AttributesImpl;
    41 import org.xml.sax.helpers.XMLFilterImpl;
    43 import javax.xml.namespace.QName;
    44 import javax.xml.soap.SOAPException;
    45 import javax.xml.soap.SOAPMessage;
    46 import javax.xml.soap.SOAPHeader;
    47 import javax.xml.stream.XMLStreamException;
    48 import javax.xml.stream.XMLStreamReader;
    49 import javax.xml.stream.XMLStreamWriter;
    50 import javax.xml.stream.util.StreamReaderDelegate;
    51 import javax.xml.ws.WebServiceException;
    53 /**
    54  * Used to represent outbound header created from {@link WSEndpointReference}'s
    55  * referenec parameters.
    56  *
    57  * <p>
    58  * This is optimized for outbound use, so it implements some of the methods lazily,
    59  * in a slow way.
    60  *
    61  * <p>
    62  * This header adds "wsa:IsReferenceParameter" and thus only used for the W3C version.
    63  *
    64  * @author Kohsuke Kawaguchi
    65  */
    66 final class OutboundReferenceParameterHeader extends AbstractHeaderImpl {
    67     private final XMLStreamBuffer infoset;
    68     private final String nsUri,localName;
    70     /**
    71      * The attributes on the header element.
    72      * Lazily parsed.
    73      * Null if not parsed yet.
    74      */
    75     private FinalArrayList<Attribute> attributes;
    77     OutboundReferenceParameterHeader(XMLStreamBuffer infoset, String nsUri, String localName) {
    78         this.infoset = infoset;
    79         this.nsUri = nsUri;
    80         this.localName = localName;
    81     }
    83     @Override
    84     public @NotNull String getNamespaceURI() {
    85         return nsUri;
    86     }
    88     @Override
    89     public @NotNull String getLocalPart() {
    90         return localName;
    91     }
    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     }
   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
   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     }
   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             }
   147             @Override
   148             public int nextTag() throws XMLStreamException {
   149                 return check(super.nextTag());
   150             }
   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                 }
   166                 return type;
   167             }
   169             @Override
   170             public int getAttributeCount() {
   171                 if (state == 1) {
   172                     return super.getAttributeCount()+1;
   173                 } else {
   174                     return super.getAttributeCount();
   175                 }
   176             }
   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             }
   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             }
   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             }
   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             }
   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             }
   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             }
   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     }
   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             }
   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             }
   265             @Override
   266             public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
   267                 super.writeStartElement(namespaceURI, localName);
   268                 writeAddedAttribute();
   269             }
   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             }
   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             }
   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     }
   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     }
   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);
   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                 }
   350                 super.startElement(uri, localName, qName, atts);
   351             }
   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         }
   362         infoset.writeTo(new Filter(contentHandler),errorHandler);
   363     }
   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;
   377         public Attribute(String nsUri, String localName, String value) {
   378             this.nsUri = fixNull(nsUri);
   379             this.localName = localName;
   380             this.value = value;
   381         }
   383         /**
   384          * Convert null to "".
   385          */
   386         private static String fixNull(String s) {
   387             return s == null ? "" : s;
   388         }
   389     }
   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 }

mercurial