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