1 package org.apache.maven.plugin.announcement;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStreamReader;
27 import java.io.UnsupportedEncodingException;
28 import java.util.List;
29
30 import javax.mail.internet.AddressException;
31 import javax.mail.internet.InternetAddress;
32
33 import org.apache.maven.model.Developer;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.announcement.mailsender.ProjectJavamailMailSender;
36 import org.apache.maven.plugins.annotations.Execute;
37 import org.apache.maven.plugins.annotations.Mojo;
38 import org.apache.maven.plugins.annotations.Parameter;
39 import org.apache.maven.project.MavenProject;
40 import org.codehaus.plexus.logging.Logger;
41 import org.codehaus.plexus.logging.console.ConsoleLogger;
42 import org.codehaus.plexus.mailsender.MailMessage;
43 import org.codehaus.plexus.mailsender.MailSenderException;
44 import org.codehaus.plexus.util.IOUtil;
45 import org.codehaus.plexus.util.ReaderFactory;
46 import org.codehaus.plexus.util.StringUtils;
47
48
49
50
51
52
53
54
55 @Mojo( name = "announcement-mail", threadSafe = true )
56 @Execute( goal = "announcement-generate" )
57 public class AnnouncementMailMojo
58 extends AbstractAnnouncementMojo
59 {
60
61
62
63
64
65
66
67 @Parameter( property = "project.developers", required = true, readonly = true )
68 private List from;
69
70
71
72
73
74
75
76 @Parameter( property = "changes.fromDeveloperId" )
77 private String fromDeveloperId;
78
79
80
81
82
83
84 @Parameter( defaultValue = "text/plain", required = true )
85 private String mailContentType;
86
87
88
89
90
91
92
93
94 @Parameter( property = "changes.mailSender" )
95 private MailSender mailSender;
96
97
98
99
100
101
102
103
104
105
106 @Parameter( property = "changes.sender" )
107 private String senderString;
108
109
110
111
112 @Parameter( property = "changes.password" )
113 private String password;
114
115
116
117 @Parameter( defaultValue = "${project}", readonly = true, required = true )
118 private MavenProject project;
119
120
121
122
123 @Parameter( property = "changes.smtpHost", required = true )
124 private String smtpHost;
125
126
127
128
129 @Parameter( property = "changes.smtpPort", defaultValue = "25", required = true )
130 private int smtpPort;
131
132
133
134
135 @Parameter( property = "changes.sslMode", defaultValue = "false" )
136 private boolean sslMode;
137
138
139
140
141
142
143 @Parameter( property = "changes.startTls", defaultValue = "false" )
144 private boolean startTls;
145
146
147
148
149 @Parameter( property = "changes.subject",
150 defaultValue = "[ANNOUNCEMENT] - ${project.name} ${project.version} released", required = true )
151 private String subject;
152
153
154
155
156
157
158 @Parameter( property = "changes.announcementFile", defaultValue = "announcement.vm", required = true )
159 private String announcementFile;
160
161
162
163
164
165
166 @Parameter( defaultValue = "${project.build.directory}/announcement", required = true )
167 private File announcementDirectory;
168
169
170
171
172
173
174 @Parameter( property = "changes.templateEncoding", defaultValue = "${project.build.sourceEncoding}" )
175 private String templateEncoding;
176
177
178
179
180
181
182 @Parameter
183 private File templateOutputDirectory;
184
185
186
187
188 @Parameter( required = true )
189 private List toAddresses;
190
191
192
193
194
195
196 @Parameter
197 private List ccAddresses;
198
199
200
201
202
203
204 @Parameter
205 private List bccAddresses;
206
207
208
209
210 @Parameter( property = "changes.username" )
211 private String username;
212
213 private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender();
214
215 public void execute()
216 throws MojoExecutionException
217 {
218
219 if ( templateOutputDirectory != null )
220 {
221 throw new MojoExecutionException( "You are using the old parameter 'templateOutputDirectory'. You must use 'announcementDirectory' instead." );
222 }
223
224
225 if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
226 {
227 getLog().info( "Skipping the announcement mail in this project because it's not the Execution Root" );
228 }
229 else
230 {
231 File file = new File( announcementDirectory, announcementFile );
232
233 ConsoleLogger logger = new ConsoleLogger( Logger.LEVEL_INFO, "base" );
234
235 if ( getLog().isDebugEnabled() )
236 {
237 logger.setThreshold( Logger.LEVEL_DEBUG );
238 }
239
240 mailer.enableLogging( logger );
241
242 mailer.setSmtpHost( getSmtpHost() );
243
244 mailer.setSmtpPort( getSmtpPort() );
245
246 mailer.setSslMode( sslMode, startTls );
247
248 if ( username != null )
249 {
250 mailer.setUsername( username );
251 }
252
253 if ( password != null )
254 {
255 mailer.setPassword( password );
256 }
257
258 mailer.initialize();
259
260 if ( getLog().isDebugEnabled() )
261 {
262 getLog().debug( "fromDeveloperId: " + getFromDeveloperId() );
263 }
264
265 if ( file.isFile() )
266 {
267 getLog().info( "Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort() );
268
269 sendMessage();
270 }
271 else
272 {
273 throw new MojoExecutionException( "Announcement file " + file + " not found..." );
274 }
275 }
276 }
277
278
279
280
281
282
283 protected void sendMessage()
284 throws MojoExecutionException
285 {
286 File file = new File( announcementDirectory, announcementFile );
287 String email = "";
288 final MailSender ms = getActualMailSender();
289 final String fromName = ms.getName();
290 final String fromAddress = ms.getEmail();
291 if ( fromAddress == null || fromAddress.equals( "" ) )
292 {
293 throw new MojoExecutionException( "Invalid mail sender: name and email is mandatory (" + ms + ")." );
294 }
295 getLog().info( "Using this sender for email announcement: " + fromAddress + " < " + fromName + " > " );
296 try
297 {
298 MailMessage mailMsg = new MailMessage();
299 mailMsg.setSubject( getSubject() );
300 mailMsg.setContent( readAnnouncement( file ) );
301 mailMsg.setContentType( this.mailContentType );
302 mailMsg.setFrom( fromAddress, fromName );
303
304 for ( Object o1 : getToAddresses() )
305 {
306 email = o1.toString();
307 getLog().info( "Sending mail to " + email + "..." );
308 mailMsg.addTo( email, "" );
309 }
310
311 if ( getCcAddresses() != null )
312 {
313 for ( Object o : getCcAddresses() )
314 {
315 email = o.toString();
316 getLog().info( "Sending cc mail to " + email + "..." );
317 mailMsg.addCc( email, "" );
318 }
319 }
320
321 if ( getBccAddresses() != null )
322 {
323 for ( Object o : getBccAddresses() )
324 {
325 email = o.toString();
326 getLog().info( "Sending bcc mail to " + email + "..." );
327 mailMsg.addBcc( email, "" );
328 }
329 }
330
331 mailer.send( mailMsg );
332 getLog().info( "Sent..." );
333 }
334 catch ( MailSenderException e )
335 {
336 throw new MojoExecutionException( "Failed to send email < " + email + " >", e );
337 }
338 }
339
340
341
342
343
344
345
346
347 protected String readAnnouncement( File file )
348 throws MojoExecutionException
349 {
350 InputStreamReader reader = null;
351 FileInputStream inputStream = null;
352 try
353 {
354 inputStream = new FileInputStream( file );
355
356 if ( StringUtils.isEmpty( templateEncoding ) )
357 {
358 templateEncoding = ReaderFactory.FILE_ENCODING;
359 getLog().warn( "File encoding has not been set, using platform encoding '" + templateEncoding
360 + "', i.e. build is platform dependent!" );
361 }
362
363 reader = new InputStreamReader( inputStream, templateEncoding );
364 return IOUtil.toString( reader );
365 }
366 catch ( FileNotFoundException fnfe )
367 {
368 throw new MojoExecutionException( "File not found. " + file );
369 }
370 catch ( UnsupportedEncodingException uee )
371 {
372 throw new MojoExecutionException( "Unsupported encoding: '" + templateEncoding + "'" );
373 }
374 catch ( IOException ioe )
375 {
376 throw new MojoExecutionException( "Failed to read the announcement file.", ioe );
377 }
378 finally
379 {
380 IOUtil.close( inputStream );
381 IOUtil.close( reader );
382 }
383 }
384
385
386
387
388
389
390
391
392
393
394
395
396
397 protected MailSender getActualMailSender()
398 throws MojoExecutionException
399 {
400 if ( senderString != null )
401 {
402 try
403 {
404 InternetAddress ia = new InternetAddress( senderString, true );
405 return new MailSender( ia.getPersonal(), ia.getAddress() );
406 }
407 catch ( AddressException e )
408 {
409 throw new MojoExecutionException( "Invalid value for change.sender: ", e );
410 }
411 }
412 if ( mailSender != null && mailSender.getEmail() != null )
413 {
414 return mailSender;
415 }
416 else if ( from == null || from.isEmpty() )
417 {
418 throw new MojoExecutionException(
419 "The <developers> section in your pom should not be empty. Add a <developer> entry or set the "
420 + "mailSender parameter." );
421 }
422 else if ( fromDeveloperId == null )
423 {
424 final Developer dev = (Developer) from.get( 0 );
425 return new MailSender( dev.getName(), dev.getEmail() );
426 }
427 else
428 {
429 for ( Object aFrom : from )
430 {
431 Developer developer = (Developer) aFrom;
432
433 if ( fromDeveloperId.equals( developer.getId() ) )
434 {
435 return new MailSender( developer.getName(), developer.getEmail() );
436 }
437 }
438 throw new MojoExecutionException(
439 "Missing developer with id '" + fromDeveloperId + "' in the <developers> section in your pom." );
440 }
441 }
442
443
444
445
446
447 public List getBccAddresses()
448 {
449 return bccAddresses;
450 }
451
452 public void setBccAddresses( List bccAddresses )
453 {
454 this.bccAddresses = bccAddresses;
455 }
456
457 public List getCcAddresses()
458 {
459 return ccAddresses;
460 }
461
462 public void setCcAddresses( List ccAddresses )
463 {
464 this.ccAddresses = ccAddresses;
465 }
466
467 public List getFrom()
468 {
469 return from;
470 }
471
472 public void setFrom( List from )
473 {
474 this.from = from;
475 }
476
477 public String getFromDeveloperId()
478 {
479 return fromDeveloperId;
480 }
481
482 public void setFromDeveloperId( String fromDeveloperId )
483 {
484 this.fromDeveloperId = fromDeveloperId;
485 }
486
487 public MailSender getMailSender()
488 {
489 return mailSender;
490 }
491
492 public void setMailSender( MailSender mailSender )
493 {
494 this.mailSender = mailSender;
495 }
496
497 public String getPassword()
498 {
499 return password;
500 }
501
502 public void setPassword( String password )
503 {
504 this.password = password;
505 }
506
507 public MavenProject getProject()
508 {
509 return project;
510 }
511
512 public void setProject( MavenProject project )
513 {
514 this.project = project;
515 }
516
517 public String getSmtpHost()
518 {
519 return smtpHost;
520 }
521
522 public void setSmtpHost( String smtpHost )
523 {
524 this.smtpHost = smtpHost;
525 }
526
527 public int getSmtpPort()
528 {
529 return smtpPort;
530 }
531
532 public void setSmtpPort( int smtpPort )
533 {
534 this.smtpPort = smtpPort;
535 }
536
537 public boolean isSslMode()
538 {
539 return sslMode;
540 }
541
542 public void setSslMode( boolean sslMode )
543 {
544 this.sslMode = sslMode;
545 }
546
547 public boolean isStartTls()
548 {
549 return startTls;
550 }
551
552 public void setStartTls( boolean startTls )
553 {
554 this.startTls = startTls;
555 }
556
557 public String getSubject()
558 {
559 return subject;
560 }
561
562 public void setSubject( String subject )
563 {
564 this.subject = subject;
565 }
566
567 public String getAnnouncementFile()
568 {
569 return announcementFile;
570 }
571
572 public void setAnnouncementFile( String announcementFile )
573 {
574 this.announcementFile = announcementFile;
575 }
576
577 public File getAnnouncementDirectory()
578 {
579 return announcementDirectory;
580 }
581
582 public void setAnnouncementDirectory( File announcementDirectory )
583 {
584 this.announcementDirectory = announcementDirectory;
585 }
586
587 public List getToAddresses()
588 {
589 return toAddresses;
590 }
591
592 public void setToAddresses( List toAddresses )
593 {
594 this.toAddresses = toAddresses;
595 }
596
597 public String getUsername()
598 {
599 return username;
600 }
601
602 public void setUsername( String username )
603 {
604 this.username = username;
605 }
606 }