Package com.qwertovsky.mailer

Source Code of com.qwertovsky.mailer.Mailer

package com.qwertovsky.mailer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Address;
import javax.mail.internet.InternetAddress;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

import au.com.bytecode.opencsv.CSVReader;

/**
* @author Qwertovsky
*
*/
class Mailer
{
  public static Logger logger = Logger.getLogger("com.qwertovsky.mailer");
 
 
  //--------------------------------------------
  public static void main(String[] args)
  {
    //logger configuration
    String pattern = "[%d{yyyy-MM-dd HH:mm:ss} %-4r][%-5p] %m%n";
      PatternLayout layout = new PatternLayout(pattern);
      //file will be rolled over every day
      DailyRollingFileAppender appender=null;
      try
    {
      File logDir = new File("log");
      if(!logDir.exists())
        logDir.mkdir();
        appender = new DailyRollingFileAppender(layout, "log/qwertomailer.log", "'.'yyyy-MM-dd'.log'");
      } catch (IOException e)
    {
      logger.error(e.getMessage());
      return;
    }
      logger.addAppender(appender);
      logger.setLevel(Level.INFO);
   
    logger.info("---------------------------------------");
    logger.info("Program started");
    InputStream manifestStream = Thread.currentThread().getContextClassLoader()
      .getResourceAsStream("META-INF/MANIFEST.MF");
    try
    {
      Manifest manifest = new Manifest(manifestStream);
      Attributes attributes = manifest.getMainAttributes();
      String impVersion = attributes.getValue("Implementation-Version");
      String builtDate = attributes.getValue("Built-Date");
      logger.info("Built date: " + builtDate +", Version: "+impVersion);
    } catch (IOException ex)
    {
      logger.warn("Error while reading version: " + ex.getMessage());
    }
    //write options
    String optionsLine = "";
    for(String arg:args)
    {
      if(arg.contains(" "))
        arg = "\"" + arg +"\"";
      optionsLine = optionsLine + " " + arg;
    }
    logger.info("Command line options: " + optionsLine);
   
      //options
    Options options = createOptions();
   
    //parse parameters
    CommandLineParser parser = new PosixParser();

    String smtpHost = null;
    int smtpPort = 25;
    String smtpUser = null;
    String smtpPassword = null;
    String hostname = null;
    String charset = "utf-8";
    String contentTransferEncoding = "8bit";
    String text = null;
    String contentType = "text/plain";
    File emlFile = null;
    String subject = null;
    String emailFrom = null;
    String personFrom = null;
    boolean haltOnFailure = false;
    Set<InternetAddress> emailsTo = new HashSet<InternetAddress>();
    ArrayList<String[]> personParameters = new ArrayList<String[]>();
    String[] personParamHeaders = null;
   
    CommandLine commandLine = null;
    try
    {
      commandLine = parser.parse(options, args, true);
    }catch(ParseException pe)
    {
      logger.error(pe.getMessage());
      System.err.println(pe.getMessage());
      HelpFormatter helpFormatter = new HelpFormatter();
      helpFormatter.printHelp("java -jar qwertomailer.jar", options, true);
      return;
    }
   
    if(commandLine.hasOption("trace"))
    {
      logger.setLevel(Level.TRACE);
    }
    if(commandLine.hasOption("haltOnFailure"))
    {
      haltOnFailure = true;
    }
   
    smtpHost = commandLine.getOptionValue("smtpHost");
    if(commandLine.hasOption("smtpPort"))
    {
      try
      {
        long port = (Long)commandLine.getParsedOptionValue("smtpPort");
        smtpPort = (int) port;
      } catch (ParseException pe)
      {
        logger.error("smtpPort has bad format");
        System.err.println("smtpPort has bad format");
        return;
      } catch (ClassCastException cce)
      {
        logger.error("smtpPort has bad format");
        System.err.println("smtpPort has bad format");
        return;
      }
    }
   
    if(commandLine.hasOption("smtpUser"))
      smtpUser = commandLine.getOptionValue("smtpUser");
    if(commandLine.hasOption("smtpPassword"))
      smtpPassword = commandLine.getOptionValue("smtpPassword");
    if(commandLine.hasOption("hostname"))
      hostname = commandLine.getOptionValue("hostname");
    charset = commandLine.getOptionValue("charset", "UTF-8");
    contentTransferEncoding = commandLine.getOptionValue("mimeTransport", "8bit");
   
    if(commandLine.hasOption("body"))
      text = commandLine.getOptionValue("body");
    else if (commandLine.hasOption("bodyFile"))
    {
      String file = commandLine.getOptionValue("bodyFile");
      text = getMessageTextFromFile(file, charset);
    }
    else if (commandLine.hasOption("EMLFile"))
    {
      emlFile = new File(commandLine.getOptionValue("EMLFile"));
      if(!emlFile.exists())
      {
        logger.error("EML file not exists");
        System.err.println("EML file not exists");
        return;
      }
    }
   
    contentType = commandLine.getOptionValue("contentType", "text/plain");
   
    if (!commandLine.hasOption("EMLFile"))
    {
      if(commandLine.hasOption("subject"))
        subject = commandLine.getOptionValue("subject");
      else if(commandLine.hasOption("subjectFile"))
      {
        String file = commandLine.getOptionValue("subjectFile");
        subject = getSubjectFromFile(file, charset);
      }
      if(subject == null)
      {
        logger.error("Missing required option: [-subjectFile file with subject line, -subject subject]");
        System.err.println("Missing required option: [-subjectFile file with subject line, -subject subject]");
        System.exit(1);
      }
    }
    else
    {
      if(commandLine.hasOption("subject") || commandLine.hasOption("subjectFile"))
      {
        logger.warn("The option 'subject' was specified but will be used subject from EML file");
        System.err.println("The option 'subject' was specified but will be used subject from EML file");
        System.exit(1);
      }
    }
   
    emailFrom = commandLine.getOptionValue("emailFrom");
    if(commandLine.hasOption("personFrom"))
      personFrom = commandLine.getOptionValue("personFrom");
   
    if(commandLine.hasOption("emailTo"))
    {
      String[] addresses = commandLine.getOptionValues("emailTo");
      Pattern addressPattern = Pattern.compile("(.+(?=<))?<?([^<>]+)?");
      for(String address:addresses)
      {
        // get email and person
        Matcher addressMatcher = addressPattern.matcher(address);
        String personal = null;
        String email = null;
        if(addressMatcher.find())
        {
          personal = addressMatcher.group(1);
          email = addressMatcher.group(2);
        }
        try
        {
          if(email != null)
            email = email.trim();
          else
            continue;
          if(personal != null)
          {
            personal = personal.trim();
            emailsTo.add(new InternetAddress(email, personal));
          }
          else
            emailsTo.add(new InternetAddress(email));
        }catch (Exception e)
        {
          logger.warn(email + ":" + e.getMessage());
        }
      }
    }
    else if(commandLine.hasOption("emailToFile"))
    {
      String file = commandLine.getOptionValue("emailToFile");
      personParamHeaders = getPersonParametersFromFile(personParameters, file, charset);
    }
   
    String alttext = null;
    boolean related = false;
    if(contentType.equalsIgnoreCase("text/html"))
    {
      //get alternative text
      if(commandLine.hasOption("alttext"))
      {
        alttext = commandLine.getOptionValue("alttext");
      }
      else if(commandLine.hasOption("alttextFile"))
      {
        String file = commandLine.getOptionValue("alttextFile");
        alttext = getAltTextFromFile(file, charset);
      }
   
      //is related
      if(commandLine.hasOption("related"))
      {
        related = true;
      }
    }
   
    //get attachments
    List<File> attachFiles = new ArrayList<File>();
    if(commandLine.hasOption("attach"))
    {
      String[] attachFilesPath = commandLine.getOptionValues("attach");
     
      for(String path:attachFilesPath)
      {
        attachFiles.add(new File(path));
      }
    }
    else if(commandLine.hasOption("attachFile"))
    {
      String file = commandLine.getOptionValue("attachFile");
      attachFiles = getAttachFilesFromFile(file, charset);
    }
   
    //create sender
    Sender sender = null;
    try
    {
      sender = new Sender(smtpHost, smtpPort, smtpUser, smtpPassword, hostname);
    } catch (Exception e)
    {
      logger.error(e.getMessage());
      System.err.println(e.getMessage());
      return;
    }
   
    //create message
    MessageContent message = null;
    try
    {
      if(emlFile != null)
        message = new MessageContent(emlFile);
      else
        message = new MessageContent(text,contentType, subject, charset);
      message.setContentTransferEncoding(contentTransferEncoding);
      message.setAddressFrom(personFrom, emailFrom, charset);
      if(alttext != null)
        message.setAlternativeText(alttext, charset);
      if(attachFiles != null && !attachFiles.isEmpty())
      {
        message.addAttachments(attachFiles);
      }
      if(related)
        message.setRelated();
    } catch (Exception e)
    {
      logger.error(e.getMessage());
      System.err.println(e.getMessage());
      logger.info("Program stoped");
      System.exit(1);
    }
   
    //send message
    try
    {
      if(commandLine.hasOption("emailTo"))
      {
        logger.info("Message count for send: " + emailsTo.size());
        sender.send(message, emailsTo);
      }
      else
      {
        //send with parameters
        logger.info("Message count for send: " + personParameters.size());
        sender.send(message, personParamHeaders, personParameters, haltOnFailure);
      }
    }catch(Exception e)
    {
      String errorMessage = e.getMessage();
      if(errorMessage != null)
      {
        logger.error(errorMessage);
        System.err.println(errorMessage);
      }
      else
      {
        logger.error("Error",e);
        System.err.println("Error");
      }
    }
   
    List<Message> sentMessages = sender.getSentMessages();
    logger.info("----");
    logger.info("Sent messages count: "
        + (sentMessages != null ? sentMessages.size() : 0));
   
    //print bad emails
    List<String> badEmails = sender.getBadEmails();
    if(badEmails != null && !badEmails.isEmpty())
    {
      System.err.println("Some emails is wrong");
      logger.warn("----");
      logger.warn("Some emails is wrong");
      for(String badEmail:badEmails)
      {
        logger.warn(badEmail);
      }
    }
   
    //print bad emails
    List<Map<String, String>> badParameters = sender.getBadParameters();
    if(badParameters != null && !badParameters.isEmpty())
    {
      System.err.println("Some parameters is wrong");
      logger.warn("----");
      logger.warn("Some parameters is wrong");
      for(Map<String, String> parameters:badParameters)
      {
        StringBuilder sb = new StringBuilder();
        Set<String> headers = parameters.keySet();
        for(String header:headers)
        {
          if(sb.length() > 0)
            sb.append(", ");
          sb.append("\"" + parameters.get(header) + "\"");
        }
        logger.warn(sb.toString());
      }
    }
   
    //print not sent messages
    List<Message> notSentMessages = sender.getNotSentMessages();
    if(notSentMessages != null && !notSentMessages.isEmpty())
    {
      System.err.println("Some messages not been sent");
      logger.warn("-----");
      logger.warn("Some messages not been sent");
      for(Message notSentMessage:notSentMessages)
      {
        StringBuilder sb = new StringBuilder();
        Address[] recipients = null;
        try
        {
          recipients = notSentMessage.getAllRecipients();
          int i=0;
          for(; i < 3 && i < recipients.length; i++)
          {
            if(sb.length() > 0)
              sb.append(", ");
            sb.append(((InternetAddress)recipients[i]).getAddress());
          }
          if(i < recipients.length)
            sb.append("...");
        } catch (Exception e1)
        {
          sb.append("error get recipients");
        }
        //append parameters
        StringBuilder sbParameters = new StringBuilder();
        Map<String, String> parametersForMessage = notSentMessage.getParameters();
        if(parametersForMessage != null)
        {
         
          sbParameters.append(" [");
          Set<String> keys = parametersForMessage.keySet();
          for(String key:keys)
          {
            if(sbParameters.length() > 2)
              sbParameters.append(", ");
            String parameter = parametersForMessage.get(key);
            sbParameters.append(parameter);
          }
          sbParameters.append("]");
        }
        sb.append(sbParameters.toString());
        logger.warn(sb.toString());
      }
    }
    logger.info("Program stoped");
  }
 
 

