001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.jaxrs.io.documents;
013
014import java.io.IOException;
015import java.util.List;
016import java.util.regex.Matcher;
017import java.util.regex.Pattern;
018
019import javax.activation.DataHandler;
020import javax.mail.MessagingException;
021import javax.mail.internet.MimeBodyPart;
022import javax.mail.internet.MimeMultipart;
023import javax.ws.rs.core.MediaType;
024import javax.ws.rs.core.Response;
025
026import org.nuxeo.ecm.automation.jaxrs.io.InputStreamDataSource;
027import org.nuxeo.ecm.core.api.Blob;
028
029/**
030 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
031 */
032public class MultipartBlobs extends MimeMultipart {
033
034    private static final Pattern BOUNDARY = Pattern.compile(";\\s*boundary\\s*=\"([^\"]+)\"");
035
036    public MultipartBlobs() {
037        super("mixed");
038    }
039
040    public MultipartBlobs(List<Blob> blobs) throws MessagingException, IOException {
041        super("mixed");
042        addBlobs(blobs);
043    }
044
045    public void addBlobs(List<Blob> blobs) throws MessagingException, IOException {
046        for (Blob blob : blobs) {
047            addBlob(blob);
048        }
049    }
050
051    public void addBlob(Blob blob) throws MessagingException, IOException {
052        MimeBodyPart part = new MimeBodyPart();
053        part.setDataHandler(new DataHandler(new InputStreamDataSource(blob.getStream(), blob.getMimeType(),
054                blob.getFilename())));
055        part.setDisposition("attachment");
056        String filename = blob.getFilename();
057        if (filename != null) {
058            part.setFileName(filename);
059        }
060        // must set the mime type at end because setFileName is also setting a
061        // wrong content type.
062        String mimeType = blob.getMimeType();
063        if (mimeType != null) {
064            part.setHeader("Content-type", mimeType);
065        }
066
067        addBodyPart(part);
068    }
069
070    public String getBoundary() {
071        Matcher m = BOUNDARY.matcher(getContentType());
072        if (m.find()) {
073            return m.group(1);
074        }
075        return null;
076    }
077
078    public Response getResponse() {
079        // jersey is not correctly reading ctype string -> it is removing quote
080        // from values..
081        // we need to rebuild ourself the correct header to preserve quotes on
082        // boundary value (otherwise javax.mail will not work on client side)
083        // for this we use our own MediaType class
084        return Response.ok(this).type(new BoundaryMediaType(getContentType())).build();
085    }
086
087    /**
088     * Workaround to be able to output boundary with quotes if needed.
089     *
090     * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
091     */
092    static class BoundaryMediaType extends MediaType {
093        private final String ctype;
094
095        BoundaryMediaType(String ctype) {
096            super("multipart", "mixed");
097            this.ctype = ctype;
098        }
099
100        @Override
101        public String toString() {
102            return ctype;
103        }
104    }
105
106}