View Javadoc

1   package org.apache.maven.report.projectinfo;
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 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   * Generates the Project Source Code Management (SCM) report.
45   *
46   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton </a>
47   * @version $Id: ScmReport.java 793977 2009-07-14 17:09:32Z dennisl $
48   * @since 2.0
49   * @goal scm
50   */
51  public class ScmReport
52      extends AbstractProjectInfoReport
53  {
54      // ----------------------------------------------------------------------
55      // Mojo parameters
56      // ----------------------------------------------------------------------
57  
58      /**
59       * Maven SCM Manager.
60       *
61       * @component
62       */
63      protected ScmManager scmManager;
64  
65      /**
66       * The directory name to checkout right after the SCM URL.
67       *
68       * @parameter default-value="${project.artifactId}"
69       * @required
70       */
71      private String checkoutDirectoryName;
72  
73      /**
74       * The SCM anonymous connection url respecting the SCM URL Format.
75       *
76       * @parameter default-value="${project.scm.connection}"
77       * @since 2.1
78       * @see <a href="http://maven.apache.org/scm/scm-url-format.html">SCM URL Format< /a>
79       */
80      private String anonymousConnection;
81  
82      /**
83       * The SCM developer connection url respecting the SCM URL Format.
84       *
85       * @parameter default-value="${project.scm.developerConnection}"
86       * @since 2.1
87       * @see <a href="http://maven.apache.org/scm/scm-url-format.html">SCM URL Format< /a>
88       */
89      private String developerConnection;
90  
91      /**
92       * The SCM web access url.
93       *
94       * @parameter default-value="${project.scm.url}"
95       * @since 2.1
96       */
97      private String webAccessUrl;
98  
99      // ----------------------------------------------------------------------
100     // Public methods
101     // ----------------------------------------------------------------------
102 
103     /** {@inheritDoc} */
104     public String getName( Locale locale )
105     {
106         return i18n.getString( "project-info-report", locale, "report.scm.name" );
107     }
108 
109     /** {@inheritDoc} */
110     public String getDescription( Locale locale )
111     {
112         return i18n.getString( "project-info-report", locale, "report.scm.description" );
113     }
114 
115     /** {@inheritDoc} */
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     /** {@inheritDoc} */
126     public String getOutputName()
127     {
128         return "source-repository";
129     }
130 
131     // ----------------------------------------------------------------------
132     // Private
133     // ----------------------------------------------------------------------
134 
135     /**
136      * Internal renderer class
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          * To support more SCM
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         /** {@inheritDoc} */
188         public String getTitle()
189         {
190             return i18n.getString( "project-info-report", locale, "report.scm.title" );
191         }
192 
193         /** {@inheritDoc} */
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             // Overview section
224             renderOverViewSection( anonymousRepository );
225 
226             // Web access section
227             renderWebAccesSection( webAccessUrl );
228 
229             // Anonymous access section if needed
230             renderAnonymousAccessSection( anonymousRepository );
231 
232             // Developer access section
233             renderDeveloperAccessSection( devRepository );
234 
235             // Access from behind a firewall section if needed
236             renderAccessBehindFirewallSection( devRepository );
237 
238             // Access through a proxy section if needed
239             renderAccessThroughProxySection( anonymousRepository, devRepository );
240         }
241 
242         /**
243          * Render the overview section
244          *
245          * @param anonymousRepository the anonymous repository
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          * Render the web access section
281          *
282          * @param scmUrl The URL to the project's browsable repository.
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          * Render the anonymous access section depending the repository.
304          * <p>Note: ClearCase, Starteam et Perforce seems to have no anonymous access.</p>
305          *
306          * @param anonymousRepository the anonymous repository
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          * Render the developer access section
345          *
346          * @param devRepository the dev repository
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          * Render the access from behind a firewall section
399          *
400          * @param devRepository the dev repository
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          * Render the access from behind a firewall section
434          *
435          * @param anonymousRepository the anonymous repository
436          * @param devRepository the dev repository
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         // Clearcase
464 
465         /**
466          * Create the documentation to provide an developer access with a <code>Clearcase</code> SCM.
467          * For example, generate the following command line:
468          * <p>cleartool checkout module</p>
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         // CVS
481 
482         /**
483          * Create the documentation to provide an anonymous access with a <code>CVS</code> SCM.
484          * For example, generate the following command line:
485          * <p>cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login</p>
486          * <p>cvs -z3 -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic co maven-plugins/dist</p>
487          *
488          * @param cvsRepo
489          * @see <a href="https://www.cvshome.org/docs/manual/cvs-1.12.12/cvs_16.html#SEC115">https://www.cvshome.org/docs/manual/cvs-1.12.12/cvs_16.html#SEC115</a>
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          * Create the documentation to provide an developer access with a <code>CVS</code> SCM.
506          * For example, generate the following command line:
507          * <p>cvs -d :pserver:username@cvs.apache.org:/home/cvs login</p>
508          * <p>cvs -z3 -d :ext:username@cvs.apache.org:/home/cvs co maven-plugins/dist</p>
509          *
510          * @param cvsRepo
511          * @see <a href="https://www.cvshome.org/docs/manual/cvs-1.12.12/cvs_16.html#SEC115">https://www.cvshome.org/docs/manual/cvs-1.12.12/cvs_16.html#SEC115</a>
512          */
513         private void developerAccessCVS( CvsScmProviderRepository cvsRepo )
514         {
515             paragraph( i18n.getString( "project-info-report", locale, "report.scm.devaccess.cvs.intro" ) );
516 
517             // Safety: remove the username if present
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         // Perforce
529 
530         /**
531          * Create the documentation to provide an developer access with a <code>Perforce</code> SCM.
532          * For example, generate the following command line:
533          * <p>p4 -H hostname -p port -u username -P password path</p>
534          * <p>p4 -H hostname -p port -u username -P password path submit -c changement</p>
535          *
536          * @param perforceRepo
537          * @see <a href="http://www.perforce.com/perforce/doc.051/manuals/cmdref/index.html">http://www.perforce.com/perforce/doc.051/manuals/cmdref/index.html</>
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         // Starteam
564 
565         /**
566          * Create the documentation to provide an developer access with a <code>Starteam</code> SCM.
567          * For example, generate the following command line:
568          * <p>stcmd co -x -nologo -stop -p myusername:mypassword@myhost:1234/projecturl -is</p>
569          * <p>stcmd ci -x -nologo -stop -p myusername:mypassword@myhost:1234/projecturl -f NCI -is</p>
570          *
571          * @param starteamRepo
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             // Safety: remove the username/password if present
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         // SVN
595 
596         /**
597          * Create the documentation to provide an anonymous access with a <code>SVN</code> SCM.
598          * For example, generate the following command line:
599          * <p>svn checkout http://svn.apache.org/repos/asf/maven/components/trunk maven</p>
600          *
601          * @param svnRepo
602          * @see <a href="http://svnbook.red-bean.com/">http://svnbook.red-bean.com/</a>
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          * Create the documentation to provide an developer access with a <code>SVN</code> SCM.
616          * For example, generate the following command line:
617          * <p>svn checkout https://svn.apache.org/repos/asf/maven/components/trunk maven</p>
618          * <p>svn commit --username your-username -m "A message"</p>
619          *
620          * @param svnRepo
621          * @see <a href="http://svnbook.red-bean.com/">http://svnbook.red-bean.com/</a>
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          * Return a <code>SCM repository</code> defined by a given url
665          *
666          * @param scmUrl an SCM URL
667          * @return a valid SCM repository or null
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                     // Ignore NoSuchScmProviderException msg
696                     // See impl of AbstractScmManager#validateScmRepository()
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                 // Should be already catched
743                 if ( log.isDebugEnabled() )
744                 {
745                     log.debug( e.getMessage(), e );
746                 }
747             }
748 
749             return repo;
750         }
751 
752         /**
753          * Convenience method that return true is the defined <code>SCM repository</code> is a known provider.
754          * <p>
755          * Actually, we fully support Clearcase, CVS, Perforce, Starteam, SVN by the maven-scm-providers component.
756          * </p>
757          *
758          * @param scmRepository a SCM repository
759          * @param scmProvider a SCM provider name
760          * @return true if the provider of the given SCM repository is equal to the given scm provider.
761          * @see <a href="http://svn.apache.org/repos/asf/maven/scm/trunk/maven-scm-providers/">maven-scm-providers</a>
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 }