Package org.apache.maven.continuum.notification.mail

Source Code of org.apache.maven.continuum.notification.mail.MailContinuumNotifier

package org.apache.maven.continuum.notification.mail;

/*
* 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.
*/

import org.apache.continuum.model.project.ProjectScmRoot;
import org.apache.maven.continuum.Continuum;
import org.apache.maven.continuum.configuration.ConfigurationService;
import org.apache.maven.continuum.execution.ExecutorConfigurator;
import org.apache.maven.continuum.execution.ant.AntBuildExecutor;
import org.apache.maven.continuum.execution.maven.m1.MavenOneBuildExecutor;
import org.apache.maven.continuum.execution.maven.m2.MavenTwoBuildExecutor;
import org.apache.maven.continuum.installation.InstallationException;
import org.apache.maven.continuum.installation.InstallationService;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.BuildResult;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectDeveloper;
import org.apache.maven.continuum.model.project.ProjectGroup;
import org.apache.maven.continuum.model.project.ProjectNotifier;
import org.apache.maven.continuum.model.scm.ChangeSet;
import org.apache.maven.continuum.model.scm.ScmResult;
import org.apache.maven.continuum.model.system.Installation;
import org.apache.maven.continuum.model.system.Profile;
import org.apache.maven.continuum.notification.AbstractContinuumNotifier;
import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
import org.apache.maven.continuum.notification.MessageContext;
import org.apache.maven.continuum.notification.NotificationException;
import org.apache.maven.continuum.project.ContinuumProjectState;
import org.apache.maven.continuum.reports.surefire.ReportTestResult;
import org.apache.maven.continuum.reports.surefire.ReportTestSuiteGenerator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.velocity.VelocityComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id: MailContinuumNotifier.java 1372260 2012-08-13 04:29:09Z brett $
*/
public class MailContinuumNotifier
    extends AbstractContinuumNotifier
    implements Initializable
{
    private static final Logger log = LoggerFactory.getLogger( MailContinuumNotifier.class );

    // ----------------------------------------------------------------------
    // Requirements
    // ----------------------------------------------------------------------

    /**
     * @plexus.requirement
     */
    private VelocityComponent velocity;

    /**
     * @plexus.requirement
     */
    private ConfigurationService configurationService;

    /**
     * @plexus.requirement
     */
    private Continuum continuum;

    /**
     * @plexus.requirement
     */
    private JavaMailSender javaMailSender;

    /**
     * @plexus.requirement
     */
    private ReportTestSuiteGenerator reportTestSuiteGenerator;

    // ----------------------------------------------------------------------
    // Configuration
    // ----------------------------------------------------------------------

    /**
     * @plexus.configuration
     */
    private String fromMailbox;

    /**
     * @plexus.configuration
     */
    private String fromName;

    /**
     * @plexus.configuration
     */
    private String toOverride;

    /**
     * @plexus.configuration
     */
    private String timestampFormat;

    /**
     * @plexus.configuration
     */
    private boolean includeBuildSummary = true;

    /**
     * @plexus.configuration
     */
    private boolean includeTestSummary = true;

    /**
     * @plexus.configuration
     */
    private boolean includeBuildOutput = false;

    /**
     * Customizable mail subject.  Use any combination of literal text, project or build attributes.
     * Examples:
     * "[continuum] BUILD ${state}: ${project.groupId} ${project.name}" results in "[continuum] BUILD SUCCESSFUL: foo.bar Hello World"
     * "[continuum] BUILD ${state}: ${project.name} ${project.scmTag}" results in "[continuum] BUILD SUCCESSFUL: Hello World Branch001"
     * "[continuum] BUILD ${state}: ${project.name} ${build.durationTime}" results in "[continuum] BUILD SUCCESSFUL: Hello World 2 sec"
     * "[continuum] BUILD ${state}: ${project.name}, Build Def - ${build.buildDefinition.description}" results in "[continuum] BUILD SUCCESSFUL: Hello World, Build Def - Nightly Test Build"
     *
     * @plexus.configuration
     */
    private String buildSubjectFormat = "[continuum] BUILD ${state}: ${project.groupId} ${project.name}";

    /**
     * Customizable mail subject
     *
     * @plexus.configuration
     */
    private String prepareBuildSubjectFormat =
        "[continuum] PREPARE BUILD ${state]: ${projectScmRoot.projectGroup.name}";

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private String buildHost;

    private FormatterTool formatterTool;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private static final String FALLBACK_FROM_MAILBOX = "continuum@localhost";

    // ----------------------------------------------------------------------
    // Component Lifecycle
    // ----------------------------------------------------------------------

    public void initialize()
    {
        try
        {
            InetAddress address = InetAddress.getLocalHost();

            buildHost = StringUtils.clean( address.getHostName() );

            if ( buildHost == null )
            {
                buildHost = "localhost";
            }
        }
        catch ( UnknownHostException ex )
        {
            fromName = "Continuum";
        }

        // ----------------------------------------------------------------------
        // From mailbox
        // ----------------------------------------------------------------------

        if ( StringUtils.isEmpty( fromMailbox ) )
        {
            log.info( "The from mailbox is not configured, will use the nag email address from the project." );

            fromMailbox = null;
        }
        else
        {
            log.info( "Using '" + fromMailbox + "' as the from mailbox for all emails." );
        }

        if ( StringUtils.isEmpty( fromName ) )
        {
            fromName = "Continuum@" + buildHost;
        }

        log.info( "From name: " + fromName );

        log.info( "Build host name: " + buildHost );

        // ----------------------------------------------------------------------
        //
        // ----------------------------------------------------------------------

        formatterTool = new FormatterTool( timestampFormat );
    }

    // ----------------------------------------------------------------------
    // Notifier Implementation
    // ----------------------------------------------------------------------

    public String getType()
    {
        return "mail";
    }

    public void sendMessage( String messageId, MessageContext context )
        throws NotificationException
    {
        Project project = context.getProject();
        List<ProjectNotifier> notifiers = context.getNotifiers();
        BuildResult build = context.getBuildResult();

        if ( build != null )
        {
            log.error( "br state=" + build.getState() );
        }

        if ( project != null )
        {
            log.error( "project state=" + project.getState() );
        }

        BuildDefinition buildDefinition = context.getBuildDefinition();
        ProjectScmRoot projectScmRoot = context.getProjectScmRoot();

        boolean isPrepareBuildComplete = messageId.equals(
            ContinuumNotificationDispatcher.MESSAGE_ID_PREPARE_BUILD_COMPLETE );

        if ( projectScmRoot == null && isPrepareBuildComplete )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // If there wasn't any building done, don't notify
        // ----------------------------------------------------------------------

        if ( build == null && !isPrepareBuildComplete )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // Generate and send email
        // ----------------------------------------------------------------------

        if ( messageId.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
        {
            buildComplete( project, notifiers, build, messageId, context, buildDefinition );
        }
        else if ( isPrepareBuildComplete )
        {
            prepareBuildComplete( projectScmRoot, notifiers, messageId, context );
        }
    }

    private void buildComplete( Project project, List<ProjectNotifier> notifiers, BuildResult build, String messageId,
                                MessageContext context, BuildDefinition buildDefinition )
        throws NotificationException
    {
        BuildResult previousBuild = getPreviousBuild( project, buildDefinition, build );

        List<ProjectNotifier> notifiersList = new ArrayList<ProjectNotifier>();
        for ( ProjectNotifier notifier : notifiers )
        {
            // ----------------------------------------------------------------------
            // Check if the mail should be sent at all
            // ----------------------------------------------------------------------

            if ( shouldNotify( build, previousBuild, notifier ) )
            {
                notifiersList.add( notifier );
            }
        }
        buildComplete( project, notifiersList, build, previousBuild, messageId, context, buildDefinition );
    }

    private void buildComplete( Project project, List<ProjectNotifier> notifiers, BuildResult build,
                                BuildResult previousBuild, String messageId, MessageContext messageContext,
                                BuildDefinition buildDefinition )
        throws NotificationException
    {
        // ----------------------------------------------------------------------
        // Generate the mail contents
        // ----------------------------------------------------------------------

        String packageName = getClass().getPackage().getName().replace( '.', '/' );

        String templateName = packageName + "/templates/" + project.getExecutorId() + "/" + messageId + ".vm";

        StringWriter writer = new StringWriter();

        String content;

        try
        {
            VelocityContext context = new VelocityContext();

            context.put( "includeTestSummary", includeTestSummary );

            context.put( "includeOutput", includeBuildOutput );

            if ( includeBuildOutput )
            {
                context.put( "buildOutput", getBuildOutput( project, build ) );
            }

            if ( includeBuildSummary )
            {
                context.put( "build", build );

                ReportTestResult reportTestResult = reportTestSuiteGenerator.generateReportTestResult( build.getId(),
                                                                                                       project.getId() );

                context.put( "testResult", reportTestResult );

                context.put( "project", project );

                context.put( "changesSinceLastSuccess", continuum.getChangesSinceLastSuccess( project.getId(),
                                                                                              build.getId() ) );

                context.put( "previousBuild", previousBuild );

                // ----------------------------------------------------------------------
                // Tools
                // ----------------------------------------------------------------------

                context.put( "formatter", formatterTool );

                // TODO: Make the build host a part of the build

                context.put( "buildHost", buildHost );

                String osName = System.getProperty( "os.name" );

                String osPatchLevel = System.getProperty( "sun.os.patch.level" );

                if ( osPatchLevel != null )
                {
                    osName = osName + "(" + osPatchLevel + ")";
                }

                context.put( "osName", osName );

                context.put( "javaVersion", System.getProperty( "java.version" ) + "(" + System.getProperty(
                    "java.vendor" ) + ")" );

                // TODO only in case of a java project ?
                context.put( "javaHomeInformations", getJavaHomeInformations( buildDefinition ) );

                context.put( "builderVersions", getBuilderVersion( buildDefinition, project ) );
            }

            // ----------------------------------------------------------------------
            // Data objects
            // ----------------------------------------------------------------------

            context.put( "reportUrl", getReportUrl( project, build, configurationService ) );

            // TODO put other profile env var could be a security if they provide passwords ?

            // ----------------------------------------------------------------------
            // Generate
            // ----------------------------------------------------------------------

            velocity.getEngine().mergeTemplate( templateName, context, writer );

            content = writer.getBuffer().toString();
        }
        catch ( ResourceNotFoundException e )
        {
            log.info( "No such template: '" + templateName + "'." );

            return;
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail contents.", e );
        }

        // ----------------------------------------------------------------------
        // Send the mail
        // ----------------------------------------------------------------------

        String subject;
        try
        {
            subject = generateSubject( project, build );
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail subject.", e );
        }

        sendMessage( project, notifiers, subject, content, messageContext );
    }

    private void prepareBuildComplete( ProjectScmRoot projectScmRoot, List<ProjectNotifier> notifiers, String messageId,
                                       MessageContext messageContext )
        throws NotificationException
    {
        // ----------------------------------------------------------------------
        // Generate the mail contents
        // ----------------------------------------------------------------------

        String packageName = getClass().getPackage().getName().replace( '.', '/' );

        String templateName = packageName + "/templates/" + messageId + ".vm";

        StringWriter writer = new StringWriter();

        String content;

        try
        {
            VelocityContext context = new VelocityContext();

            // ----------------------------------------------------------------------
            // Data objects
            // ----------------------------------------------------------------------

            context.put( "reportUrl", getReportUrl( projectScmRoot.getProjectGroup(), projectScmRoot,
                                                    configurationService ) );

            context.put( "projectScmRoot", projectScmRoot );

            // TODO put other profile env var could be a security if they provide passwords ?

            // ----------------------------------------------------------------------
            // Generate
            // ----------------------------------------------------------------------

            velocity.getEngine().mergeTemplate( templateName, context, writer );

            content = writer.getBuffer().toString();
        }
        catch ( ResourceNotFoundException e )
        {
            log.info( "No such template: '" + templateName + "'." );

            return;
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail contents.", e );
        }

        // ----------------------------------------------------------------------
        // Send the mail
        // ----------------------------------------------------------------------

        String subject;
        try
        {
            subject = generateSubject( projectScmRoot );
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail subject.", e );
        }

        sendMessage( projectScmRoot, notifiers, subject, content, messageContext );
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private List<String> getJavaHomeInformations( BuildDefinition buildDefinition )
        throws InstallationException
    {
        if ( buildDefinition == null )
        {
            return continuum.getInstallationService().getDefaultJdkInformations();
        }
        Profile profile = buildDefinition.getProfile();
        if ( profile == null )
        {
            return continuum.getInstallationService().getDefaultJdkInformations();
        }
        return continuum.getInstallationService().getJdkInformations( profile.getJdk() );
    }

    private List<String> getBuilderVersion( BuildDefinition buildDefinition, Project project )
        throws InstallationException
    {
        ExecutorConfigurator executorConfigurator;
        Installation builder = null;
        Profile profile = null;
        if ( buildDefinition != null )
        {
            profile = buildDefinition.getProfile();
            if ( profile != null )
            {
                builder = profile.getBuilder();
            }
        }
        if ( builder != null )
        {
            executorConfigurator = continuum.getInstallationService().getExecutorConfigurator( builder.getType() );
        }
        else
        {
            // depends on ExecutorId
            if ( MavenTwoBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.MAVEN2_TYPE );
            }
            else if ( MavenOneBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.MAVEN1_TYPE );
            }
            else if ( AntBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.ANT_TYPE );
            }
            else
            {
                return Arrays.asList( "No builder defined" );
            }
        }

        return continuum.getInstallationService().getExecutorConfiguratorVersion(
            builder == null ? null : builder.getVarValue(), executorConfigurator, profile );
    }

    private String generateSubject( Project project, BuildResult build )
        throws Exception
    {
        String state = getState( project, build );

        VelocityContext context = new VelocityContext();
        context.put( "project", project );
        context.put( "build", build );
        context.put( "state", state );

        StringWriter writer = new StringWriter();

        boolean velocityRes = velocity.getEngine().evaluate( context, writer, "subjectPattern", buildSubjectFormat );

        return writer.toString();
    }

    private String generateSubject( ProjectScmRoot projectScmRoot )
        throws Exception
    {
        String state = getState( projectScmRoot );

        VelocityContext context = new VelocityContext();
        context.put( "projectScmRoot", projectScmRoot );
        context.put( "state", state );

        StringWriter writer = new StringWriter();

        boolean velocityResults = velocity.getEngine().evaluate( context, writer, "subjectPattern",
                                                                 prepareBuildSubjectFormat );

        return writer.toString();
    }

    private String getState( Project project, BuildResult build )
    {
        int state = project.getState();

        if ( build != null )
        {
            state = build.getState();
        }

        if ( state == ContinuumProjectState.OK )
        {
            return "SUCCESSFUL";
        }
        else if ( state == ContinuumProjectState.FAILED )
        {
            return "FAILURE";
        }
        else if ( state == ContinuumProjectState.ERROR )
        {
            return "ERROR";
        }
        else
        {
            log.warn( "Unknown build state " + state + " for project " + project.getId() );

            return "ERROR: Unknown build state " + state;
        }
    }

    private String getState( ProjectScmRoot projectScmRoot )
    {
        int state = projectScmRoot.getState();

        if ( state == ContinuumProjectState.UPDATED )
        {
            return "SUCCESSFUL";
        }
        else if ( state == ContinuumProjectState.ERROR )
        {
            return "ERROR";
        }
        else
        {
            log.warn(
                "Unknown prepare build state " + state + " for SCM Root URL " + projectScmRoot.getScmRootAddress() +
                    " in projectGroup " + projectScmRoot.getProjectGroup().getId() );

            return "ERROR: Unknown build state " + state;
        }
    }

    private void sendMessage( Project project, List<ProjectNotifier> notifiers, String subject, String content,
                              MessageContext context )
        throws NotificationException
    {
        if ( notifiers.size() == 0 )
        {
            // This is a useful message for the users when debugging why they don't
            // receive any mails

            log.info( "No mail notifier for '" + project.getName() + "'." );

            return;
        }

        String fromMailbox = getFromMailbox( notifiers );

        if ( fromMailbox == null )
        {
            log.warn( project.getName() +
                          ": Project is missing nag email and global from mailbox is missing, not sending mail." );

            return;
        }

        try
        {

            MimeMessage message = javaMailSender.createMimeMessage();

            message.addHeader( "X-Continuum-Build-Host", buildHost );

            message.addHeader( "X-Continuum-Project-Id", Integer.toString( project.getId() ) );

            message.addHeader( "X-Continuum-Project-Name", project.getName() );

            message.setSubject( subject );

            log.info( "Message Subject: '" + subject + "'." );

            message.setText( content );

            InternetAddress from = new InternetAddress( fromMailbox, fromName );

            message.setFrom( from );

            log.info( "Sending message: From '" + from + "'." );

            if ( StringUtils.isEmpty( toOverride ) )
            {
                Set<String> listRecipents = new HashSet<String>();
                for ( ProjectNotifier notifier : notifiers )
                {
                    Map<String, String> conf = notifier.getConfiguration();
                    if ( conf != null )
                    {
                        String addressField = conf.get( ADDRESS_FIELD );

                        if ( StringUtils.isNotEmpty( addressField ) )
                        {
                            String[] addresses = StringUtils.split( addressField, "," );
                            for ( String address : addresses )
                            {
                                if ( !listRecipents.contains( address.trim() ) )
                                {
                                    // [CONTINUUM-2281] Dont repeat addesss in recipents.
                                    // TODO: set a proper name
                                    InternetAddress to = new InternetAddress( address.trim() );

                                    log.info( "Recipient: To '" + to + "'." );
                                    message.addRecipient( Message.RecipientType.TO, to );
                                    listRecipents.add( address.trim() );
                                }
                            }

                        }

                        if ( context.getBuildResult() != null )
                        {
                            String committerField = (String) notifier.getConfiguration().get( COMMITTER_FIELD );
                            String developerField = (String) notifier.getConfiguration().get( DEVELOPER_FIELD );
                            // Developers constains committers.
                            if ( StringUtils.isNotEmpty( developerField ) && Boolean.parseBoolean( developerField ) )
                            {
                                List<ProjectDeveloper> developers = project.getDevelopers();
                                if ( developers == null || developers.isEmpty() )
                                {
                                    log.warn(
                                        "No developers have been configured...notifcation email will not be sent" );
                                    return;
                                }
                                Map<String, String> developerToEmailMap = mapDevelopersToRecipients( developers );
                                for ( String email : developerToEmailMap.values() )
                                {
                                    if ( !listRecipents.contains( email.trim() ) )
                                    {
                                        InternetAddress to = new InternetAddress( email.trim() );
                                        log.info( "Recipient: To '" + to + "'." );
                                        message.addRecipient( Message.RecipientType.TO, to );
                                        listRecipents.add( email.trim() );
                                    }
                                }
                            }
                            else if ( StringUtils.isNotEmpty( committerField ) && Boolean.parseBoolean(
                                committerField ) )
                            {
                                ScmResult scmResult = context.getBuildResult().getScmResult();
                                if ( scmResult != null && scmResult.getChanges() != null &&
                                    !scmResult.getChanges().isEmpty() )
                                {
                                    List<ProjectDeveloper> developers = project.getDevelopers();
                                    if ( developers == null || developers.isEmpty() )
                                    {
                                        log.warn( "No developers have been configured...notifcation email " +
                                                      "will not be sent" );
                                        return;
                                    }

                                    Map<String, String> developerToEmailMap = mapDevelopersToRecipients( developers );

                                    List<ChangeSet> changes = scmResult.getChanges();

                                    for ( ChangeSet changeSet : changes )
                                    {
                                        String scmId = changeSet.getAuthor();
                                        if ( StringUtils.isNotEmpty( scmId ) )
                                        {
                                            String email = developerToEmailMap.get( scmId );
                                            if ( StringUtils.isEmpty( email ) )
                                            {
                                                //TODO: Add a default domain so mail address won't be required
                                                log.warn(
                                                    "no email address is defined in developers list for '" + scmId +
                                                        "' scm id." );
                                            }
                                            else if ( !listRecipents.contains( email.trim() ) )
                                            {
                                                // [CONTINUUM-2281] Dont repeat addesss in recipents.)
                                                // TODO: set a proper name
                                                InternetAddress to = new InternetAddress( email.trim() );
                                                log.info( "Recipient: To '" + to + "'." );

                                                message.addRecipient( Message.RecipientType.TO, to );
                                                listRecipents.add( email.trim() );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: use configuration file instead of to load it fron component configuration
                // TODO: set a proper name
                InternetAddress to = new InternetAddress( toOverride.trim() );
                log.info( "Recipient: To '" + to + "'." );

                message.addRecipient( Message.RecipientType.TO, to );
            }

            message.setSentDate( new Date() );

            if ( message.getAllRecipients() != null && ( message.getAllRecipients() ).length > 0 )
            {
                javaMailSender.send( message );
            }
        }
        catch ( AddressException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( MessagingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( UnsupportedEncodingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
    }

    private void sendMessage( ProjectScmRoot projectScmRoot, List<ProjectNotifier> notifiers, String subject,
                              String content, MessageContext context )
        throws NotificationException
    {
        ProjectGroup projectGroup = projectScmRoot.getProjectGroup();

        if ( notifiers.size() == 0 )
        {
            // This is a useful message for the users when debugging why they don't
            // receive any mails

            log.info( "No mail notifier for '" + projectGroup.getName() + "'." );

            return;
        }

        String fromMailbox = getFromMailbox( notifiers );

        if ( fromMailbox == null )
        {
            log.warn( projectGroup.getName() +
                          ": ProjectGroup is missing nag email and global from mailbox is missing, not sending mail." );

            return;
        }

        MimeMessage message = javaMailSender.createMimeMessage();

        try
        {
            message.setSubject( subject );

            log.info( "Message Subject: '" + subject + "'." );

            message.setText( content );

            InternetAddress from = new InternetAddress( fromMailbox, fromName );

            message.setFrom( from );

            log.info( "Sending message: From '" + from + "'." );

            if ( StringUtils.isEmpty( toOverride ) )
            {
                for ( ProjectNotifier notifier : notifiers )
                {
                    if ( !shouldNotify( projectScmRoot, notifier ) )
                    {
                        continue;
                    }

                    Map<String, String> conf = notifier.getConfiguration();
                    if ( conf != null )
                    {
                        String addressField = conf.get( ADDRESS_FIELD );

                        if ( StringUtils.isNotEmpty( addressField ) )
                        {
                            String[] addresses = StringUtils.split( addressField, "," );

                            for ( String address : addresses )
                            {
                                // TODO: set a proper name
                                InternetAddress to = new InternetAddress( address.trim() );

                                log.info( "Recipient: To '" + to + "'." );
                                message.addRecipient( Message.RecipientType.TO, to );
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: use configuration file instead of to load it fron component configuration
                // TODO: set a proper name
                InternetAddress to = new InternetAddress( toOverride.trim() );
                log.info( "Recipient: To '" + to + "'." );

                message.addRecipient( Message.RecipientType.TO, to );
            }

            message.setSentDate( new Date() );

            if ( message.getAllRecipients() != null && ( message.getAllRecipients() ).length > 0 )
            {
                javaMailSender.send( message );
            }
        }
        catch ( AddressException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( MessagingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( UnsupportedEncodingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
    }

    private Map<String, String> mapDevelopersToRecipients( List<ProjectDeveloper> developers )
    {
        Map<String, String> developersMap = new HashMap<String, String>();

        for ( ProjectDeveloper developer : developers )
        {
            if ( StringUtils.isNotEmpty( developer.getScmId() ) && StringUtils.isNotEmpty( developer.getEmail() ) )
            {
                developersMap.put( developer.getScmId(), developer.getEmail() );
            }
        }

        return developersMap;
    }

    private String getFromMailbox( List<ProjectNotifier> notifiers )
    {
        if ( fromMailbox != null )
        {
            return fromMailbox;
        }

        String address = null;

        for ( ProjectNotifier notifier : notifiers )
        {
            Map<String, String> configuration = notifier.getConfiguration();
            if ( configuration != null && StringUtils.isNotEmpty( configuration.get( ADDRESS_FIELD ) ) )
            {
                address = configuration.get( ADDRESS_FIELD );
                break;
            }
        }

        if ( StringUtils.isEmpty( address ) )
        {
            return FALLBACK_FROM_MAILBOX;
        }
        // olamy : CONTINUUM-860 if address contains commas we use only the first one
        if ( address != null && address.contains( "," ) )
        {
            String[] addresses = StringUtils.split( address, "," );
            return addresses[0];
        }
        return address;
    }

    public String getBuildHost()
    {
        return buildHost;
    }

    public void setBuildHost( String buildHost )
    {
        this.buildHost = buildHost;
    }

    public String getToOverride()
    {
        return toOverride;
    }

    public void setToOverride( String toOverride )
    {
        this.toOverride = toOverride;
    }
}
TOP

Related Classes of org.apache.maven.continuum.notification.mail.MailContinuumNotifier

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.