  //--------------------------------------------
  private static String getMessageTextFromFile(String file, String charset)
  {
    File textFile = new File(file);
    logger.info("Get message text from file: " + textFile.getAbsolutePath());
    String text = null;
    try
    {
      Scanner scanner = new Scanner(textFile, charset);
            StringBuilder textBuilder = new StringBuilder();
            while(scanner.hasNextLine())
            {
                String line = scanner.nextLine();
                textBuilder.append(line);
                textBuilder.append("\n");
            }
            text = textBuilder.toString();
    } catch (FileNotFoundException e)
    {
      System.err.println("Body file not exists: " + file);
      logger.error("Body file not exists: " + textFile.getAbsolutePath());
      System.exit(1);
    }catch(IllegalArgumentException e)
    {
      System.err.println("Specified charset is not found: " + charset);
      logger.error("Specified charset is not found: " + charset);
      System.exit(1);
    }
           
    return text;
  }
 
  //--------------------------------------------
  private static String getAltTextFromFile(String file, String charset)
  {
    File textFile = new File(file);
    logger.info("Get alternative text from file: " + textFile.getAbsolutePath());
    String text = null;
    try
    {
      Scanner scanner = new Scanner(textFile, charset);
            StringBuilder textBuilder = new StringBuilder();
            while(scanner.hasNextLine())
            {
                String line = scanner.nextLine();
                textBuilder.append(line);
                textBuilder.append("\n");
            }
            text = textBuilder.toString();
    } catch (FileNotFoundException e)
    {
      System.err.println("Alttext file not exists: " + file);
      logger.error("Alttext file not exists: " + textFile.getAbsolutePath());
      System.exit(1);
    }catch(IllegalArgumentException e)
    {
      System.err.println("Specified charset is not found: " + charset);
      logger.error("Specified charset is not found: " + charset);
      System.exit(1);
    }
           
    return text;
  }
 
