View Javadoc

1   package org.apache.maven.plugin.announcement;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.FileNotFoundException;
24  import java.io.FileReader;
25  import java.io.IOException;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  import org.apache.maven.model.Developer;
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugin.announcement.mailsender.ProjectJavamailMailSender;
32  import org.apache.maven.project.MavenProject;
33  import org.codehaus.plexus.logging.Logger;
34  import org.codehaus.plexus.logging.console.ConsoleLogger;
35  import org.codehaus.plexus.mailsender.MailMessage;
36  import org.codehaus.plexus.mailsender.MailSenderException;
37  import org.codehaus.plexus.util.IOUtil;
38  
39  /**
40   * Goal which sends an announcement through email.
41   *
42   * @author aramirez@exist.com
43   * @version $Id: AnnouncementMailMojo.html 816603 2012-05-08 12:53:30Z hboutemy $
44   * @goal announcement-mail
45   * @execute goal="announcement-generate"
46   * @since 2.0-beta-2
47   * @threadSafe
48   */
49  public class AnnouncementMailMojo
50      extends AbstractAnnouncementMojo
51  {
52      //=========================================
53      // announcement-mail goal fields
54      //=========================================
55  
56      /**
57       * Possible senders.
58       *
59       * @parameter expression="${project.developers}"
60       * @required
61       * @readonly
62       */
63      private List from;
64  
65      /**
66       * The id of the developer sending the announcement mail. Only used if the <tt>mailSender</tt>
67       * attribute is not set. In this case, this should match the id of one of the developers in
68       * the pom. If a matching developer is not found, then the first developer in the pom will be
69       * used.
70       *
71       * @parameter expression="${changes.fromDeveloperId}"
72       */
73      private String fromDeveloperId;
74  
75      /**
76       * Mail content type to use.
77       * @parameter default-value="text/plain"
78       * @required
79       * @since 2.1
80       */
81      private String mailContentType;
82  
83      /**
84       * Defines the sender of the announcement if the list of developer is empty or
85       * if the sender is not a member of the development team.
86       *
87       * @parameter expression="${changes.mailSender}"
88       */
89      private MailSender mailSender;
90  
91      /**
92       * The password used to send the email.
93       *
94       * @parameter expression="${changes.password}"
95       */
96      private String password;
97  
98      /**
99       * @parameter expression="${project}"
100      * @readonly
101      */
102     private MavenProject project;
103 
104     /**
105      * Smtp Server.
106      *
107      * @parameter expression="${changes.smtpHost}"
108      * @required
109      */
110     private String smtpHost;
111 
112     /**
113      * Port.
114      *
115      * @parameter default-value="25" expression="${changes.smtpPort}"
116      * @required
117      */
118     private int smtpPort;
119 
120     /**
121      * If the email should be sent in SSL mode.
122      *
123      * @parameter default-value="false" expression="${changes.sslMode}"
124      */
125     private boolean sslMode;
126 
127 
128     /**
129      * Subject for the email.
130      *
131      * @parameter default-value="[ANNOUNCEMENT] - ${project.name} ${project.version} released" expression="${changes.subject}"
132      * @required
133      */
134     private String subject;
135 
136     /**
137      * The Velocity template used to format the announcement.
138      *
139      * @parameter default-value="announcement.vm" expression="${changes.template}"
140      * @required
141      */
142     private String template;
143 
144     /**
145      * Directory which contains the template for announcement email.
146      *
147      * @parameter expression="${project.build.directory}/announcement"
148      * @required
149      */
150     private File templateOutputDirectory;
151 
152     /**
153      * Recipient email address.
154      *
155      * @parameter
156      * @required
157      */
158     private List toAddresses;
159 
160     /**
161      * Recipient cc email address.
162      *
163      * @parameter
164      * @since 2.5
165      */
166     private List ccAddresses;
167 
168     /**
169      * Recipient bcc email address.
170      *
171      * @parameter
172      * @since 2.5
173      */
174     private List bccAddresses;
175 
176     /**
177      * The username used to send the email.
178      *
179      * @parameter expression="${changes.username}"
180      */
181     private String username;
182 
183     private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender();
184 
185     public void execute()
186         throws MojoExecutionException
187     {
188         // Run only at the execution root
189         if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
190         {
191             getLog().info( "Skipping the announcement mail in this project because it's not the Execution Root" );
192         }
193         else
194         {
195             File templateFile = new File( templateOutputDirectory, template );
196 
197             ConsoleLogger logger = new ConsoleLogger( Logger.LEVEL_INFO, "base" );
198 
199             if ( getLog().isDebugEnabled() )
200             {
201                 logger.setThreshold( Logger.LEVEL_DEBUG );
202             }
203 
204             mailer.enableLogging( logger );
205 
206             mailer.setSmtpHost( getSmtpHost() );
207 
208             mailer.setSmtpPort( getSmtpPort() );
209 
210             mailer.setSslMode( sslMode );
211 
212             if ( username != null )
213             {
214                 mailer.setUsername( username );
215             }
216 
217             if ( password != null )
218             {
219                 mailer.setPassword( password );
220             }
221 
222             mailer.initialize();
223 
224             if ( getLog().isDebugEnabled() )
225             {
226                 getLog().debug( "fromDeveloperId: " + getFromDeveloperId() );
227             }
228 
229             if ( templateFile.isFile() )
230             {
231                 getLog().info( "Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort() );
232 
233                 sendMessage();
234             }
235             else
236             {
237                 throw new MojoExecutionException( "Announcement template " + templateFile + " not found..." );
238             }
239         }
240     }
241 
242     /**
243      * Send the email.
244      *
245      * @throws MojoExecutionException if the mail could not be sent
246      */
247     protected void sendMessage()
248         throws MojoExecutionException
249     {
250         File templateFile = new File( templateOutputDirectory, template );
251         String email = "";
252         final MailSender ms = getActualMailSender();
253         final String fromName = ms.getName();
254         final String fromAddress = ms.getEmail();
255         if ( fromAddress == null || fromAddress.equals( "" ) )
256         {
257             throw new MojoExecutionException( "Invalid mail sender: name and email is mandatory (" + ms + ")." );
258         }
259         getLog().info( "Using this sender for email announcement: " + fromAddress + " < " + fromName + " > " );
260         try
261         {
262             MailMessage mailMsg = new MailMessage();
263             mailMsg.setSubject( getSubject() );
264             mailMsg.setContent( IOUtil.toString( readAnnouncement( templateFile ) ) );
265             mailMsg.setContentType( this.mailContentType );
266             mailMsg.setFrom( fromAddress, fromName );
267 
268             final Iterator it = getToAddresses().iterator();
269             while ( it.hasNext() )
270             {
271                 email = it.next().toString();
272                 getLog().info( "Sending mail to " + email + "..." );
273                 mailMsg.addTo( email, "" );
274             }
275 
276             if(getCcAddresses() != null)
277             {
278                 final Iterator it2 = getCcAddresses().iterator();
279                 while ( it2.hasNext() )
280                 {
281                     email = it2.next().toString();
282                     getLog().info( "Sending cc mail to " + email + "..." );
283                     mailMsg.addCc( email, "" );
284                 }
285             }
286 
287             if(getBccAddresses() != null)
288             {
289                 final Iterator it3 = getBccAddresses().iterator();
290                 while ( it3.hasNext() )
291                 {
292                     email = it3.next().toString();
293                     getLog().info( "Sending bcc mail to " + email + "..." );
294                     mailMsg.addBcc( email, "" );
295                 }
296             }
297 
298             mailer.send( mailMsg );
299             getLog().info( "Sent..." );
300         }
301         catch ( IOException ioe )
302         {
303             throw new MojoExecutionException( "Failed to send email.", ioe );
304         }
305         catch ( MailSenderException e )
306         {
307             throw new MojoExecutionException( "Failed to send email < " + email + " >", e );
308         }
309     }
310 
311     /**
312      * Read the announcement generated file.
313      *
314      * @param file the file to be read
315      * @return fileReader Return the FileReader
316      * @throws MojoExecutionException if the file could not be found
317      */
318     protected FileReader readAnnouncement( File file )
319         throws MojoExecutionException
320     {
321         FileReader fileReader;
322         try
323         {
324             fileReader = new FileReader( file );
325         }
326         catch ( FileNotFoundException fnfe )
327         {
328             throw new MojoExecutionException( "File not found. " + file );
329         }
330         return fileReader;
331     }
332 
333     /**
334      * Returns the identify of the mail sender according to the plugin's configuration:
335      * <ul>
336      * <li>if the <tt>mailSender</tt> parameter is set, it is returned</li>
337      * <li>if no <tt>fromDeveloperId</tt> is set, the first developer in the list is returned</li>
338      * <li>if a <tt>fromDeveloperId</tt> is set, the developer with that id is returned</li>
339      * <li>if the developers list is empty or if the specified id does not exist, an exception is thrown</li>
340      * </ul>
341      *
342      * @return the mail sender to use
343      * @throws MojoExecutionException if the mail sender could not be retrieved
344      */
345     protected MailSender getActualMailSender()
346         throws MojoExecutionException
347     {
348         if ( mailSender != null && mailSender.getEmail() != null )
349         {
350             return mailSender;
351         }
352         else if ( from == null || from.isEmpty() )
353         {
354             throw new MojoExecutionException(
355                 "The <developers> section in your pom should not be empty. Add a <developer> entry or set the "
356                     + "mailSender parameter." );
357         }
358         else if ( fromDeveloperId == null )
359         {
360             final Developer dev = (Developer) from.get( 0 );
361             return new MailSender( dev.getName(), dev.getEmail() );
362         }
363         else
364         {
365             final Iterator it = from.iterator();
366             while ( it.hasNext() )
367             {
368                 Developer developer = (Developer) it.next();
369 
370                 if ( fromDeveloperId.equals( developer.getId() ) )
371                 {
372                     return new MailSender( developer.getName(), developer.getEmail() );
373                 }
374             }
375             throw new MojoExecutionException(
376                 "Missing developer with id '" + fromDeveloperId + "' in the <developers> section in your pom." );
377         }
378     }
379 
380     //================================
381     // announcement-mail accessors
382     //================================
383 
384     public List getBccAddresses()
385     {
386         return bccAddresses;
387     }
388 
389     public void setBccAddresses( List bccAddresses )
390     {
391         this.bccAddresses = bccAddresses;
392     }
393 
394     public List getCcAddresses()
395     {
396         return ccAddresses;
397     }
398 
399     public void setCcAddresses( List ccAddresses )
400     {
401         this.ccAddresses = ccAddresses;
402     }
403 
404     public List getFrom()
405     {
406         return from;
407     }
408 
409     public void setFrom( List from )
410     {
411         this.from = from;
412     }
413 
414     public String getFromDeveloperId()
415     {
416         return fromDeveloperId;
417     }
418 
419     public void setFromDeveloperId( String fromDeveloperId )
420     {
421         this.fromDeveloperId = fromDeveloperId;
422     }
423 
424     public MailSender getMailSender()
425     {
426         return mailSender;
427     }
428 
429     public void setMailSender( MailSender mailSender )
430     {
431         this.mailSender = mailSender;
432     }
433 
434     public String getPassword()
435     {
436         return password;
437     }
438 
439     public void setPassword( String password )
440     {
441         this.password = password;
442     }
443 
444     public MavenProject getProject()
445     {
446         return project;
447     }
448 
449     public void setProject( MavenProject project )
450     {
451         this.project = project;
452     }
453 
454     public String getSmtpHost()
455     {
456         return smtpHost;
457     }
458 
459     public void setSmtpHost( String smtpHost )
460     {
461         this.smtpHost = smtpHost;
462     }
463 
464     public int getSmtpPort()
465     {
466         return smtpPort;
467     }
468 
469     public void setSmtpPort( int smtpPort )
470     {
471         this.smtpPort = smtpPort;
472     }
473 
474     public boolean isSslMode()
475     {
476         return sslMode;
477     }
478 
479     public void setSslMode( boolean sslMode )
480     {
481         this.sslMode = sslMode;
482     }
483 
484     public String getSubject()
485     {
486         return subject;
487     }
488 
489     public void setSubject( String subject )
490     {
491         this.subject = subject;
492     }
493 
494     public String getTemplate()
495     {
496         return template;
497     }
498 
499     public void setTemplate( String template )
500     {
501         this.template = template;
502     }
503 
504     public File getTemplateOutputDirectory()
505     {
506         return templateOutputDirectory;
507     }
508 
509     public void setTemplateOutputDirectory( File templateOutputDirectory )
510     {
511         this.templateOutputDirectory = templateOutputDirectory;
512     }
513 
514     public List getToAddresses()
515     {
516         return toAddresses;
517     }
518 
519     public void setToAddresses( List toAddresses )
520     {
521         this.toAddresses = toAddresses;
522     }
523 
524     public String getUsername()
525     {
526         return username;
527     }
528 
529     public void setUsername( String username )
530     {
531         this.username = username;
532     }
533 }