001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)MessageDenormalizerImpl.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.common.soap;
030:
031: import java.io.ByteArrayInputStream;
032: import java.io.ByteArrayOutputStream;
033: import java.io.IOException;
034: import java.io.OutputStreamWriter;
035: import java.io.StringWriter;
036: import java.io.Writer;
037:
038: import java.util.Iterator;
039: import java.util.logging.Level;
040: import java.util.logging.Logger;
041:
042: import javax.jbi.messaging.Fault;
043: import javax.jbi.messaging.NormalizedMessage;
044:
045: import javax.xml.soap.MessageFactory;
046: import javax.xml.soap.SOAPException;
047: import javax.xml.soap.SOAPMessage;
048: import javax.xml.soap.SOAPHeader;
049: import javax.xml.soap.AttachmentPart;
050: import javax.xml.transform.Result;
051: import javax.xml.transform.Source;
052: import javax.xml.transform.Transformer;
053: import javax.xml.transform.TransformerFactory;
054: import javax.xml.transform.dom.DOMSource;
055: import javax.xml.transform.stream.StreamResult;
056: import javax.xml.transform.stream.StreamSource;
057:
058: import javax.activation.DataHandler;
059:
060: import java.util.logging.Logger;
061:
062: /**
063: * This Basic Profile 1.0 aware implementation is used to denormalize a JBI Normalized
064: * Message and convert it into a SOAP message format.
065: *
066: * @author Sun Microsystems, Inc.
067: */
068: public class MessageDenormalizerImpl implements MessageDenormalizer {
069: /**
070: * Namespace prefix for the payload.
071: */
072: private static final String PAYLOAD_NAMESPACE_PREFIX = "jbisb0";
073:
074: /**
075: * SOAP Namespace prefix.
076: */
077: private static final String SOAP_NAMESPACE_PREFIX = "soap";
078:
079: /**
080: * XML Schema Instance prefix.
081: */
082: private static final String XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX = "xsi";
083:
084: /**
085: * Internal handle to the message factory
086: */
087: private MessageFactory mMessageFactory;
088:
089: /**
090: * Internal handle to the logger instance
091: */
092: private Logger mLogger;
093:
094: /**
095: * Internal handle to String Translator instance.
096: */
097: private StringTranslator mStringTranslator;
098:
099: /**
100: * Internal handle to the transformer instance
101: */
102: private Transformer mTransformer;
103:
104: /**
105: * Creates a new instance of MessageDenormalizerImpl.
106: */
107: public MessageDenormalizerImpl() {
108: try {
109: mLogger = Logger.getLogger(this .getClass().getPackage()
110: .getName());
111: mStringTranslator = new StringTranslator(this .getClass()
112: .getPackage().getName(), this .getClass()
113: .getClassLoader());
114: mMessageFactory = MessageFactory.newInstance();
115:
116: TransformerFactory transformerFactory = TransformerFactory
117: .newInstance();
118: mTransformer = transformerFactory.newTransformer();
119: mTransformer.setOutputProperty("method", "xml");
120: mTransformer.setOutputProperty("omit-xml-declaration",
121: "yes");
122: } catch (Exception exception) {
123: // This should not happen. In case it does, log the exception and
124: // set the factory object to null
125: mLogger.severe(mStringTranslator
126: .getString("SBC_MESSAGE_FACTORY_CREATION_FAILURE"));
127: mLogger.severe(mStringTranslator.getString(
128: "SBC_ERROR_DETAILS", exception.toString()));
129: mMessageFactory = null;
130: mTransformer = null;
131: }
132: }
133:
134: /**
135: * Converts a JBI normalized message to a <code> javax.jbi.soap.SOAPMessage </code>
136: * instance. The SOAP Header information is extracted from the NormalizedMessage
137: * property "SoapHeader" and the SOAP Body content is extracted from the Normalized
138: * Message content. Any attachments present in the NormalizedMessage are also
139: * denormalized and added to the created <code> javax.jbi.soap.SOAPMessage </code>
140: * instance.
141: *
142: * @param normalizedMessage message to be denormalized.
143: * @param operation operation invoked
144: * @param isResponse indicates if a response messages needs to be generated
145: *
146: * @return the SOAP Message.
147: */
148: public SOAPWrapper denormalizeMessage(
149: NormalizedMessage normalizedMessage, Operation operation,
150: boolean isResponse) {
151: SOAPWrapper wrapper = null;
152: Writer writer = null;
153: mLogger.info(mStringTranslator
154: .getString("SBC_DENORMALIZE_JBI_MESSAGE"));
155:
156: try {
157: // Create a SOAP Message
158: ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
159: writer = new OutputStreamWriter(bufferedStream, "UTF-8");
160:
161: writeEnvelopeHeader(writer);
162:
163: if (normalizedMessage != null) {
164: // Writer the header to the writer instance.
165: writeHeader(normalizedMessage, writer);
166: }
167:
168: // Extract the body information from the Normalized Message
169: writeBody(normalizedMessage, operation, isResponse, writer);
170: writeEnvelopeFooter(writer);
171: writer.flush();
172:
173: // Create a soap message
174: SOAPMessage soapMessage = createSOAPMessage(bufferedStream);
175:
176: // Denormalize Attachments
177: denormalizeAttachments(soapMessage, normalizedMessage);
178: // Create a soap response wrapper
179: wrapper = new SOAPWrapper(soapMessage);
180:
181: if (normalizedMessage instanceof Fault) {
182: wrapper.setStatus(SOAPConstants.JBI_FAULT);
183: } else {
184: wrapper.setStatus(SOAPConstants.JBI_SUCCESS);
185: }
186: } catch (RuntimeException runtimeException) {
187: mLogger
188: .severe(mStringTranslator
189: .getString("SBC_DENORMALIZE_JBI_MESSAGE_FAILURE_RT_EXP"));
190: // Create a soap fault wrapper
191: wrapper = denormalizeMessage(runtimeException);
192: } catch (Exception exception) {
193: mLogger
194: .warning(mStringTranslator
195: .getString("SBC_DENORMALIZE_JBI_MESSAGE_FAILURE_EXP"));
196: mLogger.warning(mStringTranslator.getString(
197: "SBC_ERROR_DETAILS", exception.toString()));
198: mLogger.warning(mStringTranslator
199: .getString("SBC_CREATE_SOAP_FAULT"));
200:
201: // Create a soap fault wrapper
202: wrapper = denormalizeMessage(exception);
203: } finally {
204: closeWriter(writer);
205: }
206:
207: mLogger.info(mStringTranslator
208: .getString("SBC_SUCCESS_DENORMALIZE_JBI_MESSAGE"));
209:
210: return wrapper;
211: }
212:
213: /**
214: * Converts an exception to a SOAP Message. It uses the default Server fault code
215: * for denormalization.
216: *
217: * @param exception exception instance
218: *
219: * @return denormalized exception object
220: */
221: public SOAPWrapper denormalizeMessage(Exception exception) {
222: return denormalizeMessage(exception,
223: SOAPConstants.SERVER_FAULT_CODE);
224: }
225:
226: /**
227: * Converts an exception to a SOAP Message using the provided faultCode. The code
228: * expects the faultcode passed to be part of the soap namespace.
229: *
230: * @param exception exception instance
231: * @param faultCode fault code
232: *
233: * @return denormalized exception object
234: */
235: public SOAPWrapper denormalizeMessage(Exception exception,
236: String faultCode) {
237: SOAPWrapper wrapper = null;
238: Writer writer = null;
239:
240: mLogger.info(mStringTranslator
241: .getString("SBC_DENORMALIZE_EXCEPTION"));
242:
243: try {
244: // Create the ws-i compliant fault message from the exception
245: ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
246: writer = new OutputStreamWriter(bufferedStream, "UTF-8");
247:
248: if (exception == null) {
249: mLogger.warning(mStringTranslator
250: .getString("SBC_NULL_OBJECT_DENORMALIZATION"));
251: }
252:
253: writeEnvelopeHeader(writer);
254: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");
255: writeFault(exception, faultCode, writer);
256: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
257: writeEnvelopeFooter(writer);
258: writer.flush();
259:
260: // Create a soap message
261: SOAPMessage soapMessage = createSOAPMessage(bufferedStream);
262:
263: // Create a SOAP wrapper with service url as null
264: wrapper = new SOAPWrapper(soapMessage);
265: wrapper.setStatus(SOAPConstants.JBI_ERROR);
266: } catch (RuntimeException runtimeException) {
267: mLogger
268: .severe(mStringTranslator
269: .getString("SBC_SOAP_FAULT_GENERATION_FAILURE_RT_EXP"));
270: } catch (Exception denormalizationException) {
271: // This should not happen. In case it does do nothing. Log message
272: mLogger.severe(mStringTranslator
273: .getString("SBC_SOAP_FAULT_GENERATION_FAILURE"));
274: } finally {
275: closeWriter(writer);
276: }
277:
278: mLogger.info(mStringTranslator
279: .getString("SBC_SUCCESS_DENORMALIZE_EXCEPTION"));
280:
281: return wrapper;
282: }
283:
284: /**
285: * This method extracts the payload from the Normalized Message and writes it
286: * using the writer stream. The payload content is enclosed between the SOAP:Body
287: * header and SOAP:Body footer information.
288: *
289: * @param normalizedMessage normalized message
290: * @param operation operation invoked
291: * @param isResponse indicates if a response messages needs to be generated
292: * @param writer writer object to be used
293: *
294: * @throws Exception if the body cannot be written
295: */
296: protected void writeBody(NormalizedMessage normalizedMessage,
297: Operation operation, boolean isResponse, Writer writer)
298: throws Exception {
299: StringWriter stringWriter = null;
300:
301: try {
302: boolean isEmptyResponse = isResponse
303: && (normalizedMessage == null);
304: // Add the body information
305: writeBodyHeader(operation, writer, isEmptyResponse);
306: if (normalizedMessage != null) {
307: stringWriter = new StringWriter();
308: Result result = new StreamResult(stringWriter);
309: mTransformer.transform(normalizedMessage.getContent(),
310: result);
311: writer.write(stringWriter.toString());
312: }
313: writeBodyFooter(operation, writer, isEmptyResponse);
314: writer.flush();
315: } finally {
316: closeWriter(stringWriter);
317: }
318: }
319:
320: /**
321: * The method extracts the header information from the Normalized Message property
322: * "SoapHeader" and writes it using the writer instance. The header information
323: * is expected to be propagated as a <code> javax.xml.soap.SOAPHeader </code>
324: * implementation instance.
325: *
326: * @param normalizedMessage normalizedMessage
327: * @param writer writer object to be used
328: *
329: * @throws Exception if header cannot be used to write to the writer instance
330: */
331: protected void writeHeader(NormalizedMessage normalizedMessage,
332: Writer writer) throws Exception {
333: // Extract header information from the Normalized Message
334: SOAPHeader soapHeader = (SOAPHeader) normalizedMessage
335: .getProperty(SOAPConstants.HEADER_PROPERTY_NAME);
336: StringWriter stringWriter = null;
337:
338: if (soapHeader != null) {
339: try {
340: stringWriter = new StringWriter();
341:
342: Source source = new DOMSource(soapHeader);
343: Result result = new StreamResult(stringWriter);
344: mTransformer.transform(source, result);
345:
346: // Add the header information
347: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Header>");
348: writer.write(stringWriter.toString());
349: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Header>");
350: writer.flush();
351: } finally {
352: closeWriter(stringWriter);
353: }
354: } else {
355: mLogger.fine(mStringTranslator.getString("SBC_NO_HEADER"));
356: }
357: }
358:
359: /**
360: * Uses the writer object to write the SOAP:Body header information. This method
361: * is invoked before the body payload is written.
362: *
363: * @param operation operation invoked
364: * @param writer writer object to be used
365: * @param isEmptyResponse indicates if an empty response message needs to be generated
366: *
367: * @throws Exception if body header cannot be written.
368: */
369: protected void writeBodyHeader(Operation operation, Writer writer,
370: boolean isEmptyResponse) throws Exception {
371: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");
372:
373: if (isEmptyResponse) {
374: writer.write("<" + PAYLOAD_NAMESPACE_PREFIX + ":");
375: writer.write(operation.getName() + "Response");
376: writer.write(" xmlns:" + PAYLOAD_NAMESPACE_PREFIX + "=\"");
377: writer.write(operation.getOutputNamespace() + "\"");
378: writer.write(">");
379: }
380:
381: writer.flush();
382: }
383:
384: /**
385: * Uses writer object to write the SOAP:Body footer information. This method is
386: * invoked after the body payload has been written.
387: *
388: * @param operation operation invoked
389: * @param writer writer object.
390: * @param isEmptyResponse indicates if a response messages needs to be generated
391: *
392: * @throws Exception if body footer cannot be written
393: */
394: protected void writeBodyFooter(Operation operation, Writer writer,
395: boolean isEmptyResponse) throws Exception {
396:
397: if (isEmptyResponse) {
398: writer.write("</" + PAYLOAD_NAMESPACE_PREFIX + ":");
399: writer.write(operation.getName() + "Response>");
400: }
401: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
402: writer.flush();
403: }
404:
405: /**
406: * Uses the provided input data to create a <code> javax.xml.soap.SOAPMessage </code>
407: * instance.
408: *
409: * @param byteStream Stream which contains the soap messages information as bytes.
410: *
411: * @return SOAP Message object
412: *
413: * @throws SOAPException if soap message object cannot be created.
414: * @throws IOException if soap message object cannot be created.
415: */
416: protected SOAPMessage createSOAPMessage(
417: ByteArrayOutputStream byteStream) throws SOAPException,
418: IOException {
419: if (mLogger.isLoggable(Level.FINEST)) {
420: mLogger.finest(mStringTranslator.getString(
421: "SBC_DEONRMALIZED_MESSAGE_DETAILS", byteStream
422: .toString()));
423: }
424:
425: // Create a soap message
426: SOAPMessage soapMessage = mMessageFactory.createMessage();
427:
428: // Populate the fault message in the soap Message
429: byte[] data = byteStream.toByteArray();
430: ByteArrayInputStream soapInputStream = new ByteArrayInputStream(
431: data);
432: StreamSource streamSource = new StreamSource(soapInputStream);
433: soapMessage.getSOAPPart().setContent(streamSource);
434: soapInputStream.close();
435:
436: return soapMessage;
437: }
438:
439: /**
440: * Closes the writer instance. This method handles any exceptions thrown
441: * while handling this request.
442: *
443: * @param writer writer instance.
444: */
445: protected void closeWriter(Writer writer) {
446: if (writer != null) {
447: try {
448: writer.close();
449: } catch (Exception ioException) {
450: // This should not happen. In case it does do nothing
451: mLogger.warning(mStringTranslator
452: .getString("SBC_CLOSE_OUTPUT_STREAM"));
453: mLogger.warning(mStringTranslator.getString(
454: "SBC_ERROR_DETAILS", ioException.toString()));
455: }
456: }
457: }
458:
459: /**
460: * Uses writer object to write the SOAP:Envelope header information. This method
461: * is invoked before writing the envelope content ( header and body content).
462: *
463: * @param writer writer object.
464: *
465: * @throws IOException if envelope header information cannot be written.
466: */
467: protected void writeEnvelopeHeader(Writer writer)
468: throws IOException {
469: // Write the soap envelope
470: writer
471: .write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
472: + "<"
473: + SOAP_NAMESPACE_PREFIX
474: + ":Envelope xmlns:"
475: + SOAP_NAMESPACE_PREFIX
476: + "=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:"
477: + XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX
478: + "=\"http://www.w3.org/2001/XMLSchema-instance\">");
479: writer.flush();
480: }
481:
482: /**
483: * Uses writer object to write the SOAP:Envelope footer information. This method
484: * is invoked after writing the envelope content ( header and body content).
485: *
486: * @param writer writer object
487: *
488: * @throws IOException if envelope footer information cannot be written.
489: */
490: protected void writeEnvelopeFooter(Writer writer)
491: throws IOException {
492: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Envelope>");
493: writer.flush();
494: }
495:
496: /**
497: * Create the SOAP:Fault message based on the provided exception details and writes
498: * it using the writer instance.
499: *
500: * @param exception exception thrown
501: * @param faultCode fault code
502: * @param writer writer object
503: *
504: * @throws IOException if fault message cannot be generated.
505: */
506: protected void writeFault(Exception exception, String faultCode,
507: Writer writer) throws IOException {
508: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Fault><faultcode>"
509: + SOAP_NAMESPACE_PREFIX + ":" + faultCode
510: + "</faultcode>");
511:
512: if (exception != null) {
513: writer.write("<faultstring>"
514: + sanitizeMessage(exception.getMessage())
515: + "</faultstring>");
516: }
517:
518: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Fault>");
519: writer.flush();
520: }
521:
522: /**
523: * Converts a JBI Fault mesage to a standard <code> javax.xml.soap.SOAPMessage </code>
524: * message instance. It uses the default Server fault code for denormalization.
525: *
526: * @param faultMessage JBI fault message.
527: *
528: * @return a new SOAPWrapper instance which contains the SOAP fault Message.
529: */
530: public SOAPWrapper denormalizeFaultMessage(Fault faultMessage) {
531: return denormalizeFaultMessage(faultMessage,
532: SOAPConstants.SERVER_FAULT_CODE);
533: }
534:
535: /**
536: * Converts a JBI Fault mesage to a SOAP Message using the specified fault code.
537: *
538: * @param faultMessage JBI fault message.
539: * @param faultCode fault code to be used in the fault message
540: *
541: * @return a new SOAPWrapper instance which contains the SOAP fault Message.
542: */
543: public SOAPWrapper denormalizeFaultMessage(Fault faultMessage,
544: String faultCode) {
545: SOAPWrapper wrapper = null;
546: Writer writer = null;
547:
548: mLogger.info(mStringTranslator
549: .getString("SBC_DENORMALIZE_FAULT_MESSAGE"));
550:
551: try {
552: // Create the ws-i compliant fault message from the exception
553: ByteArrayOutputStream bufferedStream = new ByteArrayOutputStream();
554: String messageFaultCode = (String) faultMessage
555: .getProperty(SOAPConstants.FAULT_CODE_PROPERTY_NAME);
556: String faultString = (String) faultMessage
557: .getProperty(SOAPConstants.FAULT_STRING_PROPERTY_NAME);
558:
559: if (messageFaultCode != null) {
560: // Override the fault code with the message fault code.
561: faultCode = messageFaultCode;
562: }
563:
564: if (faultString == null) {
565: faultString = mStringTranslator
566: .getString("SBC_DEFAULT_FAULT_STRING");
567: }
568: writer = new OutputStreamWriter(bufferedStream, "UTF-8");
569: writeEnvelopeHeader(writer);
570: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Body>");
571: writer.write("<" + SOAP_NAMESPACE_PREFIX + ":Fault "
572: + XML_SCHEMA_INSTANCE_NAMESPACE_PREFIX + ":type=\""
573: + SOAP_NAMESPACE_PREFIX + ":Fault\""
574: + "><faultcode>" + SOAP_NAMESPACE_PREFIX + ":"
575: + faultCode + "</faultcode>");
576: writer.write("<faultstring>" + faultString
577: + "</faultstring>");
578: writeFaultDetail(faultMessage, writer);
579: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Fault>");
580: writer.write("</" + SOAP_NAMESPACE_PREFIX + ":Body>");
581: writeEnvelopeFooter(writer);
582: writer.flush();
583:
584: // Create a soap message
585: SOAPMessage soapMessage = createSOAPMessage(bufferedStream);
586:
587: // Create a SOAP wrapper with service url as null
588: wrapper = new SOAPWrapper(soapMessage);
589: wrapper.setStatus(SOAPConstants.JBI_FAULT);
590: } catch (RuntimeException runtimeException) {
591: mLogger
592: .severe(mStringTranslator
593: .getString("SBC_SOAP_FAULT_GENERATION_FAILURE_RT_EXP"));
594: } catch (Exception exception) {
595: // This should not happen. In case it does do nothing. Log message
596: mLogger.severe(mStringTranslator
597: .getString("SBC_SOAP_FAULT_GENERATION_FAILURE"));
598: } finally {
599: closeWriter(writer);
600: }
601:
602: mLogger.info(mStringTranslator
603: .getString("SBC_SUCCESS_DENORMALIZE_FAULT"));
604:
605: return wrapper;
606: }
607:
608: /**
609: * Writes the detailed fault message using the provided writer instance.
610: *
611: * @param faultMessage JBI Fault object which contains the fault details.
612: * @param writer writer object to be used.
613: *
614: * @throws Exception if the fault detail vould not be written.
615: */
616: private void writeFaultDetail(Fault faultMessage, Writer writer)
617: throws Exception {
618: StringWriter stringWriter = null;
619:
620: try {
621: stringWriter = new StringWriter();
622:
623: Result result = new StreamResult(stringWriter);
624: mTransformer.transform(faultMessage.getContent(), result);
625:
626: // Add the fault detail
627: String detailString = stringWriter.toString().trim();
628:
629: if (!detailString.equals("")) {
630: writer.write("<detail>");
631: writer.write(detailString);
632: writer.write("</detail>");
633: writer.flush();
634: }
635: } finally {
636: closeWriter(stringWriter);
637: }
638: }
639:
640: /**
641: * Sanitizes the messages so that it can be properly read by an XML parser.
642: *
643: * @param errorMessage error message to be sanitized.
644: *
645: * @return sanitized error message.
646: */
647: protected String sanitizeMessage(String errorMessage) {
648: StringBuffer sanitizedBuffer = new StringBuffer();
649:
650: for (int i = 0; (errorMessage != null)
651: && (i < errorMessage.length()); i++) {
652: char currentChar = errorMessage.charAt(i);
653:
654: switch (currentChar) {
655: case '"':
656: sanitizedBuffer.append(""");
657:
658: break;
659:
660: case '&':
661: sanitizedBuffer.append("&");
662:
663: break;
664:
665: case '<':
666: sanitizedBuffer.append("<");
667:
668: break;
669:
670: case '>':
671: sanitizedBuffer.append(">");
672:
673: break;
674:
675: default:
676: sanitizedBuffer.append(currentChar);
677: }
678: }
679:
680: if (errorMessage == null) {
681: return "INTERNAL SERVER ERROR";
682: } else {
683: return sanitizedBuffer.toString();
684: }
685: }
686:
687: /**
688: * Denormalizes the attachments present in the JBI Normalized Message and adds
689: * them to the <code> javax.xml.soap.SoapMessage </code> instance.
690: *
691: * @param soapMessage soap message.
692: * @param normalizedMessage normalized message instance.
693: */
694: private void denormalizeAttachments(SOAPMessage soapMessage,
695: NormalizedMessage normalizedMessage) {
696: if (normalizedMessage != null) {
697: Iterator attachmentIter = normalizedMessage
698: .getAttachmentNames().iterator();
699: for (; attachmentIter.hasNext();) {
700: String attachmentIdentifier = (String) attachmentIter
701: .next();
702: DataHandler dataHandler = normalizedMessage
703: .getAttachment(attachmentIdentifier);
704: AttachmentPart attachment = soapMessage
705: .createAttachmentPart(dataHandler);
706: attachment.setContentId(attachmentIdentifier);
707: attachment.setContentType(dataHandler.getContentType());
708: soapMessage.addAttachmentPart(attachment);
709: }
710: }
711: }
712: }
|