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.ByteArrayInputStream;
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.io.SequenceInputStream;
023    import java.util.Properties;
024    
025    import javax.mail.MessagingException;
026    import javax.mail.Session;
027    import javax.mail.internet.ContentType;
028    import javax.mail.internet.MimeBodyPart;
029    import javax.mail.internet.MimeMessage;
030    import javax.mail.internet.MimeMultipart;
031    
032    import org.apache.servicemix.soap.api.Fault;
033    import org.apache.servicemix.soap.api.Message;
034    import org.apache.servicemix.soap.core.AbstractInterceptor;
035    
036    /**
037     * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
038     */
039    public class AttachmentsInInterceptor extends AbstractInterceptor {
040    
041        public static final String MULTIPART_CONTENT = "multipart/";
042        
043        public void handleMessage(Message message) {
044            InputStream is = message.getContent(InputStream.class);
045            if (is == null) {
046                throw new NullPointerException("InputStream content not found");
047            }
048            String contentType = (String) message.get(Message.CONTENT_TYPE);
049            if (contentType != null && contentType.toLowerCase().startsWith(MULTIPART_CONTENT)) {
050                try {
051                    Session session = Session.getDefaultInstance(new Properties());
052                    is = new SequenceInputStream(new ByteArrayInputStream(new byte[] { 13, 10 }), is);
053                    MimeMessage mime = new MimeMessage(session, is);
054                    mime.setHeader(Message.CONTENT_TYPE, contentType);
055                    read(message, mime);
056                } catch (IOException e) {
057                    throw new Fault(e);
058                } catch (MessagingException e) {
059                    throw new Fault(e);
060                }
061            }
062        }
063    
064        public void read(Message message, MimeMessage mime) throws MessagingException, IOException {
065            final Object content = mime.getContent();
066            if (content instanceof MimeMultipart == false) {
067                throw new UnsupportedOperationException("Expected a javax.mail.internet.MimeMultipart object but found a " + content.getClass());
068            }
069            MimeMultipart multipart = (MimeMultipart) content;
070            ContentType type = new ContentType(mime.getContentType());
071            String contentId = type.getParameter("start");
072            // Get request
073            MimeBodyPart contentPart = null;
074            if (contentId != null) {
075                contentPart = (MimeBodyPart) multipart.getBodyPart(contentId);
076            } else {
077                for (int i = 0; i < multipart.getCount(); i++) {
078                  MimeBodyPart contentPart2 = (MimeBodyPart) multipart.getBodyPart(i);
079                  String contentType = contentPart2.getContentType();
080                  
081                  if (contentType.indexOf("xml") >= 0) {
082                    contentPart = contentPart2;
083                    break;
084                  }
085                }
086            }
087            // Set new content
088            message.setContent(InputStream.class, contentPart != null ? contentPart.getInputStream() : null);
089            // Get attachments
090            for (int i = 0; i < multipart.getCount(); i++) {
091                MimeBodyPart part = (MimeBodyPart) multipart.getBodyPart(i);
092                if (part != contentPart) {
093                    String id = part.getContentID();
094                    if (id == null) {
095                        id = "Part" + i;
096                    } else if (id.startsWith("<")) {
097                        id = id.substring(1, id.length() - 1);
098                    }
099                    message.getAttachments().put(id, part.getDataHandler());
100                }
101            }
102        }
103    
104    }