001/*
002 * (C) Copyright 2006-2016 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 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.ecm.platform.mail.listener.action;
020
021import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.ATTACHMENTS_KEY;
022import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.CC_RECIPIENTS_KEY;
023import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.CC_RECIPIENTS_PROPERTY_NAME;
024import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.CONTENT_ID;
025import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.CONTENT_KEY;
026import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.HTML_TEXT_PROPERTY_NAME;
027import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.MAIL_MESSAGE_TYPE;
028import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.MESSAGE_ID_KEY;
029import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.MESSAGE_ID_PROPERTY_NAME;
030import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.PARENT_PATH_KEY;
031import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.RECIPIENTS_KEY;
032import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.RECIPIENTS_PROPERTY_NAME;
033import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.SENDER_KEY;
034import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.SENDER_PROPERTY_NAME;
035import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.SENDING_DATE_KEY;
036import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.SENDING_DATE_PROPERTY_NAME;
037import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.SUBJECT_KEY;
038import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.TEXT_KEY;
039import static org.nuxeo.ecm.platform.mail.utils.MailCoreConstants.TEXT_PROPERTY_NAME;
040
041import java.io.IOException;
042import java.io.Serializable;
043import java.util.ArrayList;
044import java.util.Date;
045import java.util.HashMap;
046import java.util.List;
047import java.util.Map;
048
049import org.apache.commons.logging.Log;
050import org.apache.commons.logging.LogFactory;
051import org.nuxeo.ecm.core.api.Blob;
052import org.nuxeo.ecm.core.api.Blobs;
053import org.nuxeo.ecm.core.api.CoreSession;
054import org.nuxeo.ecm.core.api.DocumentModel;
055import org.nuxeo.ecm.core.api.NuxeoException;
056import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner;
057import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
058import org.nuxeo.ecm.core.api.blobholder.SimpleBlobHolder;
059import org.nuxeo.ecm.core.api.impl.blob.FileBlob;
060import org.nuxeo.ecm.core.api.pathsegment.PathSegmentService;
061import org.nuxeo.ecm.core.convert.api.ConversionService;
062import org.nuxeo.ecm.platform.mail.action.ExecutionContext;
063import org.nuxeo.runtime.api.Framework;
064
065/**
066 * Creates a MailMessage document for every new email found in the INBOX. The properties values are retrieved from the
067 * pipe execution context.
068 *
069 * @author Catalin Baican
070 */
071public class CreateDocumentsAction extends AbstractMailAction {
072
073    private static final Log log = LogFactory.getLog(CreateDocumentsAction.class);
074
075    @Override
076    @SuppressWarnings("unchecked")
077    public boolean execute(ExecutionContext context) {
078        CoreSession session = getCoreSession(context);
079        if (session == null) {
080            log.error("Could not open CoreSession");
081            return false;
082        }
083        PathSegmentService pss = Framework.getService(PathSegmentService.class);
084
085        ExecutionContext initialContext = context.getInitialContext();
086
087        String subject = (String) context.get(SUBJECT_KEY);
088        String sender = (String) context.get(SENDER_KEY);
089        Date sendingDate = (Date) context.get(SENDING_DATE_KEY);
090        ArrayList<String> recipients = (ArrayList<String>) context.get(RECIPIENTS_KEY);
091        ArrayList<String> ccRecipients = (ArrayList<String>) context.get(CC_RECIPIENTS_KEY);
092        List<FileBlob> attachments = (List<FileBlob>) context.get(ATTACHMENTS_KEY);
093        Map<String, String> contentKeys = (Map<String, String>) context.get(CONTENT_KEY);
094        String text = (String) context.get(TEXT_KEY);
095        String messageId = (String) context.get(MESSAGE_ID_KEY);
096
097        String parentPath = (String) initialContext.get(PARENT_PATH_KEY);
098
099        DocumentModel documentModel = session.createDocumentModel(MAIL_MESSAGE_TYPE);
100        documentModel.setPropertyValue("dc:title", subject + System.currentTimeMillis());
101        documentModel.setPathInfo(parentPath, pss.generatePathSegment(documentModel));
102        documentModel.setPropertyValue("dc:title", subject);
103        documentModel.setPropertyValue(MESSAGE_ID_PROPERTY_NAME, messageId);
104        documentModel.setPropertyValue(SENDER_PROPERTY_NAME, sender);
105        documentModel.setPropertyValue(SENDING_DATE_PROPERTY_NAME, sendingDate);
106        documentModel.setPropertyValue(RECIPIENTS_PROPERTY_NAME, recipients);
107        documentModel.setPropertyValue(CC_RECIPIENTS_PROPERTY_NAME, ccRecipients);
108        if (attachments != null && !attachments.isEmpty()) {
109            ArrayList<Map<String, Serializable>> files = new ArrayList<>();
110            for (FileBlob currentFileBlob : attachments) {
111                if (currentFileBlob != null) {
112                    Map<String, Serializable> file = new HashMap<>();
113                    file.put("file", currentFileBlob);
114                    files.add(file);
115                }
116            }
117            documentModel.setPropertyValue("files:files", files);
118        }
119        documentModel.setPropertyValue(CC_RECIPIENTS_PROPERTY_NAME, ccRecipients);
120
121        documentModel.setPropertyValue(HTML_TEXT_PROPERTY_NAME, text);
122        if (text != null && !text.isEmpty()) {
123            Blob sb = Blobs.createBlob(text, "text/html");
124            BlobHolder simpleBlobHolder = new SimpleBlobHolder(sb);
125            ConversionService conversionService = Framework.getService(ConversionService.class);
126            Map<String, Serializable> parameters = new HashMap<>();
127            parameters.put("tagFilter", "body");
128            BlobHolder simpleTextBH = conversionService.convert("html2text", simpleBlobHolder, parameters);
129            String simpleText;
130            try {
131                simpleText = simpleTextBH.getBlob().getString();
132            } catch (IOException e) {
133                throw new NuxeoException(e);
134            }
135            documentModel.setPropertyValue(TEXT_PROPERTY_NAME, simpleText);
136        }
137
138        UnrestrictedCreateDocument unrestrictedCreateDocument = new UnrestrictedCreateDocument(documentModel, session,
139                contentKeys);
140        unrestrictedCreateDocument.runUnrestricted();
141
142        return true;
143    }
144
145    // Helper inner class to do the unrestricted creation of the documents
146    protected class UnrestrictedCreateDocument extends UnrestrictedSessionRunner {
147
148        private DocumentModel document;
149
150        private Map<String, String> fileNames;
151
152        protected UnrestrictedCreateDocument(DocumentModel document, CoreSession session, Map<String, String> names) {
153            super(session);
154            this.document = document;
155            this.fileNames = names;
156        }
157
158        @Override
159        public void run() {
160            document = session.createDocument(document);
161
162            // Replace the content references with links to the file blobs
163            List<Map<String, Serializable>> files =
164                    (List<Map<String, Serializable>>) document.getPropertyValue("files:files");
165            if (files != null && !files.isEmpty() && !fileNames.isEmpty()) {
166                String html = (String) document.getPropertyValue(HTML_TEXT_PROPERTY_NAME);
167                if (html != null && !html.isEmpty()) {
168                    for (int i = 0; i < files.size(); i++) {
169                        Blob blob = (Blob) files.get(i).get("file");
170                        String key = fileNames.get(blob.getFilename());
171                        if (key != null) {
172                            html = html.replace(CONTENT_ID + key,
173                                    String.format("/nuxeo/nxfile/default/%s/files:files/%s/file/%s", document.getId(),
174                                            i, blob.getFilename()));
175                        }
176                    }
177                    document.setPropertyValue(HTML_TEXT_PROPERTY_NAME, html);
178                }
179            }
180            document = session.saveDocument(document);
181            session.save();
182        }
183    }
184
185}