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

org.apache.maven.plugins.changes.announcement.AnnouncementMailMojo Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.maven.plugins.changes.announcement;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.maven.model.Developer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.changes.announcement.mailsender.ProjectJavamailMailSender;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.mailsender.MailMessage;
import org.codehaus.plexus.mailsender.MailSenderException;
import org.codehaus.plexus.util.IOUtil;

/**
 * Goal which sends an announcement through email.
 *
 * @author [email protected]
 * @version $Id$
 * @since 2.0-beta-2
 */
@Mojo(name = "announcement-mail", threadSafe = true)
@Execute(goal = "announcement-generate")
public class AnnouncementMailMojo extends AbstractAnnouncementMojo {
    // =========================================
    // announcement-mail goal fields
    // =========================================

    /**
     * Possible senders.
     */
    @Parameter(property = "project.developers", required = true, readonly = true)
    private List from;

    /**
     * The id of the developer sending the announcement mail. Only used if the {@code mailSender} attribute is not set.
     * In this case, this should match the id of one of the developers in the pom. If a matching developer is not found,
     * then the first developer in the pom will be used.
     */
    @Parameter(property = "changes.fromDeveloperId")
    private String fromDeveloperId;

    /**
     * Mail content type to use.
     *
     * @since 2.1
     */
    @Parameter(defaultValue = "text/plain", required = true)
    private String mailContentType;