  //--------------------------------------------
  private static String getSubjectFromFile(String file, String charset)
  {
    File subjectFile = new File(file);
    logger.info("Get subject from file: " + subjectFile.getAbsolutePath());
    String subject = null;
    try
    {
      Scanner scanner = new Scanner(subjectFile, charset);
            if(scanner.hasNextLine())
              subject = scanner.nextLine();
            else
            {
              System.err.println("Subject file is empty: " + file);
              logger.error("Subject file is empty: " + subjectFile.getAbsolutePath());
        System.exit(1);
            }
    } catch (FileNotFoundException e)
    {
      System.err.println("Subject file not exists: " + file);
      logger.error("Subject file not exists: " + subjectFile.getAbsolutePath());
      System.exit(1);
    }catch(IllegalArgumentException e)
    {
      System.err.println("Specified charset is not found: " + charset);
      logger.error("Specified charset is not found: " + charset);
      System.exit(1);
    }
    return subject;
  }
 
  //--------------------------------------------
  private static String[] getPersonParametersFromFile(List<String[]> personParameters
      , String file, String charset)
  {
    File emailsFile = new File(file);
    logger.info("Get person parameters from file: " + emailsFile.getAbsolutePath());
    String[] headers = null;
    CSVReader reader = null;
    try
    {
      FileInputStream fis = new FileInputStream(emailsFile);
      InputStreamReader isr = new InputStreamReader(fis, charset);
      reader=new CSVReader(isr, ',','"',false);
      headers = reader.readNext();
      personParameters.addAll(reader.readAll());
      reader.close();
    }catch (FileNotFoundException fnfe)
    {
      System.err.println("File with emails not exists: " + file);
      logger.error("File with emails not exists: " + emailsFile.getAbsolutePath());
      System.exit(1);
    }catch(UnsupportedEncodingException uee)
    {
      System.err.println("Specified charset is not found: " + charset);
      logger.error("Specified charset is not found: " + charset);
      System.exit(1);
    }
    catch (IOException ioe)
    {
      System.err.println("Error read file with emails: " + file + " (" + ioe.getMessage() + ")");
      logger.error("Error read file with emails: " + emailsFile.getAbsolutePath() + " (" + ioe.getMessage() + ")");
      System.exit(1);
    }
   
        return headers;
  }

