All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.main.java.com.vincomobile.fw.basic.tools.MailerImpl Maven / Gradle / Ivy

There is a newer version: 5.1.0-RELEASE
Show newest version
package com.vincomobile.fw.basic.tools;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

@Component
public class MailerImpl implements Mailer {

    private Logger logger = LoggerFactory.getLogger(MailerImpl.class);

    private JavaMailSender mailSender;
    private String fromUser;

    private static int hear(BufferedReader in) throws IOException {
        String line = null;
        int res = 0;

        while ((line = in.readLine()) != null) {
            String pfx = line.substring(0, 3);
            try {
                res = Integer.parseInt(pfx);
            } catch (Exception ex) {
                res = -1;
            }
            if (line.charAt(3) != '-')
                break;
        }

        return res;
    }

    private static void say(BufferedWriter wr, String text) throws IOException {
        wr.write(text + "\r\n");
        wr.flush();
        return;
    }

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public String getFromUser() {
        return fromUser;
    }

    public void setFromUser(String fromUser) {
        this.fromUser = fromUser;
    }

    /**
     * Send a text mail
     *
     * @param from    From address
     * @param to      Address list (separate by , or ;)
     * @param subject Message subject
     * @param text    Message text
     * @return Success or not
     */
    @Override
    public boolean sendTextEmail(String from, String to, String subject, String text) {
        logger.debug("Sending email: " + to + ", Subject: " + subject);
        try {
            SimpleMailMessage msg = new SimpleMailMessage();
            msg.setFrom(from);
            msg.setTo(MailerUtils.getAddress(to));
            msg.setSubject(subject);
            msg.setText(text);
            this.mailSender.send(msg);
            return true;
        } catch (Throwable ex) {
            logger.error("Error in sendMessage " + to, ex);
            return false;
        }
    }

    /**
     * Send a email (MIME)
     *
     * @param from         From address
     * @param to           Address list (separate by , or ;)
     * @param subject      Message subject
     * @param body         Message text
     * @param resources    Inline resources
     * @param attachments  File attachments ([file name] -> [full path to file])
     * @param customSender User account to send email
     * @param bcc          BCC field
     * @param mimeMessage  Mime message
     * @return Success or not
     */
    @Override
    public synchronized boolean sendMimeEmail(String from, String to, String subject, String body, Map resources, Map attachments, JavaMailSender customSender, String bcc, MimeMessage mimeMessage) {
        if (customSender == null)
            customSender = mailSender;
        if (Converter.isEmpty(from)) {
            from = fromUser;
        }
        logger.debug("Sending email. Server: " + ((JavaMailSenderImpl) customSender).getHost() + ", From: " + from + ", To: " + to + ", Subject: " + subject);
        // Prepare send address
        final InternetAddress[] toAddress = MailerUtils.getInternetAddress(to);
        if (toAddress == null) {
            return false;
        }
        try {
            // Prepare the message
            if (mimeMessage == null)
                mimeMessage = customSender.createMimeMessage();
            mimeMessage.setSubject(subject, "UTF-8");
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setTo(toAddress);
            helper.setFrom(from);
            helper.setText(body, true);
            if (!MailerUtils.setBCC(helper, bcc))
                return false;
            // Inline resources
            if (resources != null && resources.size() > 0) {
                for (Map.Entry entry : resources.entrySet()) {
                    helper.addInline(entry.getKey(), new FileSystemResource(new File(entry.getValue())));
                }
            }
            // Attachments
            if (attachments != null && attachments.size() > 0) {
                for (Map.Entry entry : attachments.entrySet()) {
                    helper.addAttachment(entry.getKey(), new FileSystemResource(new File(entry.getValue())));
                }
            }
            // Send the message
            customSender.send(mimeMessage);
        } catch (Throwable ex) {
            logger.error("Error in sendMessage: " + to + "\n", ex);
            return false;
        }
        return true;
    }

    @Override
    public boolean sendMimeEmail(String from, String to, String subject, String body, Map resources, Map attachments, JavaMailSender customSender, String bcc) {
        return sendMimeEmail(from, to, subject, body, resources, attachments, customSender, bcc, null);
    }

    @Override
    public boolean sendMimeEmail(String from, String to, String subject, String body, Map resources, Map attachments, JavaMailSender customSender) {
        return sendMimeEmail(from, to, subject, body, resources, attachments, customSender, null, null);
    }

    @Override
    public boolean sendMimeEmail(String from, String to, String subject, String body, Map resources, Map attachments) {
        return sendMimeEmail(from, to, subject, body, resources, attachments, null, null, null);
    }

    /**
     * Send a email (MIME) defined in a template
     *
     * @param from         From address
     * @param to           Address list (separate by , or ;)
     * @param subject      Message subject
     * @param template     Template for Apache Velocity
     * @param model        Hashmap with model for template
     * @param resources    Inline resources
     * @param attachments  File attachments ([file name] -> [full path to file])
     * @param customSender User account to send email
     * @return Success or not
     */
    @Override
    public boolean sendTemplateEmail(String from, String to, String subject, String template, Map model, Map resources, Map attachments, JavaMailSender customSender) {
        return sendMimeEmail(from, to, subject, FreeMaker.genFreeMaker(template, model), resources, attachments, customSender);
    }

    @Override
    public boolean sendTemplateEmail(final String from, final String to, final String subject, final String template, final Map model, final Map resources, Map attachments) {
        return sendTemplateEmail(from, to, subject, template, model, resources, attachments, null);
    }

    @Override
    public boolean sendTemplateEmail(String from, String to, String subject, String template, Map model, Map resources) {
        return sendTemplateEmail(from, to, subject, template, model, resources, null, null);
    }

