1 package org.apache.maven.report.projectinfo;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.doxia.sink.Sink;
23 import org.apache.maven.model.Model;
24 import org.apache.maven.model.Scm;
25 import org.apache.maven.plugin.logging.Log;
26 import org.apache.maven.reporting.AbstractMavenReportRenderer;
27 import org.apache.maven.scm.manager.NoSuchScmProviderException;
28 import org.apache.maven.scm.manager.ScmManager;
29 import org.apache.maven.scm.provider.cvslib.repository.CvsScmProviderRepository;
30 import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
31 import org.apache.maven.scm.provider.starteam.repository.StarteamScmProviderRepository;
32 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
33 import org.apache.maven.scm.repository.ScmRepository;
34 import org.apache.maven.scm.repository.ScmRepositoryException;
35 import org.codehaus.plexus.i18n.I18N;
36 import org.codehaus.plexus.util.StringUtils;
37
38 import java.util.ArrayList;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Locale;
42
43
44
45
46
47
48
49
50
51 public class ScmReport
52 extends AbstractProjectInfoReport
53 {
54
55
56
57
58
59
60
61
62
63 protected ScmManager scmManager;
64
65
66
67
68
69
70
71 private String checkoutDirectoryName;
72
73
74
75
76
77
78
79
80 private String anonymousConnection;
81
82
83
84
85
86
87
88
89 private String developerConnection;
90
91
92
93
94
95
96
97 private String webAccessUrl;
98
99
100
101
102
103
104 public String getName( Locale locale )
105 {
106 return i18n.getString( "project-info-report", locale, "report.scm.name" );
107 }
108
109
110 public String getDescription( Locale locale )
111 {
112 return i18n.getString( "project-info-report", locale, "report.scm.description" );
113 }
114
115
116 public void executeReport( Locale locale )
117 {
118 ScmRenderer r = new ScmRenderer( getLog(), scmManager, getSink(), getProject().getModel(), i18n, locale,
119 checkoutDirectoryName, webAccessUrl, anonymousConnection,
120 developerConnection );
121
122 r.render();
123 }
124
125
126 public String getOutputName()
127 {
128 return "source-repository";
129 }
130
131
132
133
134
135
136
137
138 private static class ScmRenderer
139 extends AbstractMavenReportRenderer
140 {
141 private Log log;
142
143 private Model model;
144
145 private I18N i18n;
146
147 private Locale locale;
148
149 private ScmManager scmManager;
150
151
152
153
154 private String anonymousConnection;
155
156 private String devConnection;
157
158 private String checkoutDirectoryName;
159
160 private String webAccessUrl;
161
162 ScmRenderer( Log log, ScmManager scmManager, Sink sink, Model model, I18N i18n, Locale locale,
163 String checkoutDirName, String webAccessUrl, String anonymousConnection, String devConnection )
164 {
165 super( sink );
166
167 this.log = log;
168
169 this.scmManager = scmManager;
170
171 this.model = model;
172
173 this.i18n = i18n;
174
175 this.locale = locale;
176
177 this.checkoutDirectoryName = checkoutDirName;
178
179 this.webAccessUrl = webAccessUrl;
180
181 this.anonymousConnection = anonymousConnection;
182
183 this.devConnection = devConnection;
184
185 }
186
187
188 public String getTitle()
189 {
190 return i18n.getString( "project-info-report", locale, "report.scm.title" );
191 }
192
193
194 public void renderBody()
195 {
196 Scm scm = model.getScm();
197 if ( scm == null )
198 {
199 startSection( getTitle() );
200
201 paragraph( i18n.getString( "project-info-report", locale, "report.scm.noscm" ) );
202
203 endSection();
204
205 return;
206 }
207
208 if ( StringUtils.isEmpty( anonymousConnection ) && StringUtils.isEmpty( devConnection )
209 && StringUtils.isEmpty( scm.getUrl() ) )
210 {
211 startSection( getTitle() );
212
213 paragraph( i18n.getString( "project-info-report", locale, "report.scm.noscm" ) );
214
215 endSection();
216
217 return;
218 }
219
220 ScmRepository anonymousRepository = getScmRepository( anonymousConnection );
221 ScmRepository devRepository = getScmRepository( devConnection );
222
223
224 renderOverViewSection( anonymousRepository );
225
226
227 renderWebAccesSection( webAccessUrl );
228
229
230 renderAnonymousAccessSection( anonymousRepository );
231
232
233 renderDeveloperAccessSection( devRepository );
234
235
236 renderAccessBehindFirewallSection( devRepository );
237
238
239 renderAccessThroughProxySection( anonymousRepository, devRepository );
240 }
241
242
243
244
245
246
247 private void renderOverViewSection( ScmRepository anonymousRepository )
248 {
249 startSection( i18n.getString( "project-info-report", locale, "report.scm.overview.title" ) );
250
251 if ( isScmSystem( anonymousRepository, "clearcase" ) )
252 {
253 linkPatternedText( i18n.getString( "project-info-report", locale, "report.scm.clearcase.intro" ) );
254 }
255 else if ( isScmSystem( anonymousRepository, "cvs" ) )
256 {
257 linkPatternedText( i18n.getString( "project-info-report", locale, "report.scm.cvs.intro" ) );
258 }
259 else if ( isScmSystem( anonymousRepository, "perforce" ) )
260 {
261 linkPatternedText( i18n.getString( "project-info-report", locale, "report.scm.perforce.intro" ) );
262 }
263 else if ( isScmSystem( anonymousRepository, "starteam" ) )
264 {
265 linkPatternedText( i18n.getString( "project-info-report", locale, "report.scm.starteam.intro" ) );
266 }
267 else if ( isScmSystem( anonymousRepository, "svn" ) )
268 {
269 linkPatternedText( i18n.getString( "project-info-report", locale, "report.scm.svn.intro" ) );
270 }
271 else
272 {
273 paragraph( i18n.getString( "project-info-report", locale, "report.scm.general.intro" ) );
274 }
275
276 endSection();
277 }
278
279
280
281
282
283
284 private void renderWebAccesSection( String scmUrl )
285 {
286 startSection( i18n.getString( "project-info-report", locale, "report.scm.webaccess.title" ) );
287
288 if ( StringUtils.isEmpty( scmUrl ) )
289 {
290 paragraph( i18n.getString( "project-info-report", locale, "report.scm.webaccess.nourl" ) );
291 }
292 else
293 {
294 paragraph( i18n.getString( "project-info-report", locale, "report.scm.webaccess.url" ) );
295
296 verbatimLink( scmUrl, scmUrl );
297 }
298
299 endSection();
300 }
301
302
303
304
305
306
307
308 private void renderAnonymousAccessSection( ScmRepository anonymousRepository )
309 {
310 if ( isScmSystem( anonymousRepository, "clearcase" ) || isScmSystem( anonymousRepository, "perforce" )
311 || isScmSystem( anonymousRepository, "starteam" ) || StringUtils.isEmpty( anonymousConnection ) )
312 {
313 return;
314 }
315
316 startSection( i18n.getString( "project-info-report", locale, "report.scm.anonymousaccess.title" ) );
317
318 if ( anonymousRepository != null && isScmSystem( anonymousRepository, "cvs" ) )
319 {
320 CvsScmProviderRepository cvsRepo = (CvsScmProviderRepository) anonymousRepository
321 .getProviderRepository();
322
323 anonymousAccessCVS( cvsRepo );
324 }
325 else if ( anonymousRepository != null && isScmSystem( anonymousRepository, "svn" ) )
326 {
327 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) anonymousRepository
328 .getProviderRepository();
329
330 anonymousAccessSVN( svnRepo );
331 }
332 else
333 {
334 paragraph( i18n.getString( "project-info-report", locale,
335 "report.scm.anonymousaccess.general.intro" ) );
336
337 verbatimText( anonymousConnection.substring( 4 ) );
338 }
339
340 endSection();
341 }
342
343
344
345
346
347
348 private void renderDeveloperAccessSection( ScmRepository devRepository )
349 {
350 if ( StringUtils.isEmpty( devConnection ) )
351 {
352 return;
353 }
354
355 startSection( i18n.getString( "project-info-report", locale, "report.scm.devaccess.title" ) );
356
357 if ( devRepository != null && isScmSystem( devRepository, "clearcase" ) )
358 {
359 developerAccessClearCase();
360 }
361 else if ( devRepository != null && isScmSystem( devRepository, "cvs" ) )
362 {
363 CvsScmProviderRepository cvsRepo = (CvsScmProviderRepository) devRepository.getProviderRepository();
364
365 developerAccessCVS( cvsRepo );
366 }
367 else if ( devRepository != null && isScmSystem( devRepository, "perforce" ) )
368 {
369 PerforceScmProviderRepository perforceRepo = (PerforceScmProviderRepository) devRepository
370 .getProviderRepository();
371
372 developerAccessPerforce( perforceRepo );
373 }
374 else if ( devRepository != null && isScmSystem( devRepository, "starteam" ) )
375 {
376 StarteamScmProviderRepository starteamRepo = (StarteamScmProviderRepository) devRepository
377 .getProviderRepository();
378
379 developerAccessStarteam( starteamRepo );
380 }
381 else if ( devRepository != null && isScmSystem( devRepository, "svn" ) )
382 {
383 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) devRepository.getProviderRepository();
384
385 developerAccessSVN( svnRepo );
386 }
387 else
388 {
389 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.general.intro" ) );
390
391 verbatimText( devConnection.substring( 4 ) );
392 }
393
394 endSection();
395 }
396
397
398
399
400
401
402 private void renderAccessBehindFirewallSection( ScmRepository devRepository )
403 {
404 startSection( i18n.getString( "project-info-report", locale, "report.scm.accessbehindfirewall.title" ) );
405
406 if ( devRepository != null && isScmSystem( devRepository, "svn" ) )
407 {
408 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) devRepository.getProviderRepository();
409
410 paragraph( i18n.getString( "project-info-report", locale,
411 "report.scm.accessbehindfirewall.svn.intro" ) );
412
413 StringBuffer sb = new StringBuffer();
414 sb.append( "$ svn checkout " ).append( svnRepo.getUrl() );
415 sb.append( " " ).append( checkoutDirectoryName );
416 verbatimText( sb.toString() );
417 }
418 else if ( devRepository != null && isScmSystem( devRepository, "cvs" ) )
419 {
420 linkPatternedText( i18n.getString( "project-info-report", locale,
421 "report.scm.accessbehindfirewall.cvs.intro" ) );
422 }
423 else
424 {
425 paragraph( i18n.getString( "project-info-report", locale,
426 "report.scm.accessbehindfirewall.general.intro" ) );
427 }
428
429 endSection();
430 }
431
432
433
434
435
436
437
438 private void renderAccessThroughProxySection( ScmRepository anonymousRepository, ScmRepository devRepository )
439 {
440 if ( isScmSystem( anonymousRepository, "svn" ) || isScmSystem( devRepository, "svn" ) )
441 {
442 startSection( i18n.getString( "project-info-report", locale,
443 "report.scm.accessthroughtproxy.title" ) );
444
445 paragraph( i18n.getString( "project-info-report", locale,
446 "report.scm.accessthroughtproxy.svn.intro1" ) );
447 paragraph( i18n.getString( "project-info-report", locale,
448 "report.scm.accessthroughtproxy.svn.intro2" ) );
449 paragraph( i18n.getString( "project-info-report", locale,
450 "report.scm.accessthroughtproxy.svn.intro3" ) );
451
452 StringBuffer sb = new StringBuffer();
453 sb.append( "[global]" );
454 sb.append( "\n" );
455 sb.append( "http-proxy-host = your.proxy.name" ).append( "\n" );
456 sb.append( "http-proxy-port = 3128" ).append( "\n" );
457 verbatimText( sb.toString() );
458
459 endSection();
460 }
461 }
462
463
464
465
466
467
468
469
470 private void developerAccessClearCase()
471 {
472 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.clearcase.intro" ) );
473
474 StringBuffer command = new StringBuffer();
475 command.append( "$ cleartool checkout " );
476
477 verbatimText( command.toString() );
478 }
479
480
481
482
483
484
485
486
487
488
489
490
491 private void anonymousAccessCVS( CvsScmProviderRepository cvsRepo )
492 {
493 paragraph( i18n.getString( "project-info-report", locale, "report.scm.anonymousaccess.cvs.intro" ) );
494
495 StringBuffer command = new StringBuffer();
496 command.append( "$ cvs -d " ).append( cvsRepo.getCvsRoot() ).append( " login" );
497 command.append( "\n" );
498 command.append( "$ cvs -z3 -d " ).append( cvsRepo.getCvsRoot() );
499 command.append( " co " ).append( cvsRepo.getModule() );
500
501 verbatimText( command.toString() );
502 }
503
504
505
506
507
508
509
510
511
512
513 private void developerAccessCVS( CvsScmProviderRepository cvsRepo )
514 {
515 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.cvs.intro" ) );
516
517
518 String cvsRoot = StringUtils.replace( cvsRepo.getCvsRoot(), cvsRepo.getUser(), "username" );
519
520 StringBuffer command = new StringBuffer();
521 command.append( "$ cvs -d " ).append( cvsRoot ).append( " login" );
522 command.append( "\n" );
523 command.append( "$ cvs -z3 -d " ).append( cvsRoot ).append( " co " ).append( cvsRepo.getModule() );
524
525 verbatimText( command.toString() );
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539 private void developerAccessPerforce( PerforceScmProviderRepository perforceRepo )
540 {
541 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.perforce.intro" ) );
542
543 StringBuffer command = new StringBuffer();
544 command.append( "$ p4" );
545 if ( !StringUtils.isEmpty( perforceRepo.getHost() ) )
546 {
547 command.append( " -H " ).append( perforceRepo.getHost() );
548 }
549 if ( perforceRepo.getPort() > 0 )
550 {
551 command.append( " -p " ).append( perforceRepo.getPort() );
552 }
553 command.append( " -u username" );
554 command.append( " -P password" );
555 command.append( " " );
556 command.append( perforceRepo.getPath() );
557 command.append( "\n" );
558 command.append( "$ p4 submit -c \"A comment\"" );
559
560 verbatimText( command.toString() );
561 }
562
563
564
565
566
567
568
569
570
571
572
573 private void developerAccessStarteam( StarteamScmProviderRepository starteamRepo )
574 {
575 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.starteam.intro" ) );
576
577 StringBuffer command = new StringBuffer();
578
579
580 String fullUrl = StringUtils.replace( starteamRepo.getFullUrl(), starteamRepo.getUser(), "username" );
581 fullUrl = StringUtils.replace( fullUrl, starteamRepo.getPassword(), "password" );
582
583 command.append( "$ stcmd co -x -nologo -stop -p " );
584 command.append( fullUrl );
585 command.append( " -is" );
586 command.append( "\n" );
587 command.append( "$ stcmd ci -x -nologo -stop -p " );
588 command.append( fullUrl );
589 command.append( " -f NCI -is" );
590
591 verbatimText( command.toString() );
592 }
593
594
595
596
597
598
599
600
601
602
603
604 private void anonymousAccessSVN( SvnScmProviderRepository svnRepo )
605 {
606 paragraph( i18n.getString( "project-info-report", locale, "report.scm.anonymousaccess.svn.intro" ) );
607
608 StringBuffer sb = new StringBuffer();
609 sb.append( "$ svn checkout " ).append( svnRepo.getUrl() ).append( " " ).append( checkoutDirectoryName );
610
611 verbatimText( sb.toString() );
612 }
613
614
615
616
617
618
619
620
621
622
623 private void developerAccessSVN( SvnScmProviderRepository svnRepo )
624 {
625 if ( svnRepo.getUrl() != null )
626 {
627 if ( svnRepo.getUrl().startsWith( "https://" ) )
628 {
629 paragraph( i18n.getString( "project-info-report", locale,
630 "report.scm.devaccess.svn.intro1.https" ) );
631 }
632 else if ( svnRepo.getUrl().startsWith( "svn://" ) )
633 {
634 paragraph( i18n.getString( "project-info-report", locale,
635 "report.scm.devaccess.svn.intro1.svn" ) );
636 }
637 else if ( svnRepo.getUrl().startsWith( "svn+ssh://" ) )
638 {
639 paragraph( i18n.getString( "project-info-report", locale,
640 "report.scm.devaccess.svn.intro1.svnssh" ) );
641 }
642 else
643 {
644 paragraph( i18n.getString( "project-info-report", locale,
645 "report.scm.devaccess.svn.intro1.other" ) );
646 }
647 }
648
649 StringBuffer sb = new StringBuffer();
650
651 sb.append( "$ svn checkout " ).append( svnRepo.getUrl() ).append( " " ).append( checkoutDirectoryName );
652
653 verbatimText( sb.toString() );
654
655 paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.svn.intro2" ) );
656
657 sb = new StringBuffer();
658 sb.append( "$ svn commit --username your-username -m \"A message\"" );
659
660 verbatimText( sb.toString() );
661 }
662
663
664
665
666
667
668
669 public ScmRepository getScmRepository( String scmUrl )
670 {
671 if ( StringUtils.isEmpty( scmUrl ) )
672 {
673 return null;
674 }
675
676 ScmRepository repo = null;
677 List messages = new ArrayList();
678 try
679 {
680 messages.addAll( scmManager.validateScmRepository( scmUrl ) );
681 }
682 catch ( Exception e )
683 {
684 messages.add( e.getMessage() );
685 }
686
687 if ( messages.size() > 0 )
688 {
689 StringBuffer sb = new StringBuffer();
690 boolean isIntroAdded = false;
691 for ( Iterator it = messages.iterator(); it.hasNext(); )
692 {
693 String msg = it.next().toString();
694
695
696
697 if ( msg.startsWith( "No such provider" ) )
698 {
699 continue;
700 }
701
702 if ( !isIntroAdded )
703 {
704 sb.append( "This SCM url '" + scmUrl + "' is invalid due to the following errors:" );
705 sb.append( "\n" );
706 isIntroAdded = true;
707 }
708 sb.append( " * " );
709 sb.append( msg );
710 sb.append( "\n" );
711 }
712
713 if ( StringUtils.isNotEmpty( sb.toString() ) )
714 {
715 sb.append( "For more information about SCM URL Format, please refer to: "
716 + "http://maven.apache.org/scm/scm-url-format.html" );
717
718 throw new IllegalArgumentException( sb.toString() );
719 }
720 }
721
722 try
723 {
724 repo = scmManager.makeScmRepository( scmUrl );
725 }
726 catch ( NoSuchScmProviderException e )
727 {
728 if ( log.isDebugEnabled() )
729 {
730 log.debug( e.getMessage(), e );
731 }
732 }
733 catch ( ScmRepositoryException e )
734 {
735 if ( log.isDebugEnabled() )
736 {
737 log.debug( e.getMessage(), e );
738 }
739 }
740 catch ( Exception e )
741 {
742
743 if ( log.isDebugEnabled() )
744 {
745 log.debug( e.getMessage(), e );
746 }
747 }
748
749 return repo;
750 }
751
752
753
754
755
756
757
758
759
760
761
762
763 private static boolean isScmSystem( ScmRepository scmRepository, String scmProvider )
764 {
765 if ( StringUtils.isEmpty( scmProvider ) )
766 {
767 return false;
768 }
769
770 if ( scmRepository != null && scmProvider.equalsIgnoreCase( scmRepository.getProvider() ) )
771 {
772 return true;
773 }
774
775 return false;
776 }
777 }
778 }