001: /*
002: * Portions Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: package com.sun.xml.internal.ws.encoding.soap.client;
026:
027: import com.sun.xml.internal.ws.client.BindingProviderProperties;
028: import static com.sun.xml.internal.ws.client.BindingProviderProperties.*;
029: import com.sun.xml.internal.ws.client.RequestContext;
030: import com.sun.xml.internal.ws.client.SenderException;
031: import com.sun.xml.internal.ws.client.dispatch.DispatchContext;
032: import com.sun.xml.internal.ws.encoding.JAXWSAttachmentMarshaller;
033: import com.sun.xml.internal.ws.encoding.internal.InternalEncoder;
034: import com.sun.xml.internal.ws.encoding.jaxb.JAXBBeanInfo;
035: import com.sun.xml.internal.ws.encoding.soap.SOAPConstants;
036: import com.sun.xml.internal.ws.encoding.soap.SOAPEPTFactory;
037: import com.sun.xml.internal.ws.encoding.soap.SOAPEncoder;
038: import com.sun.xml.internal.ws.encoding.soap.internal.AttachmentBlock;
039: import com.sun.xml.internal.ws.encoding.soap.internal.BodyBlock;
040: import com.sun.xml.internal.ws.encoding.soap.internal.InternalMessage;
041: import com.sun.xml.internal.ws.pept.ept.MessageInfo;
042: import com.sun.xml.internal.ws.streaming.XMLStreamWriterFactory;
043: import com.sun.xml.internal.ws.util.ByteArrayBuffer;
044: import com.sun.xml.internal.ws.util.MessageInfoUtil;
045: import com.sun.xml.internal.ws.util.SOAPUtil;
046:
047: import javax.activation.DataHandler;
048: import javax.xml.bind.JAXBContext;
049: import javax.xml.namespace.QName;
050: import javax.xml.soap.MimeHeaders;
051: import javax.xml.soap.SOAPException;
052: import javax.xml.soap.SOAPMessage;
053: import javax.xml.stream.XMLStreamException;
054: import javax.xml.stream.XMLStreamReader;
055: import javax.xml.stream.XMLStreamWriter;
056: import javax.xml.transform.Source;
057: import javax.xml.ws.Service;
058: import javax.xml.ws.handler.MessageContext;
059: import javax.xml.ws.soap.SOAPBinding;
060: import java.io.IOException;
061: import java.util.Map;
062: import java.util.logging.Logger;
063: import static java.util.logging.Logger.getLogger;
064:
065: /**
066: * @author WS Development Team
067: */
068: public class SOAPXMLEncoder extends SOAPEncoder {
069:
070: private static final Logger logger = getLogger(new StringBuffer()
071: .append(
072: com.sun.xml.internal.ws.util.Constants.LoggingDomain)
073: .append(".client.dispatch.util").toString());
074:
075: public SOAPXMLEncoder() {
076: }
077:
078: /* moved to super
079: protected JAXBContext getJAXBContext(MessageInfo messageInfo) {
080: JAXBContext jc = null;
081: RequestContext context = (RequestContext) messageInfo.getMetaData(BindingProviderProperties.JAXWS_CONTEXT_PROPERTY);
082: if (context != null)
083: jc = (JAXBContext) context.get(BindingProviderProperties.JAXB_CONTEXT_PROPERTY);
084:
085: return jc;
086: }
087: */
088: protected boolean skipHeader(MessageInfo messageInfo) {
089: if (messageInfo
090: .getMetaData(DispatchContext.DISPATCH_MESSAGE_MODE) == Service.Mode.PAYLOAD) {
091: return true;
092: }
093: return false;
094: }
095:
096: protected QName getHeaderTag() {
097: return SOAPConstants.QNAME_SOAP_HEADER;
098: }
099:
100: protected void skipHeader(XMLStreamReader writer) {
101: //XMLStreamReaderUtil.verifyReaderState(reader, START_ELEMENT);
102: //if (!SOAPNamespaceConstants.TAG_HEADER.equals(reader.getLocalName())) {
103: // return;
104: //}
105: //XMLStreamReaderUtil.verifyTag(reader, getHeaderTag());
106: //XMLStreamReaderUtil.skipElement(reader); // Moves to </Header>
107: //XMLStreamReaderUtil.nextElementContent(reader);
108: }
109:
110: @Override
111: public InternalMessage toInternalMessage(MessageInfo messageInfo) {
112: InternalMessage internalMessage = new InternalMessage();
113: DispatchContext context = (DispatchContext) messageInfo
114: .getMetaData(BindingProviderProperties.DISPATCH_CONTEXT);
115: if (context != null) {
116: DispatchContext.MessageType type = (DispatchContext.MessageType) context
117: .getProperty(DispatchContext.DISPATCH_MESSAGE);
118: Object[] data = messageInfo.getData();
119: BodyBlock bodyBlock = null;
120: switch (type) {
121: case JAXB_MESSAGE:
122: break;
123: case JAXB_PAYLOAD:
124: JAXBBeanInfo jaxbInfo = new JAXBBeanInfo(data[0],
125: getJAXBContext(messageInfo));
126: bodyBlock = new BodyBlock(jaxbInfo);
127: break;
128: case SOURCE_PAYLOAD:
129: data = messageInfo.getData();
130: bodyBlock = new BodyBlock((Source) data[0]);
131: break;
132: default:
133: }
134: if (bodyBlock != null)
135: internalMessage.setBody(bodyBlock);
136:
137: //look for attachments here
138: Map<String, DataHandler> attMap = (Map<String, DataHandler>) ((Map<String, Object>) messageInfo
139: .getMetaData(BindingProviderProperties.JAXWS_CONTEXT_PROPERTY))
140: .get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS);
141:
142: if (attMap != null)
143: for (Map.Entry<String, DataHandler> att : attMap
144: .entrySet()) {
145: internalMessage.addAttachment(AttachmentBlock
146: .fromDataHandler(att.getKey(), att
147: .getValue()));
148: }
149:
150: } else {
151: SOAPEPTFactory eptf = (SOAPEPTFactory) messageInfo
152: .getEPTFactory();
153: InternalEncoder internalEncoder = eptf.getInternalEncoder();
154: //processProperties(messageInfo);
155: return (InternalMessage) internalEncoder
156: .toInternalMessage(messageInfo);
157: }
158: return internalMessage;
159: }
160:
161: @Override
162: public SOAPMessage toSOAPMessage(InternalMessage internalMessage,
163: MessageInfo messageInfo) {
164: SOAPMessage message = null;
165: XMLStreamWriter writer = null;
166: JAXWSAttachmentMarshaller marshaller = null;
167: boolean xopEnabled = false;
168:
169: try {
170: setAttachmentsMap(messageInfo, internalMessage);
171: ByteArrayBuffer bab = new ByteArrayBuffer();
172:
173: if (messageInfo.getMetaData(CONTENT_NEGOTIATION_PROPERTY) == "optimistic") {
174: writer = XMLStreamWriterFactory
175: .createFIStreamWriter(bab);
176:
177: // Turn XOP off for FI
178: marshaller = MessageInfoUtil
179: .getAttachmentMarshaller(messageInfo);
180: if (marshaller != null) {
181: xopEnabled = marshaller.isXOPPackage(); // last value
182: marshaller.setXOPPackage(false);
183: }
184:
185: } else {
186: // Store output stream to use in JAXB bridge (not with FI)
187: messageInfo.setMetaData(JAXB_OUTPUTSTREAM, bab);
188: writer = XMLStreamWriterFactory
189: .createXMLStreamWriter(bab);
190: }
191:
192: writer.writeStartDocument();
193: startEnvelope(writer);
194: writeEnvelopeNamespaces(writer, messageInfo);
195: if (!skipHeader(messageInfo))
196: writeHeaders(writer, internalMessage, messageInfo);
197: writeBody(writer, internalMessage, messageInfo);
198: endEnvelope(writer);
199: writer.writeEndDocument();
200: writer.close();
201:
202: // TODO: Copy the mime headers from messageInfo.METADATA
203: MimeHeaders mh = new MimeHeaders();
204: mh.addHeader("Content-Type", getContentType(messageInfo,
205: marshaller));
206: message = SOAPUtil.createMessage(mh, bab.newInputStream(),
207: getBindingId());
208: processAttachments(internalMessage, message);
209:
210: // Restore default XOP processing before returning
211: if (marshaller != null) {
212: marshaller.setXOPPackage(xopEnabled);
213: }
214: } catch (IOException e) {
215: throw new SenderException("sender.request.messageNotReady",
216: e);
217: } catch (SOAPException e) {
218: throw new SenderException(e);
219: } catch (XMLStreamException e) {
220: throw new SenderException(e);
221: } finally {
222: if (writer != null) {
223: try {
224: writer.close();
225: } catch (XMLStreamException e) {
226: throw new SenderException(e);
227: }
228: }
229: }
230:
231: return message;
232: }
233:
234: public InternalMessage createInternalMessage(MessageInfo messageInfo) {
235:
236: InternalMessage internalMessage = new InternalMessage();
237: Object response = messageInfo.getResponse();
238:
239: BodyBlock bodyBlock = null;
240: if (getJAXBContext(messageInfo) != null) {
241: JAXBBeanInfo jaxbBean = new JAXBBeanInfo(response,
242: getJAXBContext(messageInfo));
243: bodyBlock = new BodyBlock(jaxbBean);
244: } else if (response instanceof Source) {
245: bodyBlock = new BodyBlock((Source) response);
246: }
247:
248: internalMessage.setBody(bodyBlock);
249: return internalMessage;
250: }
251:
252: protected String getContentType(MessageInfo messageInfo,
253: JAXWSAttachmentMarshaller marshaller) {
254: String contentNegotiation = (String) messageInfo
255: .getMetaData(BindingProviderProperties.CONTENT_NEGOTIATION_PROPERTY);
256:
257: if (marshaller == null) {
258: marshaller = MessageInfoUtil
259: .getAttachmentMarshaller(messageInfo);
260: }
261:
262: if (marshaller != null && marshaller.isXopped()) {
263: return XOP_SOAP11_XML_TYPE_VALUE;
264: } else {
265: return (contentNegotiation == "optimistic") ? FAST_INFOSET_TYPE_SOAP11
266: : XML_CONTENT_TYPE_VALUE;
267: }
268: }
269:
270: /**
271: * This method is used to create the appropriate SOAPMessage (1.1 or 1.2 using SAAJ api).
272: *
273: * @return the BindingID associated with this encoder
274: */
275: protected String getBindingId() {
276: return SOAPBinding.SOAP11HTTP_BINDING;
277: }
278: }
|