    @Override
    public boolean sendTemplateEmail(final String from, final String to, final String subject, final String template, final Map model) {
        return sendTemplateEmail(from, to, subject, template, model, null, null, null);
    }

    /**
     * Get sender configuration
     *
     * @param sender Sender implementation
     * @return Current configuration
     */
    @Override
    public MailerSenderConfig getSenderConfig(JavaMailSenderImpl sender) {
        MailerSenderConfig config = new MailerSenderConfig();
        config.username = sender.getUsername();
        config.password = sender.getPassword();
        config.host = sender.getHost();
        config.port = sender.getPort();
        config.properties = (Properties) sender.getJavaMailProperties().clone();
        return config;
    }

    /**
     * Set sender configuration
     *
     * @param sender Sender implementation
     * @param config Configuration
     */
    @Override
    public void setSenderConfig(JavaMailSenderImpl sender, MailerSenderConfig config) {
        sender.setUsername(config.username);
        sender.setPassword(config.password);
        sender.setHost(config.host);
        sender.setPort(config.port);
        sender.setJavaMailProperties(config.properties);
    }

    /**
     * Set sender configuration to use SSL
     *
     * @param sender Sender implementation
     * @param ssl    Use or not SSL
     */
    @Override
    public void setSenderConfigSSL(JavaMailSenderImpl sender, boolean ssl) {
        Properties properties = sender.getJavaMailProperties();
        if (ssl) {
            if (!properties.containsKey("mail.smtp.starttls.enable")) {
                properties.put("mail.smtp.starttls.enable", "true");
            }
        } else {
            if (!properties.containsKey("mail.smtp.starttls.enable")) {
                properties.remove("mail.smtp.starttls.enable");
            }
        }
    }

    /**
     * Find number of MX records for the email
     *
     * @param email Email to check
     * @return Number of host with MX
     */
    @Override
    public int doLookupMX(String email) {
        int pos = email.indexOf('@');
        if (pos == -1)
            return 0;
        try {
            Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
            DirContext ictx = new InitialDirContext(env);
            Attributes attrs = ictx.getAttributes(email.substring(++pos), new String[]{"MX"});
            Attribute attr = attrs.get("MX");
            if (attr == null)
                return 0;
            return attr.size();
        } catch (NamingException ex) {
            logger.error("Error in doLookupMX: " + email);
            logger.error(ex.getMessage());
            return 0;
        }
    }

    /**
     * Get a list of email servers for a domain
     *
     * @param hostName Name of host smtp
     * @return Server list
     * @throws NamingException
     */
    public ArrayList getMX(String hostName) throws NamingException {
        // Do a DNS lookup for MX records in domain
        Hashtable env = new Hashtable();
        env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
        DirContext ictx = new InitialDirContext(env);
        Attributes attrs = ictx.getAttributes(hostName, new String[]{"MX"});
        Attribute attr = attrs.get("MX");

        // If not found MX records try to connect direct to server
        if ((attr == null) || (attr.size() == 0)) {
            attrs = ictx.getAttributes(hostName, new String[]{"A"});
            attr = attrs.get("A");
            if (attr == null)
                throw new NamingException("No match for name '" + hostName + "'");
        }

        // Server list
        ArrayList res = new ArrayList();
        NamingEnumeration en = attr.getAll();
        while (en.hasMore()) {
            String x = (String) en.next();
            String f[] = x.split(" ");
            if (f[1].endsWith("."))
                f[1] = f[1].substring(0, (f[1].length() - 1));
            res.add(f[1]);
        }
        return res;
    }

    /**
     * Check if a email is valid (checking with SMTP server)
     *
     * @param address Email
     * @return Valid or not
     */
    public boolean isAddressValid(String address) {
        int pos = address.indexOf('@');
        if (pos == -1)
            return false;

        // Get SMTP server
        String domain = address.substring(++pos);
        ArrayList mxList = null;
        try {
            mxList = getMX(domain);
        } catch (NamingException ex) {
            return false;
        }
        if (mxList.size() == 0)
            return false;

        pos = fromUser.indexOf('@');
        if (pos == -1)
            return false;
        String fromDomain = fromUser.substring(++pos);

        // SMTP Validation
        for (int mx = 0; mx < mxList.size(); mx++) {
            System.out.print(mxList.get(mx) + ": ");
            boolean valid = false;
            try {
                int res;
                Socket skt = new Socket((String) mxList.get(mx), 25);
                BufferedReader rdr = new BufferedReader(new InputStreamReader(skt.getInputStream()));
                BufferedWriter wtr = new BufferedWriter(new OutputStreamWriter(skt.getOutputStream()));

                res = hear(rdr);
                if (res != 220)
                    throw new Exception("Invalid header");
                say(wtr, "EHLO " + fromDomain);

                res = hear(rdr);
                if (res != 250)
                    throw new Exception("Not ESMTP");

                // validate the sender address
                say(wtr, "MAIL FROM: <" + fromUser + ">");
                res = hear(rdr);
                if (res != 250)
                    throw new Exception("Sender rejected");

                say(wtr, "RCPT TO: <" + address + ">");
                res = hear(rdr);

                // be polite
                say(wtr, "RSET");
                hear(rdr);
                say(wtr, "QUIT");
                hear(rdr);
                if (res != 250)
                    throw new Exception("Address is not valid!");

                valid = true;
                rdr.close();
                wtr.close();
                skt.close();
            } catch (Exception ex) {
                // Do nothing but try next host
            } finally {
                if (valid)
                    return true;
            }
        }
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy