src/share/jaxws_classes/com/sun/xml/internal/ws/message/saaj/SAAJMessage.java

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

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

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.ws.message.saaj;
aoqi@0 27
aoqi@0 28 import com.sun.istack.internal.FragmentContentHandler;
aoqi@0 29 import com.sun.istack.internal.NotNull;
aoqi@0 30 import com.sun.istack.internal.Nullable;
aoqi@0 31 import com.sun.istack.internal.XMLStreamException2;
aoqi@0 32 import com.sun.xml.internal.bind.api.Bridge;
aoqi@0 33 import com.sun.xml.internal.bind.unmarshaller.DOMScanner;
aoqi@0 34 import com.sun.xml.internal.ws.api.SOAPVersion;
aoqi@0 35 import com.sun.xml.internal.ws.api.message.*;
aoqi@0 36 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
aoqi@0 37 import com.sun.xml.internal.ws.spi.db.XMLBridge;
aoqi@0 38 import com.sun.xml.internal.ws.streaming.DOMStreamReader;
aoqi@0 39 import com.sun.xml.internal.ws.util.ASCIIUtility;
aoqi@0 40 import com.sun.xml.internal.ws.util.DOMUtil;
aoqi@0 41 import org.w3c.dom.Attr;
aoqi@0 42 import org.w3c.dom.Element;
aoqi@0 43 import org.w3c.dom.NamedNodeMap;
aoqi@0 44 import org.w3c.dom.Node;
aoqi@0 45 import org.xml.sax.ContentHandler;
aoqi@0 46 import org.xml.sax.ErrorHandler;
aoqi@0 47 import org.xml.sax.SAXException;
aoqi@0 48 import org.xml.sax.helpers.AttributesImpl;
aoqi@0 49 import org.xml.sax.helpers.LocatorImpl;
aoqi@0 50
aoqi@0 51 import javax.activation.DataHandler;
aoqi@0 52 import javax.xml.bind.JAXBException;
aoqi@0 53 import javax.xml.bind.Unmarshaller;
aoqi@0 54 import javax.xml.soap.*;
aoqi@0 55 import javax.xml.stream.XMLStreamException;
aoqi@0 56 import javax.xml.stream.XMLStreamReader;
aoqi@0 57 import javax.xml.stream.XMLStreamWriter;
aoqi@0 58 import javax.xml.transform.Source;
aoqi@0 59 import javax.xml.transform.dom.DOMSource;
aoqi@0 60 import javax.xml.transform.stream.StreamSource;
aoqi@0 61 import javax.xml.ws.WebServiceException;
aoqi@0 62 import java.io.IOException;
aoqi@0 63 import java.io.InputStream;
aoqi@0 64 import java.io.OutputStream;
aoqi@0 65 import java.util.HashMap;
aoqi@0 66 import java.util.Iterator;
aoqi@0 67 import java.util.List;
aoqi@0 68 import java.util.Map;
aoqi@0 69
aoqi@0 70 /**
aoqi@0 71 * {@link Message} implementation backed by {@link SOAPMessage}.
aoqi@0 72 *
aoqi@0 73 * @author Vivek Pandey
aoqi@0 74 * @author Rama Pulavarthi
aoqi@0 75 */
aoqi@0 76 public class SAAJMessage extends Message {
aoqi@0 77 // flag to switch between representations
aoqi@0 78 private boolean parsedMessage;
aoqi@0 79 // flag to check if Message API is exercised;
aoqi@0 80 private boolean accessedMessage;
aoqi@0 81 private final SOAPMessage sm;
aoqi@0 82
aoqi@0 83 private MessageHeaders headers;
aoqi@0 84 private List<Element> bodyParts;
aoqi@0 85 private Element payload;
aoqi@0 86
aoqi@0 87 private String payloadLocalName;
aoqi@0 88 private String payloadNamespace;
aoqi@0 89 private SOAPVersion soapVersion;
aoqi@0 90
aoqi@0 91 //Collect the attrbutes on the enclosing elements so that the same message can be reproduced without loss of any
aoqi@0 92 // valuable info
aoqi@0 93 private NamedNodeMap bodyAttrs, headerAttrs, envelopeAttrs;
aoqi@0 94
aoqi@0 95 public SAAJMessage(SOAPMessage sm) {
aoqi@0 96 this.sm = sm;
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 /**
aoqi@0 100 * This constructor is a convenience and called by the {@link #copy}
aoqi@0 101 *
aoqi@0 102 * @param headers
aoqi@0 103 * @param sm
aoqi@0 104 */
aoqi@0 105 private SAAJMessage(MessageHeaders headers, AttachmentSet as, SOAPMessage sm, SOAPVersion version) {
aoqi@0 106 this.sm = sm;
aoqi@0 107 this.parse();
aoqi@0 108 if(headers == null)
aoqi@0 109 headers = new HeaderList(version);
aoqi@0 110 this.headers = headers;
aoqi@0 111 this.attachmentSet = as;
aoqi@0 112 }
aoqi@0 113
aoqi@0 114 private void parse() {
aoqi@0 115 if (!parsedMessage) {
aoqi@0 116 try {
aoqi@0 117 access();
aoqi@0 118 if (headers == null)
aoqi@0 119 headers = new HeaderList(getSOAPVersion());
aoqi@0 120 SOAPHeader header = sm.getSOAPHeader();
aoqi@0 121 if (header != null) {
aoqi@0 122 headerAttrs = header.getAttributes();
aoqi@0 123 Iterator iter = header.examineAllHeaderElements();
aoqi@0 124 while (iter.hasNext()) {
aoqi@0 125 headers.add(new SAAJHeader((SOAPHeaderElement) iter.next()));
aoqi@0 126 }
aoqi@0 127 }
aoqi@0 128 attachmentSet = new SAAJAttachmentSet(sm);
aoqi@0 129
aoqi@0 130 parsedMessage = true;
aoqi@0 131 } catch (SOAPException e) {
aoqi@0 132 throw new WebServiceException(e);
aoqi@0 133 }
aoqi@0 134 }
aoqi@0 135 }
aoqi@0 136
aoqi@0 137 protected void access() {
aoqi@0 138 if (!accessedMessage) {
aoqi@0 139 try {
aoqi@0 140 envelopeAttrs = sm.getSOAPPart().getEnvelope().getAttributes();
aoqi@0 141 Node body = sm.getSOAPBody();
aoqi@0 142 bodyAttrs = body.getAttributes();
aoqi@0 143 soapVersion = SOAPVersion.fromNsUri(body.getNamespaceURI());
aoqi@0 144 //cature all the body elements
aoqi@0 145 bodyParts = DOMUtil.getChildElements(body);
aoqi@0 146 //we treat payload as the first body part
aoqi@0 147 payload = bodyParts.size() > 0 ? bodyParts.get(0) : null;
aoqi@0 148 // hope this is correct. Caching the localname and namespace of the payload should be fine
aoqi@0 149 // but what about if a Handler replaces the payload with something else? Weel, may be it
aoqi@0 150 // will be error condition anyway
aoqi@0 151 if (payload != null) {
aoqi@0 152 payloadLocalName = payload.getLocalName();
aoqi@0 153 payloadNamespace = payload.getNamespaceURI();
aoqi@0 154 }
aoqi@0 155 accessedMessage = true;
aoqi@0 156 } catch (SOAPException e) {
aoqi@0 157 throw new WebServiceException(e);
aoqi@0 158 }
aoqi@0 159 }
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 public boolean hasHeaders() {
aoqi@0 163 parse();
aoqi@0 164 return headers.hasHeaders();
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 public @NotNull MessageHeaders getHeaders() {
aoqi@0 168 parse();
aoqi@0 169 return headers;
aoqi@0 170 }
aoqi@0 171
aoqi@0 172 /**
aoqi@0 173 * Gets the attachments of this message
aoqi@0 174 * (attachments live outside a message.)
aoqi@0 175 */
aoqi@0 176 @Override
aoqi@0 177 public @NotNull AttachmentSet getAttachments() {
aoqi@0 178 if (attachmentSet == null) attachmentSet = new SAAJAttachmentSet(sm);
aoqi@0 179 return attachmentSet;
aoqi@0 180 }
aoqi@0 181
aoqi@0 182 /**
aoqi@0 183 * Optimization hint for the derived class to check
aoqi@0 184 * if we may have some attachments.
aoqi@0 185 */
aoqi@0 186 @Override
aoqi@0 187 protected boolean hasAttachments() {
aoqi@0 188 return !getAttachments().isEmpty();
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 public @Nullable String getPayloadLocalPart() {
aoqi@0 192 soapBodyFirstChild();
aoqi@0 193 return payloadLocalName;
aoqi@0 194 }
aoqi@0 195
aoqi@0 196 public String getPayloadNamespaceURI() {
aoqi@0 197 soapBodyFirstChild();
aoqi@0 198 return payloadNamespace;
aoqi@0 199 }
aoqi@0 200
aoqi@0 201 public boolean hasPayload() {
aoqi@0 202 return soapBodyFirstChild() != null;
aoqi@0 203 }
aoqi@0 204
aoqi@0 205 private void addAttributes(Element e, NamedNodeMap attrs) {
aoqi@0 206 if(attrs == null)
aoqi@0 207 return;
aoqi@0 208 String elPrefix = e.getPrefix();
aoqi@0 209 for(int i=0; i < attrs.getLength();i++) {
aoqi@0 210 Attr a = (Attr)attrs.item(i);
aoqi@0 211 //check if attr is ns declaration
aoqi@0 212 if("xmlns".equals(a.getPrefix()) || "xmlns".equals(a.getLocalName())) {
aoqi@0 213 if(elPrefix == null && a.getLocalName().equals("xmlns")) {
aoqi@0 214 // the target element has already default ns declaration, dont' override it
aoqi@0 215 continue;
aoqi@0 216 } else if(elPrefix != null && "xmlns".equals(a.getPrefix()) && elPrefix.equals(a.getLocalName())) {
aoqi@0 217 //dont bind the prefix to ns again, its already in the target element.
aoqi@0 218 continue;
aoqi@0 219 }
aoqi@0 220 e.setAttributeNS(a.getNamespaceURI(),a.getName(),a.getValue());
aoqi@0 221 continue;
aoqi@0 222 }
aoqi@0 223 e.setAttributeNS(a.getNamespaceURI(),a.getName(),a.getValue());
aoqi@0 224 }
aoqi@0 225 }
aoqi@0 226
aoqi@0 227 public Source readEnvelopeAsSource() {
aoqi@0 228 try {
aoqi@0 229 if (!parsedMessage) {
aoqi@0 230 SOAPEnvelope se = sm.getSOAPPart().getEnvelope();
aoqi@0 231 return new DOMSource(se);
aoqi@0 232
aoqi@0 233 } else {
aoqi@0 234 SOAPMessage msg = soapVersion.getMessageFactory().createMessage();
aoqi@0 235 addAttributes(msg.getSOAPPart().getEnvelope(),envelopeAttrs);
aoqi@0 236
aoqi@0 237 SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
aoqi@0 238 addAttributes(newBody, bodyAttrs);
aoqi@0 239 for (Element part : bodyParts) {
aoqi@0 240 Node n = newBody.getOwnerDocument().importNode(part, true);
aoqi@0 241 newBody.appendChild(n);
aoqi@0 242 }
aoqi@0 243 addAttributes(msg.getSOAPHeader(),headerAttrs);
aoqi@0 244 for (Header header : headers.asList()) {
aoqi@0 245 header.writeTo(msg);
aoqi@0 246 }
aoqi@0 247 SOAPEnvelope se = msg.getSOAPPart().getEnvelope();
aoqi@0 248 return new DOMSource(se);
aoqi@0 249 }
aoqi@0 250 } catch (SOAPException e) {
aoqi@0 251 throw new WebServiceException(e);
aoqi@0 252 }
aoqi@0 253 }
aoqi@0 254
aoqi@0 255 public SOAPMessage readAsSOAPMessage() throws SOAPException {
aoqi@0 256 if (!parsedMessage) {
aoqi@0 257 return sm;
aoqi@0 258 } else {
aoqi@0 259 SOAPMessage msg = soapVersion.getMessageFactory().createMessage();
aoqi@0 260 addAttributes(msg.getSOAPPart().getEnvelope(),envelopeAttrs);
aoqi@0 261 SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
aoqi@0 262 addAttributes(newBody, bodyAttrs);
aoqi@0 263 for (Element part : bodyParts) {
aoqi@0 264 Node n = newBody.getOwnerDocument().importNode(part, true);
aoqi@0 265 newBody.appendChild(n);
aoqi@0 266 }
aoqi@0 267 addAttributes(msg.getSOAPHeader(),headerAttrs);
aoqi@0 268 for (Header header : headers.asList()) {
aoqi@0 269 header.writeTo(msg);
aoqi@0 270 }
aoqi@0 271 for (Attachment att : getAttachments()) {
aoqi@0 272 AttachmentPart part = msg.createAttachmentPart();
aoqi@0 273 part.setDataHandler(att.asDataHandler());
aoqi@0 274 part.setContentId('<' + att.getContentId() + '>');
aoqi@0 275 addCustomMimeHeaders(att, part);
aoqi@0 276 msg.addAttachmentPart(part);
aoqi@0 277 }
aoqi@0 278 msg.saveChanges();
aoqi@0 279 return msg;
aoqi@0 280 }
aoqi@0 281 }
aoqi@0 282
aoqi@0 283 private void addCustomMimeHeaders(Attachment att, AttachmentPart part) {
aoqi@0 284 if (att instanceof AttachmentEx) {
aoqi@0 285 Iterator<AttachmentEx.MimeHeader> allMimeHeaders = ((AttachmentEx) att).getMimeHeaders();
aoqi@0 286 while (allMimeHeaders.hasNext()) {
aoqi@0 287 AttachmentEx.MimeHeader mh = allMimeHeaders.next();
aoqi@0 288 String name = mh.getName();
aoqi@0 289 if (!"Content-Type".equalsIgnoreCase(name)
aoqi@0 290 && !"Content-Id".equalsIgnoreCase(name)) {
aoqi@0 291 part.addMimeHeader(name, mh.getValue());
aoqi@0 292 }
aoqi@0 293 }
aoqi@0 294 }
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 public Source readPayloadAsSource() {
aoqi@0 298 access();
aoqi@0 299 return (payload != null) ? new DOMSource(payload) : null;
aoqi@0 300 }
aoqi@0 301
aoqi@0 302 public <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
aoqi@0 303 access();
aoqi@0 304 if (payload != null) {
aoqi@0 305 if(hasAttachments())
aoqi@0 306 unmarshaller.setAttachmentUnmarshaller(new AttachmentUnmarshallerImpl(getAttachments()));
aoqi@0 307 return (T) unmarshaller.unmarshal(payload);
aoqi@0 308
aoqi@0 309 }
aoqi@0 310 return null;
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 /** @deprecated */
aoqi@0 314 public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
aoqi@0 315 access();
aoqi@0 316 if (payload != null)
aoqi@0 317 return bridge.unmarshal(payload,hasAttachments()? new AttachmentUnmarshallerImpl(getAttachments()) : null);
aoqi@0 318 return null;
aoqi@0 319 }
aoqi@0 320 public <T> T readPayloadAsJAXB(XMLBridge<T> bridge) throws JAXBException {
aoqi@0 321 access();
aoqi@0 322 if (payload != null)
aoqi@0 323 return bridge.unmarshal(payload,hasAttachments()? new AttachmentUnmarshallerImpl(getAttachments()) : null);
aoqi@0 324 return null;
aoqi@0 325 }
aoqi@0 326
aoqi@0 327 public XMLStreamReader readPayload() throws XMLStreamException {
aoqi@0 328 return soapBodyFirstChildReader();
aoqi@0 329 }
aoqi@0 330
aoqi@0 331 public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
aoqi@0 332 access();
aoqi@0 333 try {
aoqi@0 334 for (Element part : bodyParts)
aoqi@0 335 DOMUtil.serializeNode(part, sw);
aoqi@0 336 } catch (XMLStreamException e) {
aoqi@0 337 throw new WebServiceException(e);
aoqi@0 338 }
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 public void writeTo(XMLStreamWriter writer) throws XMLStreamException {
aoqi@0 342 try {
aoqi@0 343 writer.writeStartDocument();
aoqi@0 344 if (!parsedMessage) {
aoqi@0 345 DOMUtil.serializeNode(sm.getSOAPPart().getEnvelope(), writer);
aoqi@0 346 } else {
aoqi@0 347 SOAPEnvelope env = sm.getSOAPPart().getEnvelope();
aoqi@0 348 DOMUtil.writeTagWithAttributes(env, writer);
aoqi@0 349 if (hasHeaders()) {
aoqi@0 350 if(env.getHeader() != null) {
aoqi@0 351 DOMUtil.writeTagWithAttributes(env.getHeader(), writer);
aoqi@0 352 } else {
aoqi@0 353 writer.writeStartElement(env.getPrefix(), "Header", env.getNamespaceURI());
aoqi@0 354 }
aoqi@0 355 for (Header h : headers.asList()) {
aoqi@0 356 h.writeTo(writer);
aoqi@0 357 }
aoqi@0 358 writer.writeEndElement();
aoqi@0 359 }
aoqi@0 360
aoqi@0 361 DOMUtil.serializeNode(sm.getSOAPBody(), writer);
aoqi@0 362 writer.writeEndElement();
aoqi@0 363 }
aoqi@0 364 writer.writeEndDocument();
aoqi@0 365 writer.flush();
aoqi@0 366 } catch (SOAPException ex) {
aoqi@0 367 throw new XMLStreamException2(ex);
aoqi@0 368 //for now. ask jaxws team what to do.
aoqi@0 369 }
aoqi@0 370 }
aoqi@0 371
aoqi@0 372 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
aoqi@0 373 String soapNsUri = soapVersion.nsUri;
aoqi@0 374 if (!parsedMessage) {
aoqi@0 375 DOMScanner ds = new DOMScanner();
aoqi@0 376 ds.setContentHandler(contentHandler);
aoqi@0 377 ds.scan(sm.getSOAPPart());
aoqi@0 378 } else {
aoqi@0 379 contentHandler.setDocumentLocator(NULL_LOCATOR);
aoqi@0 380 contentHandler.startDocument();
aoqi@0 381 contentHandler.startPrefixMapping("S", soapNsUri);
aoqi@0 382 startPrefixMapping(contentHandler, envelopeAttrs,"S");
aoqi@0 383 contentHandler.startElement(soapNsUri, "Envelope", "S:Envelope", getAttributes(envelopeAttrs));
aoqi@0 384 if (hasHeaders()) {
aoqi@0 385 startPrefixMapping(contentHandler, headerAttrs,"S");
aoqi@0 386 contentHandler.startElement(soapNsUri, "Header", "S:Header", getAttributes(headerAttrs));
aoqi@0 387 MessageHeaders headers = getHeaders();
aoqi@0 388 for (Header h : headers.asList()) {
aoqi@0 389 h.writeTo(contentHandler, errorHandler);
aoqi@0 390 }
aoqi@0 391 endPrefixMapping(contentHandler, headerAttrs,"S");
aoqi@0 392 contentHandler.endElement(soapNsUri, "Header", "S:Header");
aoqi@0 393
aoqi@0 394 }
aoqi@0 395 startPrefixMapping(contentHandler, bodyAttrs,"S");
aoqi@0 396 // write the body
aoqi@0 397 contentHandler.startElement(soapNsUri, "Body", "S:Body", getAttributes(bodyAttrs));
aoqi@0 398 writePayloadTo(contentHandler, errorHandler, true);
aoqi@0 399 endPrefixMapping(contentHandler, bodyAttrs,"S");
aoqi@0 400 contentHandler.endElement(soapNsUri, "Body", "S:Body");
aoqi@0 401 endPrefixMapping(contentHandler, envelopeAttrs,"S");
aoqi@0 402 contentHandler.endElement(soapNsUri, "Envelope", "S:Envelope");
aoqi@0 403 }
aoqi@0 404 }
aoqi@0 405 /**
aoqi@0 406 * Gets the Attributes that are not namesapce declarations
aoqi@0 407 * @param attrs
aoqi@0 408 * @return
aoqi@0 409 */
aoqi@0 410 private AttributesImpl getAttributes(NamedNodeMap attrs) {
aoqi@0 411 AttributesImpl atts = new AttributesImpl();
aoqi@0 412 if(attrs == null)
aoqi@0 413 return EMPTY_ATTS;
aoqi@0 414 for(int i=0; i < attrs.getLength();i++) {
aoqi@0 415 Attr a = (Attr)attrs.item(i);
aoqi@0 416 //check if attr is ns declaration
aoqi@0 417 if("xmlns".equals(a.getPrefix()) || "xmlns".equals(a.getLocalName())) {
aoqi@0 418 continue;
aoqi@0 419 }
aoqi@0 420 atts.addAttribute(fixNull(a.getNamespaceURI()),a.getLocalName(),a.getName(),a.getSchemaTypeInfo().getTypeName(),a.getValue());
aoqi@0 421 }
aoqi@0 422 return atts;
aoqi@0 423 }
aoqi@0 424
aoqi@0 425 /**
aoqi@0 426 * Collects the ns declarations and starts the prefix mapping, consequently the associated endPrefixMapping needs to be called.
aoqi@0 427 * @param contentHandler
aoqi@0 428 * @param attrs
aoqi@0 429 * @param excludePrefix , this is to excldue the global prefix mapping "S" used at the start
aoqi@0 430 * @throws SAXException
aoqi@0 431 */
aoqi@0 432 private void startPrefixMapping(ContentHandler contentHandler, NamedNodeMap attrs, String excludePrefix) throws SAXException {
aoqi@0 433 if(attrs == null)
aoqi@0 434 return;
aoqi@0 435 for(int i=0; i < attrs.getLength();i++) {
aoqi@0 436 Attr a = (Attr)attrs.item(i);
aoqi@0 437 //check if attr is ns declaration
aoqi@0 438 if("xmlns".equals(a.getPrefix()) || "xmlns".equals(a.getLocalName())) {
aoqi@0 439 if(!fixNull(a.getPrefix()).equals(excludePrefix)) {
aoqi@0 440 contentHandler.startPrefixMapping(fixNull(a.getPrefix()), a.getNamespaceURI());
aoqi@0 441 }
aoqi@0 442 }
aoqi@0 443 }
aoqi@0 444 }
aoqi@0 445
aoqi@0 446 private void endPrefixMapping(ContentHandler contentHandler, NamedNodeMap attrs, String excludePrefix) throws SAXException {
aoqi@0 447 if(attrs == null)
aoqi@0 448 return;
aoqi@0 449 for(int i=0; i < attrs.getLength();i++) {
aoqi@0 450 Attr a = (Attr)attrs.item(i);
aoqi@0 451 //check if attr is ns declaration
aoqi@0 452 if("xmlns".equals(a.getPrefix()) || "xmlns".equals(a.getLocalName())) {
aoqi@0 453 if(!fixNull(a.getPrefix()).equals(excludePrefix)) {
aoqi@0 454 contentHandler.endPrefixMapping(fixNull(a.getPrefix()));
aoqi@0 455 }
aoqi@0 456 }
aoqi@0 457 }
aoqi@0 458 }
aoqi@0 459
aoqi@0 460 private static String fixNull(String s) {
aoqi@0 461 if(s==null) return "";
aoqi@0 462 else return s;
aoqi@0 463 }
aoqi@0 464
aoqi@0 465 private void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
aoqi@0 466 if(fragment)
aoqi@0 467 contentHandler = new FragmentContentHandler(contentHandler);
aoqi@0 468 DOMScanner ds = new DOMScanner();
aoqi@0 469 ds.setContentHandler(contentHandler);
aoqi@0 470 ds.scan(payload);
aoqi@0 471 }
aoqi@0 472
aoqi@0 473 /**
aoqi@0 474 * Creates a copy of a {@link com.sun.xml.internal.ws.api.message.Message}.
aoqi@0 475 * <p/>
aoqi@0 476 * <p/>
aoqi@0 477 * This method creates a new {@link com.sun.xml.internal.ws.api.message.Message} whose header/payload/attachments/properties
aoqi@0 478 * are identical to this {@link com.sun.xml.internal.ws.api.message.Message}. Once created, the created {@link com.sun.xml.internal.ws.api.message.Message}
aoqi@0 479 * and the original {@link com.sun.xml.internal.ws.api.message.Message} behaves independently --- adding header/
aoqi@0 480 * attachment to one {@link com.sun.xml.internal.ws.api.message.Message} doesn't affect another {@link com.sun.xml.internal.ws.api.message.Message}
aoqi@0 481 * at all.
aoqi@0 482 * <p/>
aoqi@0 483 * <h3>Design Rationale</h3>
aoqi@0 484 * <p/>
aoqi@0 485 * Since a {@link com.sun.xml.internal.ws.api.message.Message} body is read-once, sometimes
aoqi@0 486 * (such as when you do fail-over, or WS-RM) you need to
aoqi@0 487 * create an idential copy of a {@link com.sun.xml.internal.ws.api.message.Message}.
aoqi@0 488 * <p/>
aoqi@0 489 * <p/>
aoqi@0 490 * The actual copy operation depends on the layout
aoqi@0 491 * of the data in memory, hence it's best to be done by
aoqi@0 492 * the {@link com.sun.xml.internal.ws.api.message.Message} implementation itself.
aoqi@0 493 */
aoqi@0 494 public Message copy() {
aoqi@0 495 try {
aoqi@0 496 if (!parsedMessage) {
aoqi@0 497 return new SAAJMessage(readAsSOAPMessage());
aoqi@0 498 } else {
aoqi@0 499 SOAPMessage msg = soapVersion.getMessageFactory().createMessage();
aoqi@0 500 SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
aoqi@0 501 for (Element part : bodyParts) {
aoqi@0 502 Node n = newBody.getOwnerDocument().importNode(part, true);
aoqi@0 503 newBody.appendChild(n);
aoqi@0 504 }
aoqi@0 505 addAttributes(newBody, bodyAttrs);
aoqi@0 506 return new SAAJMessage(getHeaders(), getAttachments(), msg, soapVersion);
aoqi@0 507 }
aoqi@0 508 } catch (SOAPException e) {
aoqi@0 509 throw new WebServiceException(e);
aoqi@0 510 }
aoqi@0 511 }
aoqi@0 512 private static final AttributesImpl EMPTY_ATTS = new AttributesImpl();
aoqi@0 513 private static final LocatorImpl NULL_LOCATOR = new LocatorImpl();
aoqi@0 514
aoqi@0 515 protected static class SAAJAttachment implements AttachmentEx {
aoqi@0 516
aoqi@0 517 final AttachmentPart ap;
aoqi@0 518
aoqi@0 519 String contentIdNoAngleBracket;
aoqi@0 520
aoqi@0 521 public SAAJAttachment(AttachmentPart part) {
aoqi@0 522 this.ap = part;
aoqi@0 523 }
aoqi@0 524
aoqi@0 525 /**
aoqi@0 526 * Content ID of the attachment. Uniquely identifies an attachment.
aoqi@0 527 */
aoqi@0 528 public String getContentId() {
aoqi@0 529 if (contentIdNoAngleBracket == null) {
aoqi@0 530 contentIdNoAngleBracket = ap.getContentId();
aoqi@0 531 if (contentIdNoAngleBracket != null && contentIdNoAngleBracket.charAt(0) == '<')
aoqi@0 532 contentIdNoAngleBracket = contentIdNoAngleBracket.substring(1, contentIdNoAngleBracket.length()-1);
aoqi@0 533 }
aoqi@0 534 return contentIdNoAngleBracket;
aoqi@0 535 }
aoqi@0 536
aoqi@0 537 /**
aoqi@0 538 * Gets the MIME content-type of this attachment.
aoqi@0 539 */
aoqi@0 540 public String getContentType() {
aoqi@0 541 return ap.getContentType();
aoqi@0 542 }
aoqi@0 543
aoqi@0 544 /**
aoqi@0 545 * Gets the attachment as an exact-length byte array.
aoqi@0 546 */
aoqi@0 547 public byte[] asByteArray() {
aoqi@0 548 try {
aoqi@0 549 return ap.getRawContentBytes();
aoqi@0 550 } catch (SOAPException e) {
aoqi@0 551 throw new WebServiceException(e);
aoqi@0 552 }
aoqi@0 553 }
aoqi@0 554
aoqi@0 555 /**
aoqi@0 556 * Gets the attachment as a {@link javax.activation.DataHandler}.
aoqi@0 557 */
aoqi@0 558 public DataHandler asDataHandler() {
aoqi@0 559 try {
aoqi@0 560 return ap.getDataHandler();
aoqi@0 561 } catch (SOAPException e) {
aoqi@0 562 throw new WebServiceException(e);
aoqi@0 563 }
aoqi@0 564 }
aoqi@0 565
aoqi@0 566 /**
aoqi@0 567 * Gets the attachment as a {@link javax.xml.transform.Source}.
aoqi@0 568 * Note that there's no guarantee that the attachment is actually an XML.
aoqi@0 569 */
aoqi@0 570 public Source asSource() {
aoqi@0 571 try {
aoqi@0 572 return new StreamSource(ap.getRawContent());
aoqi@0 573 } catch (SOAPException e) {
aoqi@0 574 throw new WebServiceException(e);
aoqi@0 575 }
aoqi@0 576 }
aoqi@0 577
aoqi@0 578 /**
aoqi@0 579 * Obtains this attachment as an {@link java.io.InputStream}.
aoqi@0 580 */
aoqi@0 581 public InputStream asInputStream() {
aoqi@0 582 try {
aoqi@0 583 return ap.getRawContent();
aoqi@0 584 } catch (SOAPException e) {
aoqi@0 585 throw new WebServiceException(e);
aoqi@0 586 }
aoqi@0 587 }
aoqi@0 588
aoqi@0 589 /**
aoqi@0 590 * Writes the contents of the attachment into the given stream.
aoqi@0 591 */
aoqi@0 592 public void writeTo(OutputStream os) throws IOException {
aoqi@0 593 try {
aoqi@0 594 ASCIIUtility.copyStream(ap.getRawContent(), os);
aoqi@0 595 } catch (SOAPException e) {
aoqi@0 596 throw new WebServiceException(e);
aoqi@0 597 }
aoqi@0 598 }
aoqi@0 599
aoqi@0 600 /**
aoqi@0 601 * Writes this attachment to the given {@link javax.xml.soap.SOAPMessage}.
aoqi@0 602 */
aoqi@0 603 public void writeTo(SOAPMessage saaj) {
aoqi@0 604 saaj.addAttachmentPart(ap);
aoqi@0 605 }
aoqi@0 606
aoqi@0 607 AttachmentPart asAttachmentPart(){
aoqi@0 608 return ap;
aoqi@0 609 }
aoqi@0 610
aoqi@0 611 public Iterator<MimeHeader> getMimeHeaders() {
aoqi@0 612 final Iterator it = ap.getAllMimeHeaders();
aoqi@0 613 return new Iterator<MimeHeader>() {
aoqi@0 614 public boolean hasNext() {
aoqi@0 615 return it.hasNext();
aoqi@0 616 }
aoqi@0 617
aoqi@0 618 public MimeHeader next() {
aoqi@0 619 final javax.xml.soap.MimeHeader mh = (javax.xml.soap.MimeHeader) it.next();
aoqi@0 620 return new MimeHeader() {
aoqi@0 621 public String getName() {
aoqi@0 622 return mh.getName();
aoqi@0 623 }
aoqi@0 624
aoqi@0 625 public String getValue() {
aoqi@0 626 return mh.getValue();
aoqi@0 627 }
aoqi@0 628 };
aoqi@0 629 }
aoqi@0 630
aoqi@0 631 public void remove() {
aoqi@0 632 throw new UnsupportedOperationException();
aoqi@0 633 }
aoqi@0 634 };
aoqi@0 635 }
aoqi@0 636 }
aoqi@0 637
aoqi@0 638 /**
aoqi@0 639 * {@link AttachmentSet} for SAAJ.
aoqi@0 640 *
aoqi@0 641 * SAAJ wants '&lt;' and '>' for the content ID, but {@link AttachmentSet}
aoqi@0 642 * doesn't. S this class also does the conversion between them.
aoqi@0 643 */
aoqi@0 644 protected static class SAAJAttachmentSet implements AttachmentSet {
aoqi@0 645
aoqi@0 646 private Map<String, Attachment> attMap;
aoqi@0 647 private Iterator attIter;
aoqi@0 648
aoqi@0 649 public SAAJAttachmentSet(SOAPMessage sm) {
aoqi@0 650 attIter = sm.getAttachments();
aoqi@0 651 }
aoqi@0 652
aoqi@0 653 /**
aoqi@0 654 * Gets the attachment by the content ID.
aoqi@0 655 *
aoqi@0 656 * @return null
aoqi@0 657 * if no such attachment exist.
aoqi@0 658 */
aoqi@0 659 public Attachment get(String contentId) {
aoqi@0 660 // if this is the first time then create the attachment Map
aoqi@0 661 if (attMap == null) {
aoqi@0 662 if (!attIter.hasNext())
aoqi@0 663 return null;
aoqi@0 664 attMap = createAttachmentMap();
aoqi@0 665 }
aoqi@0 666 if(contentId.charAt(0) != '<'){
aoqi@0 667 return attMap.get('<'+contentId+'>');
aoqi@0 668 }
aoqi@0 669 return attMap.get(contentId);
aoqi@0 670 }
aoqi@0 671
aoqi@0 672 public boolean isEmpty() {
aoqi@0 673 if(attMap!=null)
aoqi@0 674 return attMap.isEmpty();
aoqi@0 675 else
aoqi@0 676 return !attIter.hasNext();
aoqi@0 677 }
aoqi@0 678
aoqi@0 679 /**
aoqi@0 680 * Returns an iterator over a set of elements of type T.
aoqi@0 681 *
aoqi@0 682 * @return an Iterator.
aoqi@0 683 */
aoqi@0 684 public Iterator<Attachment> iterator() {
aoqi@0 685 if (attMap == null) {
aoqi@0 686 attMap = createAttachmentMap();
aoqi@0 687 }
aoqi@0 688 return attMap.values().iterator();
aoqi@0 689 }
aoqi@0 690
aoqi@0 691 private Map<String, Attachment> createAttachmentMap() {
aoqi@0 692 HashMap<String, Attachment> map = new HashMap<String, Attachment>();
aoqi@0 693 while (attIter.hasNext()) {
aoqi@0 694 AttachmentPart ap = (AttachmentPart) attIter.next();
aoqi@0 695 map.put(ap.getContentId(), new SAAJAttachment(ap));
aoqi@0 696 }
aoqi@0 697 return map;
aoqi@0 698 }
aoqi@0 699
aoqi@0 700 public void add(Attachment att) {
aoqi@0 701 attMap.put('<'+att.getContentId()+'>', att);
aoqi@0 702 }
aoqi@0 703 }
aoqi@0 704
aoqi@0 705 public SOAPVersion getSOAPVersion() {
aoqi@0 706 return soapVersion;
aoqi@0 707 }
aoqi@0 708
aoqi@0 709 private XMLStreamReader soapBodyFirstChildReader;
aoqi@0 710
aoqi@0 711 /**
aoqi@0 712 * This allow the subclass to retain the XMLStreamReader.
aoqi@0 713 */
aoqi@0 714 protected XMLStreamReader getXMLStreamReader(SOAPElement soapElement) {
aoqi@0 715 return null;
aoqi@0 716 }
aoqi@0 717
aoqi@0 718 protected XMLStreamReader createXMLStreamReader(SOAPElement soapElement) {
aoqi@0 719 DOMStreamReader dss = new DOMStreamReader();
aoqi@0 720 dss.setCurrentNode(soapElement);
aoqi@0 721 return dss;
aoqi@0 722 }
aoqi@0 723
aoqi@0 724 protected XMLStreamReader soapBodyFirstChildReader() {
aoqi@0 725 if (soapBodyFirstChildReader != null) return soapBodyFirstChildReader;
aoqi@0 726 soapBodyFirstChild();
aoqi@0 727 if (soapBodyFirstChild != null) {
aoqi@0 728 soapBodyFirstChildReader = getXMLStreamReader(soapBodyFirstChild);
aoqi@0 729 if (soapBodyFirstChildReader == null) soapBodyFirstChildReader =
aoqi@0 730 createXMLStreamReader(soapBodyFirstChild);
aoqi@0 731 if (soapBodyFirstChildReader.getEventType() == XMLStreamReader.START_DOCUMENT) {
aoqi@0 732 try {
aoqi@0 733 while(soapBodyFirstChildReader.getEventType() != XMLStreamReader.START_ELEMENT)
aoqi@0 734 soapBodyFirstChildReader.next();
aoqi@0 735 } catch (XMLStreamException e) {
aoqi@0 736 throw new RuntimeException(e);
aoqi@0 737 }
aoqi@0 738 }
aoqi@0 739 return soapBodyFirstChildReader;
aoqi@0 740 } else {
aoqi@0 741 payloadLocalName = null;
aoqi@0 742 payloadNamespace = null;
aoqi@0 743 return null;
aoqi@0 744 }
aoqi@0 745 }
aoqi@0 746
aoqi@0 747 private SOAPElement soapBodyFirstChild;
aoqi@0 748
aoqi@0 749 SOAPElement soapBodyFirstChild() {
aoqi@0 750 if (soapBodyFirstChild != null) return soapBodyFirstChild;
aoqi@0 751 try {
aoqi@0 752 boolean foundElement = false;
aoqi@0 753 for (Node n = sm.getSOAPBody().getFirstChild(); n != null && !foundElement; n = n.getNextSibling()) {
aoqi@0 754 if (n.getNodeType() == Node.ELEMENT_NODE) {
aoqi@0 755 foundElement = true;
aoqi@0 756 if (n instanceof SOAPElement) {
aoqi@0 757 soapBodyFirstChild = (SOAPElement) n;
aoqi@0 758 payloadLocalName = soapBodyFirstChild.getLocalName();
aoqi@0 759 payloadNamespace = soapBodyFirstChild.getNamespaceURI();
aoqi@0 760 return soapBodyFirstChild;
aoqi@0 761 }
aoqi@0 762 }
aoqi@0 763 }
aoqi@0 764 if(foundElement) for(Iterator i = sm.getSOAPBody().getChildElements(); i.hasNext();){
aoqi@0 765 Object o = i.next();
aoqi@0 766 if (o instanceof SOAPElement) {
aoqi@0 767 soapBodyFirstChild = (SOAPElement)o;
aoqi@0 768 payloadLocalName = soapBodyFirstChild.getLocalName();
aoqi@0 769 payloadNamespace = soapBodyFirstChild.getNamespaceURI();
aoqi@0 770 return soapBodyFirstChild;
aoqi@0 771 }
aoqi@0 772 }
aoqi@0 773 } catch (SOAPException e) {
aoqi@0 774 throw new RuntimeException(e);
aoqi@0 775 }
aoqi@0 776 return soapBodyFirstChild;
aoqi@0 777 }
aoqi@0 778 }

mercurial