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