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 816601 2012-05-08 12:50:18Z 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      * @required
165      * @since 2.5
166      */
167     private List ccAddresses;
168 
169     /**
170      * Recipient bcc email address.
171      *
172      * @parameter
173      * @required
174      * @since 2.5
175      */
176     private List bccAddresses;
177 
178     /**
179      * The username used to send the email.
180      *
181      * @parameter expression="${changes.username}"
182      */
183     private String username;
184 
185     private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender();
186 
187     public void execute()
188         throws MojoExecutionException
189     {
190         // Run only at the execution root
191         if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
192         {
193             getLog().info( "Skipping the announcement mail in this project because it's not the Execution Root" );
194         }
195         else
196         {
197             File templateFile = new File( templateOutputDirectory, template );
198 
199             ConsoleLogger logger = new ConsoleLogger( Logger.LEVEL_INFO, "base" );
200 
201             if ( getLog().isDebugEnabled() )
202             {
203                 logger.setThreshold( Logger.LEVEL_DEBUG );
204             }
205 
206             mailer.enableLogging( logger );
207 
208             mailer.setSmtpHost( getSmtpHost() );
209 
210             mailer.setSmtpPort( getSmtpPort() );
211 
212             mailer.setSslMode( sslMode );
213 
214             if ( username != null )
215             {
216                 mailer.setUsername( username );
217             }
218 
219             if ( password != null )
220             {
221                 mailer.setPassword( password );
222             }
223 
224             mailer.initialize();
225 
226             if ( getLog().isDebugEnabled() )
227             {
228                 getLog().debug( "fromDeveloperId: " + getFromDeveloperId() );
229             }
230 
231             if ( templateFile.isFile() )
232             {
233                 getLog().info( "Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort() );
234 
235                 sendMessage();
236             }
237             else
238             {
239                 throw new MojoExecutionException( "Announcement template " + templateFile + " not found..." );
240             }
241         }
242     }
243 
244     /**
245      * Send the email.
246      *
247      * @throws MojoExecutionException if the mail could not be sent
248      */
249     protected void sendMessage()
250         throws MojoExecutionException
251     {
252         File templateFile = new File( templateOutputDirectory, template );
253         String email = "";
254         final MailSender ms = getActualMailSender();
255         final String fromName = ms.getName();
256         final String fromAddress = ms.getEmail();
257         if ( fromAddress == null || fromAddress.equals( "" ) )
258         {
259             throw new MojoExecutionException( "Invalid mail sender: name and email is mandatory (" + ms + ")." );
260         }
261         getLog().info( "Using this sender for email announcement: " + fromAddress + " < " + fromName + " > " );
262         try
263         {
264             MailMessage mailMsg = new MailMessage();
265             mailMsg.setSubject( getSubject() );
266             mailMsg.setContent( IOUtil.toString( readAnnouncement( templateFile ) ) );
267             mailMsg.setContentType( this.mailContentType );
268             mailMsg.setFrom( fromAddress, fromName );
269             final Iterator it = getToAddresses().iterator();
270             while ( it.hasNext() )
271             {
272                 email = it.next().toString();
273                 getLog().info( "Sending mail to " + email + "..." );
274                 mailMsg.addTo( email, "" );
275             }
276             final Iterator it2 = getCcAddresses().iterator();
277             while ( it2.hasNext() )
278             {
279                 email = it2.next().toString();
280                 getLog().info( "Sending cc mail to " + email + "..." );
281                 mailMsg.addCc( email, "" );
282             }
283             final Iterator it3 = getBccAddresses().iterator();
284             while ( it3.hasNext() )
285             {
286                 email = it3.next().toString();
287                 getLog().info( "Sending bcc mail to " + email + "..." );
288                 mailMsg.addBcc( email, "" );
289             }
290             mailer.send( mailMsg );
291             getLog().info( "Sent..." );
292         }
293         catch ( IOException ioe )
294         {
295             throw new MojoExecutionException( "Failed to send email.", ioe );
296         }
297         catch ( MailSenderException e )
298         {
299             throw new MojoExecutionException( "Failed to send email < " + email + " >", e );
300         }
301     }
302 
303     /**
304      * Read the announcement generated file.
305      *
306      * @param file the file to be read
307      * @return fileReader Return the FileReader
308      * @throws MojoExecutionException if the file could not be found
309      */
310     protected FileReader readAnnouncement( File file )
311         throws MojoExecutionException
312     {
313         FileReader fileReader;
314         try
315         {
316             fileReader = new FileReader( file );
317         }
318         catch ( FileNotFoundException fnfe )
319         {
320             throw new MojoExecutionException( "File not found. " + file );
321         }
322         return fileReader;
323     }
324 
325     /**
326      * Returns the identify of the mail sender according to the plugin's configuration:
327      * <ul>
328      * <li>if the <tt>mailSender</tt> parameter is set, it is returned</li>
329      * <li>if no <tt>fromDeveloperId</tt> is set, the first developer in the list is returned</li>
330      * <li>if a <tt>fromDeveloperId</tt> is set, the developer with that id is returned</li>
331      * <li>if the developers list is empty or if the specified id does not exist, an exception is thrown</li>
332      * </ul>
333      *
334      * @return the mail sender to use
335      * @throws MojoExecutionException if the mail sender could not be retrieved
336      */
337     protected MailSender getActualMailSender()
338         throws MojoExecutionException
339     {
340         if ( mailSender != null && mailSender.getEmail() != null )
341         {
342             return mailSender;
343         }
344         else if ( from == null || from.isEmpty() )
345         {
346             throw new MojoExecutionException(
347                 "The <developers> section in your pom should not be empty. Add a <developer> entry or set the "
348                     + "mailSender parameter." );
349         }
350         else if ( fromDeveloperId == null )
351         {
352             final Developer dev = (Developer) from.get( 0 );
353             return new MailSender( dev.getName(), dev.getEmail() );
354         }
355         else
356         {
357             final Iterator it = from.iterator();
358             while ( it.hasNext() )
359             {
360                 Developer developer = (Developer) it.next();
361 
362                 if ( fromDeveloperId.equals( developer.getId() ) )
363                 {
364                     return new MailSender( developer.getName(), developer.getEmail() );
365                 }
366             }
367             throw new MojoExecutionException(
368                 "Missing developer with id '" + fromDeveloperId + "' in the <developers> section in your pom." );
369         }
370     }
371 
372     //================================
373     // announcement-mail accessors
374     //================================
375 
376     public List getBccAddresses()
377     {
378         return bccAddresses;
379     }
380 
381     public void setBccAddresses( List bccAddresses )
382     {
383         this.bccAddresses = bccAddresses;
384     }
385 
386     public List getCcAddresses()
387     {
388         return ccAddresses;
389     }
390 
391     public void setCcAddresses( List ccAddresses )
392     {
393         this.ccAddresses = ccAddresses;
394     }
395 
396     public List getFrom()
397     {
398         return from;
399     }
400 
401     public void setFrom( List from )
402     {
403         this.from = from;
404     }
405 
406     public String getFromDeveloperId()
407     {
408         return fromDeveloperId;
409     }
410 
411     public void setFromDeveloperId( String fromDeveloperId )
412     {
413         this.fromDeveloperId = fromDeveloperId;
414     }
415 
416     public MailSender getMailSender()
417     {
418         return mailSender;
419     }
420 
421     public void setMailSender( MailSender mailSender )
422     {
423         this.mailSender = mailSender;
424     }
425 
426     public String getPassword()
427     {
428         return password;
429     }
430 
431     public void setPassword( String password )
432     {
433         this.password = password;
434     }
435 
436     public MavenProject getProject()
437     {
438         return project;
439     }
440 
441     public void setProject( MavenProject project )
442     {
443         this.project = project;
444     }
445 
446     public String getSmtpHost()
447     {
448         return smtpHost;
449     }
450 
451     public void setSmtpHost( String smtpHost )
452     {
453         this.smtpHost = smtpHost;
454     }
455 
456     public int getSmtpPort()
457     {
458         return smtpPort;
459     }
460 
461     public void setSmtpPort( int smtpPort )
462     {
463         this.smtpPort = smtpPort;
464     }
465 
466     public boolean isSslMode()
467     {
468         return sslMode;
469     }
470 
471     public void setSslMode( boolean sslMode )
472     {
473         this.sslMode = sslMode;
474     }
475 
476     public String getSubject()
477     {
478         return subject;
479     }
480 
481     public void setSubject( String subject )
482     {
483         this.subject = subject;
484     }
485 
486     public String getTemplate()
487     {
488         return template;
489     }
490 
491     public void setTemplate( String template )
492     {
493         this.template = template;
494     }
495 
496     public File getTemplateOutputDirectory()
497     {
498         return templateOutputDirectory;
499     }
500 
501     public void setTemplateOutputDirectory( File templateOutputDirectory )
502     {
503         this.templateOutputDirectory = templateOutputDirectory;
504     }
505 
506     public List getToAddresses()
507     {
508         return toAddresses;
509     }
510 
511     public void setToAddresses( List toAddresses )
512     {
513         this.toAddresses = toAddresses;
514     }
515 
516     public String getUsername()
517     {
518         return username;
519     }
520 
521     public void setUsername( String username )
522     {
523         this.username = username;
524     }
525 }