package com.sun.xml.internal.ws.message.jaxb;
import com.sun.istack.internal.FragmentContentHandler;
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult;
import com.sun.xml.internal.ws.api.SOAPVersion;
import com.sun.xml.internal.ws.api.message.AttachmentSet;
import com.sun.xml.internal.ws.api.message.Header;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.api.message.Message;
import com.sun.xml.internal.ws.api.message.MessageHeaders;
import com.sun.xml.internal.ws.api.message.StreamingSOAP;
import com.sun.xml.internal.ws.encoding.SOAPBindingCodec;
import com.sun.xml.internal.ws.message.AbstractMessageImpl;
import com.sun.xml.internal.ws.message.AttachmentSetImpl;
import com.sun.xml.internal.ws.message.RootElementSniffer;
import com.sun.xml.internal.ws.message.stream.StreamMessage;
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 com.sun.xml.internal.ws.streaming.XMLStreamWriterUtil;
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
import com.sun.xml.internal.org.jvnet.staxex.util.MtomStreamWriter;
import com.sun.xml.internal.ws.util.xml.XMLReaderComposite;
import com.sun.xml.internal.ws.util.xml.XMLReaderComposite.ElemInfo;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.util.JAXBResult;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
import javax.xml.transform.Source;
import javax.xml.ws.WebServiceException;
import java.io.OutputStream;
import java.util.List;
public final class JAXBMessage extends AbstractMessageImpl implements StreamingSOAP {
private MessageHeaders ;
private final Object jaxbObject;
private final XMLBridge bridge;
private final JAXBContext rawContext;
private String nsUri,localName;
private XMLStreamBuffer infoset;
public static Message (BindingContext context, Object jaxbObject, SOAPVersion soapVersion, MessageHeaders headers, AttachmentSet attachments) {
if(!context.hasSwaRef()) {
return new JAXBMessage(context,jaxbObject,soapVersion,headers,attachments);
}
try {
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
Marshaller m = context.createMarshaller();
AttachmentMarshallerImpl am = new AttachmentMarshallerImpl(attachments);
m.setAttachmentMarshaller(am);
am.cleanup();
m.marshal(jaxbObject,xsb.createFromXMLStreamWriter());
return new StreamMessage(headers,attachments,xsb.readAsXMLStreamReader(),soapVersion);
} catch (JAXBException e) {
throw new WebServiceException(e);
} catch (XMLStreamException e) {
throw new WebServiceException(e);
}
}
public static Message create(BindingContext context, Object jaxbObject, SOAPVersion soapVersion) {
return create(context,jaxbObject,soapVersion,null,null);
}
public static Message create(JAXBContext context, Object jaxbObject, SOAPVersion soapVersion) {
return create(BindingContextFactory.create(context),jaxbObject,soapVersion,null,null);
}
public static Message createRaw(JAXBContext context, Object jaxbObject, SOAPVersion soapVersion) {
return new JAXBMessage(context,jaxbObject,soapVersion,null,null);
}
private ( BindingContext context, Object jaxbObject, SOAPVersion soapVer, MessageHeaders headers, AttachmentSet attachments ) {
super(soapVer);
this.bridge = context.createFragmentBridge();
this.rawContext = null;
this.jaxbObject = jaxbObject;
this.headers = headers;
this.attachmentSet = attachments;
}
private ( JAXBContext rawContext, Object jaxbObject, SOAPVersion soapVer, MessageHeaders headers, AttachmentSet attachments ) {
super(soapVer);
this.rawContext = rawContext;
this.bridge = null;
this.jaxbObject = jaxbObject;
this.headers = headers;
this.attachmentSet = attachments;
}
public static Message create(XMLBridge bridge, Object jaxbObject, SOAPVersion soapVer) {
if(!bridge.context().hasSwaRef()) {
return new JAXBMessage(bridge,jaxbObject,soapVer);
}
try {
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
AttachmentSetImpl attachments = new AttachmentSetImpl();
AttachmentMarshallerImpl am = new AttachmentMarshallerImpl(attachments);
bridge.marshal(jaxbObject,xsb.createFromXMLStreamWriter(), am);
am.cleanup();
return new StreamMessage(null,attachments,xsb.readAsXMLStreamReader(),soapVer);
} catch (JAXBException e) {
throw new WebServiceException(e);
} catch (XMLStreamException e) {
throw new WebServiceException(e);
}
}
private JAXBMessage(XMLBridge bridge, Object jaxbObject, SOAPVersion soapVer) {
super(soapVer);
this.bridge = bridge;
this.rawContext = null;
this.jaxbObject = jaxbObject;
QName tagName = bridge.getTypeInfo().tagName;
this.nsUri = tagName.getNamespaceURI();
this.localName = tagName.getLocalPart();
this.attachmentSet = new AttachmentSetImpl();
}
public JAXBMessage(JAXBMessage that) {
super(that);
this.headers = that.headers;
if(this.headers!=null)
this.headers = new HeaderList(this.headers);
this.attachmentSet = that.attachmentSet;
this.jaxbObject = that.jaxbObject;
this.bridge = that.bridge;
this.rawContext = that.rawContext;
this.copyFrom(that);
}
@Override
public boolean () {
return headers!=null && headers.hasHeaders();
}
@Override
public MessageHeaders () {
if(headers==null)
headers = new HeaderList(getSOAPVersion());
return headers;
}
@Override
public String getPayloadLocalPart() {
if(localName==null)
sniff();
return localName;
}
@Override
public String getPayloadNamespaceURI() {
if(nsUri==null)
sniff();
return nsUri;
}
@Override
public boolean hasPayload() {
return true;
}
private void sniff() {
RootElementSniffer sniffer = new RootElementSniffer(false);
try {
if (rawContext != null) {
Marshaller m = rawContext.createMarshaller();
m.setProperty("jaxb.fragment", Boolean.TRUE);
m.marshal(jaxbObject,sniffer);
} else
bridge.marshal(jaxbObject,sniffer,null);
} catch (JAXBException e) {
nsUri = sniffer.getNsUri();
localName = sniffer.getLocalName();
}
}
@Override
public Source readPayloadAsSource() {
return new JAXBBridgeSource(bridge,jaxbObject);
}
@Override
public <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
JAXBResult out = new JAXBResult(unmarshaller);
try {
out.getHandler().startDocument();
if (rawContext != null) {
Marshaller m = rawContext.createMarshaller();
m.setProperty("jaxb.fragment", Boolean.TRUE);
m.marshal(jaxbObject,out);
} else
bridge.marshal(jaxbObject,out);
out.getHandler().endDocument();
} catch (SAXException e) {
throw new JAXBException(e);
}
return (T)out.getResult();
}
@Override
public XMLStreamReader readPayload() throws XMLStreamException {
try {
if(infoset==null) {
if (rawContext != null) {
XMLStreamBufferResult sbr = new XMLStreamBufferResult();
Marshaller m = rawContext.createMarshaller();
m.setProperty("jaxb.fragment", Boolean.TRUE);
m.marshal(jaxbObject, sbr);
infoset = sbr.getXMLStreamBuffer();
} else {
MutableXMLStreamBuffer buffer = new MutableXMLStreamBuffer();
writePayloadTo(buffer.createFromXMLStreamWriter());
infoset = buffer;
}
}
XMLStreamReader reader = infoset.readAsXMLStreamReader();
if(reader.getEventType()== START_DOCUMENT)
XMLStreamReaderUtil.nextElementContent(reader);
return reader;
} catch (JAXBException e) {
throw new WebServiceException(e);
}
}
@Override
protected void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
try {
if(fragment)
contentHandler = new FragmentContentHandler(contentHandler);
AttachmentMarshallerImpl am = new AttachmentMarshallerImpl(attachmentSet);
if (rawContext != null) {
Marshaller m = rawContext.createMarshaller();
m.setProperty("jaxb.fragment", Boolean.TRUE);
m.setAttachmentMarshaller(am);
m.marshal(jaxbObject,contentHandler);
} else
bridge.marshal(jaxbObject,contentHandler, am);
am.cleanup();
} catch (JAXBException e) {
throw new WebServiceException(e.getMessage(),e);
}
}
@Override
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
try {
AttachmentMarshaller am = (sw instanceof MtomStreamWriter)
? ((MtomStreamWriter)sw).getAttachmentMarshaller()
: new AttachmentMarshallerImpl(attachmentSet);
String encoding = XMLStreamWriterUtil.getEncoding(sw);
OutputStream os = bridge.supportOutputStream() ? XMLStreamWriterUtil.getOutputStream(sw) : null;
if (rawContext != null) {
Marshaller m = rawContext.createMarshaller();
m.setProperty("jaxb.fragment", Boolean.TRUE);
m.setAttachmentMarshaller(am);
if (os != null) {
m.marshal(jaxbObject, os);
} else {
m.marshal(jaxbObject, sw);
}
} else {
if (os != null && encoding != null && encoding.equalsIgnoreCase(SOAPBindingCodec.UTF8_ENCODING)) {
bridge.marshal(jaxbObject, os, sw.getNamespaceContext(), am);
} else {
bridge.marshal(jaxbObject, sw, am);
}
}
} catch (JAXBException e) {
throw new WebServiceException(e);
}
}
@Override
public Message copy() {
return new JAXBMessage(this).copyFrom(this);
}
public XMLStreamReader readEnvelope() {
int base = soapVersion.ordinal()*3;
this.envelopeTag = DEFAULT_TAGS.get(base);
this.bodyTag = DEFAULT_TAGS.get(base+2);
List<XMLStreamReader> hReaders = new java.util.ArrayList<XMLStreamReader>();
ElemInfo envElem = new ElemInfo(envelopeTag, null);
ElemInfo bdyElem = new ElemInfo(bodyTag, envElem);
for (Header h : getHeaders().asList()) {
try {
hReaders.add(h.readHeader());
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
XMLStreamReader soapHeader = null;
if(hReaders.size()>0) {
headerTag = DEFAULT_TAGS.get(base+1);
ElemInfo hdrElem = new ElemInfo(headerTag, envElem);
soapHeader = new XMLReaderComposite(hdrElem, hReaders.toArray(new XMLStreamReader[hReaders.size()]));
}
try {
XMLStreamReader payload= readPayload();
XMLStreamReader soapBody = new XMLReaderComposite(bdyElem, new XMLStreamReader[]{payload});
XMLStreamReader[] soapContent = (soapHeader != null) ? new XMLStreamReader[]{soapHeader, soapBody} : new XMLStreamReader[]{soapBody};
return new XMLReaderComposite(envElem, soapContent);
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
public boolean isPayloadStreamReader() { return false; }
public QName getPayloadQName() {
return new QName(getPayloadNamespaceURI(), getPayloadLocalPart());
}
public XMLStreamReader readToBodyStarTag() {
int base = soapVersion.ordinal()*3;
this.envelopeTag = DEFAULT_TAGS.get(base);
this.bodyTag = DEFAULT_TAGS.get(base+2);
List<XMLStreamReader> hReaders = new java.util.ArrayList<XMLStreamReader>();
ElemInfo envElem = new ElemInfo(envelopeTag, null);
ElemInfo bdyElem = new ElemInfo(bodyTag, envElem);
for (Header h : getHeaders().asList()) {
try {
hReaders.add(h.readHeader());
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
XMLStreamReader soapHeader = null;
if(hReaders.size()>0) {
headerTag = DEFAULT_TAGS.get(base+1);
ElemInfo hdrElem = new ElemInfo(headerTag, envElem);
soapHeader = new XMLReaderComposite(hdrElem, hReaders.toArray(new XMLStreamReader[hReaders.size()]));
}
XMLStreamReader soapBody = new XMLReaderComposite(bdyElem, new XMLStreamReader[]{});
XMLStreamReader[] soapContent = (soapHeader != null) ? new XMLStreamReader[]{soapHeader, soapBody} : new XMLStreamReader[]{soapBody};
return new XMLReaderComposite(envElem, soapContent);
}
}