1 17 package org.apache.servicemix.soap.marshalers; 18 19 import java.io.ByteArrayOutputStream ; 20 import java.io.FilterOutputStream ; 21 import java.io.IOException ; 22 import java.io.OutputStream ; 23 import java.net.URI ; 24 import java.util.ArrayList ; 25 import java.util.Enumeration ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.Properties ; 30 31 import javax.activation.DataHandler ; 32 import javax.mail.Header ; 33 import javax.mail.Session ; 34 import javax.mail.internet.MimeBodyPart ; 35 import javax.mail.internet.MimeMessage ; 36 import javax.mail.internet.MimeMultipart ; 37 import javax.xml.XMLConstants ; 38 import javax.xml.namespace.QName ; 39 import javax.xml.stream.XMLStreamReader; 40 import javax.xml.stream.XMLStreamWriter; 41 import javax.xml.transform.Source ; 42 43 import org.apache.servicemix.jbi.jaxp.W3CDOMStreamReader; 44 import org.apache.servicemix.jbi.jaxp.XMLStreamHelper; 45 import org.apache.servicemix.jbi.util.ByteArrayDataSource; 46 import org.apache.servicemix.soap.SoapFault; 47 import org.w3c.dom.DocumentFragment ; 48 import org.w3c.dom.Element ; 49 50 56 public class SoapWriter { 57 58 public static final String SOAP_PART_ID = "soap-request"; 59 60 private SoapMessage message; 61 62 private String contentType; 63 64 private SoapMarshaler marshaler; 65 66 private MimeMultipart parts; 67 68 public SoapWriter(SoapMarshaler marshaler, SoapMessage message) { 69 this.marshaler = marshaler; 70 this.message = message; 71 this.contentType = prepare(); 72 } 73 74 public String getContentType() { 75 return contentType; 76 } 77 78 public void write(OutputStream out) throws Exception { 79 if (message.hasAttachments()) { 80 writeMultipartMessage(out); 81 } else { 82 writeSimpleMessage(out); 83 } 84 } 85 86 private String prepare() { 87 if (message.hasAttachments()) { 88 parts = new MimeMultipart ("related; type=\"text/xml\"; start=\"<" + SOAP_PART_ID + ">\""); 89 return parts.getContentType(); 90 } else { 91 return "text/xml"; 92 } 93 } 94 95 private void writeSimpleMessage(OutputStream out) throws Exception { 96 XMLStreamWriter writer = marshaler.getOutputFactory().createXMLStreamWriter(out); 97 writer.writeStartDocument(); 98 if (marshaler.isSoap()) { 99 writeSoapEnvelope(writer); 100 } else { 101 if (message.hasHeaders()) { 102 throw new IllegalStateException ("SOAP headers found on non-soap message"); 103 } 104 if (message.getFault() != null) { 105 if (message.getFault().getDetails() != null) { 106 XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader( 107 message.getFault().getDetails()); 108 XMLStreamHelper.copy(reader, writer); 109 } else { 110 throw new IllegalStateException ("Cannot write non xml faults for non soap messages"); 111 } 112 } else if (message.getSource() != null) { 113 writeContents(writer); 114 } 115 } 116 writer.writeEndDocument(); 117 writer.flush(); 118 } 119 120 private void writeMultipartMessage(OutputStream out) throws Exception { 121 Session session = Session.getDefaultInstance(new Properties (), null); 122 MimeMessage mime = new MimeMessage (session); 123 MimeBodyPart soapPart = new MimeBodyPart (); 125 soapPart.setContentID("<" + SOAP_PART_ID + ">"); 126 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 127 writeSimpleMessage(baos); 128 soapPart.setDataHandler(new DataHandler (new ByteArrayDataSource(baos.toByteArray(), "text/xml"))); 129 parts.addBodyPart(soapPart); 130 for (Iterator itr = message.getAttachments().entrySet().iterator(); itr.hasNext();) { 132 Map.Entry entry = (Map.Entry ) itr.next(); 133 String id = (String ) entry.getKey(); 134 DataHandler dh = (DataHandler ) entry.getValue(); 135 MimeBodyPart part = new MimeBodyPart (); 136 part.setDataHandler(dh); 137 part.setContentID("<" + id + ">"); 138 parts.addBodyPart(part); 139 } 140 mime.setContent(parts); 141 mime.setHeader(SoapMarshaler.MIME_CONTENT_TYPE, getContentType()); 142 mime.saveChanges(); 146 Enumeration headersEnum = mime.getAllHeaders(); 147 List headersList = new ArrayList (); 148 while (headersEnum.hasMoreElements()) { 149 headersList.add(((Header ) headersEnum.nextElement()).getName().toLowerCase()); 150 } 151 String [] headers = (String []) headersList.toArray(new String [0]); 152 OutputStream os = new FilterOutputStream (out) { 154 private int nb = 0; 155 public void write(int b) throws IOException { 156 if (++nb > 2) { 157 super.write(b); 158 } 159 } 160 }; 161 mime.writeTo(os, headers); 163 } 164 165 public void writeSoapEnvelope(XMLStreamWriter writer) throws Exception { 166 QName envelope = getEnvelopeName(); 167 String soapUri = envelope.getNamespaceURI(); 168 String soapPrefix = envelope.getPrefix(); 169 writer.setPrefix(soapPrefix, soapUri); 170 writer.writeStartElement(soapPrefix, SoapMarshaler.ENVELOPE, soapUri); 171 if (!marshaler.isRepairingNamespace()) { 172 writer.writeNamespace(soapPrefix, soapUri); 173 } 175 if (message.getHeaders() != null && message.getHeaders().size() > 0) { 177 writer.writeStartElement(soapPrefix, SoapMarshaler.HEADER, soapUri); 178 for (Iterator it = message.getHeaders().values().iterator(); it.hasNext();) { 179 DocumentFragment df = (DocumentFragment ) it.next(); 180 Element e = (Element ) df.getFirstChild(); 181 XMLStreamHelper.copy(new W3CDOMStreamReader(e), writer); 182 } 183 writer.writeEndElement(); 184 } 185 writer.writeStartElement(soapPrefix, SoapMarshaler.BODY, soapUri); 187 if (message.getFault() != null) { 188 writeFault(writer); 189 } else if (message.getSource() != null) { 190 writeContents(writer); 191 } 192 writer.writeEndElement(); 193 writer.writeEndElement(); 194 } 195 196 private void writeContents(XMLStreamWriter writer) throws Exception { 197 XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(message.getSource()); 198 XMLStreamHelper.copy(reader, writer); 199 } 200 201 private void writeFault(XMLStreamWriter writer) throws Exception { 202 QName envelope = getEnvelopeName(); 203 String soapUri = envelope.getNamespaceURI(); 204 if (SoapMarshaler.SOAP_11_URI.equals(soapUri)) { 205 writeSoap11Fault(writer); 206 } else if (SoapMarshaler.SOAP_12_URI.equals(soapUri)) { 207 writeSoap12Fault(writer); 208 } else { 209 throw new IllegalStateException ("Unknown soap namespace: " + soapUri); 210 } 211 } 212 213 private void writeSoap11Fault(XMLStreamWriter writer) throws Exception { 214 QName envelope = getEnvelopeName(); 215 String soapUri = envelope.getNamespaceURI(); 216 String soapPrefix = envelope.getPrefix(); 217 writer.setPrefix(soapPrefix, soapUri); 218 SoapFault fault = message.getFault(); 219 fault.translateCodeTo11(); 220 221 writer.writeStartElement(soapPrefix, SoapMarshaler.FAULT, soapUri); 222 QName code = fault.getCode(); 223 if (code != null) { 224 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTCODE); 225 XMLStreamHelper.writeTextQName(writer, code); 226 writer.writeEndElement(); 227 } 228 String reason = fault.getReason(); 229 if (reason == null && fault.getCause() != null) { 230 reason = fault.getCause().toString(); 231 } 232 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTSTRING); 233 if (reason != null) { 234 writer.writeCharacters(reason); 235 } 236 writer.writeEndElement(); 237 URI node = fault.getNode(); 238 if (node != null) { 239 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTACTOR); 240 writer.writeCharacters(node.toString()); 241 writer.writeEndElement(); 242 } 243 Source details = fault.getDetails(); 244 if (details != null) { 245 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTDETAIL); 246 XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(details); 247 XMLStreamHelper.copy(reader, writer); 248 writer.writeEndElement(); 249 } 250 251 writer.writeEndElement(); 252 } 253 254 private void writeSoap12Fault(XMLStreamWriter writer) throws Exception { 255 QName envelope = getEnvelopeName(); 256 String soapUri = envelope.getNamespaceURI(); 257 String soapPrefix = envelope.getPrefix(); 258 writer.setPrefix(soapPrefix, soapUri); 259 SoapFault fault = message.getFault(); 260 fault.translateCodeTo12(); 261 262 writer.writeStartElement(soapPrefix, SoapMarshaler.FAULT, soapUri); 263 QName code = fault.getCode(); 264 if (code != null) { 265 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTCODE); 266 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTVALUE); 267 XMLStreamHelper.writeTextQName(writer, code); 268 writer.writeEndElement(); 269 QName subcode = fault.getSubcode(); 270 if (subcode != null) { 271 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTSUBCODE); 272 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTVALUE); 273 XMLStreamHelper.writeTextQName(writer, subcode); 274 writer.writeEndElement(); 275 writer.writeEndElement(); 276 } 277 writer.writeEndElement(); 278 } 279 String reason = fault.getReason(); 280 if (reason == null && fault.getCause() != null) { 281 reason = fault.getCause().toString(); 282 } 283 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTREASON); 284 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTTEXT); 285 writer.writeAttribute(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI, "lang", "en"); 286 if (reason != null) { 287 writer.writeCharacters(reason); 288 } 289 writer.writeEndElement(); 290 writer.writeEndElement(); 291 URI node = fault.getNode(); 292 if (node != null) { 293 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTNODE); 294 writer.writeCharacters(node.toString()); 295 writer.writeEndElement(); 296 } 297 298 URI role = fault.getRole(); 299 if (role != null) { 300 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTROLE); 301 writer.writeCharacters(role.toString()); 302 writer.writeEndElement(); 303 } 304 305 Source details = fault.getDetails(); 306 if (details != null) { 307 XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTDETAIL); 308 XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(details); 309 XMLStreamHelper.copy(reader, writer); 310 writer.writeEndElement(); 311 } 312 313 writer.writeEndElement(); 314 } 315 316 protected QName getEnvelopeName() { 317 QName name = message.getEnvelopeName(); 318 if (name == null) { 319 name = new QName (marshaler.getSoapUri(), SoapMarshaler.ENVELOPE, marshaler.getPrefix()); 320 } else if (name.getPrefix() == null) { 321 name = new QName (name.getNamespaceURI(), name.getLocalPart(), marshaler.getPrefix()); 322 } 323 return name; 324 } 325 326 } 327 | Popular Tags |