001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation.jaxrs.io.documents;
020
021import java.io.IOException;
022import java.util.List;
023import java.util.regex.Matcher;
024import java.util.regex.Pattern;
025
026import javax.activation.DataHandler;
027import javax.mail.MessagingException;
028import javax.mail.internet.MimeBodyPart;
029import javax.mail.internet.MimeMultipart;
030import javax.ws.rs.core.MediaType;
031import javax.ws.rs.core.Response;
032
033import org.nuxeo.ecm.automation.jaxrs.io.InputStreamDataSource;
034import org.nuxeo.ecm.core.api.Blob;
035
036/**
037 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
038 */
039public class MultipartBlobs extends MimeMultipart {
040
041    private static final Pattern BOUNDARY = Pattern.compile(";\\s*boundary\\s*=\"([^\"]+)\"");
042
043    public MultipartBlobs() {
044        super("mixed");
045    }
046
047    public MultipartBlobs(List<Blob> blobs) throws MessagingException, IOException {
048        super("mixed");
049        addBlobs(blobs);
050    }
051
052    public void addBlobs(List<Blob> blobs) throws MessagingException, IOException {
053        for (Blob blob : blobs) {
054            addBlob(blob);
055        }
056    }
057
058    public void addBlob(Blob blob) throws MessagingException, IOException {
059        MimeBodyPart part = new MimeBodyPart();
060        part.setDataHandler(new DataHandler(new InputStreamDataSource(blob.getStream(), blob.getMimeType(),
061                blob.getFilename())));
062        part.setDisposition("attachment");
063        String filename = blob.getFilename();
064        if (filename != null) {
065            part.setFileName(filename);
066        }
067        // must set the mime type at end because setFileName is also setting a
068        // wrong content type.
069        String mimeType = blob.getMimeType();
070        if (mimeType != null) {
071            part.setHeader("Content-type", mimeType);
072        }
073
074        addBodyPart(part);
075    }
076
077    public String getBoundary() {
078        Matcher m = BOUNDARY.matcher(getContentType());
079        if (m.find()) {
080            return m.group(1);
081        }
082        return null;
083    }
084
085    public Response getResponse() {
086        // jersey is not correctly reading ctype string -> it is removing quote
087        // from values..
088        // we need to rebuild ourself the correct header to preserve quotes on
089        // boundary value (otherwise javax.mail will not work on client side)
090        // for this we use our own MediaType class
091        return Response.ok(this).type(new BoundaryMediaType(getContentType())).build();
092    }
093
094    /**
095     * Workaround to be able to output boundary with quotes if needed.
096     *
097     * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
098     */
099    static class BoundaryMediaType extends MediaType {
100        private final String ctype;
101
102        BoundaryMediaType(String ctype) {
103            super("multipart", "mixed");
104            this.ctype = ctype;
105        }
106
107        @Override
108        public String toString() {
109            return ctype;
110        }
111    }
112
113}