Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.xml.ws.message.saaj;
import com.sun.istack.NotNull;
import com.sun.istack.XMLStreamException2;
import com.sun.istack.Nullable;
import com.sun.istack.FragmentContentHandler;
import com.sun.xml.bind.api.Bridge;
import com.sun.xml.bind.unmarshaller.DOMScanner;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.message.*;
import com.sun.xml.ws.message.AttachmentUnmarshallerImpl;
import com.sun.xml.ws.message.AbstractMessageImpl;
import com.sun.xml.ws.message.AttachmentSetImpl;
import com.sun.xml.ws.streaming.DOMStreamReader;
import com.sun.xml.ws.util.DOMUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.LocatorImpl;
import javax.activation.DataHandler;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
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.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPFaultException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* {@link Message} implementation backed by {@link SOAPMessage}.
*
* @author Vivek Pandey
* @author Rama Pulavarthi
*/
public class SAAJMessage extends Message {
// flag to switch between representations
private boolean parsedMessage;
// flag to check if Message API is exercised;
private boolean accessedMessage;
private final SOAPMessage sm;
private HeaderList headers;
private List bodyParts;
private Element payload;
private String payloadLocalName;
private String payloadNamespace;
private SOAPVersion soapVersion;
public SAAJMessage(SOAPMessage sm) {
this.sm = sm;
}
/**
* This constructor is a convenience and called by the {@link #copy}
*
* @param headers
* @param sm
*/
private SAAJMessage(HeaderList headers, AttachmentSet as, SOAPMessage sm) {
this.sm = sm;
this.parse();
if(headers == null)
headers = new HeaderList();
this.headers = headers;
this.attachmentSet = as;
}
private void parse() {
if (!parsedMessage) {
try {
access();
if (headers == null)
headers = new HeaderList();
SOAPHeader header = sm.getSOAPHeader();
if (header != null) {
Iterator iter = header.examineAllHeaderElements();
while (iter.hasNext()) {
headers.add(new SAAJHeader((SOAPHeaderElement) iter.next()));
}
}
attachmentSet = new SAAJAttachmentSet(sm);
parsedMessage = true;
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
}
private void access() {
if (!accessedMessage) {
try {
Node body = sm.getSOAPBody();
soapVersion = SOAPVersion.fromNsUri(body.getNamespaceURI());
//cature all the body elements
bodyParts = DOMUtil.getChildElements(body);
//we treat payload as the first body part
payload = bodyParts.size() > 0 ? bodyParts.get(0) : null;
// hope this is correct. Caching the localname and namespace of the payload should be fine
// but what about if a Handler replaces the payload with something else? Weel, may be it
// will be error condition anyway
if (payload != null) {
payloadLocalName = payload.getLocalName();
payloadNamespace = payload.getNamespaceURI();
}
accessedMessage = true;
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
}
public boolean hasHeaders() {
parse();
return headers.size() > 0;
}
public @NotNull HeaderList getHeaders() {
parse();
return headers;
}
/**
* Gets the attachments of this message
* (attachments live outside a message.)
*/
@Override
public @NotNull AttachmentSet getAttachments() {
parse();
return attachmentSet;
}
/**
* Optimization hint for the derived class to check
* if we may have some attachments.
*/
@Override
protected boolean hasAttachments() {
parse();
return attachmentSet!=null;
}
public @Nullable String getPayloadLocalPart() {
access();
return payloadLocalName;
}
public String getPayloadNamespaceURI() {
access();
return payloadNamespace;
}
public boolean hasPayload() {
access();
return payloadNamespace != null;
}
public Source readEnvelopeAsSource() {
try {
if (!parsedMessage) {
SOAPEnvelope se = sm.getSOAPPart().getEnvelope();
return new DOMSource(se);
} else {
SOAPMessage msg = soapVersion.saajMessageFactory.createMessage();
SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
for (Element part : bodyParts) {
Node n = newBody.getOwnerDocument().importNode(part, true);
newBody.appendChild(n);
}
for (Header header : headers) {
header.writeTo(msg);
}
SOAPEnvelope se = msg.getSOAPPart().getEnvelope();
return new DOMSource(se);
}
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
public SOAPMessage readAsSOAPMessage() throws SOAPException {
if (!parsedMessage) {
return sm;
} else {
SOAPMessage msg = soapVersion.saajMessageFactory.createMessage();
SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
for (Element part : bodyParts) {
Node n = newBody.getOwnerDocument().importNode(part, true);
newBody.appendChild(n);
}
for (Header header : headers) {
header.writeTo(msg);
}
for (Attachment att : getAttachments()) {
AttachmentPart part = msg.createAttachmentPart();
part.setDataHandler(att.asDataHandler());
part.setContentId('<' + att.getContentId() + '>');
msg.addAttachmentPart(part);
}
msg.saveChanges();
return msg;
}
}
public Source readPayloadAsSource() {
access();
return (payload != null) ? new DOMSource(payload) : null;
}
public T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
access();
if (payload != null) {
if(hasAttachments())
unmarshaller.setAttachmentUnmarshaller(new AttachmentUnmarshallerImpl(getAttachments()));
return (T) unmarshaller.unmarshal(payload);
}
return null;
}
public T readPayloadAsJAXB(Bridge bridge) throws JAXBException {
access();
if (payload != null)
return bridge.unmarshal(payload,hasAttachments()? new AttachmentUnmarshallerImpl(getAttachments()) : null);
return null;
}
public XMLStreamReader readPayload() throws XMLStreamException {
access();
if (payload != null) {
DOMStreamReader dss = new DOMStreamReader();
dss.setCurrentNode(payload);
dss.nextTag();
assert dss.getEventType() == XMLStreamReader.START_ELEMENT;
return dss;
}
return null;
}
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
access();
try {
for (Element part : bodyParts)
DOMUtil.serializeNode(part, sw);
} catch (XMLStreamException e) {
throw new WebServiceException(e);
}
}
public void writeTo(XMLStreamWriter writer) throws XMLStreamException {
try {
writer.writeStartDocument();
if (!parsedMessage) {
DOMUtil.serializeNode(sm.getSOAPPart().getEnvelope(), writer);
} else {
SOAPEnvelope env = sm.getSOAPPart().getEnvelope();
DOMUtil.writeTagWithAttributes(env, writer);
if (hasHeaders()) {
writer.writeStartElement(env.getPrefix(), "Header", env.getNamespaceURI());
int len = headers.size();
for (int i = 0; i < len; i++) {
headers.get(i).writeTo(writer);
}
writer.writeEndElement();
}
DOMUtil.serializeNode(sm.getSOAPBody(), writer);
writer.writeEndElement();
}
writer.writeEndDocument();
writer.flush();
} catch (SOAPException ex) {
throw new XMLStreamException2(ex);
//for now. ask jaxws team what to do.
}
}
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
String soapNsUri = soapVersion.nsUri;
if (!parsedMessage) {
DOMScanner ds = new DOMScanner();
ds.setContentHandler(contentHandler);
ds.scan(sm.getSOAPPart());
} else {
contentHandler.setDocumentLocator(NULL_LOCATOR);
contentHandler.startDocument();
contentHandler.startPrefixMapping("S", soapNsUri);
contentHandler.startElement(soapNsUri, "Envelope", "S:Envelope", EMPTY_ATTS);
if (hasHeaders()) {
contentHandler.startElement(soapNsUri, "Header", "S:Header", EMPTY_ATTS);
HeaderList headers = getHeaders();
int len = headers.size();
for (int i = 0; i < len; i++) {
// shouldn't JDK be smart enough to use array-style indexing for this foreach!?
headers.get(i).writeTo(contentHandler, errorHandler);
}
contentHandler.endElement(soapNsUri, "Header", "S:Header");
}
// write the body
contentHandler.startElement(soapNsUri, "Body", "S:Body", EMPTY_ATTS);
writePayloadTo(contentHandler, errorHandler, true);
contentHandler.endElement(soapNsUri, "Body", "S:Body");
contentHandler.endElement(soapNsUri, "Envelope", "S:Envelope");
}
}
private void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
if(fragment)
contentHandler = new FragmentContentHandler(contentHandler);
DOMScanner ds = new DOMScanner();
ds.setContentHandler(contentHandler);
ds.scan(payload);
}
/**
* Creates a copy of a {@link com.sun.xml.ws.api.message.Message}.
*
*
* This method creates a new {@link com.sun.xml.ws.api.message.Message} whose header/payload/attachments/properties
* are identical to this {@link com.sun.xml.ws.api.message.Message}. Once created, the created {@link com.sun.xml.ws.api.message.Message}
* and the original {@link com.sun.xml.ws.api.message.Message} behaves independently --- adding header/
* attachment to one {@link com.sun.xml.ws.api.message.Message} doesn't affect another {@link com.sun.xml.ws.api.message.Message}
* at all.
*
*
Design Rationale
*
* Since a {@link com.sun.xml.ws.api.message.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 com.sun.xml.ws.api.message.Message}.
*
*
* The actual copy operation depends on the layout
* of the data in memory, hence it's best to be done by
* the {@link com.sun.xml.ws.api.message.Message} implementation itself.
*/
public Message copy() {
try {
if (!parsedMessage) {
return new SAAJMessage(readAsSOAPMessage());
} else {
SOAPMessage msg = soapVersion.saajMessageFactory.createMessage();
SOAPBody newBody = msg.getSOAPPart().getEnvelope().getBody();
for (Element part : bodyParts) {
Node n = newBody.getOwnerDocument().importNode(part, true);
newBody.appendChild(n);
}
return new SAAJMessage(getHeaders(), getAttachments(), msg);
}
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
private static final AttributesImpl EMPTY_ATTS = new AttributesImpl();
private static final LocatorImpl NULL_LOCATOR = new LocatorImpl();
private class SAAJAttachment implements Attachment {
final AttachmentPart ap;
public SAAJAttachment(AttachmentPart part) {
this.ap = part;
}
/**
* Content ID of the attachment. Uniquely identifies an attachment.
*/
public String getContentId() {
return ap.getContentId();
}
/**
* Gets the MIME content-type of this attachment.
*/
public String getContentType() {
return ap.getContentType();
}
/**
* Gets the attachment as an exact-length byte array.
*/
public byte[] asByteArray() {
try {
return ap.getRawContentBytes();
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
/**
* Gets the attachment as a {@link javax.activation.DataHandler}.
*/
public DataHandler asDataHandler() {
try {
return ap.getDataHandler();
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
/**
* Gets the attachment as a {@link javax.xml.transform.Source}.
* Note that there's no guarantee that the attachment is actually an XML.
*/
public Source asSource() {
try {
return new StreamSource(ap.getRawContent());
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
/**
* Obtains this attachment as an {@link java.io.InputStream}.
*/
public InputStream asInputStream() {
try {
return ap.getRawContent();
} catch (SOAPException e) {
throw new WebServiceException(e);
}
}
/**
* Writes the contents of the attachment into the given stream.
*/
public void writeTo(OutputStream os) throws IOException {
os.write(asByteArray());
}
/**
* Writes this attachment to the given {@link javax.xml.soap.SOAPMessage}.
*/
public void writeTo(SOAPMessage saaj) {
saaj.addAttachmentPart(ap);
}
AttachmentPart asAttachmentPart(){
return ap;
}
}
/**
* {@link AttachmentSet} for SAAJ.
*
* SAAJ wants '<' and '>' for the content ID, but {@link AttachmentSet}
* doesn't. S this class also does the conversion between them.
*/
private class SAAJAttachmentSet implements AttachmentSet {
private Map attMap;
private Iterator attIter;
public SAAJAttachmentSet(SOAPMessage sm) {
attIter = sm.getAttachments();
}
/**
* Gets the attachment by the content ID.
*
* @return null
* if no such attachment exist.
*/
public Attachment get(String contentId) {
// if this is the first time then create the attachment Map
if (attMap == null) {
if (!attIter.hasNext())
return null;
attMap = createAttachmentMap();
}
if(contentId.charAt(0) != '<'){
return attMap.get('<'+contentId+'>');
}
return attMap.get(contentId);
}
public boolean isEmpty() {
if(attMap!=null)
return attMap.isEmpty();
else
return !attIter.hasNext();
}
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
public Iterator iterator() {
if (attMap == null) {
attMap = createAttachmentMap();
}
return attMap.values().iterator();
}
private Map createAttachmentMap() {
HashMap map = new HashMap();
while (attIter.hasNext()) {
AttachmentPart ap = (AttachmentPart) attIter.next();
map.put(ap.getContentId(), new SAAJAttachment(ap));
}
return map;
}
public void add(Attachment att) {
attMap.put('<'+att.getContentId()+'>', att);
}
}
}