  //--------------------------------------------
  private static List<File> getAttachFilesFromFile(String file, String charset)
  {
    File attachFiles = new File(file);
    logger.info("Get attach files from file: " + attachFiles.getAbsolutePath());
    List<File> files = new ArrayList<File>();
    try
    {
      Scanner scanner = new Scanner(attachFiles, charset);
            while(scanner.hasNextLine())
            {
                String attachFile = scanner.nextLine();
                files.add(new File(attachFile));
            }
    } catch (FileNotFoundException e)
    {
      System.err.println("File with attachments not exists: " + file);
      logger.error("File with attachments not exists: " + attachFiles.getAbsolutePath());
      System.exit(1);
    }
           
    return files;
  }
 
  //--------------------------------------------
  @SuppressWarnings("static-access")
  private static Options createOptions()
  {
    Options options = new Options();
    Option oSmtpHost = OptionBuilder.withArgName("host")
        .withDescription("specify SMTP server")
        .hasArg()
        .isRequired()
        .create("smtpHost");
    Option oSmtpPort = OptionBuilder.withArgName("port")
        .withDescription("specify SMTP port (default 25)")
        .hasArg()
        .withType(Number.class)
        .create("smtpPort");
    Option oSmtpUser = OptionBuilder.withArgName("username")
        .withDescription("specify SMTP user")
        .hasArg()
        .create("smtpUser");
    Option oSmtpPassword = OptionBuilder.withArgName("password")
        .withDescription("specify SMTP password")
        .hasArg()
        .create("smtpPassword");
    Option oHostName = OptionBuilder.withArgName("hostname")
        .withDescription("replace your local machine name")
        .hasArg()
        .create("hostname");
    Option oCharset = OptionBuilder.withArgName("charset")
        .withDescription("specify message encoding (default utf-8)")
        .hasArg()
        .create("charset");
    Option oContentTransferEncoding = OptionBuilder.withArgName("transport")
        .withDescription("specify MIME Transport (default 8bit)")
        .hasArg()
        .create("mimeTransport");
   
    Option oMessage = OptionBuilder.withArgName("message")
        .withDescription("message body")
        .hasArg()
        .create("body");
    Option oMessageFile = OptionBuilder.withArgName("file")
        .withDescription("message body file")
        .hasArg()
        .create("bodyFile");
    Option oEMLFile = OptionBuilder.withArgName("file")
        .withDescription("get content from EML file")
        .hasArg()
        .create("EMLFile");
    OptionGroup ogMessage = new OptionGroup();
    ogMessage.setRequired(true);
    ogMessage.addOption(oMessage);
    ogMessage.addOption(oMessageFile);
    ogMessage.addOption(oEMLFile);
   
    Option oContentType = OptionBuilder.withArgName("type")
        .withDescription("specify content type (default text/plain)")
        .hasArg()
        .create("contentType");
   
    Option oSubject = OptionBuilder.withArgName("subject")
        .withDescription("subject")
        .hasArg()
        .create("subject");
    Option oSubjectFile = OptionBuilder.withArgName("file")
        .withDescription("file with subject line")
        .hasArg()
        .create("subjectFile");
    OptionGroup ogSubject = new OptionGroup();
    ogSubject.setRequired(false);
    ogSubject.addOption(oSubject);
    ogSubject.addOption(oSubjectFile);
   
    Option oEmailTo = OptionBuilder.withArgName("recipients")
        .withDescription("specify recipients (comma separated)")
        .hasArgs()
        .withValueSeparator(',')
        .create("emailTo");
    Option oEmailToFile = OptionBuilder.withArgName("file")
        .withDescription("specify file with recipients list")
        .hasArg()
        .create("emailToFile");
    OptionGroup ogEmailTo = new OptionGroup();
    ogEmailTo.setRequired(true);
    ogEmailTo.addOption(oEmailTo);
    ogEmailTo.addOption(oEmailToFile);
   
    Option oPersonFrom = OptionBuilder.withArgName("person")
        .withDescription("specify sender name")
        .hasArg()
        .create("personFrom");
    Option oEmailFrom = OptionBuilder.withArgName("email")
        .withDescription("specify sender email")
        .hasArg()
        .isRequired()
        .create("emailFrom");
   
    Option oAltText = OptionBuilder.withArgName("text")
        .withDescription("Add alternative plain text")
        .hasArg()
        .create("alttext");
    Option oAltTextFile = OptionBuilder.withArgName("file")
        .withDescription("Add alternative plain text from file")
        .hasArg()
        .create("alttextFile");
    OptionGroup ogAltText = new OptionGroup();
    ogAltText.addOption(oAltText);
    ogAltText.addOption(oAltTextFile);
   
    Option  oAttach = OptionBuilder.withArgName("files")
        .withDescription("attach files (comma separated)")
        .hasArgs()
        .withValueSeparator(',')
        .create("attach");
    Option  oAttachFile = OptionBuilder.withArgName("file")
        .withDescription("file with list of attach file")
        .hasArgs()
        .create("attachFile");
    OptionGroup ogAttach = new OptionGroup();
    ogAttach.addOption(oAttach);
    ogAttach.addOption(oAttachFile);
   
    Option oRelated = new Option("related","Create message with inline images");
   
    Option oTrace = OptionBuilder
        .withDescription("Set trace log level. Send messages will be saved on disk")
        .create("trace");
   
    Option oHaltOnFailure = OptionBuilder
        .withDescription("Stop program if exists bad emails or wrong parameters")
        .create("haltOnFailure");
       
    options.addOption(oSmtpHost);
    options.addOption(oSmtpPort);
    options.addOption(oSmtpUser);
    options.addOption(oSmtpPassword);
    options.addOption(oHostName);
    options.addOption(oCharset);
    options.addOption(oContentTransferEncoding);
    options.addOptionGroup(ogMessage);
    options.addOption(oContentType);
    options.addOptionGroup(ogSubject);
    options.addOption(oEmailFrom);
    options.addOptionGroup(ogEmailTo);
    options.addOption(oPersonFrom);
    options.addOptionGroup(ogAttach);
    options.addOptionGroup(ogAltText);
    options.addOption(oRelated);
    options.addOption(oTrace);
    options.addOption(oHaltOnFailure);
    return options;
  }

}
TOP

Related Classes of com.qwertovsky.mailer.Mailer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.