    /**
     * Defines the sender of the announcement email. This takes precedence over the list of developers specified in the
     * POM. if the sender is not a member of the development team. Note that since this is a bean type, you cannot
     * specify it from command level with
     *
     * 
     * -D
     * 
* * . Use * *
     * -Dchanges.sender='Your Name <you@domain>'
     * 
* * instead. */ @Parameter(property = "changes.mailSender") private MailSender mailSender; /** * Defines the sender of the announcement. This takes precedence over both ${changes.mailSender} and the list of * developers in the POM. *

* This parameter parses an email address in standard RFC822 format, e.g. * *

     * -Dchanges.sender='Your Name <you@domain>'
     * 
* * . * * @since 2.7 */ @Parameter(property = "changes.sender") private String senderString; /** * The password used to send the email. */ @Parameter(property = "changes.password") private String password; /** */ @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; /** * Smtp Server. */ @Parameter(property = "changes.smtpHost", required = true) private String smtpHost; /** * Port. */ @Parameter(property = "changes.smtpPort", defaultValue = "25", required = true) private int smtpPort; /** * If the email should be sent in SSL mode. */ @Parameter(property = "changes.sslMode", defaultValue = "false") private boolean sslMode; /** * If the option startTls should be used. * * @since 2.10 */ @Parameter(property = "changes.startTls", defaultValue = "false") private boolean startTls; /** * Subject for the email. */ // CHECKSTYLE_OFF: LineLength @Parameter( property = "changes.subject", defaultValue = "[ANNOUNCEMENT] - ${project.name} ${project.version} released", required = true) private String subject; // CHECKSTYLE_ON: LineLength /** * The file that contains the generated announcement. * * @since 2.10 */ @Parameter(property = "changes.announcementFile", defaultValue = "announcement.vm", required = true) private String announcementFile; /** * Directory where the generated announcement file exists. * * @since 2.10 */ @Parameter(defaultValue = "${project.build.directory}/announcement", required = true) private File announcementDirectory; /** * The encoding used in the announcement template. * * @since 2.10 */ @Parameter(property = "changes.templateEncoding", defaultValue = "${project.build.sourceEncoding}") private String templateEncoding; /** * Recipient email address. */ @Parameter(required = true) private List toAddresses; /** * Recipient cc email address. * * @since 2.5 */ @Parameter private List ccAddresses; /** * Recipient bcc email address. * * @since 2.5 */ @Parameter private List bccAddresses; /** * The username used to send the email. */ @Parameter(property = "changes.username") private String username; private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender(); public void execute() throws MojoExecutionException { // Run only at the execution root if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) { getLog().info("Skipping the announcement mail in this project because it's not the Execution Root"); } else { File file = new File(announcementDirectory, announcementFile); ConsoleLogger logger = new ConsoleLogger(Logger.LEVEL_INFO, "base"); if (getLog().isDebugEnabled()) { logger.setThreshold(Logger.LEVEL_DEBUG); } mailer.enableLogging(logger); mailer.setSmtpHost(getSmtpHost()); mailer.setSmtpPort(getSmtpPort()); mailer.setSslMode(sslMode, startTls); if (username != null) { mailer.setUsername(username); } if (password != null) { mailer.setPassword(password); } mailer.initialize(); if (getLog().isDebugEnabled()) { getLog().debug("fromDeveloperId: " + getFromDeveloperId()); } if (file.isFile()) { getLog().info("Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort()); sendMessage(); } else { throw new MojoExecutionException("Announcement file " + file + " not found..."); } } } /** * Send the email. * * @throws MojoExecutionException if the mail could not be sent */ protected void sendMessage() throws MojoExecutionException { File file = new File(announcementDirectory, announcementFile); String email = ""; final MailSender ms = getActualMailSender(); final String fromName = ms.getName(); final String fromAddress = ms.getEmail(); if (fromAddress == null || fromAddress.equals("")) { throw new MojoExecutionException("Invalid mail sender: name and email is mandatory (" + ms + ")."); } getLog().info("Using this sender for email announcement: " + fromAddress + " < " + fromName + " > "); try { MailMessage mailMsg = new MailMessage(); mailMsg.setSubject(getSubject()); mailMsg.setContent(readAnnouncement(file)); mailMsg.setContentType(this.mailContentType); mailMsg.setFrom(fromAddress, fromName); for (Object o1 : getToAddresses()) { email = o1.toString(); getLog().info("Sending mail to " + email + "..."); mailMsg.addTo(email, ""); } if (getCcAddresses() != null) { for (Object o : getCcAddresses()) { email = o.toString(); getLog().info("Sending cc mail to " + email + "..."); mailMsg.addCc(email, ""); } } if (getBccAddresses() != null) { for (Object o : getBccAddresses()) { email = o.toString(); getLog().info("Sending bcc mail to " + email + "..."); mailMsg.addBcc(email, ""); } } mailer.send(mailMsg); getLog().info("Sent..."); } catch (MailSenderException e) { throw new MojoExecutionException("Failed to send email < " + email + " >", e); } } /** * Read the content of the generated announcement file. * * @param file the file to be read * @return Return the announcement text * @throws MojoExecutionException if the file could not be found, or if the encoding is unsupported */ protected String readAnnouncement(File file) throws MojoExecutionException { try { if (templateEncoding == null || templateEncoding.isEmpty()) { templateEncoding = Charset.defaultCharset().displayName(); getLog().warn("File encoding has not been set, using platform encoding '" + templateEncoding + "', i.e. build is platform dependent!"); } try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), templateEncoding)) { return IOUtil.toString(reader); } } catch (FileNotFoundException fnfe) { throw new MojoExecutionException("File not found. " + file); } catch (UnsupportedEncodingException uee) { throw new MojoExecutionException("Unsupported encoding: '" + templateEncoding + "'"); } catch (IOException ioe) { throw new MojoExecutionException("Failed to read the announcement file.", ioe); } } /** * Returns the identify of the mail sender according to the plugin's configuration: *
    *
  • if the {@code mailSender} parameter is set, it is returned
  • *
  • if no {@code fromDeveloperId} is set, the first developer in the list is returned
  • *
  • if a {@code fromDeveloperId} is set, the developer with that id is returned
  • *
  • if the developers list is empty or if the specified id does not exist, an exception is thrown
  • *
* * @return the mail sender to use * @throws MojoExecutionException if the mail sender could not be retrieved */ protected MailSender getActualMailSender() throws MojoExecutionException { if (senderString != null) { try { InternetAddress ia = new InternetAddress(senderString, true); return new MailSender(ia.getPersonal(), ia.getAddress()); } catch (AddressException e) { throw new MojoExecutionException("Invalid value for change.sender: ", e); } } if (mailSender != null && mailSender.getEmail() != null) { return mailSender; } else if (from == null || from.isEmpty()) { throw new MojoExecutionException("The section in your pom should not be empty. " + "Add a entry or set the mailSender parameter."); } else if (fromDeveloperId == null) { final Developer dev = from.get(0); return new MailSender(dev.getName(), dev.getEmail()); } else { for (Developer developer : from) { if (fromDeveloperId.equals(developer.getId())) { return new MailSender(developer.getName(), developer.getEmail()); } } throw new MojoExecutionException( "Missing developer with id '" + fromDeveloperId + "' in the section in your pom."); } } // ================================ // announcement-mail accessors // ================================ public List getBccAddresses() { return bccAddresses; } public void setBccAddresses(List bccAddresses) { this.bccAddresses = bccAddresses; } public List getCcAddresses() { return ccAddresses; } public void setCcAddresses(List ccAddresses) { this.ccAddresses = ccAddresses; } public List getFrom() { return from; } public void setFrom(List from) { this.from = from; } public String getFromDeveloperId() { return fromDeveloperId; } public void setFromDeveloperId(String fromDeveloperId) { this.fromDeveloperId = fromDeveloperId; } public MailSender getMailSender() { return mailSender; } public void setMailSender(MailSender mailSender) { this.mailSender = mailSender; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public MavenProject getProject() { return project; } public void setProject(MavenProject project) { this.project = project; } public String getSmtpHost() { return smtpHost; } public void setSmtpHost(String smtpHost) { this.smtpHost = smtpHost; } public int getSmtpPort() { return smtpPort; } public void setSmtpPort(int smtpPort) { this.smtpPort = smtpPort; } public boolean isSslMode() { return sslMode; } public void setSslMode(boolean sslMode) { this.sslMode = sslMode; } public boolean isStartTls() { return startTls; } public void setStartTls(boolean startTls) { this.startTls = startTls; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getAnnouncementFile() { return announcementFile; } public void setAnnouncementFile(String announcementFile) { this.announcementFile = announcementFile; } public File getAnnouncementDirectory() { return announcementDirectory; } public void setAnnouncementDirectory(File announcementDirectory) { this.announcementDirectory = announcementDirectory; } public List getToAddresses() { return toAddresses; } public void setToAddresses(List toAddresses) { this.toAddresses = toAddresses; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }