001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.transport.http;
021:
022: import org.apache.axiom.om.OMElement;
023: import org.apache.axiom.om.OMOutputFormat;
024: import org.apache.axiom.om.impl.MIMEOutputUtils;
025: import org.apache.axiom.om.util.UUIDGenerator;
026: import org.apache.axis2.AxisFault;
027: import org.apache.axis2.Constants;
028: import org.apache.axis2.context.MessageContext;
029: import org.apache.axis2.transport.MessageFormatter;
030: import org.apache.axis2.transport.http.util.URLTemplatingUtil;
031: import org.apache.axis2.util.JavaUtils;
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: import javax.xml.stream.FactoryConfigurationError;
036: import javax.xml.stream.XMLStreamException;
037: import java.io.ByteArrayOutputStream;
038: import java.io.OutputStream;
039: import java.io.StringWriter;
040: import java.net.URL;
041:
042: public class SOAPMessageFormatter implements MessageFormatter {
043:
044: private static final Log log = LogFactory
045: .getLog(SOAPMessageFormatter.class);
046:
047: public void writeTo(MessageContext msgCtxt, OMOutputFormat format,
048: OutputStream out, boolean preserve) throws AxisFault {
049: if (log.isDebugEnabled()) {
050: log.debug("start writeTo()");
051: log.debug(" preserve=" + preserve);
052: log.debug(" isOptimized=" + format.isOptimized());
053: log.debug(" isDoingSWA=" + format.isDoingSWA());
054: }
055: OMElement element = msgCtxt.getEnvelope();
056: try {
057: if (!(format.isOptimized()) & format.isDoingSWA()) {
058: StringWriter bufferedSOAPBody = new StringWriter();
059: if (preserve) {
060: element.serialize(bufferedSOAPBody, format);
061: } else {
062: element.serializeAndConsume(bufferedSOAPBody,
063: format);
064: }
065: writeSwAMessage(msgCtxt, bufferedSOAPBody, out, format);
066: } else {
067: if (preserve) {
068: element.serialize(out, format);
069: } else {
070: element.serializeAndConsume(out, format);
071: }
072: }
073: } catch (XMLStreamException e) {
074: throw AxisFault.makeFault(e);
075: } finally {
076: if (log.isDebugEnabled()) {
077: log.debug("end writeTo()");
078: }
079: }
080: }
081:
082: public byte[] getBytes(MessageContext msgCtxt, OMOutputFormat format)
083: throws AxisFault {
084: if (log.isDebugEnabled()) {
085: log.debug("start getBytes()");
086: log.debug(" isOptimized=" + format.isOptimized());
087: log.debug(" isDoingSWA=" + format.isDoingSWA());
088: }
089: OMElement element = msgCtxt.getEnvelope();
090: try {
091: ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
092: if (!format.isOptimized()) {
093: if (format.isDoingSWA()) {
094: // Why are we creating a new OMOutputFormat
095: OMOutputFormat format2 = new OMOutputFormat();
096: format2.setCharSetEncoding(format
097: .getCharSetEncoding());
098: StringWriter bufferedSOAPBody = new StringWriter();
099: element.serializeAndConsume(bufferedSOAPBody,
100: format2);
101: writeSwAMessage(msgCtxt, bufferedSOAPBody,
102: bytesOut, format);
103: } else {
104: element.serializeAndConsume(bytesOut, format);
105: }
106: return bytesOut.toByteArray();
107: } else {
108: element.serializeAndConsume(bytesOut, format);
109: return bytesOut.toByteArray();
110: }
111: } catch (XMLStreamException e) {
112: throw AxisFault.makeFault(e);
113: } catch (FactoryConfigurationError e) {
114: throw AxisFault.makeFault(e);
115: } finally {
116: if (log.isDebugEnabled()) {
117: log.debug("end getBytes()");
118: }
119: }
120: }
121:
122: public String getContentType(MessageContext msgCtxt,
123: OMOutputFormat format, String soapActionString) {
124: String encoding = format.getCharSetEncoding();
125: String contentType = format.getContentType();
126: if (log.isDebugEnabled()) {
127: log.debug("contentType from the OMOutputFormat ="
128: + contentType);
129: }
130: if (encoding != null
131: && contentType != null
132: && contentType
133: .indexOf(HTTPConstants.MEDIA_TYPE_MULTIPART_RELATED) == -1) {
134: contentType += "; charset=" + encoding;
135: }
136:
137: // action header is not mandated in SOAP 1.2. So putting it, if
138: // available
139: if (!msgCtxt.isSOAP11() && (soapActionString != null)
140: && !"".equals(soapActionString.trim())
141: && !"\"\"".equals(soapActionString.trim())) {
142: contentType = contentType + "; action=\""
143: + soapActionString + "\"";
144: }
145: if (log.isDebugEnabled()) {
146: log.debug("contentType returned =" + contentType);
147: }
148: return contentType;
149: }
150:
151: public String formatSOAPAction(MessageContext msgCtxt,
152: OMOutputFormat format, String soapActionString) {
153: // if SOAP 1.2 we attach the soap action to the content-type
154: // No need to set it as a header.
155: if (msgCtxt.isSOAP11()) {
156: if ("".equals(soapActionString)) {
157: return "\"\"";
158: } else {
159: if (soapActionString != null
160: && !soapActionString.startsWith("\"")) {
161: // SOAPAction string must be a quoted string
162: soapActionString = "\"" + soapActionString + "\"";
163: }
164: return soapActionString;
165: }
166: }
167: return null;
168: }
169:
170: public URL getTargetAddress(MessageContext msgCtxt,
171: OMOutputFormat format, URL targetURL) throws AxisFault {
172:
173: // Check whether there is a template in the URL, if so we have to replace then with data
174: // values and create a new target URL.
175: targetURL = URLTemplatingUtil.getTemplatedURL(targetURL,
176: msgCtxt, false);
177: return targetURL;
178: }
179:
180: private void writeSwAMessage(MessageContext msgCtxt,
181: StringWriter bufferedSOAPBody, OutputStream outputStream,
182: OMOutputFormat format) {
183: if (log.isDebugEnabled()) {
184: log.debug("start writeSwAMessage()");
185: }
186: Object property = msgCtxt
187: .getProperty(Constants.Configuration.MM7_COMPATIBLE);
188: boolean MM7CompatMode = false;
189: if (property != null) {
190: MM7CompatMode = JavaUtils.isTrueExplicitly(property);
191: }
192: if (!MM7CompatMode) {
193: MIMEOutputUtils.writeSOAPWithAttachmentsMessage(
194: bufferedSOAPBody, outputStream, msgCtxt
195: .getAttachmentMap(), format);
196: } else {
197: String innerBoundary;
198: String partCID;
199: Object innerBoundaryProperty = msgCtxt
200: .getProperty(Constants.Configuration.MM7_INNER_BOUNDARY);
201: if (innerBoundaryProperty != null) {
202: innerBoundary = (String) innerBoundaryProperty;
203: } else {
204: innerBoundary = "innerBoundary"
205: + UUIDGenerator.getUUID().replace(':', '_');
206: }
207: Object partCIDProperty = msgCtxt
208: .getProperty(Constants.Configuration.MM7_PART_CID);
209: if (partCIDProperty != null) {
210: partCID = (String) partCIDProperty;
211: } else {
212: partCID = "innerCID"
213: + UUIDGenerator.getUUID().replace(':', '_');
214: }
215: MIMEOutputUtils.writeMM7Message(bufferedSOAPBody,
216: outputStream, msgCtxt.getAttachmentMap(), format,
217: partCID, innerBoundary);
218: }
219: if (log.isDebugEnabled()) {
220: log.debug("end writeSwAMessage()");
221: }
222: }
223:
224: }
|