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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.api.addressing;
ohair@286 27
ohair@286 28 import com.sun.istack.internal.FinalArrayList;
ohair@286 29 import com.sun.istack.internal.NotNull;
ohair@286 30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
ohair@286 31 import com.sun.xml.internal.stream.buffer.XMLStreamBufferException;
ohair@286 32 import com.sun.xml.internal.ws.api.message.Header;
ohair@286 33 import com.sun.xml.internal.ws.message.AbstractHeaderImpl;
ohair@286 34 import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter;
ohair@286 35 import org.w3c.dom.Element;
ohair@286 36 import org.xml.sax.Attributes;
ohair@286 37 import org.xml.sax.ContentHandler;
ohair@286 38 import org.xml.sax.ErrorHandler;
ohair@286 39 import org.xml.sax.SAXException;
ohair@286 40 import org.xml.sax.helpers.AttributesImpl;
ohair@286 41 import org.xml.sax.helpers.XMLFilterImpl;
ohair@286 42
ohair@286 43 import javax.xml.namespace.QName;
ohair@286 44 import javax.xml.soap.SOAPException;
ohair@286 45 import javax.xml.soap.SOAPMessage;
ohair@286 46 import javax.xml.soap.SOAPHeader;
ohair@286 47 import javax.xml.stream.XMLStreamException;
ohair@286 48 import javax.xml.stream.XMLStreamReader;
ohair@286 49 import javax.xml.stream.XMLStreamWriter;
ohair@286 50 import javax.xml.stream.util.StreamReaderDelegate;
ohair@286 51 import javax.xml.ws.WebServiceException;
ohair@286 52
ohair@286 53 /**
ohair@286 54 * Used to represent outbound header created from {@link WSEndpointReference}'s
ohair@286 55 * referenec parameters.
ohair@286 56 *
ohair@286 57 * <p>
ohair@286 58 * This is optimized for outbound use, so it implements some of the methods lazily,
ohair@286 59 * in a slow way.
ohair@286 60 *
ohair@286 61 * <p>
ohair@286 62 * This header adds "wsa:IsReferenceParameter" and thus only used for the W3C version.
ohair@286 63 *
ohair@286 64 * @author Kohsuke Kawaguchi
ohair@286 65 */
ohair@286 66 final class OutboundReferenceParameterHeader extends AbstractHeaderImpl {
ohair@286 67 private final XMLStreamBuffer infoset;
ohair@286 68 private final String nsUri,localName;
ohair@286 69
ohair@286 70 /**
ohair@286 71 * The attributes on the header element.
ohair@286 72 * Lazily parsed.
ohair@286 73 * Null if not parsed yet.
ohair@286 74 */
ohair@286 75 private FinalArrayList<Attribute> attributes;
ohair@286 76
ohair@286 77 OutboundReferenceParameterHeader(XMLStreamBuffer infoset, String nsUri, String localName) {
ohair@286 78 this.infoset = infoset;
ohair@286 79 this.nsUri = nsUri;
ohair@286 80 this.localName = localName;
ohair@286 81 }
ohair@286 82
alanb@368 83 @Override
ohair@286 84 public @NotNull String getNamespaceURI() {
ohair@286 85 return nsUri;
ohair@286 86 }
ohair@286 87
alanb@368 88 @Override
ohair@286 89 public @NotNull String getLocalPart() {
ohair@286 90 return localName;
ohair@286 91 }
ohair@286 92
alanb@368 93 @Override
ohair@286 94 public String getAttribute(String nsUri, String localName) {
alanb@368 95 if(attributes==null) {
ohair@286 96 parseAttributes();
alanb@368 97 }
ohair@286 98 for(int i=attributes.size()-1; i>=0; i-- ) {
ohair@286 99 Attribute a = attributes.get(i);
alanb@368 100 if (a.localName.equals(localName) && a.nsUri.equals(nsUri)) {
ohair@286 101 return a.value;
alanb@368 102 }
ohair@286 103 }
ohair@286 104 return null;
ohair@286 105 }
ohair@286 106
ohair@286 107 /**
ohair@286 108 * We don't really expect this to be used, but just to satisfy
ohair@286 109 * the {@link Header} contract.
ohair@286 110 *
ohair@286 111 * So this is rather slow.
ohair@286 112 */
ohair@286 113 private void parseAttributes() {
ohair@286 114 try {
ohair@286 115 XMLStreamReader reader = readHeader();
ohair@286 116 reader.nextTag(); // move to the first element, which is the header element
ohair@286 117
ohair@286 118 attributes = new FinalArrayList<Attribute>();
ohair@286 119 boolean refParamAttrWritten = false;
ohair@286 120 for (int i = 0; i < reader.getAttributeCount(); i++) {
alanb@368 121 final String attrLocalName = reader.getAttributeLocalName(i);
ohair@286 122 final String namespaceURI = reader.getAttributeNamespace(i);
ohair@286 123 final String value = reader.getAttributeValue(i);
alanb@368 124 if (namespaceURI.equals(AddressingVersion.W3C.nsUri)&& attrLocalName.equals("IS_REFERENCE_PARAMETER")) {
ohair@286 125 refParamAttrWritten = true;
alanb@368 126 }
alanb@368 127 attributes.add(new Attribute(namespaceURI,attrLocalName,value));
ohair@286 128 }
ohair@286 129 // we are adding one more attribute "wsa:IsReferenceParameter", if its not alrady there
alanb@368 130 if (!refParamAttrWritten) {
ohair@286 131 attributes.add(new Attribute(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE));
alanb@368 132 }
ohair@286 133 } catch (XMLStreamException e) {
ohair@286 134 throw new WebServiceException("Unable to read the attributes for {"+nsUri+"}"+localName+" header",e);
ohair@286 135 }
ohair@286 136 }
ohair@286 137
alanb@368 138 @Override
ohair@286 139 public XMLStreamReader readHeader() throws XMLStreamException {
ohair@286 140 return new StreamReaderDelegate(infoset.readAsXMLStreamReader()) {
ohair@286 141 int state=0; /* 0:expecting root, 1:in root, 2:past root */
alanb@368 142 @Override
ohair@286 143 public int next() throws XMLStreamException {
ohair@286 144 return check(super.next());
ohair@286 145 }
ohair@286 146
alanb@368 147 @Override
ohair@286 148 public int nextTag() throws XMLStreamException {
ohair@286 149 return check(super.nextTag());
ohair@286 150 }
ohair@286 151
ohair@286 152 private int check(int type) {
alanb@368 153 switch (state) {
alanb@368 154 case 0:
alanb@368 155 if (type == START_ELEMENT) {
alanb@368 156 state = 1;
alanb@368 157 }
alanb@368 158 break;
alanb@368 159 case 1:
alanb@368 160 state = 2;
alanb@368 161 break;
alanb@368 162 default:
alanb@368 163 break;
ohair@286 164 }
ohair@286 165
ohair@286 166 return type;
ohair@286 167 }
ohair@286 168
alanb@368 169 @Override
ohair@286 170 public int getAttributeCount() {
alanb@368 171 if (state == 1) {
alanb@368 172 return super.getAttributeCount()+1;
alanb@368 173 } else {
alanb@368 174 return super.getAttributeCount();
alanb@368 175 }
ohair@286 176 }
ohair@286 177
alanb@368 178 @Override
ohair@286 179 public String getAttributeLocalName(int index) {
alanb@368 180 if (state == 1 && index == super.getAttributeCount()) {
ohair@286 181 return IS_REFERENCE_PARAMETER;
alanb@368 182 } else {
ohair@286 183 return super.getAttributeLocalName(index);
alanb@368 184 }
ohair@286 185 }
ohair@286 186
alanb@368 187 @Override
ohair@286 188 public String getAttributeNamespace(int index) {
alanb@368 189 if (state == 1 && index==super.getAttributeCount()) {
ohair@286 190 return AddressingVersion.W3C.nsUri;
alanb@368 191 }
alanb@368 192 else {
ohair@286 193 return super.getAttributeNamespace(index);
alanb@368 194 }
ohair@286 195 }
ohair@286 196
alanb@368 197 @Override
ohair@286 198 public String getAttributePrefix(int index) {
alanb@368 199 if(state==1 && index==super.getAttributeCount()) {
ohair@286 200 return "wsa";
alanb@368 201 } else {
ohair@286 202 return super.getAttributePrefix(index);
alanb@368 203 }
ohair@286 204 }
ohair@286 205
alanb@368 206 @Override
ohair@286 207 public String getAttributeType(int index) {
alanb@368 208 if(state==1 && index==super.getAttributeCount()) {
ohair@286 209 return "CDATA";
alanb@368 210 } else {
ohair@286 211 return super.getAttributeType(index);
alanb@368 212 }
ohair@286 213 }
ohair@286 214
alanb@368 215 @Override
ohair@286 216 public String getAttributeValue(int index) {
alanb@368 217 if(state==1 && index==super.getAttributeCount()) {
ohair@286 218 return TRUE_VALUE;
alanb@368 219 } else {
ohair@286 220 return super.getAttributeValue(index);
alanb@368 221 }
ohair@286 222 }
ohair@286 223
alanb@368 224 @Override
ohair@286 225 public QName getAttributeName(int index) {
alanb@368 226 if(state==1 && index==super.getAttributeCount()) {
ohair@286 227 return new QName(AddressingVersion.W3C.nsUri, IS_REFERENCE_PARAMETER, "wsa");
alanb@368 228 } else {
ohair@286 229 return super.getAttributeName(index);
alanb@368 230 }
ohair@286 231 }
ohair@286 232
alanb@368 233 @Override
ohair@286 234 public String getAttributeValue(String namespaceUri, String localName) {
alanb@368 235 if(state==1 && localName.equals(IS_REFERENCE_PARAMETER) && namespaceUri.equals(AddressingVersion.W3C.nsUri)) {
ohair@286 236 return TRUE_VALUE;
alanb@368 237 } else {
ohair@286 238 return super.getAttributeValue(namespaceUri, localName);
alanb@368 239 }
ohair@286 240 }
ohair@286 241 };
ohair@286 242 }
ohair@286 243
alanb@368 244 @Override
ohair@286 245 public void writeTo(XMLStreamWriter w) throws XMLStreamException {
ohair@286 246 infoset.writeToXMLStreamWriter(new XMLStreamWriterFilter(w) {
ohair@286 247 private boolean root=true;
ohair@286 248 private boolean onRootEl = true;
alanb@368 249 @Override
ohair@286 250 public void writeStartElement(String localName) throws XMLStreamException {
ohair@286 251 super.writeStartElement(localName);
ohair@286 252 writeAddedAttribute();
ohair@286 253 }
ohair@286 254
ohair@286 255 private void writeAddedAttribute() throws XMLStreamException {
ohair@286 256 if(!root) {
ohair@286 257 onRootEl = false;
ohair@286 258 return;
ohair@286 259 }
ohair@286 260 root=false;
ohair@286 261 writeNamespace("wsa",AddressingVersion.W3C.nsUri);
ohair@286 262 super.writeAttribute("wsa",AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE);
ohair@286 263 }
ohair@286 264
alanb@368 265 @Override
ohair@286 266 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
ohair@286 267 super.writeStartElement(namespaceURI, localName);
ohair@286 268 writeAddedAttribute();
ohair@286 269 }
ohair@286 270
alanb@368 271 @Override
ohair@286 272 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
ohair@286 273 //TODO: Verify with KK later
ohair@286 274 //check if prefix is declared before writing start element.
ohair@286 275 boolean prefixDeclared = isPrefixDeclared(prefix,namespaceURI);
ohair@286 276 super.writeStartElement(prefix, localName, namespaceURI);
alanb@368 277 if (!prefixDeclared && !prefix.equals("")) {
ohair@286 278 super.writeNamespace(prefix,namespaceURI);
alanb@368 279 }
ohair@286 280 writeAddedAttribute();
ohair@286 281 }
alanb@368 282 @Override
ohair@286 283 public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException{
alanb@368 284 if (!isPrefixDeclared(prefix, namespaceURI)) {
ohair@286 285 super.writeNamespace(prefix,namespaceURI);
alanb@368 286 }
ohair@286 287 }
ohair@286 288
alanb@368 289 @Override
ohair@286 290 public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
ohair@286 291 //skip if its on root element and attribute is wsa;IsReferenceParameter, as we write it.
ohair@286 292 if(onRootEl && namespaceURI.equals(AddressingVersion.W3C.nsUri)
alanb@368 293 && localName.equals(IS_REFERENCE_PARAMETER)) {
ohair@286 294 return;
alanb@368 295 }
ohair@286 296 writer.writeAttribute(prefix, namespaceURI, localName, value);
ohair@286 297 }
alanb@368 298
alanb@368 299 @Override
ohair@286 300 public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
ohair@286 301 writer.writeAttribute(namespaceURI, localName, value);
ohair@286 302 }
ohair@286 303 private boolean isPrefixDeclared(String prefix, String namespaceURI ) {
ohair@286 304 return namespaceURI.equals(getNamespaceContext().getNamespaceURI(prefix));
ohair@286 305 }
ohair@286 306 },true);
ohair@286 307 }
ohair@286 308
alanb@368 309 @Override
ohair@286 310 public void writeTo(SOAPMessage saaj) throws SOAPException {
ohair@286 311 //TODO: SAAJ returns null instead of throwing SOAPException,
ohair@286 312 // when there is no SOAPHeader in the message,
ohair@286 313 // which leads to NPE.
ohair@286 314 try {
ohair@286 315 SOAPHeader header = saaj.getSOAPHeader();
alanb@368 316 if (header == null) {
ohair@286 317 header = saaj.getSOAPPart().getEnvelope().addHeader();
alanb@368 318 }
ohair@286 319 Element node = (Element)infoset.writeTo(header);
ohair@286 320 node.setAttributeNS(AddressingVersion.W3C.nsUri,AddressingVersion.W3C.getPrefix()+":"+IS_REFERENCE_PARAMETER,TRUE_VALUE);
ohair@286 321 } catch (XMLStreamBufferException e) {
ohair@286 322 throw new SOAPException(e);
ohair@286 323 }
ohair@286 324 }
ohair@286 325
alanb@368 326 @Override
ohair@286 327 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
ohair@286 328 class Filter extends XMLFilterImpl {
ohair@286 329 Filter(ContentHandler ch) { setContentHandler(ch); }
ohair@286 330 private int depth=0;
alanb@368 331 @Override
ohair@286 332 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
ohair@286 333 if(depth++==0) {
ohair@286 334 // add one more attribute
ohair@286 335 super.startPrefixMapping("wsa",AddressingVersion.W3C.nsUri);
ohair@286 336
ohair@286 337 //Add the attirbute wsa:IsReferenceParameter if not present already
ohair@286 338 if(atts.getIndex(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER) == -1) {
ohair@286 339 AttributesImpl atts2 = new AttributesImpl(atts);
ohair@286 340 atts2.addAttribute(
ohair@286 341 AddressingVersion.W3C.nsUri,
ohair@286 342 IS_REFERENCE_PARAMETER,
ohair@286 343 "wsa:IsReferenceParameter",
ohair@286 344 "CDATA",
ohair@286 345 TRUE_VALUE);
ohair@286 346 atts = atts2;
ohair@286 347 }
ohair@286 348 }
ohair@286 349
ohair@286 350 super.startElement(uri, localName, qName, atts);
ohair@286 351 }
ohair@286 352
alanb@368 353 @Override
ohair@286 354 public void endElement(String uri, String localName, String qName) throws SAXException {
ohair@286 355 super.endElement(uri, localName, qName);
alanb@368 356 if (--depth == 0) {
ohair@286 357 super.endPrefixMapping("wsa");
alanb@368 358 }
ohair@286 359 }
ohair@286 360 }
ohair@286 361
ohair@286 362 infoset.writeTo(new Filter(contentHandler),errorHandler);
ohair@286 363 }
ohair@286 364
ohair@286 365
ohair@286 366 /**
ohair@286 367 * Keep the information about an attribute on the header element.
ohair@286 368 */
ohair@286 369 static final class Attribute {
ohair@286 370 /**
ohair@286 371 * Can be empty but never null.
ohair@286 372 */
ohair@286 373 final String nsUri;
ohair@286 374 final String localName;
ohair@286 375 final String value;
ohair@286 376
ohair@286 377 public Attribute(String nsUri, String localName, String value) {
ohair@286 378 this.nsUri = fixNull(nsUri);
ohair@286 379 this.localName = localName;
ohair@286 380 this.value = value;
ohair@286 381 }
ohair@286 382
ohair@286 383 /**
ohair@286 384 * Convert null to "".
ohair@286 385 */
ohair@286 386 private static String fixNull(String s) {
alanb@368 387 return s == null ? "" : s;
ohair@286 388 }
ohair@286 389 }
ohair@286 390
ohair@286 391 /**
ohair@286 392 * We the performance paranoid people in the JAX-WS RI thinks
ohair@286 393 * saving three bytes is worth while...
ohair@286 394 */
ohair@286 395 private static final String TRUE_VALUE = "1";
ohair@286 396 private static final String IS_REFERENCE_PARAMETER = "IsReferenceParameter";
ohair@286 397 }

mercurial