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 816595 2012-05-08 12:43:00Z hboutemy $
44   * @goal announcement-mail
45   * @execute goal="announcement-generate"
46   */
47  public class AnnouncementMailMojo
48      extends AbstractAnnouncementMojo
49  {
50      //=========================================
51      // announcement-mail goal fields
52      //=========================================
53  
54      /**
55       * @parameter expression="${project}"
56       * @readonly
57       */
58      private MavenProject project;
59  
60      /**
61       * Smtp Server.
62       *
63       * @parameter expression="${changes.smtpHost}"
64       * @required
65       */
66      private String smtpHost;
67  
68      /**
69       * Port.
70       *
71       * @parameter default-value="25" expression="${changes.smtpPort}"
72       * @required
73       */
74      private int smtpPort;
75  
76      /**
77       * The username used to send the email.
78       *
79       * @parameter expression="${changes.username}"
80       */
81      private String username;
82  
83      /**
84       * The password used to send the email.
85       *
86       * @parameter expression="${changes.password}"
87       */
88      private String password;
89  
90      /**
91       * If the email should be sent in SSL mode.
92       *
93       * @parameter default-value="false" expression="${changes.sslMode}"
94       */
95      private boolean sslMode;
96  
97      /**
98       * Subject for the email.
99       *
100      * @parameter default-value="[ANNOUNCEMENT] - ${project.name} ${project.version} released" expression="${changes.subject}"
101      * @required
102      */
103     private String subject;
104 
105     /**
106      * The id of the developer sending the announcement mail. Only used if the <tt>mailSender</tt>
107      * attribute is not set. In this case, this should match the id of one of the developers in
108      * the pom. If a matching developer is not found, then the first developer in the pom will be
109      * used.
110      *
111      * @parameter expression="${changes.fromDeveloperId}"
112      */
113     private String fromDeveloperId;
114 
115     /**
116      * Defines the sender of the announcement if the list of developer is empty or
117      * if the sender is not a member of the development team.
118      *
119      * @parameter expression="${changes.mailSender}"
120      */
121     private MailSender mailSender;
122 
123 
124     /**
125      * Recipient email address.
126      *
127      * @parameter
128      * @required
129      */
130     private List toAddresses;
131 
132     /**
133      * Possible senders.
134      *
135      * @parameter expression="${project.developers}"
136      * @required
137      * @readonly
138      */
139     private List from;
140 
141     /**
142      * Directory which contains the template for announcement email.
143      *
144      * @parameter expression="${project.build.directory}/announcement"
145      * @required
146      */
147     private File templateOutputDirectory;
148 
149     /**
150      * The Velocity template used to format the announcement.
151      *
152      * @parameter default-value="announcement.vm" expression="${changes.template}"
153      * @required
154      */
155     private String template;
156 
157     /**
158      * Mail content type to use.
159      * @parameter default-value="text/plain"
160      * @required
161      * @since 2.1
162      */
163     private String mailContentType;
164 
165     private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender();
166 
167     public void execute()
168         throws MojoExecutionException
169     {
170         // Run only at the execution root
171         if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
172         {
173             getLog().info( "Skipping the announcement mail in this project because it's not the Execution Root" );
174         }
175         else
176         {
177             File templateFile = new File( templateOutputDirectory, template );
178 
179             ConsoleLogger logger = new ConsoleLogger( Logger.LEVEL_INFO, "base" );
180 
181             if ( getLog().isDebugEnabled() )
182             {
183                 logger.setThreshold( Logger.LEVEL_DEBUG );
184             }
185 
186             mailer.enableLogging( logger );
187 
188             mailer.setSmtpHost( getSmtpHost() );
189 
190             mailer.setSmtpPort( getSmtpPort() );
191 
192             mailer.setSslMode( sslMode );
193 
194             if ( username != null )
195             {
196                 mailer.setUsername( username );
197             }
198 
199             if ( password != null )
200             {
201                 mailer.setPassword( password );
202             }
203 
204             mailer.initialize();
205 
206             if ( getLog().isDebugEnabled() )
207             {
208                 getLog().debug( "fromDeveloperId: " + getFromDeveloperId() );
209             }
210 
211             if ( templateFile.isFile() )
212             {
213                 getLog().info( "Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort() );
214 
215                 sendMessage();
216             }
217             else
218             {
219                 throw new MojoExecutionException( "Announcement template " + templateFile + " not found..." );
220             }
221         }
222     }
223 
224     /**
225      * Send the email.
226      *
227      * @throws MojoExecutionException if the mail could not be sent
228      */
229     protected void sendMessage()
230         throws MojoExecutionException
231     {
232         File templateFile = new File( templateOutputDirectory, template );
233         String email = "";
234         final MailSender ms = getActualMailSender();
235         final String fromName = ms.getName();
236         final String fromAddress = ms.getEmail();
237         if ( fromAddress == null || fromAddress.equals( "" ) )
238         {
239             throw new MojoExecutionException( "Invalid mail sender: name and email is mandatory (" + ms + ")." );
240         }
241         getLog().info( "Using this sender for email announcement: " + fromAddress + " < " + fromName + " > " );
242         try
243         {
244             MailMessage mailMsg = new MailMessage();
245             mailMsg.setSubject( getSubject() );
246             mailMsg.setContent( IOUtil.toString( readAnnouncement( templateFile ) ) );
247             mailMsg.setContentType( this.mailContentType );
248             mailMsg.setFrom( fromAddress, fromName );
249             final Iterator it = getToAddresses().iterator();
250             while ( it.hasNext() )
251             {
252                 email = it.next().toString();
253                 getLog().info( "Sending mail to " + email + "..." );
254                 mailMsg.addTo( email, "" );
255 
256             }
257             mailer.send( mailMsg );
258             getLog().info( "Sent..." );
259         }
260         catch ( IOException ioe )
261         {
262             throw new MojoExecutionException( "Failed to send email.", ioe );
263         }
264         catch ( MailSenderException e )
265         {
266             throw new MojoExecutionException( "Failed to send email < " + email + " >", e );
267         }
268     }
269 
270     /**
271      * Read the announcement generated file.
272      *
273      * @param file the file to be read
274      * @return fileReader Return the FileReader
275      * @throws MojoExecutionException if the file could not be found
276      */
277     protected FileReader readAnnouncement( File file )
278         throws MojoExecutionException
279     {
280         FileReader fileReader;
281         try
282         {
283             fileReader = new FileReader( file );
284         }
285         catch ( FileNotFoundException fnfe )
286         {
287             throw new MojoExecutionException( "File not found. " + file );
288         }
289         return fileReader;
290     }
291 
292     /**
293      * Returns the identify of the mail sender according to the plugin's configuration:
294      * <ul>
295      * <li>if the <tt>mailSender</tt> parameter is set, it is returned</li>
296      * <li>if no <tt>fromDeveloperId</tt> is set, the first developer in the list is returned</li>
297      * <li>if a <tt>fromDeveloperId</tt> is set, the developer with that id is returned</li>
298      * <li>if the developers list is empty or if the specified id does not exist, an exception is thrown</li>
299      * </ul>
300      *
301      * @return the mail sender to use
302      * @throws MojoExecutionException if the mail sender could not be retrieved
303      */
304     protected MailSender getActualMailSender()
305         throws MojoExecutionException
306     {
307         if ( mailSender != null && mailSender.getEmail() != null )
308         {
309             return mailSender;
310         }
311         else if ( from == null || from.isEmpty() )
312         {
313             throw new MojoExecutionException(
314                 "The <developers> section in your pom should not be empty. Add a <developer> entry or set the "
315                     + "mailSender parameter." );
316         }
317         else if ( fromDeveloperId == null )
318         {
319             final Developer dev = (Developer) from.get( 0 );
320             return new MailSender( dev.getName(), dev.getEmail() );
321         }
322         else
323         {
324             final Iterator it = from.iterator();
325             while ( it.hasNext() )
326             {
327                 Developer developer = (Developer) it.next();
328 
329                 if ( fromDeveloperId.equals( developer.getId() ) )
330                 {
331                     return new MailSender( developer.getName(), developer.getEmail() );
332                 }
333             }
334             throw new MojoExecutionException(
335                 "Missing developer with id '" + fromDeveloperId + "' in the <developers> section in your pom." );
336         }
337     }
338 
339     //================================
340     // announcement-mail accessors
341     //================================
342 
343     public String getSmtpHost()
344     {
345         return smtpHost;
346     }
347 
348     public void setSmtpHost( String smtpHost )
349     {
350         this.smtpHost = smtpHost;
351     }
352 
353     public int getSmtpPort()
354     {
355         return smtpPort;
356     }
357 
358     public void setSmtpPort( int smtpPort )
359     {
360         this.smtpPort = smtpPort;
361     }
362 
363     public String getSubject()
364     {
365         return subject;
366     }
367 
368     public void setSubject( String subject )
369     {
370         this.subject = subject;
371     }
372 
373     public List getFrom()
374     {
375         return from;
376     }
377 
378     public void setFrom( List from )
379     {
380         this.from = from;
381     }
382 
383     public MavenProject getProject()
384     {
385         return project;
386     }
387 
388     public void setProject( MavenProject project )
389     {
390         this.project = project;
391     }
392 
393     public List getToAddresses()
394     {
395         return toAddresses;
396     }
397 
398     public void setToAddresses( List toAddresses )
399     {
400         this.toAddresses = toAddresses;
401     }
402 
403     public String getFromDeveloperId()
404     {
405         return fromDeveloperId;
406     }
407 
408     public void setFromDeveloperId( String fromDeveloperId )
409     {
410         this.fromDeveloperId = fromDeveloperId;
411     }
412 
413 
414     public String getUsername()
415     {
416         return username;
417     }
418 
419     public void setUsername( String username )
420     {
421         this.username = username;
422     }
423 
424     public String getPassword()
425     {
426         return password;
427     }
428 
429     public void setPassword( String password )
430     {
431         this.password = password;
432     }
433 
434     public boolean isSslMode()
435     {
436         return sslMode;
437     }
438 
439     public void setSslMode( boolean sslMode )
440     {
441         this.sslMode = sslMode;
442     }
443 
444     public MailSender getMailSender()
445     {
446         return mailSender;
447     }
448 
449     public void setMailSender( MailSender mailSender )
450     {
451         this.mailSender = mailSender;
452     }
453 
454     public File getTemplateOutputDirectory()
455     {
456         return templateOutputDirectory;
457     }
458 
459     public void setTemplateOutputDirectory( File templateOutputDirectory )
460     {
461         this.templateOutputDirectory = templateOutputDirectory;
462     }
463 
464     public String getTemplate()
465     {
466         return template;
467     }
468 
469     public void setTemplate( String template )
470     {
471         this.template = template;
472     }
473 }