001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.soap.interceptors.mime;
018
019 import java.io.ByteArrayOutputStream;
020 import java.io.FilterOutputStream;
021 import java.io.IOException;
022 import java.io.OutputStream;
023 import java.util.ArrayList;
024 import java.util.Enumeration;
025 import java.util.Iterator;
026 import java.util.List;
027 import java.util.Map;
028 import java.util.Properties;
029
030 import javax.activation.DataHandler;
031 import javax.mail.Header;
032 import javax.mail.MessagingException;
033 import javax.mail.Session;
034 import javax.mail.util.ByteArrayDataSource;
035 import javax.mail.internet.MimeBodyPart;
036 import javax.mail.internet.MimeMessage;
037 import javax.mail.internet.MimeMultipart;
038
039 import org.apache.servicemix.soap.api.Fault;
040 import org.apache.servicemix.soap.api.InterceptorChain;
041 import org.apache.servicemix.soap.api.Message;
042 import org.apache.servicemix.soap.core.AbstractInterceptor;
043
044 /**
045 * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
046 */
047 public class AttachmentsOutInterceptor extends AbstractInterceptor {
048
049 public static final String PIPE_ATTACHMENT_STREAM = "PipeAttachmentStream";
050
051 public static final String SOAP_PART_ID = "soap-request";
052
053 public void handleMessage(final Message message) {
054 if (message.getAttachments().size() == 0) {
055 return;
056 }
057 OutputStream os = message.getContent(OutputStream.class);
058 if (os == null) {
059 throw new NullPointerException("OutputStream content not found");
060 }
061 try {
062 ByteArrayOutputStream baos = new ByteArrayOutputStream();
063 message.setContent(OutputStream.class, baos);
064 message.put(Message.CONTENT_TYPE, "multipart/related; type=\"text/xml\"; start=\"<" + SOAP_PART_ID + ">\"");
065 InterceptorChain chain = message.get(InterceptorChain.class);
066 chain.doIntercept(message);
067 writeMultipartMessage(message, os, baos.toByteArray());
068 } catch (MessagingException e) {
069 throw new Fault(e);
070 } catch (IOException e) {
071 throw new Fault(e);
072 }
073 }
074
075 protected boolean getBoolean(Message message, String name, boolean def) {
076 Object b = message.get(name);
077 if (b instanceof Boolean) {
078 return ((Boolean) b).booleanValue();
079 } else if (b != null) {
080 return Boolean.parseBoolean(b.toString());
081 } else {
082 return def;
083 }
084 }
085
086 @SuppressWarnings("unchecked")
087 private void writeMultipartMessage(Message message, OutputStream out, byte[] data) throws MessagingException, IOException {
088 MimeMultipart parts = new MimeMultipart("related; type=\"text/xml\"; start=\"<" + SOAP_PART_ID + ">\"");
089 Session session = Session.getDefaultInstance(new Properties(), null);
090 MimeMessage mime = new MimeMessage(session);
091 // Add soap part
092 MimeBodyPart soapPart = new MimeBodyPart();
093 soapPart.setContentID("<" + SOAP_PART_ID + ">");
094 soapPart.addHeader("Content-Transfer-Encoding", "8bit");
095 soapPart.setDataHandler(new DataHandler(new ByteArrayDataSource(data, "text/xml")));
096 parts.addBodyPart(soapPart);
097 // Add attachments
098 for (Iterator itr = message.getAttachments().entrySet().iterator(); itr.hasNext();) {
099 Map.Entry entry = (Map.Entry) itr.next();
100 String id = (String) entry.getKey();
101 DataHandler dh = (DataHandler) entry.getValue();
102 MimeBodyPart part = new MimeBodyPart();
103 part.setDataHandler(dh);
104 part.setContentID("<" + id + ">");
105 part.addHeader("Content-Transfer-Encoding", "binary");
106 parts.addBodyPart(part);
107 }
108 mime.setContent(parts);
109 mime.setHeader(Message.CONTENT_TYPE, parts.getContentType());
110 // We do not want headers, so
111 // * retrieve all headers
112 // * skip first 2 bytes (CRLF)
113 mime.saveChanges();
114 Enumeration<Header> headersEnum = mime.getAllHeaders();
115 List<String> headersList = new ArrayList<String>();
116 while (headersEnum.hasMoreElements()) {
117 headersList.add(headersEnum.nextElement().getName().toLowerCase());
118 }
119 String[] headers = headersList.toArray(new String[0]);
120 // Skip first 2 bytes
121 OutputStream os = new FilterOutputStream(out) {
122 private int nb = 0;
123 public void write(int b) throws IOException {
124 if (++nb > 2) {
125 super.write(b);
126 }
127 }
128 };
129 // Write
130 mime.writeTo(os, headers);
131 }
132
133 }