es.ucm.fdi.dalgs.mailbox.service.MailBoxService.java Source code

Java tutorial

Introduction

Here is the source code for es.ucm.fdi.dalgs.mailbox.service.MailBoxService.java

Source

/**
 * This file is part of D.A.L.G.S.
 *
 * D.A.L.G.S is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * D.A.L.G.S is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with D.A.L.G.S.  If not, see <http://www.gnu.org/licenses/>.
 */
package es.ucm.fdi.dalgs.mailbox.service;

import java.io.IOException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeUtility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import es.ucm.fdi.dalgs.classes.ResultClass;
import es.ucm.fdi.dalgs.course.service.CourseService;
import es.ucm.fdi.dalgs.domain.Course;
import es.ucm.fdi.dalgs.domain.Group;
import es.ucm.fdi.dalgs.domain.MessageBox;
import es.ucm.fdi.dalgs.group.service.GroupService;
import es.ucm.fdi.dalgs.mailbox.respository.MailBoxRepository;
import es.ucm.fdi.storage.business.boundary.StorageManager;

/**
 * Get e-mail messages from a POP3/IMAP server
 *
 */
@Service
public class MailBoxService {

    @Value("${mail.protocol}")
    private String protocol;

    @Value("${mail.host}")
    private String host;

    @Value("${mail.port}")
    private String port;

    @Value("${mail.userName}")
    private String userName;

    @Value("${mail.password}")
    private String password;

    private static final String pattern = "^\\s*(Re:\\s*)?\\[(course|group):(\\d+)\\]";

    @Autowired
    private MailBoxRepository repositoryMailBox;

    @Autowired
    CourseService serviceCourse;

    @Autowired
    GroupService serviceGroup;

    @Autowired
    private StorageManager storageManager;

    private static final Logger logger = LoggerFactory.getLogger(MailBoxService.class);

    // app-config.xml
    @Value("#{attachmentsPrefs[bucket]}")
    private String bucket;

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Returns a Properties object which is configured for a POP3/IMAP server
     */
    private Properties getServerProperties(String protocol, String host, String port) {
        Properties properties = new Properties();

        // server setting
        properties.put(String.format("mail.%s.host", protocol), host);
        properties.put(String.format("mail.%s.port", protocol), port);

        // SSL setting
        properties.setProperty(String.format("mail.%s.socketFactory.class", protocol),
                "javax.net.ssl.SSLSocketFactory");
        properties.setProperty(String.format("mail.%s.socketFactory.fallback", protocol), "false");
        properties.setProperty(String.format("mail.%s.socketFactory.port", protocol), String.valueOf(port));

        return properties;
    }

    /**
     * Returns new messages and fetches details for each message.
     */
    @Transactional(readOnly = false)
    public ResultClass<Boolean> downloadEmails() {

        ResultClass<Boolean> result = new ResultClass<>();
        Properties properties = getServerProperties(protocol, host, port);
        Session session = Session.getDefaultInstance(properties);

        try {

            // connects to the message store
            Store store = session.getStore(protocol);

            store.connect(userName, password);
            // opens the inbox folder
            Folder folderInbox = store.getFolder("INBOX");
            folderInbox.open(Folder.READ_ONLY);
            // fetches new messages from server
            Message[] messages = folderInbox.getMessages();
            for (int i = 0; i < messages.length; i++) {
                Message msg = messages[i];

                String[] idHeaders = msg.getHeader("MESSAGE-ID");
                if (idHeaders != null && idHeaders.length > 0) {

                    MessageBox exists = repositoryMailBox.getMessageBox(idHeaders[0]);
                    if (exists == null) {

                        MessageBox messageBox = new MessageBox();
                        messageBox.setSubject(msg.getSubject());
                        messageBox.setCode(idHeaders[0]);

                        Address[] fromAddresses = msg.getFrom();
                        String from = InternetAddress.toString(fromAddresses);

                        if (from.startsWith("=?")) {
                            from = MimeUtility.decodeWord(from);
                        }
                        messageBox.setFrom(from);
                        String to = InternetAddress.toString(msg.getRecipients(RecipientType.TO));

                        if (to.startsWith("=?")) {
                            to = MimeUtility.decodeWord(to);
                        }
                        messageBox.setTo(to);

                        String[] replyHeaders = msg.getHeader("References");

                        if (replyHeaders != null && replyHeaders.length > 0) {
                            StringTokenizer tokens = new StringTokenizer(replyHeaders[0]);
                            MessageBox parent = repositoryMailBox.getMessageBox(tokens.nextToken());
                            if (parent != null)
                                parent.addReply(messageBox);
                        }

                        result = parseSubjectAndCreate(messageBox, msg);
                    }
                }
            }

            folderInbox.close(false);
            store.close();

            return result;

        } catch (NoSuchProviderException ex) {
            logger.error("No provider for protocol: " + protocol);
            ex.printStackTrace();
        } catch (MessagingException ex) {
            logger.error("Could not connect to the message store");
            ex.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }
        result.setSingleElement(false);
        return result;
    }

    private ResultClass<Boolean> parseSubjectAndCreate(MessageBox messageBox, Message msg)
            throws MessagingException, IOException {

        ResultClass<Boolean> result = new ResultClass<>();

        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(messageBox.getSubject());
        if (m.matches()) {

            String mimeType = msg.getAllHeaders() + msg.getContentType();
            String key = getStorageKey(Long.parseLong(m.group(3)));

            storageManager.putObject(bucket, key, mimeType, msg.getInputStream());
            String aaa = storageManager.getUrl(bucket, key).toExternalForm();
            messageBox.setFile(aaa);

            if (("group").equalsIgnoreCase(m.group(2))) {
                Group group = serviceGroup.getGroupFormatter(Long.parseLong(m.group(3)));
                if (group != null) {
                    group.getMessages().add(messageBox);
                    result = serviceGroup.updateGroup(group);
                }

            }

            else if (("course").equalsIgnoreCase(m.group(2))) {
                Course course = serviceCourse.getCourseFormatter(Long.parseLong(m.group(3)));
                if (course != null) {
                    course.getMessages().add(messageBox);
                    result = serviceCourse.updateCourse(course);
                }
            }

        }
        return result;
    }

    @Transactional(readOnly = true)
    public ResultClass<MessageBox> getMessages() {

        ResultClass<MessageBox> result = new ResultClass<>();

        result.addAll(repositoryMailBox.getAllMessages());

        return result;

    }

    private String getStorageKey(Long id) {
        return "attachment/" + Long.toString(id);
    }

}