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