KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > soap > marshalers > SoapWriter


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.servicemix.soap.marshalers;
18
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.FilterOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23 import java.net.URI JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Properties JavaDoc;
30
31 import javax.activation.DataHandler JavaDoc;
32 import javax.mail.Header JavaDoc;
33 import javax.mail.Session JavaDoc;
34 import javax.mail.internet.MimeBodyPart JavaDoc;
35 import javax.mail.internet.MimeMessage JavaDoc;
36 import javax.mail.internet.MimeMultipart JavaDoc;
37 import javax.xml.XMLConstants JavaDoc;
38 import javax.xml.namespace.QName JavaDoc;
39 import javax.xml.stream.XMLStreamReader;
40 import javax.xml.stream.XMLStreamWriter;
41 import javax.xml.transform.Source JavaDoc;
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 JavaDoc;
48 import org.w3c.dom.Element JavaDoc;
49
50 /**
51  *
52  * @author Guillaume Nodet
53  * @version $Revision: 1.5 $
54  * @since 3.0
55  */

56 public class SoapWriter {
57
58     public static final String JavaDoc SOAP_PART_ID = "soap-request";
59
60     private SoapMessage message;
61
62     private String JavaDoc contentType;
63
64     private SoapMarshaler marshaler;
65
66     private MimeMultipart JavaDoc 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 JavaDoc getContentType() {
75         return contentType;
76     }
77
78     public void write(OutputStream JavaDoc out) throws Exception JavaDoc {
79         if (message.hasAttachments()) {
80             writeMultipartMessage(out);
81         } else {
82             writeSimpleMessage(out);
83         }
84     }
85
86     private String JavaDoc prepare() {
87         if (message.hasAttachments()) {
88             parts = new MimeMultipart JavaDoc("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 JavaDoc out) throws Exception JavaDoc {
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 JavaDoc("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 JavaDoc("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 JavaDoc out) throws Exception JavaDoc {
121         Session JavaDoc session = Session.getDefaultInstance(new Properties JavaDoc(), null);
122         MimeMessage JavaDoc mime = new MimeMessage JavaDoc(session);
123         // Add soap part
124
MimeBodyPart JavaDoc soapPart = new MimeBodyPart JavaDoc();
125         soapPart.setContentID("<" + SOAP_PART_ID + ">");
126         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
127         writeSimpleMessage(baos);
128         soapPart.setDataHandler(new DataHandler JavaDoc(new ByteArrayDataSource(baos.toByteArray(), "text/xml")));
129         parts.addBodyPart(soapPart);
130         // Add attachments
131
for (Iterator JavaDoc itr = message.getAttachments().entrySet().iterator(); itr.hasNext();) {
132             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) itr.next();
133             String JavaDoc id = (String JavaDoc) entry.getKey();
134             DataHandler JavaDoc dh = (DataHandler JavaDoc) entry.getValue();
135             MimeBodyPart JavaDoc part = new MimeBodyPart JavaDoc();
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         // We do not want headers, so
143
// * retrieve all headers
144
// * skip first 2 bytes (CRLF)
145
mime.saveChanges();
146         Enumeration JavaDoc headersEnum = mime.getAllHeaders();
147         List JavaDoc headersList = new ArrayList JavaDoc();
148         while (headersEnum.hasMoreElements()) {
149             headersList.add(((Header JavaDoc) headersEnum.nextElement()).getName().toLowerCase());
150         }
151         String JavaDoc[] headers = (String JavaDoc[]) headersList.toArray(new String JavaDoc[0]);
152         // Skip first 2 bytes
153
OutputStream JavaDoc os = new FilterOutputStream JavaDoc(out) {
154             private int nb = 0;
155             public void write(int b) throws IOException JavaDoc {
156                 if (++nb > 2) {
157                     super.write(b);
158                 }
159             }
160         };
161         // Write
162
mime.writeTo(os, headers);
163     }
164
165     public void writeSoapEnvelope(XMLStreamWriter writer) throws Exception JavaDoc {
166         QName JavaDoc envelope = getEnvelopeName();
167         String JavaDoc soapUri = envelope.getNamespaceURI();
168         String JavaDoc 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             // XMLStreamHelper.writeNamespacesExcludingPrefixAndNamespace(out, in, soapPrefix, soapUri);
174
}
175         // Write Header
176
if (message.getHeaders() != null && message.getHeaders().size() > 0) {
177             writer.writeStartElement(soapPrefix, SoapMarshaler.HEADER, soapUri);
178             for (Iterator JavaDoc it = message.getHeaders().values().iterator(); it.hasNext();) {
179                 DocumentFragment JavaDoc df = (DocumentFragment JavaDoc) it.next();
180                 Element JavaDoc e = (Element JavaDoc) df.getFirstChild();
181                 XMLStreamHelper.copy(new W3CDOMStreamReader(e), writer);
182             }
183             writer.writeEndElement();
184         }
185         // Write Body
186
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 JavaDoc {
197         XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(message.getSource());
198         XMLStreamHelper.copy(reader, writer);
199     }
200
201     private void writeFault(XMLStreamWriter writer) throws Exception JavaDoc {
202         QName JavaDoc envelope = getEnvelopeName();
203         String JavaDoc 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 JavaDoc("Unknown soap namespace: " + soapUri);
210         }
211     }
212
213     private void writeSoap11Fault(XMLStreamWriter writer) throws Exception JavaDoc {
214         QName JavaDoc envelope = getEnvelopeName();
215         String JavaDoc soapUri = envelope.getNamespaceURI();
216         String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc {
255         QName JavaDoc envelope = getEnvelopeName();
256         String JavaDoc soapUri = envelope.getNamespaceURI();
257         String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc getEnvelopeName() {
317         QName JavaDoc name = message.getEnvelopeName();
318         if (name == null) {
319             name = new QName JavaDoc(marshaler.getSoapUri(), SoapMarshaler.ENVELOPE, marshaler.getPrefix());
320         } else if (name.getPrefix() == null) {
321             name = new QName JavaDoc(name.getNamespaceURI(), name.getLocalPart(), marshaler.getPrefix());
322         }
323         return name;
324     }
325     
326 }
327
Popular Tags