feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.soap.SOAPBinding;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.addressing.WsaTubeHelper;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingPropertySet;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.OneWayFeature;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.message.RelatesToHeader;
|
||||
import com.sun.xml.internal.ws.message.StringHeader;
|
||||
import com.sun.xml.internal.ws.resources.AddressingMessages;
|
||||
import com.sun.xml.internal.ws.resources.ClientMessages;
|
||||
|
||||
public class AddressingUtils {
|
||||
//TODO is MessageHeaders to be implicitly assumed? Or moved to utility class and taken out from interface?
|
||||
public static void fillRequestAddressingHeaders(MessageHeaders headers, Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action) {
|
||||
fillRequestAddressingHeaders(headers, packet, av, sv, oneway, action, false);
|
||||
}
|
||||
public static void fillRequestAddressingHeaders(MessageHeaders headers, Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action, boolean mustUnderstand) {
|
||||
fillCommonAddressingHeaders(headers, packet, av, sv, action, mustUnderstand);
|
||||
|
||||
// wsa:ReplyTo
|
||||
// null or "true" is equivalent to request/response MEP
|
||||
if (!oneway) {
|
||||
WSEndpointReference epr = av.anonymousEpr;
|
||||
if (headers.get(av.replyToTag, false) == null) {
|
||||
headers.add(epr.createHeader(av.replyToTag));
|
||||
}
|
||||
|
||||
// wsa:FaultTo
|
||||
if (headers.get(av.faultToTag, false) == null) {
|
||||
headers.add(epr.createHeader(av.faultToTag));
|
||||
}
|
||||
|
||||
// wsa:MessageID
|
||||
if (packet.getMessage().getHeaders().get(av.messageIDTag, false) == null) {
|
||||
if (headers.get(av.messageIDTag, false) == null) {
|
||||
Header h = new StringHeader(av.messageIDTag, Message.generateMessageID());
|
||||
headers.add(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// private void fillRequestAddressingHeaders(Packet packet, AddressingVersion av, SOAPVersion sv, OneWayFeature oneWayFeature, boolean oneway, String action);
|
||||
public static void fillRequestAddressingHeaders(MessageHeaders headers, WSDLPort wsdlPort, WSBinding binding, Packet packet) {
|
||||
if (binding == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_BINDING());
|
||||
}
|
||||
|
||||
if (binding.isFeatureEnabled(SuppressAutomaticWSARequestHeadersFeature.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//See if WSA headers are already set by the user.
|
||||
MessageHeaders hl = packet.getMessage().getHeaders();
|
||||
String action = AddressingUtils.getAction(hl, binding.getAddressingVersion(), binding.getSOAPVersion());
|
||||
if (action != null) {
|
||||
//assume that all the WSA headers are set by the user
|
||||
return;
|
||||
}
|
||||
AddressingVersion addressingVersion = binding.getAddressingVersion();
|
||||
//seiModel is passed as null as it is not needed.
|
||||
WsaTubeHelper wsaHelper = addressingVersion.getWsaHelper(wsdlPort, null, binding);
|
||||
|
||||
// wsa:Action
|
||||
String effectiveInputAction = wsaHelper.getEffectiveInputAction(packet);
|
||||
if (effectiveInputAction == null || effectiveInputAction.equals("") && binding.getSOAPVersion() == SOAPVersion.SOAP_11) {
|
||||
throw new WebServiceException(ClientMessages.INVALID_SOAP_ACTION());
|
||||
}
|
||||
boolean oneway = !packet.expectReply;
|
||||
if (wsdlPort != null) {
|
||||
// if WSDL has <wsaw:Anonymous>prohibited</wsaw:Anonymous>, then throw an error
|
||||
// as anonymous ReplyTo MUST NOT be added in that case. BindingProvider need to
|
||||
// disable AddressingFeature and MemberSubmissionAddressingFeature and hand-craft
|
||||
// the SOAP message with non-anonymous ReplyTo/FaultTo.
|
||||
if (!oneway && packet.getMessage() != null && packet.getWSDLOperation() != null) {
|
||||
WSDLBoundOperation wbo = wsdlPort.getBinding().get(packet.getWSDLOperation());
|
||||
if (wbo != null && wbo.getAnonymous() == WSDLBoundOperation.ANONYMOUS.prohibited) {
|
||||
throw new WebServiceException(AddressingMessages.WSAW_ANONYMOUS_PROHIBITED());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OneWayFeature oneWayFeature = binding.getFeature(OneWayFeature.class);
|
||||
final AddressingPropertySet addressingPropertySet = packet.getSatellite(AddressingPropertySet.class);
|
||||
oneWayFeature = addressingPropertySet == null ? oneWayFeature : new OneWayFeature(addressingPropertySet, addressingVersion);
|
||||
|
||||
if (oneWayFeature == null || !oneWayFeature.isEnabled()) {
|
||||
// standard oneway
|
||||
fillRequestAddressingHeaders(headers, packet, addressingVersion, binding.getSOAPVersion(), oneway, effectiveInputAction, AddressingVersion.isRequired(binding));
|
||||
} else {
|
||||
// custom oneway
|
||||
fillRequestAddressingHeaders(headers, packet, addressingVersion, binding.getSOAPVersion(), oneWayFeature, oneway, effectiveInputAction);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAction(@NotNull MessageHeaders headers, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
String action = null;
|
||||
Header h = getFirstHeader(headers, av.actionTag, true, sv);
|
||||
if (h != null) {
|
||||
action = h.getStringContent();
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
public static WSEndpointReference getFaultTo(@NotNull MessageHeaders headers, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
Header h = getFirstHeader(headers, av.faultToTag, true, sv);
|
||||
WSEndpointReference faultTo = null;
|
||||
if (h != null) {
|
||||
try {
|
||||
faultTo = h.readAsEPR(av);
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(AddressingMessages.FAULT_TO_CANNOT_PARSE(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return faultTo;
|
||||
}
|
||||
|
||||
public static String getMessageID(@NotNull MessageHeaders headers, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
Header h = getFirstHeader(headers, av.messageIDTag, true, sv);
|
||||
String messageId = null;
|
||||
if (h != null) {
|
||||
messageId = h.getStringContent();
|
||||
}
|
||||
|
||||
return messageId;
|
||||
}
|
||||
public static String getRelatesTo(@NotNull MessageHeaders headers, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
Header h = getFirstHeader(headers, av.relatesToTag, true, sv);
|
||||
String relatesTo = null;
|
||||
if (h != null) {
|
||||
relatesTo = h.getStringContent();
|
||||
}
|
||||
|
||||
return relatesTo;
|
||||
}
|
||||
public static WSEndpointReference getReplyTo(@NotNull MessageHeaders headers, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
Header h = getFirstHeader(headers, av.replyToTag, true, sv);
|
||||
WSEndpointReference replyTo;
|
||||
if (h != null) {
|
||||
try {
|
||||
replyTo = h.readAsEPR(av);
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(AddressingMessages.REPLY_TO_CANNOT_PARSE(), e);
|
||||
}
|
||||
} else {
|
||||
replyTo = av.anonymousEpr;
|
||||
}
|
||||
|
||||
return replyTo;
|
||||
}
|
||||
public static String getTo(MessageHeaders headers, AddressingVersion av, SOAPVersion sv) {
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
Header h = getFirstHeader(headers, av.toTag, true, sv);
|
||||
String to;
|
||||
if (h != null) {
|
||||
to = h.getStringContent();
|
||||
} else {
|
||||
to = av.anonymousUri;
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
public static Header getFirstHeader(MessageHeaders headers, QName name, boolean markUnderstood, SOAPVersion sv) {
|
||||
if (sv == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_SOAP_VERSION());
|
||||
}
|
||||
|
||||
Iterator<Header> iter = headers.getHeaders(name.getNamespaceURI(), name.getLocalPart(), markUnderstood);
|
||||
while (iter.hasNext()) {
|
||||
Header h = iter.next();
|
||||
if (h.getRole(sv).equals(sv.implicitRole)) {
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void fillRequestAddressingHeaders(@NotNull MessageHeaders headers, @NotNull Packet packet, @NotNull AddressingVersion av, @NotNull SOAPVersion sv, @NotNull OneWayFeature oneWayFeature, boolean oneway, @NotNull String action) {
|
||||
if (!oneway&&!oneWayFeature.isUseAsyncWithSyncInvoke() && Boolean.TRUE.equals(packet.isSynchronousMEP)) {
|
||||
fillRequestAddressingHeaders(headers, packet, av, sv, oneway, action);
|
||||
} else {
|
||||
fillCommonAddressingHeaders(headers, packet, av, sv, action, false);
|
||||
|
||||
boolean isMessageIdAdded = false;
|
||||
|
||||
// wsa:ReplyTo
|
||||
// add if it doesn't already exist and OneWayFeature requests a specific ReplyTo
|
||||
if (headers.get(av.replyToTag, false) == null) {
|
||||
WSEndpointReference replyToEpr = oneWayFeature.getReplyTo();
|
||||
if (replyToEpr != null) {
|
||||
headers.add(replyToEpr.createHeader(av.replyToTag));
|
||||
// add wsa:MessageID only for non-null ReplyTo
|
||||
if (packet.getMessage().getHeaders().get(av.messageIDTag, false) == null) {
|
||||
// if header doesn't exist, method getID creates a new random id
|
||||
String newID = oneWayFeature.getMessageId() == null ? Message.generateMessageID() : oneWayFeature.getMessageId();
|
||||
headers.add(new StringHeader(av.messageIDTag, newID));
|
||||
isMessageIdAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the user sets a messageId, use it.
|
||||
final String messageId = oneWayFeature.getMessageId();
|
||||
if (!isMessageIdAdded && messageId != null) {
|
||||
headers.add(new StringHeader(av.messageIDTag, messageId));
|
||||
}
|
||||
|
||||
// wsa:FaultTo
|
||||
// add if it doesn't already exist and OneWayFeature requests a specific FaultTo
|
||||
if (headers.get(av.faultToTag, false) == null) {
|
||||
WSEndpointReference faultToEpr = oneWayFeature.getFaultTo();
|
||||
if (faultToEpr != null) {
|
||||
headers.add(faultToEpr.createHeader(av.faultToTag));
|
||||
// add wsa:MessageID only for non-null FaultTo
|
||||
if (headers.get(av.messageIDTag, false) == null) {
|
||||
headers.add(new StringHeader(av.messageIDTag, Message.generateMessageID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wsa:From
|
||||
if (oneWayFeature.getFrom() != null) {
|
||||
headers.addOrReplace(oneWayFeature.getFrom().createHeader(av.fromTag));
|
||||
}
|
||||
|
||||
// wsa:RelatesTo
|
||||
if (oneWayFeature.getRelatesToID() != null) {
|
||||
headers.addOrReplace(new RelatesToHeader(av.relatesToTag, oneWayFeature.getRelatesToID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates wsa:To, wsa:Action and wsa:MessageID header on the client
|
||||
*
|
||||
* @param packet request packet
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @param action Action Message Addressing Property value
|
||||
* @throws IllegalArgumentException if any of the parameters is null.
|
||||
*/
|
||||
private static void fillCommonAddressingHeaders(MessageHeaders headers, Packet packet, @NotNull AddressingVersion av, @NotNull SOAPVersion sv, @NotNull String action, boolean mustUnderstand) {
|
||||
if (packet == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_PACKET());
|
||||
}
|
||||
|
||||
if (av == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ADDRESSING_VERSION());
|
||||
}
|
||||
|
||||
if (sv == null) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_SOAP_VERSION());
|
||||
}
|
||||
|
||||
if (action == null && !sv.httpBindingId.equals(SOAPBinding.SOAP12HTTP_BINDING)) {
|
||||
throw new IllegalArgumentException(AddressingMessages.NULL_ACTION());
|
||||
}
|
||||
|
||||
// wsa:To
|
||||
if (headers.get(av.toTag, false) == null) {
|
||||
StringHeader h = new StringHeader(av.toTag, packet.endpointAddress.toString());
|
||||
headers.add(h);
|
||||
}
|
||||
|
||||
// wsa:Action
|
||||
if (action != null) {
|
||||
packet.soapAction = action;
|
||||
if (headers.get(av.actionTag, false) == null) {
|
||||
//As per WS-I BP 1.2/2.0, if one of the WSA headers is MU, then all WSA headers should be treated as MU.,
|
||||
// so just set MU on action header
|
||||
StringHeader h = new StringHeader(av.actionTag, action, sv, mustUnderstand);
|
||||
headers.add(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
100
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Attachment.java
Normal file
100
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Attachment.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.transform.Source;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Attachment.
|
||||
*/
|
||||
public interface Attachment {
|
||||
|
||||
/**
|
||||
* Content ID of the attachment. Uniquely identifies an attachment.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc2392.txt (which is referred by the ws-i attachment profile
|
||||
* http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html)
|
||||
*
|
||||
* content-id = url-addr-spec
|
||||
* url-addr-spec = addr-spec ; URL encoding of RFC 822 addr-spec
|
||||
* cid-url = "cid" ":" content-id
|
||||
*
|
||||
* A "cid" URL is converted to the corresponding Content-ID message header [MIME] by
|
||||
* removing the "cid:" prefix, converting the % encoded character to their equivalent
|
||||
* US-ASCII characters, and enclosing the remaining parts with an angle bracket pair,
|
||||
* "<" and ">". For example, "cid:foo4%25foo1@bar.net" corresponds to
|
||||
* Content-ID: <foo4%25foo1@bar.net>
|
||||
*
|
||||
* @return
|
||||
* The content ID like "foo-bar-zot@abc.com", without
|
||||
* surrounding '<' and '>' used as the transfer syntax.
|
||||
*/
|
||||
@NotNull String getContentId();
|
||||
|
||||
/**
|
||||
* Gets the MIME content-type of this attachment.
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* Gets the attachment as an exact-length byte array.
|
||||
*/
|
||||
byte[] asByteArray();
|
||||
|
||||
/**
|
||||
* Gets the attachment as a {@link DataHandler}.
|
||||
*/
|
||||
DataHandler asDataHandler();
|
||||
|
||||
/**
|
||||
* Gets the attachment as a {@link Source}.
|
||||
* Note that there's no guarantee that the attachment is actually an XML.
|
||||
*/
|
||||
Source asSource();
|
||||
|
||||
/**
|
||||
* Obtains this attachment as an {@link InputStream}.
|
||||
*/
|
||||
InputStream asInputStream();
|
||||
|
||||
/**
|
||||
* Writes the contents of the attachment into the given stream.
|
||||
*/
|
||||
void writeTo(OutputStream os) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes this attachment to the given {@link SOAPMessage}.
|
||||
*/
|
||||
void writeTo(SOAPMessage saaj) throws SOAPException;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Attachment extended interface exposing custom MIME headers.
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public interface AttachmentEx extends Attachment {
|
||||
/**
|
||||
* MIME header
|
||||
*/
|
||||
public interface MimeHeader {
|
||||
/**
|
||||
* MIME header name
|
||||
* @return name
|
||||
*/
|
||||
public String getName();
|
||||
/**
|
||||
* MIME header value
|
||||
* @return value
|
||||
*/
|
||||
public String getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator of custom MIME headers associated with this attachment
|
||||
* @return MIME header iterator
|
||||
*/
|
||||
public @NotNull Iterator<MimeHeader> getMimeHeaders();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
|
||||
/**
|
||||
* A set of {@link Attachment} on a {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* A particular attention is made to ensure that attachments
|
||||
* can be read and parsed lazily as requested.
|
||||
*
|
||||
* @see Message#getAttachments()
|
||||
*/
|
||||
public interface AttachmentSet extends Iterable<Attachment> {
|
||||
/**
|
||||
* Gets the attachment by the content ID.
|
||||
*
|
||||
* @param contentId
|
||||
* The content ID like "foo-bar-zot@abc.com", without
|
||||
* surrounding '<' and '>' used as the transfer syntax.
|
||||
*
|
||||
* @return null
|
||||
* if no such attachment exist.
|
||||
*/
|
||||
@Nullable
|
||||
Attachment get(String contentId);
|
||||
|
||||
/**
|
||||
* Returns true if there's no attachment.
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Adds an attachment to this set.
|
||||
*
|
||||
* <p>
|
||||
* Note that it's OK for an {@link Attachment} to belong to
|
||||
* more than one {@link AttachmentSet} (which is in fact
|
||||
* necessary when you wrap a {@link Message} into another.
|
||||
*
|
||||
* @param att
|
||||
* must not be null.
|
||||
*/
|
||||
public void add(Attachment att);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.xml.internal.ws.util.exception.JAXWSExceptionBase;
|
||||
import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
|
||||
|
||||
/**
|
||||
* This class represents an Exception that needs to be marshalled
|
||||
* with a specific protocol wire format. For example, the SOAP's
|
||||
* VersionMismatchFault needs to be written with a correct fault code.
|
||||
* In that case, decoder could throw {@link VersionMismatchException},
|
||||
* and the corresponding fault {@link Message} from {@link ExceptionHasMessage#getFaultMessage()}
|
||||
* is sent on the wire.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class ExceptionHasMessage extends JAXWSExceptionBase {
|
||||
|
||||
public ExceptionHasMessage(String key, Object... args) {
|
||||
super(key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception into a fault Message
|
||||
*
|
||||
* @return Message for this exception
|
||||
*/
|
||||
public abstract Message getFaultMessage();
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
/**
|
||||
* A <code>FilterMessageImpl</code> contains some other Message, which it uses
|
||||
* as its basic source of message data, possibly transforming the data along
|
||||
* the way or providing additional functionality.
|
||||
*
|
||||
* <p>
|
||||
* The class <code>FilterMessageImpl</code> itself simply overrides
|
||||
* all the methods of <code>Message</code> and invokes them on
|
||||
* contained Message delegate. Subclasses of <code>FilterMessageImpl</code>
|
||||
* may further override some of these methods and may also provide
|
||||
* additional methods and fields.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class FilterMessageImpl extends Message {
|
||||
private final Message delegate;
|
||||
|
||||
protected FilterMessageImpl(Message delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public boolean hasHeaders() {
|
||||
return delegate.hasHeaders();
|
||||
}
|
||||
|
||||
public @NotNull MessageHeaders getHeaders() {
|
||||
return delegate.getHeaders();
|
||||
}
|
||||
|
||||
public @NotNull AttachmentSet getAttachments() {
|
||||
return delegate.getAttachments();
|
||||
}
|
||||
|
||||
protected boolean hasAttachments() {
|
||||
return delegate.hasAttachments();
|
||||
}
|
||||
|
||||
public boolean isOneWay(@NotNull WSDLPort port) {
|
||||
return delegate.isOneWay(port);
|
||||
}
|
||||
|
||||
public @Nullable String getPayloadLocalPart() {
|
||||
return delegate.getPayloadLocalPart();
|
||||
}
|
||||
|
||||
public String getPayloadNamespaceURI() {
|
||||
return delegate.getPayloadNamespaceURI();
|
||||
}
|
||||
|
||||
public boolean hasPayload() {
|
||||
return delegate.hasPayload();
|
||||
}
|
||||
|
||||
public boolean isFault() {
|
||||
return delegate.isFault();
|
||||
}
|
||||
|
||||
public @Nullable QName getFirstDetailEntryName() {
|
||||
return delegate.getFirstDetailEntryName();
|
||||
}
|
||||
|
||||
public Source readEnvelopeAsSource() {
|
||||
return delegate.readEnvelopeAsSource();
|
||||
}
|
||||
|
||||
public Source readPayloadAsSource() {
|
||||
return delegate.readPayloadAsSource();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage() throws SOAPException {
|
||||
return delegate.readAsSOAPMessage();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage(Packet packet, boolean inbound) throws SOAPException {
|
||||
return delegate.readAsSOAPMessage(packet, inbound);
|
||||
}
|
||||
|
||||
public <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
|
||||
return (T)delegate.readPayloadAsJAXB(unmarshaller);
|
||||
}
|
||||
/** @deprecated */
|
||||
public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
|
||||
return delegate.readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
public <T> T readPayloadAsJAXB(XMLBridge<T> bridge) throws JAXBException {
|
||||
return delegate.readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
public XMLStreamReader readPayload() throws XMLStreamException {
|
||||
return delegate.readPayload();
|
||||
}
|
||||
|
||||
public void consume() {
|
||||
delegate.consume();
|
||||
}
|
||||
|
||||
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
delegate.writePayloadTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
delegate.writeTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
|
||||
delegate.writeTo(contentHandler, errorHandler);
|
||||
}
|
||||
|
||||
public Message copy() {
|
||||
return delegate.copy();
|
||||
}
|
||||
|
||||
public @NotNull String getID(@NotNull WSBinding binding) {
|
||||
return delegate.getID(binding);
|
||||
}
|
||||
|
||||
public @NotNull String getID(AddressingVersion av, SOAPVersion sv) {
|
||||
return delegate.getID(av, sv);
|
||||
}
|
||||
|
||||
public SOAPVersion getSOAPVersion() {
|
||||
return delegate.getSOAPVersion();
|
||||
}
|
||||
}
|
||||
334
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Header.java
Normal file
334
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Header.java
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* A SOAP header.
|
||||
*
|
||||
* <p>
|
||||
* A header is immutable, but unlike body it can be read
|
||||
* multiple times.
|
||||
* The {@link Header} abstraction hides how the header
|
||||
* data is represented in memory; instead, it commits to
|
||||
* the ability to write itself to XML infoset.
|
||||
*
|
||||
* <p>
|
||||
* When a message is received from the transport and
|
||||
* being processed, the processor needs to "peek"
|
||||
* some information of a header, such as the tag name,
|
||||
* the mustUnderstand attribute, and so on. Therefore,
|
||||
* the {@link Header} interface exposes those information
|
||||
* as properties, so that they can be checked without
|
||||
* replaying the infoset, which is efficiently but still
|
||||
* costly.
|
||||
*
|
||||
* <p>
|
||||
* A {@link Header} may belong to more than one {@link HeaderList}
|
||||
* due to wrapping of {@link Message}.
|
||||
*
|
||||
* @see HeaderList
|
||||
* @see Headers
|
||||
*/
|
||||
public interface Header {
|
||||
// TODO: Vivek pointed out that the only time we are looking at
|
||||
// mustUnderstand and role are when we do the mustUnderstand error check
|
||||
// (that is, to find out if there's any header with @mustUnderstand that
|
||||
// has appropriate role for us.)
|
||||
// if that's the case, it might be better if we define this whole operation
|
||||
// as one method, instead of exposing two properties.
|
||||
|
||||
/**
|
||||
* Checks if this header is ignorable for us (IOW, make sure
|
||||
* that this header has a problematic "mustUnderstand" header value
|
||||
* that we have to reject.)
|
||||
*
|
||||
* <p>
|
||||
* This method is used as a part of the
|
||||
* <a href="HeaderList.html#MU">mustUnderstanx processing</a>.
|
||||
* At the end of the processing, the JAX-WS identifies a list of {@link Header}s
|
||||
* that were not understood. This method is invoked on those {@link Header}s,
|
||||
* to verify that we don't need to report an error for it.
|
||||
*
|
||||
* <p>
|
||||
* specifically, this method has to perform the following tasks:
|
||||
*
|
||||
* <ul>
|
||||
* <li>If this header does not have <tt>mustUnderstand</tt> as "1" nor "true",
|
||||
* then this method must return true.
|
||||
* <li>Otherwise, check the role attribute (for SOAP 1.2) or the actor attribute (for SOAP 1.1).
|
||||
* When those attributes are absent, the default values have to be assumed.
|
||||
* See {@link #getRole(SOAPVersion)} for how the values are defaulted.
|
||||
* Now, see if the {@code roles} set contains the value.
|
||||
* If so, this method must return false (indicating that an error is in order.)
|
||||
* <li>Otherwise return true (since we don't play the role this header is intended for.)
|
||||
* </ul>
|
||||
*
|
||||
* @param soapVersion
|
||||
* The caller specifies the SOAP version that the pipeline is working against.
|
||||
* Often each {@link Header} implementation already knows the SOAP version
|
||||
* anyway, but this allows some {@link Header}s to avoid keeping it.
|
||||
* That's why this redundant parameter is passed in.
|
||||
* @param roles
|
||||
* The set of role values that the current JAX-WS pipeline is assuming.
|
||||
* Note that SOAP 1.1 and SOAP 1.2 use different strings for the same role,
|
||||
* and the caller is responsible for supplying a proper value depending on the
|
||||
* active SOAP version in use.
|
||||
*
|
||||
* @return
|
||||
* true if no error needs to be reported. False if an error needs to be raised.
|
||||
* See the method javadoc for more discussion.
|
||||
*/
|
||||
public boolean isIgnorable(@NotNull SOAPVersion soapVersion, @NotNull Set<String> roles);
|
||||
|
||||
/**
|
||||
* Gets the value of the soap:role attribute (or soap:actor for SOAP 1.1).
|
||||
*
|
||||
* <p>
|
||||
* If the attribute is omitted, the value defaults to {@link SOAPVersion#implicitRole}.
|
||||
*
|
||||
* @param soapVersion
|
||||
* The caller specifies the SOAP version that the pipeline is working against.
|
||||
* Often each {@link Header} implementation already knows the SOAP version
|
||||
* anyway, but this allows some {@link Header}s to avoid keeping it.
|
||||
* That's why this redundant parameter is passed in.
|
||||
* @return
|
||||
* never null. This string need not be interned.
|
||||
*/
|
||||
public @NotNull String getRole(@NotNull SOAPVersion soapVersion);
|
||||
|
||||
/**
|
||||
* True if this header is to be relayed if not processed.
|
||||
* For SOAP 1.1 messages, this method always return false.
|
||||
*
|
||||
* <p>
|
||||
* IOW, this method returns true if there's @soap:relay='true'
|
||||
* is present.
|
||||
*
|
||||
* <h3>Implementation Note</h3>
|
||||
* <p>
|
||||
* The implementation needs to check for both "true" and "1",
|
||||
* but because attribute values are normalized, it doesn't have
|
||||
* to consider " true", " 1 ", and so on.
|
||||
*
|
||||
* @return
|
||||
* false.
|
||||
*/
|
||||
public boolean isRelay();
|
||||
|
||||
/**
|
||||
* Gets the namespace URI of this header element.
|
||||
*
|
||||
* @return
|
||||
* this string must be interned.
|
||||
*/
|
||||
public @NotNull String getNamespaceURI();
|
||||
|
||||
/**
|
||||
* Gets the local name of this header element.
|
||||
*
|
||||
* @return
|
||||
* this string must be interned.
|
||||
*/
|
||||
public @NotNull String getLocalPart();
|
||||
|
||||
/**
|
||||
* Gets the attribute value on the header element.
|
||||
*
|
||||
* @param nsUri
|
||||
* The namespace URI of the attribute. Can be empty.
|
||||
* @param localName
|
||||
* The local name of the attribute.
|
||||
*
|
||||
* @return
|
||||
* if the attribute is found, return the whitespace normalized value.
|
||||
* (meaning no leading/trailing space, no consequtive whitespaces in-between.)
|
||||
* Otherwise null. Note that the XML parsers are responsible for
|
||||
* whitespace-normalizing attributes, so {@link Header} implementation
|
||||
* doesn't have to do anything.
|
||||
*/
|
||||
@Nullable String getAttribute(@NotNull String nsUri, @NotNull String localName);
|
||||
|
||||
/**
|
||||
* Gets the attribute value on the header element.
|
||||
*
|
||||
* <p>
|
||||
* This is a convenience method that calls into {@link #getAttribute(String, String)}
|
||||
*
|
||||
* @param name
|
||||
* Never null.
|
||||
*
|
||||
* @see #getAttribute(String, String)
|
||||
*/
|
||||
@Nullable String getAttribute(@NotNull QName name);
|
||||
|
||||
/**
|
||||
* Reads the header as a {@link XMLStreamReader}.
|
||||
*
|
||||
* <p>
|
||||
* The returned parser points at the start element of this header.
|
||||
* (IOW, {@link XMLStreamReader#getEventType()} would return
|
||||
* {@link XMLStreamReader#START_ELEMENT}.
|
||||
*
|
||||
* <h3>Performance Expectation</h3>
|
||||
* <p>
|
||||
* For some {@link Header} implementations, this operation
|
||||
* is a non-trivial operation. Therefore, use of this method
|
||||
* is discouraged unless the caller is interested in reading
|
||||
* the whole header.
|
||||
*
|
||||
* <p>
|
||||
* Similarly, if the caller wants to use this method only to do
|
||||
* the API conversion (such as simply firing SAX events from
|
||||
* {@link XMLStreamReader}), then the JAX-WS team requests
|
||||
* that you talk to us.
|
||||
*
|
||||
* <p>
|
||||
* {@link Message}s that come from tranport usually provides
|
||||
* a reasonably efficient implementation of this method.
|
||||
*
|
||||
* @return
|
||||
* must not null.
|
||||
*/
|
||||
public XMLStreamReader readHeader() throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Reads the header as a JAXB object by using the given unmarshaller.
|
||||
*/
|
||||
public <T> T readAsJAXB(Unmarshaller unmarshaller) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads the header as a JAXB object by using the given unmarshaller.
|
||||
* @deprecated
|
||||
*/
|
||||
public <T> T readAsJAXB(Bridge<T> bridge) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads the header as a data-bond object
|
||||
*/
|
||||
public <T> T readAsJAXB(XMLBridge<T> bridge) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads this header as an {@link WSEndpointReference}.
|
||||
*
|
||||
* @param expected
|
||||
* The version of the addressing used to parse the EPR.
|
||||
* If the actual infoset and this doesn't agree, then
|
||||
* you'll get an {@link WebServiceException} stating that fact.
|
||||
*
|
||||
* @return
|
||||
* On a successful return, this method never returns null.
|
||||
*/
|
||||
public @NotNull WSEndpointReference readAsEPR(AddressingVersion expected) throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Writes out the header as a fragment.
|
||||
*
|
||||
* @throws XMLStreamException
|
||||
* if the operation fails for some reason. This leaves the
|
||||
* writer to an undefined state.
|
||||
*/
|
||||
public void writeTo(XMLStreamWriter w) throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Writes out the header to the given SOAPMessage.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes a {@link Message} needs to produce itself
|
||||
* as {@link SOAPMessage}, in which case each header needs
|
||||
* to turn itself into a header.
|
||||
*
|
||||
* @throws SOAPException
|
||||
* if the operation fails for some reason. This leaves the
|
||||
* writer to an undefined state.
|
||||
*/
|
||||
public void writeTo(SOAPMessage saaj) throws SOAPException;
|
||||
|
||||
/**
|
||||
* Writes out the header as SAX events.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes a {@link Message} needs to produce SAX events,
|
||||
* and this method is necessary for headers to participate to it.
|
||||
*
|
||||
* <p>
|
||||
* A header is responsible for producing the SAX events for its part,
|
||||
* including <tt>startPrefixMapping</tt> and <tt>endPrefixMapping</tt>,
|
||||
* but not startDocument/endDocument.
|
||||
*
|
||||
* <p>
|
||||
* Note that SAX contract requires that any error that does NOT originate
|
||||
* from {@link ContentHandler} (meaning any parsing error and etc) must
|
||||
* be first reported to {@link ErrorHandler}. If the SAX event production
|
||||
* cannot be continued and the processing needs to abort, the code may
|
||||
* then throw the same {@link SAXParseException} reported to {@link ErrorHandler}.
|
||||
*
|
||||
* @param contentHandler
|
||||
* The {@link ContentHandler} that receives SAX events.
|
||||
*
|
||||
* @param errorHandler
|
||||
* The {@link ErrorHandler} that receives parsing errors.
|
||||
*/
|
||||
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException;
|
||||
|
||||
/**
|
||||
* Used to obtain value XYZ from a header that looks like
|
||||
* "<header>XYZ</header>". The primary use of this header
|
||||
* for now is to access certain Addressing headers quickly.
|
||||
*
|
||||
* @throws WebServiceException
|
||||
* If the structure of the header is more complicated than
|
||||
* a simple string header.
|
||||
*
|
||||
* @return
|
||||
* Can be empty but always non-null.
|
||||
*/
|
||||
public @NotNull String getStringContent();
|
||||
}
|
||||
976
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/HeaderList.java
Normal file
976
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/HeaderList.java
Normal file
@@ -0,0 +1,976 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.Pipe;
|
||||
import com.sun.xml.internal.ws.binding.SOAPBindingImpl;
|
||||
import com.sun.xml.internal.ws.protocol.soap.ClientMUTube;
|
||||
import com.sun.xml.internal.ws.protocol.soap.ServerMUTube;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A list of {@link Header}s on a {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* This list can be modified to add headers
|
||||
* from outside a {@link Message}, this is necessary
|
||||
* since intermediate processing layers often need to
|
||||
* put additional headers.
|
||||
*
|
||||
* <p>
|
||||
* Following the SOAP convention, the order among headers
|
||||
* are not significant. However, {@link Codec}s are
|
||||
* expected to preserve the order of headers in the input
|
||||
* message as much as possible.
|
||||
*
|
||||
*
|
||||
* <a name="MU"></a>
|
||||
* <h3>MustUnderstand Processing</h3>
|
||||
* <p>
|
||||
* To perform SOAP mustUnderstang processing correctly, we need to keep
|
||||
* track of headers that are understood and headers that are not.
|
||||
* This is a collaborative process among {@link Pipe}s, thus it's something
|
||||
* a {@link Pipe} author needs to keep in mind.
|
||||
*
|
||||
* <p>
|
||||
* Specifically, when a {@link Pipe} sees a header and processes it
|
||||
* (that is, if it did enough computing with the header to claim that
|
||||
* the header is understood), then it should mark the corresponding
|
||||
* header as "understood". For example, when a pipe that handles JAX-WSA
|
||||
* examins the <wsa:To> header, it can claim that it understood the header.
|
||||
* But for example, if a pipe that does the signature verification checks
|
||||
* <wsa:To> for a signature, that would not be considered as "understood".
|
||||
*
|
||||
* <p>
|
||||
* There are two ways to mark a header as understood:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Use one of the <tt>getXXX</tt> methods that take a
|
||||
* boolean <tt>markAsUnderstood</tt> parameter.
|
||||
* Most often, a {@link Pipe} knows it's going to understand a header
|
||||
* as long as it's present, so this is the easiest and thus the preferred way.
|
||||
*
|
||||
* For example, if JAX-WSA looks for <wsa:To>, then it can set
|
||||
* <tt>markAsUnderstand</tt> to true, to do the obtaining of a header
|
||||
* and marking at the same time.
|
||||
*
|
||||
* <li>Call {@link #understood(int)}.
|
||||
* If under a rare circumstance, a pipe cannot determine whether
|
||||
* it can understand it or not when you are fetching a header, then
|
||||
* you can use this method afterward to mark it as understood.
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* Intuitively speaking, at the end of the day, if a header is not
|
||||
* understood but {@link Header#isIgnorable(SOAPVersion, java.util.Set)} is false, a bad thing
|
||||
* will happen. The actual implementation of the checking is more complicated,
|
||||
* for that see {@link ClientMUTube}/{@link ServerMUTube}.
|
||||
*
|
||||
* @see Message#getHeaders()
|
||||
*/
|
||||
public class HeaderList extends ArrayList<Header> implements MessageHeaders {
|
||||
|
||||
private static final long serialVersionUID = -6358045781349627237L;
|
||||
/**
|
||||
* Bit set to keep track of which headers are understood.
|
||||
* <p>
|
||||
* The first 32 headers use this field, and the rest will use
|
||||
* {@link #moreUnderstoodBits}. The expectation is that
|
||||
* most of the time a SOAP message will only have up to 32 headers,
|
||||
* so we can avoid allocating separate objects for {@link BitSet}.
|
||||
*/
|
||||
private int understoodBits;
|
||||
/**
|
||||
* If there are more than 32 headers, we use this {@link BitSet}
|
||||
* to keep track of whether those headers are understood.
|
||||
* Lazily allocated.
|
||||
*/
|
||||
private BitSet moreUnderstoodBits = null;
|
||||
|
||||
private SOAPVersion soapVersion;
|
||||
|
||||
/**
|
||||
* This method is deprecated - instead use this one:
|
||||
* public HeaderList(SOAPVersion)
|
||||
* Creates an empty {@link HeaderList}.
|
||||
*/
|
||||
@Deprecated
|
||||
public HeaderList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty {@link HeaderList} with the given soap version
|
||||
* @param soapVersion
|
||||
*/
|
||||
public HeaderList(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
public HeaderList(HeaderList that) {
|
||||
super(that);
|
||||
this.understoodBits = that.understoodBits;
|
||||
if (that.moreUnderstoodBits != null) {
|
||||
this.moreUnderstoodBits = (BitSet) that.moreUnderstoodBits.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public HeaderList(MessageHeaders that) {
|
||||
super(that.asList());
|
||||
if (that instanceof HeaderList) {
|
||||
HeaderList hThat = (HeaderList) that;
|
||||
this.understoodBits = hThat.understoodBits;
|
||||
if (hThat.moreUnderstoodBits != null) {
|
||||
this.moreUnderstoodBits = (BitSet) hThat.moreUnderstoodBits.clone();
|
||||
}
|
||||
} else {
|
||||
Set<QName> understood = that.getUnderstoodHeaders();
|
||||
if (understood != null) {
|
||||
for (QName qname : understood) {
|
||||
understood(qname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of headers.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return super.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHeaders() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all the headers.
|
||||
* @deprecated throws UnsupportedOperationException from some HeaderList implementations - better iterate over items one by one
|
||||
*/
|
||||
@Deprecated
|
||||
public void addAll(Header... headers) {
|
||||
addAll(Arrays.asList(headers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Header} at the specified index.
|
||||
*
|
||||
* <p>
|
||||
* This method does not mark the returned {@link Header} as understood.
|
||||
*
|
||||
* @see #understood(int)
|
||||
*/
|
||||
@Override
|
||||
public Header get(int index) {
|
||||
return super.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the {@link Header} at the specified index as
|
||||
* <a href="#MU">"understood"</a>.
|
||||
*/
|
||||
public void understood(int index) {
|
||||
// check that index is in range
|
||||
if (index >= size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
|
||||
if (index < 32) {
|
||||
understoodBits |= 1 << index;
|
||||
} else {
|
||||
if (moreUnderstoodBits == null) {
|
||||
moreUnderstoodBits = new BitSet();
|
||||
}
|
||||
moreUnderstoodBits.set(index - 32);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a {@link Header} at the given index
|
||||
* was <a href="#MU">"understood"</a>.
|
||||
*/
|
||||
public boolean isUnderstood(int index) {
|
||||
// check that index is in range
|
||||
if (index >= size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
|
||||
if (index < 32) {
|
||||
return understoodBits == (understoodBits | (1 << index));
|
||||
} else {
|
||||
if (moreUnderstoodBits == null) {
|
||||
return false;
|
||||
}
|
||||
return moreUnderstoodBits.get(index - 32);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the specified {@link Header} as <a href="#MU">"understood"</a>.
|
||||
*
|
||||
* @deprecated
|
||||
* By the definition of {@link ArrayList}, this operation requires
|
||||
* O(n) search of the array, and thus inherently inefficient.
|
||||
*
|
||||
* Because of this, if you are developing a {@link Pipe} for
|
||||
* a performance sensitive environment, do not use this method.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the given header is not {@link #contains(Object) contained}
|
||||
* in this header.
|
||||
*/
|
||||
@Override
|
||||
public void understood(@NotNull Header header) {
|
||||
int sz = size();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
if (get(i) == header) {
|
||||
understood(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first {@link Header} of the specified name.
|
||||
*
|
||||
* @param markAsUnderstood
|
||||
* If this parameter is true, the returned header will
|
||||
* be marked as <a href="#MU">"understood"</a>.
|
||||
* @return null if not found.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable Header get(@NotNull String nsUri, @NotNull String localName, boolean markAsUnderstood) {
|
||||
int len = size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Header h = get(i);
|
||||
if (h.getLocalPart().equals(localName) && h.getNamespaceURI().equals(nsUri)) {
|
||||
if (markAsUnderstood) {
|
||||
understood(i);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #get(String, String, boolean)}
|
||||
*/
|
||||
public Header get(String nsUri, String localName) {
|
||||
return get(nsUri, localName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first {@link Header} of the specified name.
|
||||
*
|
||||
* @param markAsUnderstood
|
||||
* If this parameter is true, the returned header will
|
||||
* be marked as <a href="#MU">"understood"</a>.
|
||||
* @return null
|
||||
* if not found.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable Header get(@NotNull QName name, boolean markAsUnderstood) {
|
||||
return get(name.getNamespaceURI(), name.getLocalPart(), markAsUnderstood);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #get(QName)}
|
||||
*/
|
||||
public
|
||||
@Nullable
|
||||
Header get(@NotNull QName name) {
|
||||
return get(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #getHeaders(String, String, boolean)}
|
||||
*/
|
||||
public Iterator<Header> getHeaders(final String nsUri, final String localName) {
|
||||
return getHeaders(nsUri, localName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the {@link Header}s of the specified name,
|
||||
* including duplicates (if any.)
|
||||
*
|
||||
* @param markAsUnderstood
|
||||
* If this parameter is true, the returned headers will
|
||||
* be marked as <a href="#MU">"understood"</a> when they are returned
|
||||
* from {@link Iterator#next()}.
|
||||
* @return empty iterator if not found.
|
||||
*/
|
||||
public
|
||||
@NotNull
|
||||
@Override
|
||||
Iterator<Header> getHeaders(@NotNull final String nsUri, @NotNull final String localName, final boolean markAsUnderstood) {
|
||||
return new Iterator<Header>() {
|
||||
|
||||
int idx = 0;
|
||||
Header next;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (next == null) {
|
||||
fetch();
|
||||
}
|
||||
return next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header next() {
|
||||
if (next == null) {
|
||||
fetch();
|
||||
if (next == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
if (markAsUnderstood) {
|
||||
assert get(idx - 1) == next;
|
||||
understood(idx - 1);
|
||||
}
|
||||
|
||||
Header r = next;
|
||||
next = null;
|
||||
return r;
|
||||
}
|
||||
|
||||
private void fetch() {
|
||||
while (idx < size()) {
|
||||
Header h = get(idx++);
|
||||
if (h.getLocalPart().equals(localName) && h.getNamespaceURI().equals(nsUri)) {
|
||||
next = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getHeaders(String, String, boolean)
|
||||
*/
|
||||
public
|
||||
@NotNull
|
||||
@Override
|
||||
Iterator<Header> getHeaders(@NotNull QName headerName, final boolean markAsUnderstood) {
|
||||
return getHeaders(headerName.getNamespaceURI(), headerName.getLocalPart(), markAsUnderstood);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use {@link #getHeaders(String, boolean)}.
|
||||
*/
|
||||
public
|
||||
@NotNull
|
||||
Iterator<Header> getHeaders(@NotNull final String nsUri) {
|
||||
return getHeaders(nsUri, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an iteration of headers {@link Header} in the specified namespace,
|
||||
* including duplicates (if any.)
|
||||
*
|
||||
* @param markAsUnderstood
|
||||
* If this parameter is true, the returned headers will
|
||||
* be marked as <a href="#MU">"understood"</a> when they are returned
|
||||
* from {@link Iterator#next()}.
|
||||
* @return
|
||||
* empty iterator if not found.
|
||||
*/
|
||||
public
|
||||
@NotNull
|
||||
@Override
|
||||
Iterator<Header> getHeaders(@NotNull final String nsUri, final boolean markAsUnderstood) {
|
||||
return new Iterator<Header>() {
|
||||
|
||||
int idx = 0;
|
||||
Header next;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (next == null) {
|
||||
fetch();
|
||||
}
|
||||
return next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header next() {
|
||||
if (next == null) {
|
||||
fetch();
|
||||
if (next == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
if (markAsUnderstood) {
|
||||
assert get(idx - 1) == next;
|
||||
understood(idx - 1);
|
||||
}
|
||||
|
||||
Header r = next;
|
||||
next = null;
|
||||
return r;
|
||||
}
|
||||
|
||||
private void fetch() {
|
||||
while (idx < size()) {
|
||||
Header h = get(idx++);
|
||||
if (h.getNamespaceURI().equals(nsUri)) {
|
||||
next = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>To</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>To</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing To header, anonymous URI if no header is present
|
||||
*/
|
||||
public String getTo(AddressingVersion av, SOAPVersion sv) {
|
||||
return AddressingUtils.getTo(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>Action</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>Action</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing Action header, null if no header is present
|
||||
*/
|
||||
public String getAction(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
return AddressingUtils.getAction(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>ReplyTo</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>ReplyTo</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing ReplyTo header, null if no header is present
|
||||
*/
|
||||
public WSEndpointReference getReplyTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
return AddressingUtils.getReplyTo(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>FaultTo</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>FaultTo</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws IllegalArgumentException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing FaultTo header, null if no header is present
|
||||
*/
|
||||
public WSEndpointReference getFaultTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
return AddressingUtils.getFaultTo(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>MessageID</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>MessageID</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws WebServiceException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing MessageID header, null if no header is present
|
||||
*/
|
||||
public String getMessageID(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
return AddressingUtils.getMessageID(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of WS-Addressing <code>RelatesTo</code> header. The <code>version</code>
|
||||
* identifies the WS-Addressing version and the header returned is targeted at
|
||||
* the current implicit role. Caches the value for subsequent invocation.
|
||||
* Duplicate <code>RelatesTo</code> headers are detected earlier.
|
||||
*
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @throws WebServiceException if either <code>av</code> or <code>sv</code> is null.
|
||||
* @return Value of WS-Addressing RelatesTo header, null if no header is present
|
||||
*/
|
||||
public String getRelatesTo(@NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
return AddressingUtils.getRelatesTo(this, av, sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a set of outbound WS-Addressing headers on the client with the
|
||||
* specified Action Message Addressing Property value.
|
||||
* <p><p>
|
||||
* This method needs to be invoked right after such a Message is
|
||||
* created which is error prone but so far only MEX, RM and JAX-WS
|
||||
* creates a request so this ugliness is acceptable. This method is also used
|
||||
* to create protocol messages that are not associated with any {@link WSBinding}
|
||||
* and {@link WSDLPort}.
|
||||
*
|
||||
* @param packet request packet
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @param oneway Indicates if the message exchange pattern is oneway
|
||||
* @param action Action Message Addressing Property value
|
||||
* @param mustUnderstand to indicate if the addressing headers are set with mustUnderstand attribute
|
||||
*/
|
||||
public void fillRequestAddressingHeaders(Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action, boolean mustUnderstand) {
|
||||
AddressingUtils.fillRequestAddressingHeaders(this, packet, av, sv, oneway, action, mustUnderstand);
|
||||
}
|
||||
|
||||
public void fillRequestAddressingHeaders(Packet packet, AddressingVersion av, SOAPVersion sv, boolean oneway, String action) {
|
||||
AddressingUtils.fillRequestAddressingHeaders(this, packet, av, sv, oneway, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a set of outbound WS-Addressing headers on the client with the
|
||||
* default Action Message Addressing Property value.
|
||||
* <p><p>
|
||||
* This method needs to be invoked right after such a Message is
|
||||
* created which is error prone but so far only MEX, RM and JAX-WS
|
||||
* creates a request so this ugliness is acceptable. If more components
|
||||
* are identified using this, then we may revisit this.
|
||||
* <p><p>
|
||||
* This method is used if default Action Message Addressing Property is to
|
||||
* be used. See
|
||||
* {@link #fillRequestAddressingHeaders(Packet, com.sun.xml.internal.ws.api.addressing.AddressingVersion, com.sun.xml.internal.ws.api.SOAPVersion, boolean, String)}
|
||||
* if non-default Action is to be used, for example when creating a protocol message not
|
||||
* associated with {@link WSBinding} and {@link WSDLPort}.
|
||||
* This method uses SOAPAction as the Action unless set expplicitly in the wsdl.
|
||||
* @param wsdlPort request WSDL port
|
||||
* @param binding request WSBinding
|
||||
* @param packet request packet
|
||||
*/
|
||||
public void fillRequestAddressingHeaders(WSDLPort wsdlPort, @NotNull WSBinding binding, Packet packet) {
|
||||
AddressingUtils.fillRequestAddressingHeaders(this, wsdlPort, binding, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new {@link Header}.
|
||||
*
|
||||
* <p>
|
||||
* Order doesn't matter in headers, so this method
|
||||
* does not make any guarantee as to where the new header
|
||||
* is inserted.
|
||||
*
|
||||
* @return
|
||||
* always true. Don't use the return value.
|
||||
*/
|
||||
@Override
|
||||
public boolean add(Header header) {
|
||||
return super.add(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first {@link Header} of the specified name.
|
||||
* @param nsUri namespace URI of the header to remove
|
||||
* @param localName local part of the FQN of the header to remove
|
||||
*
|
||||
* @return null if not found.
|
||||
*/
|
||||
public
|
||||
@Nullable
|
||||
@Override
|
||||
Header remove(@NotNull String nsUri, @NotNull String localName) {
|
||||
int len = size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Header h = get(i);
|
||||
if (h.getLocalPart().equals(localName) && h.getNamespaceURI().equals(nsUri)) {
|
||||
return remove(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an existing {@link Header} or adds a new {@link Header}.
|
||||
*
|
||||
* <p>
|
||||
* Order doesn't matter in headers, so this method
|
||||
* does not make any guarantee as to where the new header
|
||||
* is inserted.
|
||||
*
|
||||
* @return
|
||||
* always true. Don't use the return value.
|
||||
*/
|
||||
@Override
|
||||
public boolean addOrReplace(Header header) {
|
||||
for (int i=0; i < size(); i++) {
|
||||
Header hdr = get(i);
|
||||
if (hdr.getNamespaceURI().equals(header.getNamespaceURI()) &&
|
||||
hdr.getLocalPart().equals(header.getLocalPart())) {
|
||||
// Put the new header in the old position. Call super versions
|
||||
// internally to avoid UnsupportedOperationException
|
||||
removeInternal(i);
|
||||
addInternal(i, header);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return add(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(Header old, Header header) {
|
||||
for (int i=0; i < size(); i++) {
|
||||
Header hdr = get(i);
|
||||
if (hdr.getNamespaceURI().equals(header.getNamespaceURI()) &&
|
||||
hdr.getLocalPart().equals(header.getLocalPart())) {
|
||||
// Put the new header in the old position. Call super versions
|
||||
// internally to avoid UnsupportedOperationException
|
||||
removeInternal(i);
|
||||
addInternal(i, header);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
protected void addInternal(int index, Header header) {
|
||||
super.add(index, header);
|
||||
}
|
||||
|
||||
protected Header removeInternal(int index) {
|
||||
return super.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first {@link Header} of the specified name.
|
||||
*
|
||||
* @param name fully qualified name of the header to remove
|
||||
*
|
||||
* @return null if not found.
|
||||
*/
|
||||
public
|
||||
@Nullable
|
||||
@Override
|
||||
Header remove(@NotNull QName name) {
|
||||
return remove(name.getNamespaceURI(), name.getLocalPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first {@link Header} of the specified name.
|
||||
*
|
||||
* @param index index of the header to remove
|
||||
*
|
||||
* @return removed header
|
||||
*/
|
||||
@Override
|
||||
public Header remove(int index) {
|
||||
removeUnderstoodBit(index);
|
||||
return super.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "understood" bit for header on the position specified by {@code index} parameter
|
||||
* from the set of understood header bits.
|
||||
*
|
||||
* @param index position of the bit to remove
|
||||
*/
|
||||
private void removeUnderstoodBit(int index) {
|
||||
assert index < size();
|
||||
|
||||
if (index < 32) {
|
||||
/**
|
||||
* Let
|
||||
* R be the bit to be removed
|
||||
* M be a more significant "upper" bit than bit R
|
||||
* L be a less significant "lower" bit than bit R
|
||||
*
|
||||
* Then following 3 lines of code produce these results:
|
||||
*
|
||||
* old understoodBits = MMMMMMMMMMMMRLLLLLLLLLLLLLLLLLLL
|
||||
*
|
||||
* shiftedUpperBits = 0MMMMMMMMMMMM0000000000000000000
|
||||
*
|
||||
* lowerBits = 0000000000000LLLLLLLLLLLLLLLLLLL
|
||||
*
|
||||
* new understoodBits = 0MMMMMMMMMMMMLLLLLLLLLLLLLLLLLLL
|
||||
*
|
||||
* The R bit is removed and all the upper bits are shifted right (unsigned)
|
||||
*/
|
||||
int shiftedUpperBits = understoodBits >>> -31 + index << index;
|
||||
int lowerBits = understoodBits << -index >>> 31 - index >>> 1;
|
||||
understoodBits = shiftedUpperBits | lowerBits;
|
||||
|
||||
if (moreUnderstoodBits != null && moreUnderstoodBits.cardinality() > 0) {
|
||||
if (moreUnderstoodBits.get(0)) {
|
||||
understoodBits |= 0x80000000;
|
||||
}
|
||||
|
||||
moreUnderstoodBits.clear(0);
|
||||
for (int i = moreUnderstoodBits.nextSetBit(1); i > 0; i = moreUnderstoodBits.nextSetBit(i + 1)) {
|
||||
moreUnderstoodBits.set(i - 1);
|
||||
moreUnderstoodBits.clear(i);
|
||||
}
|
||||
}
|
||||
} else if (moreUnderstoodBits != null && moreUnderstoodBits.cardinality() > 0) {
|
||||
index -= 32;
|
||||
moreUnderstoodBits.clear(index);
|
||||
for (int i = moreUnderstoodBits.nextSetBit(index); i >= 1; i = moreUnderstoodBits.nextSetBit(i + 1)) {
|
||||
moreUnderstoodBits.set(i - 1);
|
||||
moreUnderstoodBits.clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
// remove bit set if the new size will be < 33 => we fit all bits into int
|
||||
if (size() - 1 <= 33 && moreUnderstoodBits != null) {
|
||||
moreUnderstoodBits = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this
|
||||
* header list, if it is present. More formally,
|
||||
* removes a header <tt>h</tt> such that <tt>(o==null ? h==null :
|
||||
* o.equals(h))</tt>, if the header list contains one or more such
|
||||
* headers. Returns <tt>true</tt> if the list contained the
|
||||
* specified element (or equivalently, if the list changed as a
|
||||
* result of the call).<p>
|
||||
*
|
||||
* @param o element to be removed from this list, if present.
|
||||
* @return <tt>true</tt> if the list contained the specified element.
|
||||
* @see #remove(javax.xml.namespace.QName)
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
if (o != null) {
|
||||
for (int index = 0; index < this.size(); index++) {
|
||||
if (o.equals(this.get(index))) {
|
||||
remove(index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Header remove(Header h) {
|
||||
if (remove((Object) h)) {
|
||||
return h;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy.
|
||||
*
|
||||
* This handles null {@link HeaderList} correctly.
|
||||
*
|
||||
* @param original
|
||||
* Can be null, in which case null will be returned.
|
||||
*/
|
||||
public static HeaderList copy(MessageHeaders original) {
|
||||
if (original == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new HeaderList(original);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy.
|
||||
*
|
||||
* This handles null {@link HeaderList} correctly.
|
||||
*
|
||||
* @param original
|
||||
* Can be null, in which case null will be returned.
|
||||
*/
|
||||
public static HeaderList copy(HeaderList original) {
|
||||
return copy((MessageHeaders) original);
|
||||
}
|
||||
|
||||
public void readResponseAddressingHeaders(WSDLPort wsdlPort, WSBinding binding) {
|
||||
// read Action
|
||||
// String wsaAction = getAction(binding.getAddressingVersion(), binding.getSOAPVersion());
|
||||
// TODO: validate client-inbound Action
|
||||
}
|
||||
|
||||
@Override
|
||||
public void understood(QName name) {
|
||||
get(name, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void understood(String nsUri, String localName) {
|
||||
get(nsUri, localName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getUnderstoodHeaders() {
|
||||
Set<QName> understoodHdrs = new HashSet<QName>();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (isUnderstood(i)) {
|
||||
Header header = get(i);
|
||||
understoodHdrs.add(new QName(header.getNamespaceURI(), header.getLocalPart()));
|
||||
}
|
||||
}
|
||||
return understoodHdrs;
|
||||
// throw new UnsupportedOperationException("getUnderstoodHeaders() is not implemented by HeaderList");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnderstood(Header header) {
|
||||
return isUnderstood(header.getNamespaceURI(), header.getLocalPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnderstood(String nsUri, String localName) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Header h = get(i);
|
||||
if (h.getLocalPart().equals(localName) && h.getNamespaceURI().equals(nsUri)) {
|
||||
return isUnderstood(i);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnderstood(QName name) {
|
||||
return isUnderstood(name.getNamespaceURI(), name.getLocalPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getNotUnderstoodHeaders(Set<String> roles, Set<QName> knownHeaders, WSBinding binding) {
|
||||
Set<QName> notUnderstoodHeaders = null;
|
||||
if (roles == null) {
|
||||
roles = new HashSet<String>();
|
||||
}
|
||||
SOAPVersion effectiveSoapVersion = getEffectiveSOAPVersion(binding);
|
||||
roles.add(effectiveSoapVersion.implicitRole);
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (!isUnderstood(i)) {
|
||||
Header header = get(i);
|
||||
if (!header.isIgnorable(effectiveSoapVersion, roles)) {
|
||||
QName qName = new QName(header.getNamespaceURI(), header.getLocalPart());
|
||||
if (binding == null) {
|
||||
//if binding is null, no further checks needed...we already
|
||||
//know this header is not understood from the isUnderstood
|
||||
//check above
|
||||
if (notUnderstoodHeaders == null) {
|
||||
notUnderstoodHeaders = new HashSet<QName>();
|
||||
}
|
||||
notUnderstoodHeaders.add(qName);
|
||||
} else {
|
||||
// if the binding is not null, see if the binding can understand it
|
||||
if (binding instanceof SOAPBindingImpl && !((SOAPBindingImpl) binding).understandsHeader(qName)) {
|
||||
if (!knownHeaders.contains(qName)) {
|
||||
//logger.info("Element not understood=" + qName);
|
||||
if (notUnderstoodHeaders == null) {
|
||||
notUnderstoodHeaders = new HashSet<QName>();
|
||||
}
|
||||
notUnderstoodHeaders.add(qName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return notUnderstoodHeaders;
|
||||
}
|
||||
|
||||
private SOAPVersion getEffectiveSOAPVersion(WSBinding binding) {
|
||||
SOAPVersion mySOAPVersion = (soapVersion != null) ? soapVersion : binding.getSOAPVersion();
|
||||
if (mySOAPVersion == null) {
|
||||
mySOAPVersion = SOAPVersion.SOAP_11;
|
||||
}
|
||||
return mySOAPVersion;
|
||||
}
|
||||
|
||||
public void setSoapVersion(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Header> getHeaders() {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Header> asList() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
185
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Headers.java
Normal file
185
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Headers.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.bind.api.JAXBRIContext;
|
||||
import com.sun.xml.internal.bind.v2.runtime.MarshallerImpl;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.pipe.Pipe;
|
||||
import com.sun.xml.internal.ws.message.DOMHeader;
|
||||
import com.sun.xml.internal.ws.message.StringHeader;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBHeader;
|
||||
import com.sun.xml.internal.ws.message.saaj.SAAJHeader;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader11;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader12;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingContext;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingContextFactory;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPHeaderElement;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* Factory methods for various {@link Header} implementations.
|
||||
*
|
||||
* <p>
|
||||
* This class provides various methods to create different
|
||||
* flavors of {@link Header} classes that store data
|
||||
* in different formats.
|
||||
*
|
||||
* <p>
|
||||
* This is a part of the JAX-WS RI internal API so that
|
||||
* {@link Pipe} implementations can reuse the implementations
|
||||
* done inside the JAX-WS without having a strong dependency
|
||||
* to the actual class.
|
||||
*
|
||||
* <p>
|
||||
* If you find some of the useful convenience methods missing
|
||||
* from this class, please talk to us.
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class Headers {
|
||||
private Headers() {}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #create(BindingContext, Object)} instead.
|
||||
*/
|
||||
public static Header create(SOAPVersion soapVersion, Marshaller m, Object o) {
|
||||
return new JAXBHeader(BindingContextFactory.getBindingContext(m),o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Header} backed a by a JAXB bean.
|
||||
*/
|
||||
public static Header create(JAXBContext context, Object o) {
|
||||
return new JAXBHeader(BindingContextFactory.create(context),o);
|
||||
}
|
||||
|
||||
public static Header create(BindingContext context, Object o) {
|
||||
return new JAXBHeader(context,o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Header} backed a by a JAXB bean, with the given tag name.
|
||||
*
|
||||
* See {@link #create(SOAPVersion, Marshaller, Object)} for the meaning
|
||||
* of other parameters.
|
||||
*
|
||||
* @param tagName
|
||||
* The name of the newly created header. Must not be null.
|
||||
* @param o
|
||||
* The JAXB bean that represents the contents of the header. Must not be null.
|
||||
*/
|
||||
public static Header create(SOAPVersion soapVersion, Marshaller m, QName tagName, Object o) {
|
||||
return create(soapVersion,m,new JAXBElement(tagName,o.getClass(),o));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Header} backed a by a JAXB bean.
|
||||
* @deprecated
|
||||
*/
|
||||
public static Header create(Bridge bridge, Object jaxbObject) {
|
||||
return new JAXBHeader(new com.sun.xml.internal.ws.db.glassfish.BridgeWrapper(null,bridge), jaxbObject);
|
||||
}
|
||||
|
||||
public static Header create(XMLBridge bridge, Object jaxbObject) {
|
||||
return new JAXBHeader(bridge, jaxbObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Header} backed by a SAAJ object.
|
||||
*/
|
||||
public static Header create(SOAPHeaderElement header) {
|
||||
return new SAAJHeader(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Header} backed by an {@link Element}.
|
||||
*/
|
||||
public static Header create( Element node ) {
|
||||
return new DOMHeader<Element>(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #create(Element)}
|
||||
*/
|
||||
public static Header create( SOAPVersion soapVersion, Element node ) {
|
||||
return create(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Header} that reads from {@link XMLStreamReader}.
|
||||
*
|
||||
* <p>
|
||||
* Note that the header implementation will read the entire data
|
||||
* into memory anyway, so this might not be as efficient as you might hope.
|
||||
*/
|
||||
public static Header create( SOAPVersion soapVersion, XMLStreamReader reader ) throws XMLStreamException {
|
||||
switch(soapVersion) {
|
||||
case SOAP_11:
|
||||
return new StreamHeader11(reader);
|
||||
case SOAP_12:
|
||||
return new StreamHeader12(reader);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Header} that that has a single text value in it
|
||||
* (IOW, of the form <foo>text</foo>.)
|
||||
*
|
||||
* @param name QName of the header element
|
||||
* @param value text value of the header
|
||||
*/
|
||||
public static Header create(QName name, String value) {
|
||||
return new StringHeader(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Header} that that has a single text value in it
|
||||
* (IOW, of the form <foo>text</foo>.)
|
||||
*
|
||||
* @param name QName of the header element
|
||||
* @param value text value of the header
|
||||
*/
|
||||
public static Header createMustUnderstand(@NotNull SOAPVersion soapVersion, @NotNull QName name,@NotNull String value) {
|
||||
return new StringHeader(name, value,soapVersion,true);
|
||||
}
|
||||
}
|
||||
789
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Message.java
Normal file
789
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Message.java
Normal file
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.ws.api.BindingID;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.model.JavaMethod;
|
||||
import com.sun.xml.internal.ws.api.model.SEIModel;
|
||||
import com.sun.xml.internal.ws.api.model.WSDLOperationMapping;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundPortType;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.Pipe;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import com.sun.xml.internal.ws.client.dispatch.DispatchImpl;
|
||||
import com.sun.xml.internal.ws.message.AttachmentSetImpl;
|
||||
import com.sun.xml.internal.ws.message.StringHeader;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Dispatch;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a SOAP message.
|
||||
*
|
||||
*
|
||||
* <h2>What is a message?</h2>
|
||||
* <p>
|
||||
* A {@link Message} consists of the following:
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* Random-accessible list of headers.
|
||||
* a header is a representation of an element inside
|
||||
* <soap:Header>.
|
||||
* It can be read multiple times,
|
||||
* can be added or removed, but it is not modifiable.
|
||||
* See {@link HeaderList} for more about headers.
|
||||
*
|
||||
* <li>
|
||||
* The payload of the message, which is a representation
|
||||
* of an element inside <soap:Body>.
|
||||
* the payload is streamed, and therefore it can be
|
||||
* only read once (or can be only written to something once.)
|
||||
* once a payload is used, a message is said to be <b>consumed</b>.
|
||||
* A message {@link #hasPayload() may not have any payload.}
|
||||
*
|
||||
* <li>
|
||||
* Attachments.
|
||||
* TODO: can attachments be streamed? I suspect so.
|
||||
* does anyone need to read attachment twice?
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
*
|
||||
* <h2>How does this abstraction work?</h2>
|
||||
* <p>
|
||||
* The basic idea behind the {@link Message} is to hide the actual
|
||||
* data representation. For example, a {@link Message} might be
|
||||
* constructed on top of an {@link InputStream} from the accepted HTTP connection,
|
||||
* or it might be constructed on top of a JAXB object as a result
|
||||
* of the method invocation through {@link Proxy}. There will be
|
||||
* a {@link Message} implementation for each of those cases.
|
||||
*
|
||||
* <p>
|
||||
* This interface provides a lot of methods that access the payload
|
||||
* in many different forms, and implementations can implement those
|
||||
* methods in the best possible way.
|
||||
*
|
||||
* <p>
|
||||
* A particular attention is paid to make sure that a {@link Message}
|
||||
* object can be constructed on a stream that is not fully read yet.
|
||||
* We believe this improves the turn-around time on the server side.
|
||||
*
|
||||
* <p>
|
||||
* It is often useful to wrap a {@link Message} into another {@link Message},
|
||||
* for example to encrypt the body, or to verify the signature as the body
|
||||
* is read.
|
||||
*
|
||||
* <p>
|
||||
* This representation is also used for a REST-ful XML message.
|
||||
* In such case we'll construct a {@link Message} with empty
|
||||
* attachments and headers, and when serializing all headers
|
||||
* and attachments will be ignored.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <h2>Message and XOP</h2>
|
||||
* <p>
|
||||
* XOP is considered as an {@link Codec}, and therefore when you are looking at
|
||||
* {@link Message}, you'll never see <xop:Include> or any such elements
|
||||
* (instead you'll see the base64 data inlined.) If a consumer of infoset isn't
|
||||
* interested in handling XOP by himself, this allows him to work with XOP
|
||||
* correctly even without noticing it.
|
||||
*
|
||||
* <p>
|
||||
* For producers and consumers that are interested in accessing the binary data
|
||||
* more efficiently, they can use {@link XMLStreamReaderEx} and
|
||||
* {@link XMLStreamWriterEx}.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <h2>Message lifespan</h2>
|
||||
* <p>
|
||||
* Often {@link Packet} include information local to a particular
|
||||
* invocaion (such as {@code HttpServletRequest}, from this angle, it makes sense
|
||||
* to tie a lifespan of a message to one pipeline invocation.
|
||||
* <p>
|
||||
* On the other hand, if you think about WS-RM, it often needs to hold on to
|
||||
* a message longer than a pipeline invocation (you might get an HTTP request,
|
||||
* get a message X, get a second HTTP request, get another message Y, and
|
||||
* only then you might want to process X.)
|
||||
* <p>
|
||||
* TODO: what do we do about this?
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* TODO: can body element have foreign attributes? maybe ID for security?
|
||||
* Yes, when the SOAP body is signed there will be an ID attribute present
|
||||
* But in this case any security based impl may need access
|
||||
* to the concrete representation.
|
||||
* TODO: HTTP headers?
|
||||
* Yes. Abstracted as transport-based properties.
|
||||
* TODO: who handles SOAP 1.1 and SOAP 1.2 difference?
|
||||
* As separate channel implementations responsible for the creation of the
|
||||
* message?
|
||||
* TODO: session?
|
||||
* TODO: Do we need to expose SOAPMessage explicitly?
|
||||
* SOAPMessage could be the concrete representation but is it necessary to
|
||||
* transform between different concrete representations?
|
||||
* Perhaps this comes down to how use channels for creation and processing.
|
||||
* TODO: Do we need to distinguish better between creation and processing?
|
||||
* Do we really need the requirement that a created message can be resused
|
||||
* for processing. Shall we bifurcate?
|
||||
*
|
||||
* TODO: SOAP version issue
|
||||
* SOAP version is determined by the context, so message itself doesn't carry it around (?)
|
||||
*
|
||||
* TODO: wrapping message needs easier. in particular properties and attachments.
|
||||
* </pre>
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class Message {
|
||||
|
||||
/**
|
||||
* Returns true if headers are present in the message.
|
||||
*
|
||||
* @return
|
||||
* true if headers are present.
|
||||
*/
|
||||
public abstract boolean hasHeaders();
|
||||
|
||||
/**
|
||||
* Gets all the headers of this message.
|
||||
*
|
||||
* <h3>Implementation Note</h3>
|
||||
* <p>
|
||||
* {@link Message} implementation is allowed to defer
|
||||
* the construction of {@link MessageHeaders} object. So
|
||||
* if you only want to check for the existence of any header
|
||||
* element, use {@link #hasHeaders()}.
|
||||
*
|
||||
* @return
|
||||
* always return the same non-null object.
|
||||
*/
|
||||
public abstract @NotNull MessageHeaders getHeaders();
|
||||
|
||||
/**
|
||||
* Gets the attachments of this message
|
||||
* (attachments live outside a message.)
|
||||
*/
|
||||
public @NotNull AttachmentSet getAttachments() {
|
||||
if (attachmentSet == null) {
|
||||
attachmentSet = new AttachmentSetImpl();
|
||||
}
|
||||
return attachmentSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimization hint for the derived class to check
|
||||
* if we may have some attachments.
|
||||
*/
|
||||
protected boolean hasAttachments() {
|
||||
return attachmentSet!=null;
|
||||
}
|
||||
|
||||
protected AttachmentSet attachmentSet;
|
||||
|
||||
private WSDLBoundOperation operation = null;
|
||||
|
||||
private WSDLOperationMapping wsdlOperationMapping = null;
|
||||
|
||||
private MessageMetadata messageMetadata = null;
|
||||
|
||||
public void setMessageMedadata(MessageMetadata metadata) {
|
||||
messageMetadata = metadata;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the operation of which this message is an instance of.
|
||||
*
|
||||
* <p>
|
||||
* This method relies on {@link WSDLBoundPortType#getOperation(String, String)} but
|
||||
* it does so in an efficient way.
|
||||
*
|
||||
* @deprecated It is not always possible to uniquely identify the WSDL Operation from just the
|
||||
* information in the Message. Instead, Use {@link com.sun.xml.internal.ws.api.message.Packet#getWSDLOperation()}
|
||||
* to get it correctly.
|
||||
*
|
||||
* <p>
|
||||
* This method works only for a request. A pipe can determine an operation for a request,
|
||||
* and then keep it in a local variable to use it with a response, so there should be
|
||||
* no need to find out operation from a response (besides, there might not be any response!).
|
||||
*
|
||||
* @param boundPortType
|
||||
* This represents the port for which this message is used.
|
||||
* Most {@link Pipe}s should get this information when they are created,
|
||||
* since a pippeline always work against a particular type of {@link WSDLPort}.
|
||||
*
|
||||
* @return
|
||||
* Null if the operation was not found. This is possible, for example when a protocol
|
||||
* message is sent through a pipeline, or when we receive an invalid request on the server,
|
||||
* or when we are on the client and the user appliation sends a random DOM through
|
||||
* {@link Dispatch}, so this error needs to be handled gracefully.
|
||||
*/
|
||||
@Deprecated
|
||||
public final @Nullable WSDLBoundOperation getOperation(@NotNull WSDLBoundPortType boundPortType) {
|
||||
if (operation == null && messageMetadata != null) {
|
||||
if (wsdlOperationMapping == null) wsdlOperationMapping = messageMetadata.getWSDLOperationMapping();
|
||||
if (wsdlOperationMapping != null) operation = wsdlOperationMapping.getWSDLBoundOperation();
|
||||
}
|
||||
if(operation==null)
|
||||
operation = boundPortType.getOperation(getPayloadNamespaceURI(),getPayloadLocalPart());
|
||||
return operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #getOperation(WSDLBoundPortType)} but
|
||||
* takes {@link WSDLPort} for convenience.
|
||||
*
|
||||
* @deprecated It is not always possible to uniquely identify the WSDL Operation from just the
|
||||
* information in the Message. Instead, Use {@link com.sun.xml.internal.ws.api.message.Packet#getWSDLOperation()}
|
||||
* to get it correctly.
|
||||
*/
|
||||
@Deprecated
|
||||
public final @Nullable WSDLBoundOperation getOperation(@NotNull WSDLPort port) {
|
||||
return getOperation(port.getBinding());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the java Method of which this message is an instance of.
|
||||
*
|
||||
* It is not always possible to uniquely identify the WSDL Operation from just the
|
||||
* information in the Message. Instead, Use {@link com.sun.xml.internal.ws.api.message.Packet#getWSDLOperation()}
|
||||
* to get the QName of the associated wsdl operation correctly.
|
||||
*
|
||||
* <p>
|
||||
* This method works only for a request. A pipe can determine a {@link Method}
|
||||
* for a request, and then keep it in a local variable to use it with a response,
|
||||
* so there should be no need to find out operation from a response (besides,
|
||||
* there might not be any response!).
|
||||
*
|
||||
* @param seiModel
|
||||
* This represents the java model for the endpoint
|
||||
* Some server {@link Pipe}s would get this information when they are created.
|
||||
*
|
||||
* @return
|
||||
* Null if there is no corresponding Method for this message. This is
|
||||
* possible, for example when a protocol message is sent through a
|
||||
* pipeline, or when we receive an invalid request on the server,
|
||||
* or when we are on the client and the user appliation sends a random
|
||||
* DOM through {@link Dispatch}, so this error needs to be handled
|
||||
* gracefully.
|
||||
*/
|
||||
@Deprecated
|
||||
public final @Nullable JavaMethod getMethod(@NotNull SEIModel seiModel) {
|
||||
if (wsdlOperationMapping == null && messageMetadata != null) {
|
||||
wsdlOperationMapping = messageMetadata.getWSDLOperationMapping();
|
||||
}
|
||||
if (wsdlOperationMapping != null) {
|
||||
return wsdlOperationMapping.getJavaMethod();
|
||||
}
|
||||
//fall back to the original logic which could be incorrect ...
|
||||
String localPart = getPayloadLocalPart();
|
||||
String nsUri;
|
||||
if (localPart == null) {
|
||||
localPart = "";
|
||||
nsUri = "";
|
||||
} else {
|
||||
nsUri = getPayloadNamespaceURI();
|
||||
}
|
||||
QName name = new QName(nsUri, localPart);
|
||||
return seiModel.getJavaMethod(name);
|
||||
}
|
||||
|
||||
private Boolean isOneWay;
|
||||
|
||||
/**
|
||||
* Returns true if this message is a request message for a
|
||||
* one way operation according to the given WSDL. False otherwise.
|
||||
*
|
||||
* <p>
|
||||
* This method is functionally equivalent as doing
|
||||
* {@code getOperation(port).getOperation().isOneWay()}
|
||||
* (with proper null check and all.) But this method
|
||||
* can sometimes work faster than that (for example,
|
||||
* on the client side when used with SEI.)
|
||||
*
|
||||
* @param port
|
||||
* {@link Message}s are always created under the context of
|
||||
* one {@link WSDLPort} and they never go outside that context.
|
||||
* Pass in that "governing" {@link WSDLPort} object here.
|
||||
* We chose to receive this as a parameter instead of
|
||||
* keeping {@link WSDLPort} in a message, just to save the storage.
|
||||
*
|
||||
* <p>
|
||||
* The implementation of this method involves caching the return
|
||||
* value, so the behavior is undefined if multiple callers provide
|
||||
* different {@link WSDLPort} objects, which is a bug of the caller.
|
||||
*/
|
||||
public boolean isOneWay(@NotNull WSDLPort port) {
|
||||
if(isOneWay==null) {
|
||||
// we don't know, so compute.
|
||||
WSDLBoundOperation op = getOperation(port);
|
||||
if(op!=null)
|
||||
isOneWay = op.getOperation().isOneWay();
|
||||
else
|
||||
// the contract is to return true only when it's known to be one way.
|
||||
isOneWay = false;
|
||||
}
|
||||
return isOneWay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an assertion that this {@link Message} is
|
||||
* a request message for an one-way operation according
|
||||
* to the context WSDL.
|
||||
*
|
||||
* <p>
|
||||
* This method is really only intended to be invoked from within
|
||||
* the JAX-WS runtime, and not by any code building on top of it.
|
||||
*
|
||||
* <p>
|
||||
* This method can be invoked only when the caller "knows" what
|
||||
* WSDL says. Also, there's no point in invoking this method if the caller
|
||||
* is doing {@code getOperation(port).getOperation().isOneWay()},
|
||||
* or sniffing the payload tag name.
|
||||
* In particular, this includes {@link DispatchImpl}.
|
||||
*
|
||||
* <p>
|
||||
* Once called, this allows {@link #isOneWay(WSDLPort)} method
|
||||
* to return a value quickly.
|
||||
*
|
||||
* @see #isOneWay(WSDLPort)
|
||||
*/
|
||||
public final void assertOneWay(boolean value) {
|
||||
// if two callers make different assertions, that's a bug.
|
||||
// this is an assertion, not a runtime check because
|
||||
// nobody outside JAX-WS should be using this.
|
||||
assert isOneWay==null || isOneWay==value;
|
||||
|
||||
isOneWay = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the local name of the payload element.
|
||||
*
|
||||
* @return
|
||||
* null if a {@link Message} doesn't have any payload.
|
||||
*/
|
||||
public abstract @Nullable String getPayloadLocalPart();
|
||||
|
||||
/**
|
||||
* Gets the namespace URI of the payload element.
|
||||
*
|
||||
* @return
|
||||
* null if a {@link Message} doesn't have any payload.
|
||||
*/
|
||||
public abstract String getPayloadNamespaceURI();
|
||||
// I'm not putting @Nullable on it because doing null check on getPayloadLocalPart() should be suffice
|
||||
|
||||
/**
|
||||
* Returns true if a {@link Message} has a payload.
|
||||
*
|
||||
* <p>
|
||||
* A message without a payload is a SOAP message that looks like:
|
||||
* <pre><xmp>
|
||||
* <S:Envelope>
|
||||
* <S:Header>
|
||||
* ...
|
||||
* </S:Header>
|
||||
* <S:Body />
|
||||
* </S:Envelope>
|
||||
* </xmp></pre>
|
||||
*/
|
||||
public abstract boolean hasPayload();
|
||||
|
||||
/**
|
||||
* Returns true if this message is a fault.
|
||||
*
|
||||
* <p>
|
||||
* Just a convenience method built on {@link #getPayloadNamespaceURI()}
|
||||
* and {@link #getPayloadLocalPart()}.
|
||||
*/
|
||||
public boolean isFault() {
|
||||
// TODO: is SOAP version a property of a Message?
|
||||
// or is it defined by external factors?
|
||||
// how do I compare?
|
||||
String localPart = getPayloadLocalPart();
|
||||
if(localPart==null || !localPart.equals("Fault"))
|
||||
return false;
|
||||
|
||||
String nsUri = getPayloadNamespaceURI();
|
||||
return nsUri.equals(SOAPVersion.SOAP_11.nsUri) || nsUri.equals(SOAPVersion.SOAP_12.nsUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* It gives S:Envelope/S:Body/S:Fault/detail 's first child's name. Should
|
||||
* be called for messages that have SOAP Fault.
|
||||
*
|
||||
* <p> This implementation is expensive so concrete implementations are
|
||||
* expected to override this one.
|
||||
*
|
||||
* @return first detail entry's name, if there is one
|
||||
* else null
|
||||
*/
|
||||
public @Nullable QName getFirstDetailEntryName() {
|
||||
assert isFault();
|
||||
Message msg = copy();
|
||||
try {
|
||||
SOAPFaultBuilder fault = SOAPFaultBuilder.create(msg);
|
||||
return fault.getFirstDetailEntryName();
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes this message including the envelope.
|
||||
* returns it as a {@link Source} object.
|
||||
*/
|
||||
public abstract Source readEnvelopeAsSource();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the payload as a {@link Source} object.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @return
|
||||
* if there's no payload, this method returns null.
|
||||
*/
|
||||
public abstract Source readPayloadAsSource();
|
||||
|
||||
/**
|
||||
* Creates the equivalent {@link SOAPMessage} from this message.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @throws SOAPException
|
||||
* if there's any error while creating a {@link SOAPMessage}.
|
||||
*/
|
||||
public abstract SOAPMessage readAsSOAPMessage() throws SOAPException;
|
||||
|
||||
/**
|
||||
* Creates the equivalent {@link SOAPMessage} from this message. It also uses
|
||||
* transport specific headers from Packet during the SOAPMessage construction
|
||||
* so that {@link SOAPMessage#getMimeHeaders()} gives meaningful transport
|
||||
* headers.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @throws SOAPException
|
||||
* if there's any error while creating a {@link SOAPMessage}.
|
||||
*/
|
||||
public SOAPMessage readAsSOAPMessage(Packet packet, boolean inbound) throws SOAPException {
|
||||
return readAsSOAPMessage();
|
||||
}
|
||||
|
||||
public static Map<String, List<String>> getTransportHeaders(Packet packet) {
|
||||
return getTransportHeaders(packet, packet.getState().isInbound());
|
||||
}
|
||||
|
||||
public static Map<String, List<String>> getTransportHeaders(Packet packet, boolean inbound) {
|
||||
Map<String, List<String>> headers = null;
|
||||
String key = inbound ? Packet.INBOUND_TRANSPORT_HEADERS : Packet.OUTBOUND_TRANSPORT_HEADERS;
|
||||
if (packet.supports(key)) {
|
||||
headers = (Map<String, List<String>>)packet.get(key);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
public static void addSOAPMimeHeaders(MimeHeaders mh, Map<String, List<String>> headers) {
|
||||
for(Map.Entry<String, List<String>> e : headers.entrySet()) {
|
||||
if (!e.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
for(String value : e.getValue()) {
|
||||
mh.addHeader(e.getKey(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reads the payload as a JAXB object by using the given unmarshaller.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @throws JAXBException
|
||||
* If JAXB reports an error during the processing.
|
||||
*/
|
||||
public abstract <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads the payload as a JAXB object according to the given {@link Bridge}.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @deprecated
|
||||
* @return null
|
||||
* if there's no payload.
|
||||
* @throws JAXBException
|
||||
* If JAXB reports an error during the processing.
|
||||
*/
|
||||
public abstract <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads the payload as a Data-Bond object
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @return null
|
||||
* if there's no payload.
|
||||
* @throws JAXBException
|
||||
* If JAXB reports an error during the processing.
|
||||
*/
|
||||
public abstract <T> T readPayloadAsJAXB(XMLBridge<T> bridge) throws JAXBException;
|
||||
|
||||
/**
|
||||
* Reads the payload as a {@link XMLStreamReader}
|
||||
*
|
||||
* This consumes the message. The caller is encouraged to call
|
||||
* {@link XMLStreamReaderFactory#recycle(XMLStreamReader)} when finished using
|
||||
* the instance.
|
||||
*
|
||||
* @return
|
||||
* If there's no payload, this method returns null.
|
||||
* Otherwise always non-null valid {@link XMLStreamReader} that points to
|
||||
* the payload tag name.
|
||||
*/
|
||||
public abstract XMLStreamReader readPayload() throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Marks the message as consumed, without actually reading the contents.
|
||||
*
|
||||
* <p>
|
||||
* This method provides an opportunity for implementations to reuse
|
||||
* any reusable resources needed for representing the payload.
|
||||
*
|
||||
* <p>
|
||||
* This method may not be called more than once since it may have
|
||||
* released the reusable resources.
|
||||
*/
|
||||
public void consume() {}
|
||||
|
||||
/**
|
||||
* Writes the payload to StAX.
|
||||
*
|
||||
* This method writes just the payload of the message to the writer.
|
||||
* This consumes the message.
|
||||
* The implementation will not write
|
||||
* {@link XMLStreamWriter#writeStartDocument()}
|
||||
* nor
|
||||
* {@link XMLStreamWriter#writeEndDocument()}
|
||||
*
|
||||
* <p>
|
||||
* If there's no payload, this method is no-op.
|
||||
*
|
||||
* @throws XMLStreamException
|
||||
* If the {@link XMLStreamWriter} reports an error,
|
||||
* or some other errors happen during the processing.
|
||||
*/
|
||||
public abstract void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Writes the whole SOAP message (but not attachments)
|
||||
* to the given writer.
|
||||
*
|
||||
* This consumes the message.
|
||||
*
|
||||
* @throws XMLStreamException
|
||||
* If the {@link XMLStreamWriter} reports an error,
|
||||
* or some other errors happen during the processing.
|
||||
*/
|
||||
public abstract void writeTo(XMLStreamWriter sw) throws XMLStreamException;
|
||||
|
||||
/**
|
||||
* Writes the whole SOAP envelope as SAX events.
|
||||
*
|
||||
* <p>
|
||||
* This consumes the message.
|
||||
*
|
||||
* @param contentHandler
|
||||
* must not be nulll.
|
||||
* @param errorHandler
|
||||
* must not be null.
|
||||
* any error encountered during the SAX event production must be
|
||||
* first reported to this error handler. Fatal errors can be then
|
||||
* thrown as {@link SAXParseException}. {@link SAXException}s thrown
|
||||
* from {@link ErrorHandler} should propagate directly through this method.
|
||||
*/
|
||||
public abstract void writeTo( ContentHandler contentHandler, ErrorHandler errorHandler ) throws SAXException;
|
||||
|
||||
// TODO: do we need a method that reads payload as a fault?
|
||||
// do we want a separte streaming representation of fault?
|
||||
// or would SOAPFault in SAAJ do?
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a copy of a {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* This method creates a new {@link Message} whose header/payload/attachments/properties
|
||||
* are identical to this {@link Message}. Once created, the created {@link Message}
|
||||
* and the original {@link Message} behaves independently --- adding header/
|
||||
* attachment to one {@link Message} doesn't affect another {@link Message}
|
||||
* at all.
|
||||
*
|
||||
* <p>
|
||||
* This method does <b>NOT</b> consume a message.
|
||||
*
|
||||
* <p>
|
||||
* To enable efficient copy operations, there's a few restrictions on
|
||||
* how copied message can be used.
|
||||
*
|
||||
* <ol>
|
||||
* <li>The original and the copy may not be
|
||||
* used concurrently by two threads (this allows two {@link Message}s
|
||||
* to share some internal resources, such as JAXB marshallers.)
|
||||
* Note that it's OK for the original and the copy to be processed
|
||||
* by two threads, as long as they are not concurrent.
|
||||
*
|
||||
* <li>The copy has the same 'life scope'
|
||||
* as the original (this allows shallower copy, such as
|
||||
* JAXB beans wrapped in {@link JAXBMessage}.)
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* A 'life scope' of a message created during a message processing
|
||||
* in a pipeline is until a pipeline processes the next message.
|
||||
* A message cannot be kept beyond its life scope.
|
||||
*
|
||||
* (This experimental design is to allow message objects to be reused
|
||||
* --- feedback appreciated.)
|
||||
*
|
||||
*
|
||||
*
|
||||
* <h3>Design Rationale</h3>
|
||||
* <p>
|
||||
* Since a {@link Message} body is read-once, sometimes
|
||||
* (such as when you do fail-over, or WS-RM) you need to
|
||||
* create an idential copy of a {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* The actual copy operation depends on the layout
|
||||
* of the data in memory, hence it's best to be done by
|
||||
* the {@link Message} implementation itself.
|
||||
*
|
||||
* <p>
|
||||
* The restrictions placed on the use of copied {@link Message} can be
|
||||
* relaxed if necessary, but it will make the copy method more expensive.
|
||||
*/
|
||||
// TODO: update the class javadoc with 'lifescope'
|
||||
// and move the discussion about life scope there.
|
||||
public abstract Message copy();
|
||||
|
||||
/**
|
||||
* Retuns a unique id for the message. The id can be used for various things,
|
||||
* like debug assistance, logging, and MIME encoding(say for boundary).
|
||||
*
|
||||
* <p>
|
||||
* This method will check the existence of the addressing <MessageID> header,
|
||||
* and if present uses that value. Otherwise it generates one from UUID.random(),
|
||||
* and return it without adding a new header. But it doesn't add a <MessageID>
|
||||
* to the header list since we expect them to be added before calling this
|
||||
* method.
|
||||
*
|
||||
* <p>
|
||||
* Addressing tube will go do a separate verification on inbound
|
||||
* headers to make sure that <MessageID> header is present when it's
|
||||
* supposed to be.
|
||||
*
|
||||
* @param binding object created by {@link BindingID#createBinding()}
|
||||
*
|
||||
* @return unique id for the message
|
||||
* @deprecated
|
||||
*/
|
||||
public @NotNull String getID(@NotNull WSBinding binding) {
|
||||
return getID(binding.getAddressingVersion(), binding.getSOAPVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retuns a unique id for the message.
|
||||
* <p><p>
|
||||
* @see {@link #getID(com.sun.xml.internal.ws.api.WSBinding)} for detailed description.
|
||||
* @param av WS-Addressing version
|
||||
* @param sv SOAP version
|
||||
* @return unique id for the message
|
||||
* @deprecated
|
||||
*/
|
||||
public @NotNull String getID(AddressingVersion av, SOAPVersion sv) {
|
||||
String uuid = null;
|
||||
if (av != null) {
|
||||
uuid = AddressingUtils.getMessageID(getHeaders(), av, sv);
|
||||
}
|
||||
if (uuid == null) {
|
||||
uuid = generateMessageID();
|
||||
getHeaders().add(new StringHeader(av.messageIDTag, uuid));
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID suitable for use as a MessageID value
|
||||
* @return generated UUID
|
||||
*/
|
||||
public static String generateMessageID() {
|
||||
return "uuid:" + UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public SOAPVersion getSOAPVersion() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.soap.MimeHeader;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
|
||||
import com.oracle.webservices.internal.api.EnvelopeStyle;
|
||||
import com.oracle.webservices.internal.api.EnvelopeStyleFeature;
|
||||
import com.oracle.webservices.internal.api.message.MessageContext;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codecs;
|
||||
import static com.sun.xml.internal.ws.transport.http.HttpAdapter.fixQuotesAroundSoapAction;
|
||||
|
||||
/**
|
||||
* The MessageContextFactory implements com.oracle.webservices.internal.api.message.MessageContextFactory as
|
||||
* a factory of Packet and public facade of Codec(s).
|
||||
*
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
public class MessageContextFactory extends com.oracle.webservices.internal.api.message.MessageContextFactory {
|
||||
|
||||
private WSFeatureList features;
|
||||
private Codec soapCodec;
|
||||
private Codec xmlCodec;
|
||||
private EnvelopeStyleFeature envelopeStyle;
|
||||
private EnvelopeStyle.Style singleSoapStyle;
|
||||
|
||||
public MessageContextFactory(WebServiceFeature[] wsf) {
|
||||
this(new com.sun.xml.internal.ws.binding.WebServiceFeatureList(wsf));
|
||||
}
|
||||
|
||||
public MessageContextFactory(WSFeatureList wsf) {
|
||||
features = wsf;
|
||||
envelopeStyle = features.get(EnvelopeStyleFeature.class);
|
||||
if (envelopeStyle == null) {//Default to SOAP11
|
||||
envelopeStyle = new EnvelopeStyleFeature(new EnvelopeStyle.Style[]{EnvelopeStyle.Style.SOAP11});
|
||||
features.mergeFeatures(new WebServiceFeature[]{envelopeStyle}, false);
|
||||
}
|
||||
for (EnvelopeStyle.Style s : envelopeStyle.getStyles()) {
|
||||
if (s.isXML()) {
|
||||
if (xmlCodec == null) xmlCodec = Codecs.createXMLCodec(features);
|
||||
} else {
|
||||
if (soapCodec == null) soapCodec = Codecs.createSOAPBindingCodec(features);
|
||||
singleSoapStyle = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected com.oracle.webservices.internal.api.message.MessageContextFactory newFactory(WebServiceFeature... f) {
|
||||
return new com.sun.xml.internal.ws.api.message.MessageContextFactory(f);
|
||||
}
|
||||
|
||||
|
||||
public com.oracle.webservices.internal.api.message.MessageContext createContext() {
|
||||
return packet(null);
|
||||
}
|
||||
|
||||
public com.oracle.webservices.internal.api.message.MessageContext createContext(SOAPMessage soap) {
|
||||
throwIfIllegalMessageArgument(soap);
|
||||
return packet(Messages.create(soap));
|
||||
}
|
||||
|
||||
public MessageContext createContext(Source m, com.oracle.webservices.internal.api.EnvelopeStyle.Style envelopeStyle) {
|
||||
throwIfIllegalMessageArgument(m);
|
||||
return packet(Messages.create(m, SOAPVersion.from(envelopeStyle)));
|
||||
}
|
||||
|
||||
public com.oracle.webservices.internal.api.message.MessageContext createContext(Source m) {
|
||||
throwIfIllegalMessageArgument(m);
|
||||
return packet(Messages.create(m, SOAPVersion.from(singleSoapStyle)));
|
||||
}
|
||||
|
||||
public com.oracle.webservices.internal.api.message.MessageContext createContext(InputStream in, String contentType) throws IOException {
|
||||
throwIfIllegalMessageArgument(in);
|
||||
//TODO when do we use xmlCodec?
|
||||
Packet p = packet(null);
|
||||
soapCodec.decode(in, contentType, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated http://java.net/jira/browse/JAX_WS-1077
|
||||
*/
|
||||
@Deprecated
|
||||
public com.oracle.webservices.internal.api.message.MessageContext createContext(InputStream in, MimeHeaders headers) throws IOException {
|
||||
String contentType = getHeader(headers, "Content-Type");
|
||||
Packet packet = (Packet) createContext(in, contentType);
|
||||
packet.acceptableMimeTypes = getHeader(headers, "Accept");
|
||||
packet.soapAction = fixQuotesAroundSoapAction(getHeader(headers, "SOAPAction"));
|
||||
// packet.put(Packet.INBOUND_TRANSPORT_HEADERS, toMap(headers));
|
||||
return packet;
|
||||
}
|
||||
|
||||
static String getHeader(MimeHeaders headers, String name) {
|
||||
String[] values = headers.getHeader(name);
|
||||
return (values != null && values.length > 0) ? values[0] : null;
|
||||
}
|
||||
|
||||
static Map<String, List<String>> toMap(MimeHeaders headers) {
|
||||
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
|
||||
for (Iterator<MimeHeader> i = headers.getAllHeaders(); i.hasNext();) {
|
||||
MimeHeader mh = i.next();
|
||||
List<String> values = map.get(mh.getName());
|
||||
if (values == null) {
|
||||
values = new ArrayList<String>();
|
||||
map.put(mh.getName(), values);
|
||||
}
|
||||
values.add(mh.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public MessageContext createContext(Message m) {
|
||||
throwIfIllegalMessageArgument(m);
|
||||
return packet(m);
|
||||
}
|
||||
|
||||
private Packet packet(Message m) {
|
||||
final Packet p = new Packet();
|
||||
//TODO when do we use xmlCodec?
|
||||
p.codec = soapCodec;
|
||||
if (m != null) p.setMessage(m);
|
||||
MTOMFeature mf = features.get(MTOMFeature.class);
|
||||
if (mf != null) {
|
||||
p.setMtomFeature(mf);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private void throwIfIllegalMessageArgument(Object message)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (message == null) {
|
||||
throw new IllegalArgumentException("null messages are not allowed. Consider using MessageContextFactory.createContext()");
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public com.oracle.webservices.internal.api.message.MessageContext doCreate() {
|
||||
return packet(null);
|
||||
}
|
||||
@Deprecated
|
||||
public com.oracle.webservices.internal.api.message.MessageContext doCreate(SOAPMessage m) {
|
||||
return createContext(m);
|
||||
}
|
||||
@Deprecated
|
||||
public com.oracle.webservices.internal.api.message.MessageContext doCreate(Source x, SOAPVersion soapVersion) {
|
||||
return packet(Messages.create(x, soapVersion));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
|
||||
/**
|
||||
* Interface representing all the headers of a {@link Message}
|
||||
*/
|
||||
public interface MessageHeaders {
|
||||
public void understood(Header header);
|
||||
public void understood(QName name);
|
||||
public void understood(String nsUri, String localName);
|
||||
public Header get(String nsUri, String localName, boolean markAsUnderstood);
|
||||
public Header get(QName name, boolean markAsUnderstood);
|
||||
public Iterator<Header> getHeaders(String nsUri, String localName, final boolean markAsUnderstood);
|
||||
/**
|
||||
* Get all headers in specified namespace
|
||||
* @param nsUri
|
||||
* @param markAsUnderstood
|
||||
* @return
|
||||
*/
|
||||
public Iterator<Header> getHeaders(String nsUri, final boolean markAsUnderstood);
|
||||
public Iterator<Header> getHeaders(QName headerName, final boolean markAsUnderstood);
|
||||
public Iterator<Header> getHeaders();
|
||||
public boolean hasHeaders();
|
||||
public boolean add(Header header);
|
||||
public Header remove(QName name);
|
||||
public Header remove(String nsUri, String localName);
|
||||
//DONT public Header remove(Header header);
|
||||
public void replace(Header old, Header header);
|
||||
|
||||
/**
|
||||
* Replaces an existing {@link Header} or adds a new {@link Header}.
|
||||
*
|
||||
* <p>
|
||||
* Order doesn't matter in headers, so this method
|
||||
* does not make any guarantee as to where the new header
|
||||
* is inserted.
|
||||
*
|
||||
* @return
|
||||
* always true. Don't use the return value.
|
||||
*/
|
||||
public boolean addOrReplace(Header header);
|
||||
|
||||
/**
|
||||
* Return a Set of QNames of headers that have been explicitly marked as understood.
|
||||
* If none have been marked, this method could return null
|
||||
*/
|
||||
public Set<QName> getUnderstoodHeaders();
|
||||
|
||||
/**
|
||||
* Returns a Set of QNames of headers that satisfy ALL the following conditions:
|
||||
* (a) Have mustUnderstand = true
|
||||
* (b) have NOT been explicitly marked as understood
|
||||
* (c) If roles argument is non-null, the header has isIgnorable = false
|
||||
* for the roles argument and SOAP version
|
||||
* (d) If non-null binding is passed in, are NOT understood by the binding
|
||||
* (e) If (d) is met, the header is NOT in the knownHeaders list passed in
|
||||
*
|
||||
* @param roles
|
||||
* @param knownHeaders
|
||||
* @param binding
|
||||
* @return
|
||||
*/
|
||||
public Set<QName> getNotUnderstoodHeaders(Set<String> roles, Set<QName> knownHeaders, WSBinding binding);
|
||||
|
||||
/**
|
||||
* True if the header has been explicitly marked understood, false otherwise
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public boolean isUnderstood(Header header);
|
||||
|
||||
/**
|
||||
* True if the header has been explicitly marked understood, false otherwise
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public boolean isUnderstood(QName header);
|
||||
|
||||
/**
|
||||
* True if the header has been explicitly marked understood, false otherwise
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public boolean isUnderstood(String nsUri, String header);
|
||||
|
||||
/**
|
||||
* Returns <code>Header</code> instances in a <code>List</code>.
|
||||
* @return <code>List</code> containing <code>Header</code> instances
|
||||
*/
|
||||
public List<Header> asList();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.xml.internal.ws.api.model.WSDLOperationMapping;
|
||||
|
||||
/**
|
||||
* In order for the Message to get properties from the Packet ...
|
||||
*
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
public interface MessageMetadata {
|
||||
public WSDLOperationMapping getWSDLOperationMapping();
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.message.saaj.SAAJMessage;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamMessage;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
/**
|
||||
* A <code>MessageWrapper</code> wraps the Message for the access through Packet.
|
||||
*
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
class MessageWrapper extends StreamMessage {
|
||||
|
||||
Packet packet;
|
||||
Message delegate;
|
||||
StreamMessage streamDelegate;
|
||||
|
||||
@Override
|
||||
public void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
|
||||
streamDelegate.writePayloadTo(contentHandler, errorHandler, fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBodyPrologue() {
|
||||
return streamDelegate.getBodyPrologue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBodyEpilogue() {
|
||||
return streamDelegate.getBodyEpilogue();
|
||||
}
|
||||
|
||||
MessageWrapper(Packet p, Message m) {
|
||||
super(m.getSOAPVersion());
|
||||
packet = p;
|
||||
delegate = m;
|
||||
streamDelegate = (m instanceof StreamMessage) ? (StreamMessage) m : null;
|
||||
setMessageMedadata(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHeaders() {
|
||||
return delegate.hasHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttachmentSet getAttachments() {
|
||||
return delegate.getAttachments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOneWay(WSDLPort port) {
|
||||
return delegate.isOneWay(port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPayloadLocalPart() {
|
||||
return delegate.getPayloadLocalPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPayloadNamespaceURI() {
|
||||
return delegate.getPayloadNamespaceURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return delegate.hasPayload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFault() {
|
||||
return delegate.isFault();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QName getFirstDetailEntryName() {
|
||||
return delegate.getFirstDetailEntryName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Source readEnvelopeAsSource() {
|
||||
//TODO if (delegate instanceof SAAJMessage)
|
||||
return delegate.readEnvelopeAsSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Source readPayloadAsSource() {
|
||||
//TODO if (delegate instanceof SAAJMessage)
|
||||
return delegate.readPayloadAsSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SOAPMessage readAsSOAPMessage() throws SOAPException {
|
||||
if (!(delegate instanceof SAAJMessage)) {
|
||||
delegate = toSAAJ(packet, null);
|
||||
}
|
||||
return delegate.readAsSOAPMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SOAPMessage readAsSOAPMessage(Packet p, boolean inbound) throws SOAPException {
|
||||
if (!(delegate instanceof SAAJMessage)) {
|
||||
delegate = toSAAJ(p, inbound);
|
||||
}
|
||||
return delegate.readAsSOAPMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
|
||||
return delegate.readPayloadAsJAXB(unmarshaller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
|
||||
return delegate.readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T readPayloadAsJAXB(XMLBridge<T> bridge) throws JAXBException {
|
||||
return delegate.readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLStreamReader readPayload() {
|
||||
try {
|
||||
return delegate.readPayload();
|
||||
} catch (XMLStreamException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume() {
|
||||
delegate.consume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
delegate.writePayloadTo(sw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
delegate.writeTo(sw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler)
|
||||
throws SAXException {
|
||||
delegate.writeTo(contentHandler, errorHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message copy() {
|
||||
return delegate.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID(WSBinding binding) {
|
||||
return delegate.getID(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID(AddressingVersion av, SOAPVersion sv) {
|
||||
return delegate.getID(av, sv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SOAPVersion getSOAPVersion() {
|
||||
return delegate.getSOAPVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MessageHeaders getHeaders() {
|
||||
return delegate.getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessageMedadata(MessageMetadata metadata) {
|
||||
super.setMessageMedadata(metadata);
|
||||
delegate.setMessageMedadata(metadata);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
|
||||
import com.oracle.webservices.internal.api.message.ContentType;
|
||||
|
||||
/**
|
||||
* A Message implementation may implement this interface as an alternative way to write the
|
||||
* message into the OutputStream.
|
||||
*
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
public interface MessageWritable {
|
||||
|
||||
/**
|
||||
* Gets the Content-type of this message.
|
||||
*
|
||||
* @return The MIME content type of this message
|
||||
*/
|
||||
ContentType getContentType();
|
||||
|
||||
/**
|
||||
* Writes the XML infoset portion of this MessageContext
|
||||
* (from <soap:Envelope> to </soap:Envelope>).
|
||||
*
|
||||
* @param out
|
||||
* Must not be null. The caller is responsible for closing the stream,
|
||||
* not the callee.
|
||||
*
|
||||
* @return
|
||||
* The MIME content type of this message (such as "application/xml").
|
||||
* This information is often ncessary by transport.
|
||||
*
|
||||
* @throws IOException
|
||||
* if a {@link OutputStream} throws {@link IOException}.
|
||||
*/
|
||||
ContentType writeTo( OutputStream out ) throws IOException;
|
||||
|
||||
/**
|
||||
* Passes configuration information to this message to ensure the proper
|
||||
* wire format is created. (from <soap:Envelope> to </soap:Envelope>).
|
||||
*
|
||||
* @param mtomFeature
|
||||
* The standard <code>WebServicesFeature</code> for specifying
|
||||
* the MTOM enablement and possibly threshold for the endpoint.
|
||||
* This value may be <code>null</code>.
|
||||
*/
|
||||
void setMTOMConfiguration(final MTOMFeature mtomFeature);
|
||||
}
|
||||
420
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Messages.java
Normal file
420
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Messages.java
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory;
|
||||
import com.sun.xml.internal.ws.api.pipe.Tube;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codecs;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.message.AttachmentSetImpl;
|
||||
import com.sun.xml.internal.ws.message.DOMMessage;
|
||||
import com.sun.xml.internal.ws.message.EmptyMessageImpl;
|
||||
import com.sun.xml.internal.ws.message.ProblemActionHeader;
|
||||
import com.sun.xml.internal.ws.message.stream.PayloadStreamReaderMessage;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.message.source.PayloadSourceMessage;
|
||||
import com.sun.xml.internal.ws.message.source.ProtocolSourceMessage;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingContextFactory;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderException;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.util.DOMUtil;
|
||||
import com.sun.xml.internal.ws.addressing.WsaTubeHelper;
|
||||
import com.sun.xml.internal.ws.addressing.model.MissingAddressingHeaderException;
|
||||
import com.sun.xml.internal.ws.resources.AddressingMessages;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.*;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.ws.ProtocolException;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* Factory methods for various {@link Message} implementations.
|
||||
*
|
||||
* <p>
|
||||
* This class provides various methods to create different
|
||||
* flavors of {@link Message} classes that store data
|
||||
* in different formats.
|
||||
*
|
||||
* <p>
|
||||
* This is a part of the JAX-WS RI internal API so that
|
||||
* {@link Tube} implementations can reuse the implementations
|
||||
* done inside the JAX-WS.
|
||||
*
|
||||
* <p>
|
||||
* If you find some of the useful convenience methods missing
|
||||
* from this class, please talk to us.
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class Messages {
|
||||
private Messages() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} backed by a JAXB bean.
|
||||
* @deprecated
|
||||
* @param context
|
||||
* The context to be used to produce infoset from the object. Must not be null.
|
||||
* @param jaxbObject
|
||||
* The JAXB object that represents the payload. must not be null. This object
|
||||
* must be bound to an element (which means it either is a {@link JAXBElement} or
|
||||
* an instanceof a class with {@link XmlRootElement}).
|
||||
* @param soapVersion
|
||||
* The SOAP version of the message. Must not be null.
|
||||
*/
|
||||
public static Message create(JAXBContext context, Object jaxbObject, SOAPVersion soapVersion) {
|
||||
return JAXBMessage.create(context,jaxbObject,soapVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* For use when creating a Dispatch object with an unknown JAXB implementation
|
||||
* for he JAXBContext parameter.
|
||||
*
|
||||
*/
|
||||
public static Message createRaw(JAXBContext context, Object jaxbObject, SOAPVersion soapVersion) {
|
||||
return JAXBMessage.createRaw(context,jaxbObject,soapVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #create(JAXBRIContext, Object, SOAPVersion)}
|
||||
*/
|
||||
public static Message create(Marshaller marshaller, Object jaxbObject, SOAPVersion soapVersion) {
|
||||
return create(BindingContextFactory.getBindingContext(marshaller).getJAXBContext(),jaxbObject,soapVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} backed by a SAAJ {@link SOAPMessage} object.
|
||||
*
|
||||
* <p>
|
||||
* If the {@link SOAPMessage} contains headers and attachments, this method
|
||||
* does the right thing.
|
||||
*
|
||||
* @param saaj
|
||||
* The SOAP message to be represented as a {@link Message}.
|
||||
* Must not be null. Once this method is invoked, the created
|
||||
* {@link Message} will own the {@link SOAPMessage}, so it shall
|
||||
* never be touched directly.
|
||||
*/
|
||||
public static Message create(SOAPMessage saaj) {
|
||||
return SAAJFactory.create(saaj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} using {@link Source} as payload.
|
||||
*
|
||||
* @param payload
|
||||
* Source payload is {@link Message}'s payload
|
||||
* Must not be null. Once this method is invoked, the created
|
||||
* {@link Message} will own the {@link Source}, so it shall
|
||||
* never be touched directly.
|
||||
*
|
||||
* @param ver
|
||||
* The SOAP version of the message. Must not be null.
|
||||
*/
|
||||
public static Message createUsingPayload(Source payload, SOAPVersion ver) {
|
||||
if (payload instanceof DOMSource) {
|
||||
if (((DOMSource)payload).getNode() == null) {
|
||||
return new EmptyMessageImpl(ver);
|
||||
}
|
||||
} else if (payload instanceof StreamSource) {
|
||||
StreamSource ss = (StreamSource)payload;
|
||||
if (ss.getInputStream() == null && ss.getReader() == null && ss.getSystemId() == null) {
|
||||
return new EmptyMessageImpl(ver);
|
||||
}
|
||||
} else if (payload instanceof SAXSource) {
|
||||
SAXSource ss = (SAXSource)payload;
|
||||
if (ss.getInputSource() == null && ss.getXMLReader() == null) {
|
||||
return new EmptyMessageImpl(ver);
|
||||
}
|
||||
}
|
||||
return new PayloadSourceMessage(payload, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} using {@link XMLStreamReader} as payload.
|
||||
*
|
||||
* @param payload
|
||||
* XMLStreamReader payload is {@link Message}'s payload
|
||||
* Must not be null. Once this method is invoked, the created
|
||||
* {@link Message} will own the {@link XMLStreamReader}, so it shall
|
||||
* never be touched directly.
|
||||
*
|
||||
* @param ver
|
||||
* The SOAP version of the message. Must not be null.
|
||||
*/
|
||||
public static Message createUsingPayload(XMLStreamReader payload, SOAPVersion ver) {
|
||||
return new PayloadStreamReaderMessage(payload, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} from an {@link Element} that represents
|
||||
* a payload.
|
||||
*
|
||||
* @param payload
|
||||
* The element that becomes the child element of the SOAP body.
|
||||
* Must not be null.
|
||||
*
|
||||
* @param ver
|
||||
* The SOAP version of the message. Must not be null.
|
||||
*/
|
||||
public static Message createUsingPayload(Element payload, SOAPVersion ver) {
|
||||
return new DOMMessage(ver,payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} from an {@link Element} that represents
|
||||
* the whole SOAP message.
|
||||
*
|
||||
* @param soapEnvelope
|
||||
* The SOAP envelope element.
|
||||
*/
|
||||
public static Message create(Element soapEnvelope) {
|
||||
SOAPVersion ver = SOAPVersion.fromNsUri(soapEnvelope.getNamespaceURI());
|
||||
// find the headers
|
||||
Element header = DOMUtil.getFirstChild(soapEnvelope, ver.nsUri, "Header");
|
||||
HeaderList headers = null;
|
||||
if(header!=null) {
|
||||
for( Node n=header.getFirstChild(); n!=null; n=n.getNextSibling() ) {
|
||||
if(n.getNodeType()==Node.ELEMENT_NODE) {
|
||||
if(headers==null)
|
||||
headers = new HeaderList(ver);
|
||||
headers.add(Headers.create((Element)n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find the payload
|
||||
Element body = DOMUtil.getFirstChild(soapEnvelope, ver.nsUri, "Body");
|
||||
if(body==null)
|
||||
throw new WebServiceException("Message doesn't have <S:Body> "+soapEnvelope);
|
||||
Element payload = DOMUtil.getFirstChild(soapEnvelope, ver.nsUri, "Body");
|
||||
|
||||
if(payload==null) {
|
||||
return new EmptyMessageImpl(headers, new AttachmentSetImpl(), ver);
|
||||
} else {
|
||||
return new DOMMessage(ver,headers,payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} using Source as entire envelope.
|
||||
*
|
||||
* @param envelope
|
||||
* Source envelope is used to create {@link Message}
|
||||
* Must not be null. Once this method is invoked, the created
|
||||
* {@link Message} will own the {@link Source}, so it shall
|
||||
* never be touched directly.
|
||||
*
|
||||
*/
|
||||
public static Message create(Source envelope, SOAPVersion soapVersion) {
|
||||
return new ProtocolSourceMessage(envelope, soapVersion);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} that doesn't have any payload.
|
||||
*/
|
||||
public static Message createEmpty(SOAPVersion soapVersion) {
|
||||
return new EmptyMessageImpl(soapVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} from {@link XMLStreamReader} that points to
|
||||
* the start of the envelope.
|
||||
*
|
||||
* @param reader
|
||||
* can point to the start document or the start element (of <s:Envelope>)
|
||||
*/
|
||||
public static @NotNull Message create(@NotNull XMLStreamReader reader) {
|
||||
// skip until the root element
|
||||
if(reader.getEventType()!=XMLStreamConstants.START_ELEMENT)
|
||||
XMLStreamReaderUtil.nextElementContent(reader);
|
||||
assert reader.getEventType()== XMLStreamConstants.START_ELEMENT :reader.getEventType();
|
||||
|
||||
SOAPVersion ver = SOAPVersion.fromNsUri(reader.getNamespaceURI());
|
||||
|
||||
return Codecs.createSOAPEnvelopeXmlCodec(ver).decode(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} from {@link XMLStreamBuffer} that retains the
|
||||
* whole envelope infoset.
|
||||
*
|
||||
* @param xsb
|
||||
* This buffer must contain the infoset of the whole envelope.
|
||||
*/
|
||||
public static @NotNull Message create(@NotNull XMLStreamBuffer xsb) {
|
||||
// TODO: we should be able to let Messae know that it's working off from a buffer,
|
||||
// to make some of the operations more efficient.
|
||||
// meanwhile, adding this as an API so that our users can take advantage of it
|
||||
// when we get around to such an implementation later.
|
||||
try {
|
||||
return create(xsb.readAsXMLStreamReader());
|
||||
} catch (XMLStreamException e) {
|
||||
throw new XMLStreamReaderException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} that represents an exception as a fault. The
|
||||
* created message reflects if t or t.getCause() is SOAPFaultException.
|
||||
*
|
||||
* creates a fault message with default faultCode env:Server if t or t.getCause()
|
||||
* is not SOAPFaultException. Otherwise, it use SOAPFaultException's faultCode
|
||||
*
|
||||
* @return
|
||||
* Always non-null. A message that wraps this {@link Throwable}.
|
||||
*
|
||||
*/
|
||||
public static Message create(Throwable t, SOAPVersion soapVersion) {
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fault {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* This method is not designed for efficiency, and we don't expect
|
||||
* to be used for the performance critical codepath.
|
||||
*
|
||||
* @param fault
|
||||
* The populated SAAJ data structure that represents a fault
|
||||
* in detail.
|
||||
*
|
||||
* @return
|
||||
* Always non-null. A message that wraps this {@link SOAPFault}.
|
||||
*/
|
||||
public static Message create(SOAPFault fault) {
|
||||
SOAPVersion ver = SOAPVersion.fromNsUri(fault.getNamespaceURI());
|
||||
return new DOMMessage(ver,fault);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #createAddressingFaultMessage(WSBinding, Packet, QName)}
|
||||
*/
|
||||
public static Message createAddressingFaultMessage(WSBinding binding, QName missingHeader) {
|
||||
return createAddressingFaultMessage(binding,null,missingHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fault {@link Message} that captures the code/subcode/subsubcode
|
||||
* defined by WS-Addressing if one of the expected WS-Addressing headers is
|
||||
* missing in the message
|
||||
*
|
||||
* @param binding WSBinding
|
||||
* @param p
|
||||
* {@link Packet} that was missing a WS-Addressing header.
|
||||
* @param missingHeader The missing WS-Addressing Header
|
||||
* @return
|
||||
* A message representing SOAPFault that contains the WS-Addressing code/subcode/subsubcode.
|
||||
*/
|
||||
public static Message createAddressingFaultMessage(WSBinding binding, Packet p, QName missingHeader) {
|
||||
AddressingVersion av = binding.getAddressingVersion();
|
||||
if(av == null) {
|
||||
// Addressing is not enabled.
|
||||
throw new WebServiceException(AddressingMessages.ADDRESSING_SHOULD_BE_ENABLED());
|
||||
}
|
||||
WsaTubeHelper helper = av.getWsaHelper(null,null,binding);
|
||||
return create(helper.newMapRequiredFault(new MissingAddressingHeaderException(missingHeader,p)));
|
||||
}
|
||||
/**
|
||||
* Creates a fault {@link Message} that captures the code/subcode/subsubcode
|
||||
* defined by WS-Addressing if wsa:Action is not supported.
|
||||
*
|
||||
* @param unsupportedAction The unsupported Action. Must not be null.
|
||||
* @param av The WS-Addressing version of the message. Must not be null.
|
||||
* @param sv The SOAP Version of the message. Must not be null.
|
||||
*
|
||||
* @return
|
||||
* A message representing SOAPFault that contains the WS-Addressing code/subcode/subsubcode.
|
||||
*/
|
||||
public static Message create(@NotNull String unsupportedAction, @NotNull AddressingVersion av, @NotNull SOAPVersion sv) {
|
||||
QName subcode = av.actionNotSupportedTag;
|
||||
String faultstring = String.format(av.actionNotSupportedText, unsupportedAction);
|
||||
|
||||
Message faultMessage;
|
||||
SOAPFault fault;
|
||||
try {
|
||||
if (sv == SOAPVersion.SOAP_12) {
|
||||
fault = SOAPVersion.SOAP_12.getSOAPFactory().createFault();
|
||||
fault.setFaultCode(SOAPConstants.SOAP_SENDER_FAULT);
|
||||
fault.appendFaultSubcode(subcode);
|
||||
Detail detail = fault.addDetail();
|
||||
SOAPElement se = detail.addChildElement(av.problemActionTag);
|
||||
se = se.addChildElement(av.actionTag);
|
||||
se.addTextNode(unsupportedAction);
|
||||
} else {
|
||||
fault = SOAPVersion.SOAP_11.getSOAPFactory().createFault();
|
||||
fault.setFaultCode(subcode);
|
||||
}
|
||||
fault.setFaultString(faultstring);
|
||||
|
||||
faultMessage = SOAPFaultBuilder.createSOAPFaultMessage(sv, fault);
|
||||
if (sv == SOAPVersion.SOAP_11) {
|
||||
faultMessage.getHeaders().add(new ProblemActionHeader(unsupportedAction, av));
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
|
||||
return faultMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called to convert a {@link ProtocolException} and faultcode for a given {@link SOAPVersion} in to a {@link Message}.
|
||||
*
|
||||
* @param soapVersion {@link SOAPVersion#SOAP_11} or {@link SOAPVersion#SOAP_12}
|
||||
* @param pex a ProtocolException
|
||||
* @param faultcode soap faultcode. Its ignored if the {@link ProtocolException} instance is {@link javax.xml.ws.soap.SOAPFaultException} and it has a
|
||||
* faultcode present in the underlying {@link SOAPFault}.
|
||||
* @return {@link Message} representing SOAP fault
|
||||
*/
|
||||
public static @NotNull Message create(@NotNull SOAPVersion soapVersion, @NotNull ProtocolException pex, @Nullable QName faultcode){
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, pex, faultcode);
|
||||
}
|
||||
}
|
||||
1475
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Packet.java
Normal file
1475
jdkSrc/jdk8/com/sun/xml/internal/ws/api/message/Packet.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
public interface StreamingSOAP {
|
||||
public XMLStreamReader readEnvelope();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
|
||||
/**
|
||||
* Suppresses automatic generation of WS-Addressing headers in request messages. Use this in cases
|
||||
* where required headers will be generated by other means.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public class SuppressAutomaticWSARequestHeadersFeature extends
|
||||
WebServiceFeature {
|
||||
|
||||
public SuppressAutomaticWSARequestHeadersFeature() {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return SuppressAutomaticWSARequestHeadersFeature.class.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@link com.sun.xml.internal.ws.api.message.Message} and related abstractions that represent a SOAP message.
|
||||
*/
|
||||
package com.sun.xml.internal.ws.api.message;
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.saaj;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.xml.soap.AttachmentPart;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SAAJMetaFactory;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPFactory;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sun.xml.internal.bind.marshaller.SAX2DOMEx;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentEx;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.message.saaj.SAAJMessage;
|
||||
import com.sun.xml.internal.ws.util.ServiceFinder;
|
||||
import com.sun.xml.internal.ws.util.xml.XmlUtil;
|
||||
|
||||
/**
|
||||
* Factory SPI for SAAJ implementations
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public class SAAJFactory {
|
||||
private static final SAAJFactory instance = new SAAJFactory();
|
||||
|
||||
/**
|
||||
* Creates a new <code>MessageFactory</code> object that is an instance
|
||||
* of the specified implementation. May be a dynamic message factory,
|
||||
* a SOAP 1.1 message factory, or a SOAP 1.2 message factory. A dynamic
|
||||
* message factory creates messages based on the MIME headers specified
|
||||
* as arguments to the <code>createMessage</code> method.
|
||||
*
|
||||
* This method uses the SAAJMetaFactory to locate the implementation class
|
||||
* and create the MessageFactory instance.
|
||||
*
|
||||
* @return a new instance of a <code>MessageFactory</code>
|
||||
*
|
||||
* @param protocol a string constant representing the class of the
|
||||
* specified message factory implementation. May be
|
||||
* either <code>DYNAMIC_SOAP_PROTOCOL</code>,
|
||||
* <code>DEFAULT_SOAP_PROTOCOL</code> (which is the same
|
||||
* as) <code>SOAP_1_1_PROTOCOL</code>, or
|
||||
* <code>SOAP_1_2_PROTOCOL</code>.
|
||||
*
|
||||
* @exception SOAPException if there was an error in creating the
|
||||
* specified implementation of <code>MessageFactory</code>.
|
||||
* @see SAAJMetaFactory
|
||||
*/
|
||||
public static MessageFactory getMessageFactory(String protocol) throws SOAPException {
|
||||
for (SAAJFactory s : ServiceFinder.find(SAAJFactory.class)) {
|
||||
MessageFactory mf = s.createMessageFactory(protocol);
|
||||
if (mf != null)
|
||||
return mf;
|
||||
}
|
||||
|
||||
return instance.createMessageFactory(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SOAPFactory</code> object that is an instance of
|
||||
* the specified implementation, this method uses the SAAJMetaFactory to
|
||||
* locate the implementation class and create the SOAPFactory instance.
|
||||
*
|
||||
* @return a new instance of a <code>SOAPFactory</code>
|
||||
*
|
||||
* @param protocol a string constant representing the protocol of the
|
||||
* specified SOAP factory implementation. May be
|
||||
* either <code>DYNAMIC_SOAP_PROTOCOL</code>,
|
||||
* <code>DEFAULT_SOAP_PROTOCOL</code> (which is the same
|
||||
* as) <code>SOAP_1_1_PROTOCOL</code>, or
|
||||
* <code>SOAP_1_2_PROTOCOL</code>.
|
||||
*
|
||||
* @exception SOAPException if there was an error creating the
|
||||
* specified <code>SOAPFactory</code>
|
||||
* @see SAAJMetaFactory
|
||||
*/
|
||||
public static SOAPFactory getSOAPFactory(String protocol) throws SOAPException {
|
||||
for (SAAJFactory s : ServiceFinder.find(SAAJFactory.class)) {
|
||||
SOAPFactory sf = s.createSOAPFactory(protocol);
|
||||
if (sf != null)
|
||||
return sf;
|
||||
}
|
||||
|
||||
return instance.createSOAPFactory(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Message from SOAPMessage
|
||||
* @param saaj SOAPMessage
|
||||
* @return created Message
|
||||
*/
|
||||
public static Message create(SOAPMessage saaj) {
|
||||
for (SAAJFactory s : ServiceFinder.find(SAAJFactory.class)) {
|
||||
Message m = s.createMessage(saaj);
|
||||
if (m != null)
|
||||
return m;
|
||||
}
|
||||
|
||||
return instance.createMessage(saaj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Message as SOAPMessage. After this call message is consumed.
|
||||
* @param soapVersion SOAP version
|
||||
* @param message Message
|
||||
* @return Created SOAPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public static SOAPMessage read(SOAPVersion soapVersion, Message message) throws SOAPException {
|
||||
for (SAAJFactory s : ServiceFinder.find(SAAJFactory.class)) {
|
||||
SOAPMessage msg = s.readAsSOAPMessage(soapVersion, message);
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
return instance.readAsSOAPMessage(soapVersion, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Message as SOAPMessage. After this call message is consumed.
|
||||
* @param soapVersion SOAP version
|
||||
* @param message Message
|
||||
* @param packet The packet that owns the Message
|
||||
* @return Created SOAPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public static SOAPMessage read(SOAPVersion soapVersion, Message message, Packet packet) throws SOAPException {
|
||||
for (SAAJFactory s : ServiceFinder.find(SAAJFactory.class)) {
|
||||
SOAPMessage msg = s.readAsSOAPMessage(soapVersion, message, packet);
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
return instance.readAsSOAPMessage(soapVersion, message, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the message within the Packet to a SAAJMessage. After this call message is consumed.
|
||||
* @param packet Packet
|
||||
* @return Created SAAJPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public static SAAJMessage read(Packet packet) throws SOAPException {
|
||||
// Use the Component from the Packet if it exists. Note the logic
|
||||
// in the ServiceFinder is such that find(Class) is not equivalent
|
||||
// to find (Class, null), so the ternary operator is needed.
|
||||
ServiceFinder<SAAJFactory> factories = (packet.component != null ?
|
||||
ServiceFinder.find(SAAJFactory.class, packet.component) :
|
||||
ServiceFinder.find(SAAJFactory.class));
|
||||
for (SAAJFactory s : factories) {
|
||||
SAAJMessage msg = s.readAsSAAJ(packet);
|
||||
if (msg != null) return msg;
|
||||
}
|
||||
return instance.readAsSAAJ(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the message within the Packet to a SAAJMessage. After this call message is consumed.
|
||||
* @param packet Packet
|
||||
* @return Created SAAJPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public SAAJMessage readAsSAAJ(Packet packet) throws SOAPException {
|
||||
SOAPVersion v = packet.getMessage().getSOAPVersion();
|
||||
SOAPMessage msg = readAsSOAPMessage(v, packet.getMessage());
|
||||
return new SAAJMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>MessageFactory</code> object that is an instance
|
||||
* of the specified implementation. May be a dynamic message factory,
|
||||
* a SOAP 1.1 message factory, or a SOAP 1.2 message factory. A dynamic
|
||||
* message factory creates messages based on the MIME headers specified
|
||||
* as arguments to the <code>createMessage</code> method.
|
||||
*
|
||||
* This method uses the SAAJMetaFactory to locate the implementation class
|
||||
* and create the MessageFactory instance.
|
||||
*
|
||||
* @return a new instance of a <code>MessageFactory</code>
|
||||
*
|
||||
* @param protocol a string constant representing the class of the
|
||||
* specified message factory implementation. May be
|
||||
* either <code>DYNAMIC_SOAP_PROTOCOL</code>,
|
||||
* <code>DEFAULT_SOAP_PROTOCOL</code> (which is the same
|
||||
* as) <code>SOAP_1_1_PROTOCOL</code>, or
|
||||
* <code>SOAP_1_2_PROTOCOL</code>.
|
||||
*
|
||||
* @exception SOAPException if there was an error in creating the
|
||||
* specified implementation of <code>MessageFactory</code>.
|
||||
* @see SAAJMetaFactory
|
||||
*/
|
||||
public MessageFactory createMessageFactory(String protocol) throws SOAPException {
|
||||
return MessageFactory.newInstance(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SOAPFactory</code> object that is an instance of
|
||||
* the specified implementation, this method uses the SAAJMetaFactory to
|
||||
* locate the implementation class and create the SOAPFactory instance.
|
||||
*
|
||||
* @return a new instance of a <code>SOAPFactory</code>
|
||||
*
|
||||
* @param protocol a string constant representing the protocol of the
|
||||
* specified SOAP factory implementation. May be
|
||||
* either <code>DYNAMIC_SOAP_PROTOCOL</code>,
|
||||
* <code>DEFAULT_SOAP_PROTOCOL</code> (which is the same
|
||||
* as) <code>SOAP_1_1_PROTOCOL</code>, or
|
||||
* <code>SOAP_1_2_PROTOCOL</code>.
|
||||
*
|
||||
* @exception SOAPException if there was an error creating the
|
||||
* specified <code>SOAPFactory</code>
|
||||
* @see SAAJMetaFactory
|
||||
*/
|
||||
public SOAPFactory createSOAPFactory(String protocol) throws SOAPException {
|
||||
return SOAPFactory.newInstance(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Message from SOAPMessage
|
||||
* @param saaj SOAPMessage
|
||||
* @return created Message
|
||||
*/
|
||||
public Message createMessage(SOAPMessage saaj) {
|
||||
return new SAAJMessage(saaj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Message as SOAPMessage. After this call message is consumed.
|
||||
* @param soapVersion SOAP version
|
||||
* @param message Message
|
||||
* @return Created SOAPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public SOAPMessage readAsSOAPMessage(final SOAPVersion soapVersion, final Message message) throws SOAPException {
|
||||
SOAPMessage msg = soapVersion.getMessageFactory().createMessage();
|
||||
SaajStaxWriter writer = new SaajStaxWriter(msg);
|
||||
try {
|
||||
message.writeTo(writer);
|
||||
} catch (XMLStreamException e) {
|
||||
throw (e.getCause() instanceof SOAPException) ? (SOAPException) e.getCause() : new SOAPException(e);
|
||||
}
|
||||
msg = writer.getSOAPMessage();
|
||||
addAttachmentsToSOAPMessage(msg, message);
|
||||
if (msg.saveRequired())
|
||||
msg.saveChanges();
|
||||
return msg;
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessageSax2Dom(final SOAPVersion soapVersion, final Message message) throws SOAPException {
|
||||
SOAPMessage msg = soapVersion.getMessageFactory().createMessage();
|
||||
SAX2DOMEx s2d = new SAX2DOMEx(msg.getSOAPPart());
|
||||
try {
|
||||
message.writeTo(s2d, XmlUtil.DRACONIAN_ERROR_HANDLER);
|
||||
} catch (SAXException e) {
|
||||
throw new SOAPException(e);
|
||||
}
|
||||
addAttachmentsToSOAPMessage(msg, message);
|
||||
if (msg.saveRequired())
|
||||
msg.saveChanges();
|
||||
return msg;
|
||||
}
|
||||
|
||||
static protected void addAttachmentsToSOAPMessage(SOAPMessage msg, Message message) {
|
||||
for(Attachment att : message.getAttachments()) {
|
||||
AttachmentPart part = msg.createAttachmentPart();
|
||||
part.setDataHandler(att.asDataHandler());
|
||||
|
||||
// Be safe and avoid double angle-brackets.
|
||||
String cid = att.getContentId();
|
||||
if (cid != null) {
|
||||
if (cid.startsWith("<") && cid.endsWith(">"))
|
||||
part.setContentId(cid);
|
||||
else
|
||||
part.setContentId('<' + cid + '>');
|
||||
}
|
||||
|
||||
// Add any MIME headers beside Content-ID, which is already
|
||||
// accounted for above, and Content-Type, which is provided
|
||||
// by the DataHandler above.
|
||||
if (att instanceof AttachmentEx) {
|
||||
AttachmentEx ax = (AttachmentEx) att;
|
||||
Iterator<AttachmentEx.MimeHeader> imh = ax.getMimeHeaders();
|
||||
while (imh.hasNext()) {
|
||||
AttachmentEx.MimeHeader ame = imh.next();
|
||||
if ((!"Content-ID".equals(ame.getName()))
|
||||
&& (!"Content-Type".equals(ame.getName())))
|
||||
part.addMimeHeader(ame.getName(), ame.getValue());
|
||||
}
|
||||
}
|
||||
msg.addAttachmentPart(part);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Message as SOAPMessage. After this call message is consumed.
|
||||
* The implementation in this class simply calls readAsSOAPMessage(SOAPVersion, Message),
|
||||
* and ignores the other parameters
|
||||
* Subclasses can override and choose to base SOAPMessage creation on Packet properties if needed
|
||||
* @param soapVersion SOAP version
|
||||
* @param message Message
|
||||
* @return Created SOAPMessage
|
||||
* @throws SOAPException if SAAJ processing fails
|
||||
*/
|
||||
public SOAPMessage readAsSOAPMessage(SOAPVersion soapVersion, Message message, Packet packet) throws SOAPException {
|
||||
return readAsSOAPMessage(soapVersion, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.saaj;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPHeader;
|
||||
import javax.xml.soap.SOAPHeaderElement;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Header;
|
||||
import com.sun.xml.internal.ws.api.message.MessageHeaders;
|
||||
import com.sun.xml.internal.ws.binding.SOAPBindingImpl;
|
||||
import com.sun.xml.internal.ws.message.saaj.SAAJHeader;
|
||||
|
||||
public class SAAJMessageHeaders implements MessageHeaders {
|
||||
SOAPMessage sm;
|
||||
Map<SOAPHeaderElement, Header> nonSAAJHeaders;
|
||||
Map<QName, Integer> notUnderstoodCount;
|
||||
SOAPVersion soapVersion;
|
||||
private Set<QName> understoodHeaders;
|
||||
|
||||
public SAAJMessageHeaders(SOAPMessage sm, SOAPVersion version) {
|
||||
this.sm = sm;
|
||||
this.soapVersion = version;
|
||||
initHeaderUnderstanding();
|
||||
}
|
||||
|
||||
/** Set the initial understood/not understood state of the headers in this
|
||||
* object
|
||||
*/
|
||||
private void initHeaderUnderstanding() {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
while(allHeaders.hasNext()) {
|
||||
SOAPHeaderElement nextHdrElem = (SOAPHeaderElement) allHeaders.next();
|
||||
if (nextHdrElem == null) {
|
||||
continue;
|
||||
}
|
||||
if (nextHdrElem.getMustUnderstand()) {
|
||||
notUnderstood(nextHdrElem.getElementQName());
|
||||
}
|
||||
//only headers explicitly marked as understood should be
|
||||
//in the understoodHeaders set, so don't add anything to
|
||||
//that set at the beginning
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void understood(Header header) {
|
||||
understood(header.getNamespaceURI(), header.getLocalPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void understood(String nsUri, String localName) {
|
||||
understood(new QName(nsUri, localName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void understood(QName qName) {
|
||||
if (notUnderstoodCount == null) {
|
||||
notUnderstoodCount = new HashMap<QName, Integer>();
|
||||
}
|
||||
|
||||
Integer count = notUnderstoodCount.get(qName);
|
||||
if (count != null && count.intValue() > 0) {
|
||||
//found the header in notUnderstood headers - decrement count
|
||||
count = count.intValue() - 1;
|
||||
if (count <= 0) {
|
||||
//if the value is zero or negative, remove that header name
|
||||
//since all headers by that name are understood now
|
||||
notUnderstoodCount.remove(qName);
|
||||
} else {
|
||||
notUnderstoodCount.put(qName, count);
|
||||
}
|
||||
}
|
||||
|
||||
if (understoodHeaders == null) {
|
||||
understoodHeaders = new HashSet<QName>();
|
||||
}
|
||||
//also add it to the understood headers list (optimization for getUnderstoodHeaders)
|
||||
understoodHeaders.add(qName);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnderstood(Header header) {
|
||||
return isUnderstood(header.getNamespaceURI(), header.getLocalPart());
|
||||
}
|
||||
@Override
|
||||
public boolean isUnderstood(String nsUri, String localName) {
|
||||
return isUnderstood(new QName(nsUri, localName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnderstood(QName name) {
|
||||
if (understoodHeaders == null) {
|
||||
return false;
|
||||
}
|
||||
return understoodHeaders.contains(name);
|
||||
}
|
||||
|
||||
public boolean isUnderstood(int index) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header get(String nsUri, String localName, boolean markAsUnderstood) {
|
||||
SOAPHeaderElement h = find(nsUri, localName);
|
||||
if (h != null) {
|
||||
if (markAsUnderstood) {
|
||||
understood(nsUri, localName);
|
||||
}
|
||||
return new SAAJHeader(h);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header get(QName name, boolean markAsUnderstood) {
|
||||
return get(name.getNamespaceURI(), name.getLocalPart(), markAsUnderstood);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Header> getHeaders(QName headerName,
|
||||
boolean markAsUnderstood) {
|
||||
return getHeaders(headerName.getNamespaceURI(), headerName.getLocalPart(), markAsUnderstood);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Header> getHeaders(final String nsUri, final String localName,
|
||||
final boolean markAsUnderstood) {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return null;
|
||||
}
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
if (markAsUnderstood) {
|
||||
//mark all the matchingheaders as understood up front
|
||||
//make an iterator while we're doing that
|
||||
List<Header> headers = new ArrayList<Header>();
|
||||
while (allHeaders.hasNext()) {
|
||||
SOAPHeaderElement nextHdr = (SOAPHeaderElement) allHeaders.next();
|
||||
if (nextHdr != null &&
|
||||
nextHdr.getNamespaceURI().equals(nsUri)) {
|
||||
if (localName == null ||
|
||||
nextHdr.getLocalName().equals(localName)) {
|
||||
understood(nextHdr.getNamespaceURI(), nextHdr.getLocalName());
|
||||
headers.add(new SAAJHeader(nextHdr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return headers.iterator();
|
||||
}
|
||||
//if we got here markAsUnderstood is false - return a lazy iterator rather
|
||||
//than traverse the entire list of headers now
|
||||
return new HeaderReadIterator(allHeaders, nsUri, localName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Header> getHeaders(String nsUri, boolean markAsUnderstood) {
|
||||
return getHeaders(nsUri, null, markAsUnderstood);
|
||||
}
|
||||
@Override
|
||||
public boolean add(Header header) {
|
||||
try {
|
||||
header.writeTo(sm);
|
||||
} catch (SOAPException e) {
|
||||
//TODO log exception
|
||||
return false;
|
||||
}
|
||||
|
||||
//the newly added header is not understood by default
|
||||
notUnderstood(new QName(header.getNamespaceURI(), header.getLocalPart()));
|
||||
|
||||
//track non saaj headers so that they can be retrieved later
|
||||
if (isNonSAAJHeader(header)) {
|
||||
//TODO assumes only one header with that name?
|
||||
addNonSAAJHeader(find(header.getNamespaceURI(), header.getLocalPart()),
|
||||
header);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header remove(QName name) {
|
||||
return remove(name.getNamespaceURI(), name.getLocalPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header remove(String nsUri, String localName) {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return null;
|
||||
}
|
||||
SOAPHeaderElement headerElem = find(nsUri, localName);
|
||||
if (headerElem == null) {
|
||||
return null;
|
||||
}
|
||||
headerElem = (SOAPHeaderElement) soapHeader.removeChild(headerElem);
|
||||
|
||||
//it might have been a nonSAAJHeader - remove from that map
|
||||
removeNonSAAJHeader(headerElem);
|
||||
|
||||
//remove it from understoodHeaders and notUnderstoodHeaders if present
|
||||
QName hdrName = (nsUri == null) ? new QName(localName) : new QName(nsUri, localName);
|
||||
if (understoodHeaders != null) {
|
||||
understoodHeaders.remove(hdrName);
|
||||
}
|
||||
removeNotUnderstood(hdrName);
|
||||
|
||||
return new SAAJHeader(headerElem);
|
||||
}
|
||||
|
||||
private void removeNotUnderstood(QName hdrName) {
|
||||
if (notUnderstoodCount == null) {
|
||||
return;
|
||||
}
|
||||
Integer notUnderstood = notUnderstoodCount.get(hdrName);
|
||||
if (notUnderstood != null) {
|
||||
int intNotUnderstood = notUnderstood;
|
||||
intNotUnderstood--;
|
||||
if (intNotUnderstood <= 0) {
|
||||
notUnderstoodCount.remove(hdrName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SOAPHeaderElement find(QName qName) {
|
||||
return find(qName.getNamespaceURI(), qName.getLocalPart());
|
||||
}
|
||||
|
||||
private SOAPHeaderElement find(String nsUri, String localName) {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return null;
|
||||
}
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
while(allHeaders.hasNext()) {
|
||||
SOAPHeaderElement nextHdrElem = (SOAPHeaderElement) allHeaders.next();
|
||||
if (nextHdrElem.getNamespaceURI().equals(nsUri) &&
|
||||
nextHdrElem.getLocalName().equals(localName)) {
|
||||
return nextHdrElem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void notUnderstood(QName qName) {
|
||||
if (notUnderstoodCount == null) {
|
||||
notUnderstoodCount = new HashMap<QName, Integer>();
|
||||
}
|
||||
Integer count = notUnderstoodCount.get(qName);
|
||||
if (count == null) {
|
||||
notUnderstoodCount.put(qName, 1);
|
||||
} else {
|
||||
notUnderstoodCount.put(qName, count + 1);
|
||||
}
|
||||
|
||||
//if for some strange reason it was previously understood and now is not,
|
||||
//remove it from understoodHeaders if it exists there
|
||||
if (understoodHeaders != null) {
|
||||
understoodHeaders.remove(qName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the SOAPHeader from a SOAPMessage, adding one if
|
||||
* one is not present in the original message.
|
||||
*/
|
||||
private SOAPHeader ensureSOAPHeader() {
|
||||
SOAPHeader header;
|
||||
try {
|
||||
header = sm.getSOAPPart().getEnvelope().getHeader();
|
||||
if (header != null) {
|
||||
return header;
|
||||
} else {
|
||||
return sm.getSOAPPart().getEnvelope().addHeader();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNonSAAJHeader(Header header) {
|
||||
return !(header instanceof SAAJHeader);
|
||||
}
|
||||
|
||||
private void addNonSAAJHeader(SOAPHeaderElement headerElem, Header header) {
|
||||
if (nonSAAJHeaders == null) {
|
||||
nonSAAJHeaders = new HashMap<SOAPHeaderElement, Header>();
|
||||
}
|
||||
nonSAAJHeaders.put(headerElem, header);
|
||||
}
|
||||
|
||||
private void removeNonSAAJHeader(SOAPHeaderElement headerElem) {
|
||||
if (nonSAAJHeaders != null) {
|
||||
nonSAAJHeaders.remove(headerElem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addOrReplace(Header header) {
|
||||
remove(header.getNamespaceURI(), header.getLocalPart());
|
||||
return add(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(Header old, Header header) {
|
||||
if (remove(old.getNamespaceURI(), old.getLocalPart()) == null)
|
||||
throw new IllegalArgumentException();
|
||||
add(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getUnderstoodHeaders() {
|
||||
return understoodHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<QName> getNotUnderstoodHeaders(Set<String> roles,
|
||||
Set<QName> knownHeaders, WSBinding binding) {
|
||||
Set<QName> notUnderstoodHeaderNames = new HashSet<QName>();
|
||||
if (notUnderstoodCount == null) {
|
||||
return notUnderstoodHeaderNames;
|
||||
}
|
||||
for (QName headerName : notUnderstoodCount.keySet()) {
|
||||
int count = notUnderstoodCount.get(headerName);
|
||||
if (count <= 0) {
|
||||
continue;
|
||||
}
|
||||
SOAPHeaderElement hdrElem = find(headerName);
|
||||
if (!hdrElem.getMustUnderstand()) {
|
||||
continue;
|
||||
}
|
||||
SAAJHeader hdr = new SAAJHeader(hdrElem);
|
||||
//mustUnderstand attribute is true - but there may be
|
||||
//additional criteria
|
||||
boolean understood = false;
|
||||
if (roles != null) {
|
||||
understood = !roles.contains(hdr.getRole(soapVersion));
|
||||
}
|
||||
if (understood) {
|
||||
continue;
|
||||
}
|
||||
//if it must be understood see if it is understood by the binding
|
||||
//or is in knownheaders
|
||||
if (binding != null && binding instanceof SOAPBindingImpl) {
|
||||
understood = ((SOAPBindingImpl) binding).understandsHeader(headerName);
|
||||
if (!understood) {
|
||||
if (knownHeaders != null && knownHeaders.contains(headerName)) {
|
||||
understood = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!understood) {
|
||||
notUnderstoodHeaderNames.add(headerName);
|
||||
}
|
||||
}
|
||||
return notUnderstoodHeaderNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Header> getHeaders() {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return null;
|
||||
}
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
return new HeaderReadIterator(allHeaders, null, null);
|
||||
}
|
||||
|
||||
private static class HeaderReadIterator implements Iterator<Header> {
|
||||
SOAPHeaderElement current;
|
||||
Iterator soapHeaders;
|
||||
String myNsUri;
|
||||
String myLocalName;
|
||||
|
||||
public HeaderReadIterator(Iterator allHeaders, String nsUri,
|
||||
String localName) {
|
||||
this.soapHeaders = allHeaders;
|
||||
this.myNsUri = nsUri;
|
||||
this.myLocalName = localName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (current == null) {
|
||||
advance();
|
||||
}
|
||||
return (current != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header next() {
|
||||
if (!hasNext()) {
|
||||
return null;
|
||||
}
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SAAJHeader ret = new SAAJHeader(current);
|
||||
current = null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void advance() {
|
||||
while (soapHeaders.hasNext()) {
|
||||
SOAPHeaderElement nextHdr = (SOAPHeaderElement) soapHeaders.next();
|
||||
if (nextHdr != null &&
|
||||
(myNsUri == null || nextHdr.getNamespaceURI().equals(myNsUri)) &&
|
||||
(myLocalName == null || nextHdr.getLocalName().equals(myLocalName))) {
|
||||
current = nextHdr;
|
||||
//found it
|
||||
return;
|
||||
}
|
||||
}
|
||||
//if we got here we didn't find a match
|
||||
current = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHeaders() {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
return allHeaders.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Header> asList() {
|
||||
SOAPHeader soapHeader = ensureSOAPHeader();
|
||||
if (soapHeader == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Iterator allHeaders = soapHeader.examineAllHeaderElements();
|
||||
List<Header> headers = new ArrayList<Header>();
|
||||
while (allHeaders.hasNext()) {
|
||||
SOAPHeaderElement nextHdr = (SOAPHeaderElement) allHeaders.next();
|
||||
headers.add(new SAAJHeader(nextHdr));
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.saaj;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPElement;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
|
||||
import org.w3c.dom.Comment;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface.
|
||||
*
|
||||
* <p>
|
||||
* Defers creation of SOAPElement until all the aspects of the name of the element are known.
|
||||
* In some cases, the namespace uri is indicated only by the {@link #writeNamespace(String, String)} call.
|
||||
* After opening an element ({@code writeStartElement}, {@code writeEmptyElement} methods), all attributes
|
||||
* and namespace assignments are retained within {@link DeferredElement} object ({@code deferredElement} field).
|
||||
* As soon as any other method than {@code writeAttribute}, {@code writeNamespace}, {@code writeDefaultNamespace}
|
||||
* or {@code setNamespace} is called, the contents of {@code deferredElement} is transformed into new SOAPElement
|
||||
* (which is appropriately inserted into the SOAPMessage under construction).
|
||||
* This mechanism is necessary to fix JDK-8159058 issue.
|
||||
* </p>
|
||||
*
|
||||
* @author shih-chang.chen@oracle.com
|
||||
*/
|
||||
public class SaajStaxWriter implements XMLStreamWriter {
|
||||
|
||||
protected SOAPMessage soap;
|
||||
protected String envURI;
|
||||
protected SOAPElement currentElement;
|
||||
protected DeferredElement deferredElement;
|
||||
|
||||
static final protected String Envelope = "Envelope";
|
||||
static final protected String Header = "Header";
|
||||
static final protected String Body = "Body";
|
||||
static final protected String xmlns = "xmlns";
|
||||
|
||||
public SaajStaxWriter(final SOAPMessage msg) throws SOAPException {
|
||||
soap = msg;
|
||||
currentElement = soap.getSOAPPart().getEnvelope();
|
||||
envURI = currentElement.getNamespaceURI();
|
||||
this.deferredElement = new DeferredElement();
|
||||
}
|
||||
|
||||
public SOAPMessage getSOAPMessage() {
|
||||
return soap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartElement(final String localName) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
deferredElement.setLocalName(localName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartElement(final String ns, final String ln) throws XMLStreamException {
|
||||
writeStartElement(null, ln, ns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
|
||||
if (envURI.equals(ns)) {
|
||||
try {
|
||||
if (Envelope.equals(ln)) {
|
||||
currentElement = soap.getSOAPPart().getEnvelope();
|
||||
fixPrefix(prefix);
|
||||
return;
|
||||
} else if (Header.equals(ln)) {
|
||||
currentElement = soap.getSOAPHeader();
|
||||
fixPrefix(prefix);
|
||||
return;
|
||||
} else if (Body.equals(ln)) {
|
||||
currentElement = soap.getSOAPBody();
|
||||
fixPrefix(prefix);
|
||||
return;
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deferredElement.setLocalName(ln);
|
||||
deferredElement.setNamespaceUri(ns);
|
||||
deferredElement.setPrefix(prefix);
|
||||
|
||||
}
|
||||
|
||||
private void fixPrefix(final String prfx) throws XMLStreamException {
|
||||
String oldPrfx = currentElement.getPrefix();
|
||||
if (prfx != null && !prfx.equals(oldPrfx)) {
|
||||
currentElement.setPrefix(prfx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEmptyElement(final String uri, final String ln) throws XMLStreamException {
|
||||
writeStartElement(null, ln, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEmptyElement(final String prefix, final String ln, final String uri) throws XMLStreamException {
|
||||
writeStartElement(prefix, ln, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEmptyElement(final String ln) throws XMLStreamException {
|
||||
writeStartElement(null, ln, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEndElement() throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
if (currentElement != null) currentElement = currentElement.getParentElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEndDocument() throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws XMLStreamException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws XMLStreamException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAttribute(final String ln, final String val) throws XMLStreamException {
|
||||
writeAttribute(null, null, ln, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException {
|
||||
if (ns == null && prefix == null && xmlns.equals(ln)) {
|
||||
writeNamespace("", value);
|
||||
} else {
|
||||
if (deferredElement.isInitialized()) {
|
||||
deferredElement.addAttribute(prefix, ns, ln, value);
|
||||
} else {
|
||||
addAttibuteToElement(currentElement, prefix, ns, ln, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAttribute(final String ns, final String ln, final String val) throws XMLStreamException {
|
||||
writeAttribute(null, ns, ln, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNamespace(String prefix, final String uri) throws XMLStreamException {
|
||||
// make prefix default if null or "xmlns" (according to javadoc)
|
||||
String thePrefix = prefix == null || "xmlns".equals(prefix) ? "" : prefix;
|
||||
if (deferredElement.isInitialized()) {
|
||||
deferredElement.addNamespaceDeclaration(thePrefix, uri);
|
||||
} else {
|
||||
try {
|
||||
currentElement.addNamespaceDeclaration(thePrefix, uri);
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDefaultNamespace(final String uri) throws XMLStreamException {
|
||||
writeNamespace("", uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeComment(final String data) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
Comment c = soap.getSOAPPart().createComment(data);
|
||||
currentElement.appendChild(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProcessingInstruction(final String target) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
Node n = soap.getSOAPPart().createProcessingInstruction(target, "");
|
||||
currentElement.appendChild(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
Node n = soap.getSOAPPart().createProcessingInstruction(target, data);
|
||||
currentElement.appendChild(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCData(final String data) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
Node n = soap.getSOAPPart().createCDATASection(data);
|
||||
currentElement.appendChild(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDTD(final String dtd) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityRef(final String name) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
Node n = soap.getSOAPPart().createEntityReference(name);
|
||||
currentElement.appendChild(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartDocument() throws XMLStreamException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartDocument(final String version) throws XMLStreamException {
|
||||
if (version != null) soap.getSOAPPart().setXmlVersion(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartDocument(final String encoding, final String version) throws XMLStreamException {
|
||||
if (version != null) soap.getSOAPPart().setXmlVersion(version);
|
||||
if (encoding != null) {
|
||||
try {
|
||||
soap.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, encoding);
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCharacters(final String text) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
try {
|
||||
currentElement.addTextNode(text);
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
|
||||
currentElement = deferredElement.flushTo(currentElement);
|
||||
char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len);
|
||||
try {
|
||||
currentElement.addTextNode(new String(chr));
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix(final String uri) throws XMLStreamException {
|
||||
return currentElement.lookupPrefix(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
|
||||
// TODO: this in fact is not what would be expected from XMLStreamWriter
|
||||
// (e.g. XMLStreamWriter for writing to output stream does not write anything as result of
|
||||
// this method, it just rememebers that given prefix is associated with the given uri
|
||||
// for the scope; to actually declare the prefix assignment in the resulting XML, one
|
||||
// needs to call writeNamespace(...) method
|
||||
// Kept for backwards compatibility reasons - this might be worth of further investigation.
|
||||
if (deferredElement.isInitialized()) {
|
||||
deferredElement.addNamespaceDeclaration(prefix, uri);
|
||||
} else {
|
||||
throw new XMLStreamException("Namespace not associated with any element");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultNamespace(final String uri) throws XMLStreamException {
|
||||
setPrefix("", uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNamespaceContext(final NamespaceContext context)throws XMLStreamException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(final String name) throws IllegalArgumentException {
|
||||
//TODO the following line is to make eclipselink happy ... they are aware of this problem -
|
||||
if (javax.xml.stream.XMLOutputFactory.IS_REPAIRING_NAMESPACES.equals(name)) return Boolean.FALSE;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceContext getNamespaceContext() {
|
||||
return new NamespaceContext() {
|
||||
public String getNamespaceURI(final String prefix) {
|
||||
return currentElement.getNamespaceURI(prefix);
|
||||
}
|
||||
public String getPrefix(final String namespaceURI) {
|
||||
return currentElement.lookupPrefix(namespaceURI);
|
||||
}
|
||||
public Iterator getPrefixes(final String namespaceURI) {
|
||||
return new Iterator<String>() {
|
||||
String prefix = getPrefix(namespaceURI);
|
||||
public boolean hasNext() {
|
||||
return (prefix != null);
|
||||
}
|
||||
public String next() {
|
||||
if (!hasNext()) throw new java.util.NoSuchElementException();
|
||||
String next = prefix;
|
||||
prefix = null;
|
||||
return next;
|
||||
}
|
||||
public void remove() {}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void addAttibuteToElement(SOAPElement element, String prefix, String ns, String ln, String value)
|
||||
throws XMLStreamException {
|
||||
try {
|
||||
if (ns == null) {
|
||||
element.setAttributeNS("", ln, value);
|
||||
} else {
|
||||
QName name = prefix == null ? new QName(ns, ln) : new QName(ns, ln, prefix);
|
||||
element.addAttribute(name, value);
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds details of element that needs to be deferred in order to manage namespace assignments correctly.
|
||||
*
|
||||
* <p>
|
||||
* An instance of can be set with all the aspects of the element name (local name, prefix, namespace uri).
|
||||
* Attributes and namespace declarations (special case of attribute) can be added.
|
||||
* Namespace declarations are handled so that the element namespace is updated if it is implied by the namespace
|
||||
* declaration and the namespace was not set to non-{@code null} value previously.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The state of this object can be {@link #flushTo(SOAPElement) flushed} to SOAPElement - new SOAPElement will
|
||||
* be added a child element; the new element will have exactly the shape as represented by the state of this
|
||||
* object. Note that the {@link #flushTo(SOAPElement)} method does nothing
|
||||
* (and returns the argument immediately) if the state of this object is not initialized
|
||||
* (i.e. local name is null).
|
||||
* </p>
|
||||
*
|
||||
* @author ondrej.cerny@oracle.com
|
||||
*/
|
||||
static class DeferredElement {
|
||||
private String prefix;
|
||||
private String localName;
|
||||
private String namespaceUri;
|
||||
private final List<NamespaceDeclaration> namespaceDeclarations;
|
||||
private final List<AttributeDeclaration> attributeDeclarations;
|
||||
|
||||
DeferredElement() {
|
||||
this.namespaceDeclarations = new LinkedList<NamespaceDeclaration>();
|
||||
this.attributeDeclarations = new LinkedList<AttributeDeclaration>();
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set prefix of the element.
|
||||
* @param prefix namespace prefix
|
||||
*/
|
||||
public void setPrefix(final String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set local name of the element.
|
||||
*
|
||||
* <p>
|
||||
* This method initializes the element.
|
||||
* </p>
|
||||
*
|
||||
* @param localName local name {@code not null}
|
||||
*/
|
||||
public void setLocalName(final String localName) {
|
||||
if (localName == null) {
|
||||
throw new IllegalArgumentException("localName can not be null");
|
||||
}
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set namespace uri.
|
||||
*
|
||||
* @param namespaceUri namespace uri
|
||||
*/
|
||||
public void setNamespaceUri(final String namespaceUri) {
|
||||
this.namespaceUri = namespaceUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds namespace prefix assignment to the element.
|
||||
*
|
||||
* @param prefix prefix (not {@code null})
|
||||
* @param namespaceUri namespace uri
|
||||
*/
|
||||
public void addNamespaceDeclaration(final String prefix, final String namespaceUri) {
|
||||
if (null == this.namespaceUri && null != namespaceUri && prefix.equals(emptyIfNull(this.prefix))) {
|
||||
this.namespaceUri = namespaceUri;
|
||||
}
|
||||
this.namespaceDeclarations.add(new NamespaceDeclaration(prefix, namespaceUri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attribute to the element.
|
||||
* @param prefix prefix
|
||||
* @param ns namespace
|
||||
* @param ln local name
|
||||
* @param value value
|
||||
*/
|
||||
public void addAttribute(final String prefix, final String ns, final String ln, final String value) {
|
||||
if (ns == null && prefix == null && xmlns.equals(ln)) {
|
||||
this.addNamespaceDeclaration(prefix, value);
|
||||
} else {
|
||||
this.attributeDeclarations.add(new AttributeDeclaration(prefix, ns, ln, value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes state of this element to the {@code target} element.
|
||||
*
|
||||
* <p>
|
||||
* If this element is initialized then it is added with all the namespace declarations and attributes
|
||||
* to the {@code target} element as a child. The state of this element is reset to uninitialized.
|
||||
* The newly added element object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* If this element is not initialized then the {@code target} is returned immediately, nothing else is done.
|
||||
* </p>
|
||||
*
|
||||
* @param target target element
|
||||
* @return {@code target} or new element
|
||||
* @throws XMLStreamException on error
|
||||
*/
|
||||
public SOAPElement flushTo(final SOAPElement target) throws XMLStreamException {
|
||||
try {
|
||||
if (this.localName != null) {
|
||||
// add the element appropriately (based on namespace declaration)
|
||||
final SOAPElement newElement;
|
||||
if (this.namespaceUri == null) {
|
||||
// add element with inherited scope
|
||||
newElement = target.addChildElement(this.localName);
|
||||
} else if (prefix == null) {
|
||||
newElement = target.addChildElement(new QName(this.namespaceUri, this.localName));
|
||||
} else {
|
||||
newElement = target.addChildElement(this.localName, this.prefix, this.namespaceUri);
|
||||
}
|
||||
// add namespace declarations
|
||||
for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
|
||||
newElement.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
|
||||
}
|
||||
// add attribute declarations
|
||||
for (AttributeDeclaration attribute : this.attributeDeclarations) {
|
||||
addAttibuteToElement(newElement,
|
||||
attribute.prefix, attribute.namespaceUri, attribute.localName, attribute.value);
|
||||
}
|
||||
// reset state
|
||||
this.reset();
|
||||
|
||||
return newElement;
|
||||
} else {
|
||||
return target;
|
||||
}
|
||||
// else after reset state -> not initialized
|
||||
} catch (SOAPException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the element initialized?
|
||||
* @return boolean indicating whether it was initialized after last flush
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return this.localName != null;
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
this.localName = null;
|
||||
this.prefix = null;
|
||||
this.namespaceUri = null;
|
||||
this.namespaceDeclarations.clear();
|
||||
this.attributeDeclarations.clear();
|
||||
}
|
||||
|
||||
private static String emptyIfNull(String s) {
|
||||
return s == null ? "" : s;
|
||||
}
|
||||
}
|
||||
|
||||
static class NamespaceDeclaration {
|
||||
final String prefix;
|
||||
final String namespaceUri;
|
||||
|
||||
NamespaceDeclaration(String prefix, String namespaceUri) {
|
||||
this.prefix = prefix;
|
||||
this.namespaceUri = namespaceUri;
|
||||
}
|
||||
}
|
||||
|
||||
static class AttributeDeclaration {
|
||||
final String prefix;
|
||||
final String namespaceUri;
|
||||
final String localName;
|
||||
final String value;
|
||||
|
||||
AttributeDeclaration(String prefix, String namespaceUri, String localName, String value) {
|
||||
this.prefix = prefix;
|
||||
this.namespaceUri = namespaceUri;
|
||||
this.localName = localName;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.stream;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Low level representation of an XML or SOAP message as an {@link InputStream}.
|
||||
*
|
||||
*/
|
||||
public class InputStreamMessage extends StreamBasedMessage {
|
||||
/**
|
||||
* The MIME content-type of the encoding.
|
||||
*/
|
||||
public final String contentType;
|
||||
|
||||
/**
|
||||
* The message represented as an {@link InputStream}.
|
||||
*/
|
||||
public final InputStream msg;
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
* @param contentType
|
||||
* the MIME content-type of the encoding.
|
||||
*
|
||||
* @param msg
|
||||
* always a non-null unconsumed {@link InputStream} that
|
||||
* represents a request.
|
||||
*/
|
||||
public InputStreamMessage(Packet properties, String contentType, InputStream msg) {
|
||||
super(properties);
|
||||
|
||||
this.contentType = contentType;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
* @param attachments
|
||||
* the attachments of the message.
|
||||
*
|
||||
* @param contentType
|
||||
* the MIME content-type of the encoding.
|
||||
*
|
||||
* @param msg
|
||||
* always a non-null unconsumed {@link InputStream} that
|
||||
* represents a request.
|
||||
*/
|
||||
public InputStreamMessage(Packet properties, AttachmentSet attachments,
|
||||
String contentType, InputStream msg) {
|
||||
super(properties, attachments);
|
||||
|
||||
this.contentType = contentType;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.stream;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.message.AttachmentSetImpl;
|
||||
|
||||
/**
|
||||
* Base representation an XML or SOAP message as stream.
|
||||
*
|
||||
*/
|
||||
abstract class StreamBasedMessage {
|
||||
/**
|
||||
* The properties of the message.
|
||||
*/
|
||||
public final Packet properties;
|
||||
|
||||
/**
|
||||
* The attachments of this message
|
||||
* (attachments live outside a message.)
|
||||
*/
|
||||
public final AttachmentSet attachments;
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
*/
|
||||
protected StreamBasedMessage(Packet properties) {
|
||||
this.properties = properties;
|
||||
this.attachments = new AttachmentSetImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
* @param attachments
|
||||
* the attachments of the message.
|
||||
*/
|
||||
protected StreamBasedMessage(Packet properties, AttachmentSet attachments) {
|
||||
this.properties = properties;
|
||||
this.attachments = attachments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.api.message.stream;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* Low level representation of an XML or SOAP message as an {@link XMLStreamReader}.
|
||||
*
|
||||
*/
|
||||
public class XMLStreamReaderMessage extends StreamBasedMessage {
|
||||
/**
|
||||
* The message represented as an {@link XMLStreamReader}.
|
||||
*/
|
||||
public final XMLStreamReader msg;
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
* @param msg
|
||||
* always a non-null unconsumed {@link XMLStreamReader} that
|
||||
* represents a request.
|
||||
*/
|
||||
public XMLStreamReaderMessage(Packet properties, XMLStreamReader msg) {
|
||||
super(properties);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message.
|
||||
*
|
||||
* @param properties
|
||||
* the properties of the message.
|
||||
*
|
||||
* @param attachments
|
||||
* the attachments of the message.
|
||||
*
|
||||
* @param msg
|
||||
* always a non-null unconsumed {@link XMLStreamReader} that
|
||||
* represents a request.
|
||||
*/
|
||||
public XMLStreamReaderMessage(Packet properties, AttachmentSet attachments, XMLStreamReader msg) {
|
||||
super(properties, attachments);
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user