Coverage Report - org.apache.maven.scm.provider.cvslib.AbstractCvsScmProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractCvsScmProvider
54 %
111/205
61 %
66/108
2,551
AbstractCvsScmProvider$ScmUrlParserResult
63 %
7/11
N/A
2,551
 
 1  
 package org.apache.maven.scm.provider.cvslib;
 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.IOException;
 24  
 import java.util.ArrayList;
 25  
 import java.util.List;
 26  
 
 27  
 import org.apache.maven.scm.CommandParameters;
 28  
 import org.apache.maven.scm.ScmException;
 29  
 import org.apache.maven.scm.ScmFileSet;
 30  
 import org.apache.maven.scm.ScmResult;
 31  
 import org.apache.maven.scm.ScmTagParameters;
 32  
 import org.apache.maven.scm.command.Command;
 33  
 import org.apache.maven.scm.command.add.AddScmResult;
 34  
 import org.apache.maven.scm.command.blame.BlameScmResult;
 35  
 import org.apache.maven.scm.command.branch.BranchScmResult;
 36  
 import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
 37  
 import org.apache.maven.scm.command.checkin.CheckInScmResult;
 38  
 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
 39  
 import org.apache.maven.scm.command.diff.DiffScmResult;
 40  
 import org.apache.maven.scm.command.export.ExportScmResult;
 41  
 import org.apache.maven.scm.command.list.ListScmResult;
 42  
 import org.apache.maven.scm.command.login.LoginScmResult;
 43  
 import org.apache.maven.scm.command.mkdir.MkdirScmResult;
 44  
 import org.apache.maven.scm.command.remove.RemoveScmResult;
 45  
 import org.apache.maven.scm.command.status.StatusScmResult;
 46  
 import org.apache.maven.scm.command.tag.TagScmResult;
 47  
 import org.apache.maven.scm.command.update.UpdateScmResult;
 48  
 import org.apache.maven.scm.provider.AbstractScmProvider;
 49  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 50  
 import org.apache.maven.scm.provider.cvslib.repository.CvsScmProviderRepository;
 51  
 import org.apache.maven.scm.repository.ScmRepositoryException;
 52  
 import org.apache.maven.scm.repository.UnknownRepositoryStructure;
 53  
 import org.codehaus.plexus.util.FileUtils;
 54  
 import org.codehaus.plexus.util.StringUtils;
 55  
 
 56  
 /**
 57  
  * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse </a>
 58  
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 59  
  * @version $Id: AbstractCvsScmProvider.java 1134851 2011-06-12 01:24:05Z godin $
 60  
  */
 61  16
 public abstract class AbstractCvsScmProvider
 62  
     extends AbstractScmProvider
 63  
 {
 64  
     /** ext transport method */
 65  
     public static final String TRANSPORT_EXT = "ext";
 66  
 
 67  
     /** local transport method */
 68  
     public static final String TRANSPORT_LOCAL = "local";
 69  
 
 70  
     /** lserver transport method */
 71  
     public static final String TRANSPORT_LSERVER = "lserver";
 72  
 
 73  
     /** pserver transport method */
 74  
     public static final String TRANSPORT_PSERVER = "pserver";
 75  
 
 76  
     /** sspi transport method */
 77  
     public static final String TRANSPORT_SSPI = "sspi";
 78  
 
 79  
     // ----------------------------------------------------------------------
 80  
     //
 81  
     // ----------------------------------------------------------------------
 82  
 
 83  
     /**
 84  
      * The current ScmUrlParserResult
 85  
      *
 86  
      * @since 1.1.1
 87  
      */
 88  16
     public static class ScmUrlParserResult
 89  
     {
 90  
         private List<String> messages;
 91  
 
 92  
         private ScmProviderRepository repository;
 93  
 
 94  
         public ScmUrlParserResult()
 95  23
         {
 96  23
             messages = new ArrayList<String>();
 97  23
         }
 98  
 
 99  
         /**
 100  
          * @return the messages
 101  
          */
 102  
         public List<String> getMessages()
 103  
         {
 104  26
             return messages;
 105  
         }
 106  
 
 107  
         /**
 108  
          * @param messages the messages to set
 109  
          */
 110  
         public void setMessages( List<String> messages )
 111  
         {
 112  0
             this.messages = messages;
 113  0
         }
 114  
 
 115  
         /**
 116  
          * @return the repository
 117  
          */
 118  
         public ScmProviderRepository getRepository()
 119  
         {
 120  12
             return repository;
 121  
         }
 122  
 
 123  
         /**
 124  
          * @param repository the repository to set
 125  
          */
 126  
         public void setRepository( ScmProviderRepository repository )
 127  
         {
 128  21
             this.repository = repository;
 129  21
         }
 130  
 
 131  
         /**
 132  
          * Reset messages.
 133  
          */
 134  
         public void resetMessages()
 135  
         {
 136  0
             this.messages = new ArrayList<String>();
 137  0
         }
 138  
     }
 139  
 
 140  
     // ----------------------------------------------------------------------
 141  
     // ScmProvider Implementation
 142  
     // ----------------------------------------------------------------------
 143  
 
 144  
     /** {@inheritDoc} */
 145  
     public String getScmSpecificFilename()
 146  
     {
 147  1
         return "CVS";
 148  
     }
 149  
 
 150  
     /* From the Cederqvist:
 151  
     *
 152  
     * "Tag names must start with an uppercase or lowercase letter and can
 153  
     * contain uppercase and lowercase letters, digits, `-', and `_'. The
 154  
     * two tag names BASE and HEAD are reserved for use by CVS. It is expected
 155  
     * that future names which are special to CVS will be specially named,
 156  
     * for example by starting with `.', rather than being named analogously
 157  
     * to BASE and HEAD, to avoid conflicts with actual tag names."
 158  
     */
 159  
     /** {@inheritDoc} */
 160  
     public String sanitizeTagName( String arg0 )
 161  
     {
 162  2
         if ( validateTagName( arg0 ) )
 163  
         {
 164  0
             return arg0;
 165  
         }
 166  
 
 167  2
         if ( arg0.equals( "HEAD" ) || arg0.equals( "BASE" ) || !arg0.matches( "[A-Za-z].*" ) )
 168  
             /* we don't even bother to sanitize these, they're just silly */
 169  
         {
 170  0
             throw new RuntimeException(
 171  
                 "Unable to sanitize tag " + arg0 + ": must begin with a letter" + "and not be HEAD or BASE" );
 172  
         }
 173  
 
 174  
         /* swap all illegal characters for a _ */
 175  2
         return arg0.replaceAll( "[^A-Za-z0-9_-]", "_" );
 176  
     }
 177  
 
 178  
     /** {@inheritDoc} */
 179  
     public boolean validateTagName( String arg0 )
 180  
     {
 181  12
         return ( arg0.matches( "[A-Za-z][A-Za-z0-9_-]*" ) && !arg0.equals( "HEAD" ) && !arg0.equals( "BASE" ) );
 182  
     }
 183  
 
 184  
     /** {@inheritDoc} */
 185  
     public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
 186  
         throws ScmRepositoryException
 187  
     {
 188  13
         ScmUrlParserResult result = parseScmUrl( scmSpecificUrl, delimiter );
 189  
 
 190  13
         if ( result.getMessages().size() > 0 )
 191  
         {
 192  1
             throw new ScmRepositoryException( "The scm url is invalid.", result.getMessages() );
 193  
         }
 194  
 
 195  12
         return result.getRepository();
 196  
     }
 197  
 
 198  
     /** {@inheritDoc} */
 199  
     public ScmProviderRepository makeProviderScmRepository( File path )
 200  
         throws ScmRepositoryException, UnknownRepositoryStructure
 201  
     {
 202  1
         if ( path == null || !path.isDirectory() )
 203  
         {
 204  0
             throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
 205  
         }
 206  
 
 207  1
         File cvsDirectory = new File( path, "CVS" );
 208  
 
 209  1
         if ( !cvsDirectory.exists() )
 210  
         {
 211  0
             throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a cvs checkout directory." );
 212  
         }
 213  
 
 214  1
         File cvsRootFile = new File( cvsDirectory, "Root" );
 215  
 
 216  1
         File moduleFile = new File( cvsDirectory, "Repository" );
 217  
 
 218  
         String cvsRoot;
 219  
 
 220  
         String module;
 221  
 
 222  
         try
 223  
         {
 224  1
             cvsRoot = FileUtils.fileRead( cvsRootFile ).trim().substring( 1 );
 225  
         }
 226  0
         catch ( IOException e )
 227  
         {
 228  0
             throw new ScmRepositoryException( "Can't read " + cvsRootFile.getAbsolutePath() );
 229  1
         }
 230  
         try
 231  
         {
 232  1
             module = FileUtils.fileRead( moduleFile ).trim();
 233  
         }
 234  0
         catch ( IOException e )
 235  
         {
 236  0
             throw new ScmRepositoryException( "Can't read " + moduleFile.getAbsolutePath() );
 237  1
         }
 238  
 
 239  1
         return makeProviderScmRepository( cvsRoot + ":" + module, ':' );
 240  
     }
 241  
 
 242  
     /** {@inheritDoc} */
 243  
     public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
 244  
     {
 245  10
         ScmUrlParserResult result = parseScmUrl( scmSpecificUrl, delimiter );
 246  
 
 247  10
         return result.getMessages();
 248  
     }
 249  
 
 250  
     /** {@inheritDoc} */
 251  
     public String getScmType()
 252  
     {
 253  0
         return "cvs";
 254  
     }
 255  
 
 256  
     /** {@inheritDoc} */
 257  
     public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 258  
         throws ScmException
 259  
     {
 260  0
         return (AddScmResult) executeCommand( getAddCommand(), repository, fileSet, parameters );
 261  
     }
 262  
 
 263  
     /** {@inheritDoc} */
 264  
     public BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 265  
         throws ScmException
 266  
     {
 267  0
         return (BranchScmResult) executeCommand( getBranchCommand(), repository, fileSet, parameters );
 268  
     }
 269  
 
 270  
     /** {@inheritDoc} */
 271  
     protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 272  
         throws ScmException
 273  
     {
 274  0
         return (BlameScmResult) executeCommand( getBlameCommand(), repository, fileSet, parameters );
 275  
     }
 276  
 
 277  
     /** {@inheritDoc} */
 278  
     public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
 279  
                                          CommandParameters parameters )
 280  
         throws ScmException
 281  
     {
 282  0
         return (ChangeLogScmResult) executeCommand( getChangeLogCommand(), repository, fileSet, parameters );
 283  
     }
 284  
 
 285  
     /** {@inheritDoc} */
 286  
     public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
 287  
                                      CommandParameters parameters )
 288  
         throws ScmException
 289  
     {
 290  0
         return (CheckInScmResult) executeCommand( getCheckInCommand(), repository, fileSet, parameters );
 291  
     }
 292  
 
 293  
     /** {@inheritDoc} */
 294  
     public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
 295  
                                        CommandParameters parameters )
 296  
         throws ScmException
 297  
     {
 298  0
         return (CheckOutScmResult) executeCommand( getCheckOutCommand(), repository, fileSet, parameters );
 299  
     }
 300  
 
 301  
     /** {@inheritDoc} */
 302  
     public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 303  
         throws ScmException
 304  
     {
 305  0
         return (DiffScmResult) executeCommand( getDiffCommand(), repository, fileSet, parameters );
 306  
     }
 307  
 
 308  
     /** {@inheritDoc} */
 309  
     protected ExportScmResult export( ScmProviderRepository repository, ScmFileSet fileSet,
 310  
                                       CommandParameters parameters )
 311  
         throws ScmException
 312  
     {
 313  0
         return (ExportScmResult) executeCommand( getExportCommand(), repository, fileSet, parameters );
 314  
     }
 315  
 
 316  
     /** {@inheritDoc} */
 317  
     public LoginScmResult login( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 318  
         throws ScmException
 319  
     {
 320  0
         return (LoginScmResult) executeCommand( getLoginCommand(), repository, fileSet, parameters );
 321  
     }
 322  
 
 323  
     /** {@inheritDoc} */
 324  
     public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 325  
         throws ScmException
 326  
     {
 327  0
         return (RemoveScmResult) executeCommand( getRemoveCommand(), repository, fileSet, parameters );
 328  
     }
 329  
 
 330  
     /** {@inheritDoc} */
 331  
     public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 332  
         throws ScmException
 333  
     {
 334  0
         return (StatusScmResult) executeCommand( getStatusCommand(), repository, fileSet, parameters );
 335  
     }
 336  
 
 337  
     /** {@inheritDoc} */
 338  
     public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 339  
         throws ScmException
 340  
     {
 341  0
         return (TagScmResult) executeCommand( getTagCommand(), repository, fileSet, parameters );
 342  
     }
 343  
     
 344  
     protected TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters,
 345  
                                 ScmTagParameters scmParameters )
 346  
         throws ScmException
 347  
     {
 348  0
         return (TagScmResult) getTagCommand().execute( repository, fileSet, parameters );
 349  
     }
 350  
     
 351  
 
 352  
     /** {@inheritDoc} */
 353  
     public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 354  
         throws ScmException
 355  
     {
 356  0
         return (UpdateScmResult) executeCommand( getUpdateCommand(), repository, fileSet, parameters );
 357  
     }
 358  
 
 359  
     /** {@inheritDoc} */
 360  
     protected ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 361  
         throws ScmException
 362  
     {
 363  0
         return (ListScmResult) executeCommand( getListCommand(), repository, fileSet, parameters );
 364  
     }
 365  
     
 366  
     /** {@inheritDoc} */
 367  
     protected MkdirScmResult mkdir( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
 368  
         throws ScmException
 369  
     {
 370  0
         return (MkdirScmResult) executeCommand( getMkdirCommand(), repository, fileSet, parameters );
 371  
     }
 372  
 
 373  
     /**
 374  
      * @param basedir not null
 375  
      * @param f not null
 376  
      * @return the relative path
 377  
      * @throws ScmException if any
 378  
      * @throws IOException if any
 379  
      */
 380  
     public static String getRelativePath( File basedir, File f )
 381  
         throws ScmException, IOException
 382  
     {
 383  0
         File fileOrDir = getAbsoluteFilePath( f );
 384  
 
 385  0
         if ( !fileOrDir.getPath().startsWith( basedir.getPath() ) )
 386  
         {
 387  0
             throw new ScmException( fileOrDir.getPath() + " was not contained in " + basedir.getPath() );
 388  
         }
 389  
 
 390  0
         return fileOrDir.getPath().substring( basedir.getPath().length() + 1, fileOrDir.getPath().length() );
 391  
     }
 392  
 
 393  
     // ----------------------------------------------------------------------
 394  
     // Protected methods
 395  
     // ----------------------------------------------------------------------
 396  
 
 397  
     protected ScmUrlParserResult parseScmUrl( String scmSpecificUrl, char delimiter )
 398  
     {
 399  23
         ScmUrlParserResult result = new ScmUrlParserResult();
 400  
 
 401  23
         String[] tokens = StringUtils.split( scmSpecificUrl, Character.toString( delimiter ) );
 402  
 
 403  23
         if ( tokens.length < 3 )
 404  
         {
 405  0
             result.getMessages().add( "The connection string contains too few tokens." );
 406  
 
 407  0
             return result;
 408  
         }
 409  
 
 410  
         String cvsroot;
 411  
 
 412  23
         String transport = tokens[0];
 413  
 
 414  23
         if ( transport.equalsIgnoreCase( TRANSPORT_LOCAL ) )
 415  
         {
 416  
             // use the local repository directory eg. '/home/cvspublic'
 417  3
             cvsroot = tokens[1];
 418  
         }
 419  20
         else if ( transport.equalsIgnoreCase( TRANSPORT_PSERVER ) || transport.equalsIgnoreCase( TRANSPORT_LSERVER )
 420  
             || transport.equalsIgnoreCase( TRANSPORT_EXT ) || transport.equalsIgnoreCase( TRANSPORT_SSPI ) )
 421  
         {
 422  18
             if ( tokens.length != 4 && transport.equalsIgnoreCase( TRANSPORT_EXT ) )
 423  
             {
 424  0
                 result.getMessages().add( "The connection string contains too few tokens." );
 425  
 
 426  0
                 return result;
 427  
             }
 428  18
             else if ( ( tokens.length < 4 || tokens.length > 6 ) && transport.equalsIgnoreCase( TRANSPORT_PSERVER ) )
 429  
             {
 430  0
                 result.getMessages().add( "The connection string contains too few tokens." );
 431  
 
 432  0
                 return result;
 433  
             }
 434  18
             else if ( tokens.length < 4 || tokens.length > 5 && !transport.equalsIgnoreCase( TRANSPORT_PSERVER ) )
 435  
             {
 436  0
                 result.getMessages().add( "The connection string contains too few tokens." );
 437  
 
 438  0
                 return result;
 439  
             }
 440  18
             else if ( tokens.length < 4 || tokens.length > 5 && transport.equalsIgnoreCase( TRANSPORT_SSPI ) )
 441  
             {
 442  0
                 result.getMessages().add( "The connection string contains too few tokens." );
 443  
 
 444  0
                 return result;
 445  
             }
 446  
 
 447  18
             if ( transport.equalsIgnoreCase( TRANSPORT_LSERVER ) )
 448  
             {
 449  
                 //create the cvsroot as the local socket cvsroot
 450  0
                 cvsroot = tokens[1] + ":" + tokens[2];
 451  
             }
 452  
             else
 453  
             {
 454  
                 //create the cvsroot as the remote cvsroot
 455  18
                 if ( tokens.length == 4 )
 456  
                 {
 457  9
                     cvsroot = ":" + transport + ":" + tokens[1] + ":" + tokens[2];
 458  
                 }
 459  
                 else
 460  
                 {
 461  9
                     cvsroot = ":" + transport + ":" + tokens[1] + ":" + tokens[2] + ":" + tokens[3];
 462  
                 }
 463  
             }
 464  
         }
 465  
         else
 466  
         {
 467  2
             result.getMessages().add( "Unknown transport: " + transport );
 468  
 
 469  2
             return result;
 470  
         }
 471  
 
 472  21
         String user = null;
 473  
 
 474  21
         String password = null;
 475  
 
 476  21
         String host = null;
 477  
 
 478  21
         String path = null;
 479  
 
 480  21
         String module = null;
 481  
 
 482  21
         int port = -1;
 483  
 
 484  21
         if ( transport.equalsIgnoreCase( TRANSPORT_PSERVER ) )
 485  
         {
 486  
             // set default port, it's necessary for checking entries in .cvspass
 487  17
             port = 2401;
 488  
 
 489  17
             if ( tokens.length == 4 )
 490  
             {
 491  
                 //pserver:[username@]host:path:module
 492  8
                 String userhost = tokens[1];
 493  
 
 494  8
                 int index = userhost.indexOf( '@' );
 495  
 
 496  8
                 if ( index == -1 )
 497  
                 {
 498  4
                     host = userhost;
 499  
                 }
 500  
                 else
 501  
                 {
 502  4
                     user = userhost.substring( 0, index );
 503  
 
 504  4
                     host = userhost.substring( index + 1 );
 505  
                 }
 506  
 
 507  8
                 path = tokens[2];
 508  
 
 509  8
                 module = tokens[3];
 510  8
             }
 511  9
             else if ( tokens.length == 6 )
 512  
             {
 513  
                 //pserver:username:password@host:port:path:module
 514  4
                 user = tokens[1];
 515  
 
 516  4
                 String passhost = tokens[2];
 517  
 
 518  4
                 int index = passhost.indexOf( '@' );
 519  
 
 520  4
                 if ( index == -1 )
 521  
                 {
 522  0
                     result.getMessages()
 523  
                         .add( "The user_password_host part must be on the form: <username>:<password>@<hostname>." );
 524  
 
 525  0
                     return result;
 526  
                 }
 527  
 
 528  4
                 password = passhost.substring( 0, index );
 529  
 
 530  4
                 host = passhost.substring( index + 1 );
 531  
 
 532  4
                 port = new Integer( tokens[3] ).intValue();
 533  
 
 534  4
                 path = tokens[4];
 535  
 
 536  4
                 module = tokens[5];
 537  4
             }
 538  
             else
 539  
             {
 540  
                 //tokens.length == 5
 541  5
                 if ( tokens[1].indexOf( '@' ) > 0 )
 542  
                 {
 543  
                     //pserver:username@host:port:path:module
 544  1
                     String userhost = tokens[1];
 545  
 
 546  1
                     int index = userhost.indexOf( '@' );
 547  
 
 548  1
                     user = userhost.substring( 0, index );
 549  
 
 550  1
                     host = userhost.substring( index + 1 );
 551  
 
 552  1
                     port = new Integer( tokens[2] ).intValue();
 553  1
                 }
 554  4
                 else if ( tokens[2].indexOf( '@' ) >= 0 )
 555  
                 {
 556  
                     //pserver:username:password@host:path:module
 557  
                     //<username>:<password>@<hostname>
 558  4
                     user = tokens[1];
 559  
 
 560  4
                     String passhost = tokens[2];
 561  
 
 562  4
                     int index = passhost.indexOf( '@' );
 563  
 
 564  4
                     password = passhost.substring( 0, index );
 565  
 
 566  4
                     host = passhost.substring( index + 1 );
 567  4
                 }
 568  
                 else
 569  
                 {
 570  
                     //pserver:host:port:path:module
 571  
                     try
 572  
                     {
 573  0
                         port = new Integer( tokens[2] ).intValue();
 574  
                     }
 575  0
                     catch ( Exception e )
 576  
                     {
 577  
                         //incorrect
 578  0
                         result.getMessages().add( "Your scm url is invalid." );
 579  
 
 580  0
                         return result;
 581  0
                     }
 582  
 
 583  0
                     host = tokens[1];
 584  
                 }
 585  
 
 586  5
                 path = tokens[3];
 587  
 
 588  5
                 module = tokens[4];
 589  
             }
 590  
 
 591  17
             String userHost = host;
 592  
 
 593  17
             if ( user != null )
 594  
             {
 595  13
                 userHost = user + "@" + host;
 596  
             }
 597  
 
 598  
             // cvsroot format is :pserver:[user@]host:[port]path
 599  17
             cvsroot = ":" + transport + ":" + userHost + ":";
 600  
 
 601  17
             if ( port != -1 )
 602  
             {
 603  17
                 cvsroot += port;
 604  
             }
 605  
 
 606  17
             cvsroot += path;
 607  17
         }
 608  4
         else if ( transport.equalsIgnoreCase( TRANSPORT_SSPI ) )
 609  
         {
 610  
             //sspi:[username@]host:[port]path:module
 611  0
             String userhost = tokens[1];
 612  
 
 613  0
             int index = userhost.indexOf( '@' );
 614  
 
 615  0
             if ( index == -1 )
 616  
             {
 617  0
                 user = "";
 618  
 
 619  0
                 host = userhost;
 620  
             }
 621  
             else
 622  
             {
 623  0
                 user = userhost.substring( 0, index );
 624  
 
 625  0
                 host = userhost.substring( index + 1 );
 626  
             }
 627  
 
 628  
             // no port specified
 629  0
             if ( tokens.length == 4 )
 630  
             {
 631  0
                 path = tokens[2];
 632  0
                 module = tokens[3];
 633  
             }
 634  
             else
 635  
             {
 636  
                 // getting port
 637  
                 try
 638  
                 {
 639  0
                     port = new Integer( tokens[2] ).intValue();
 640  0
                     path = tokens[3];
 641  0
                     module = tokens[4];
 642  
                 }
 643  0
                 catch ( Exception e )
 644  
                 {
 645  
                     //incorrect
 646  0
                     result.getMessages().add( "Your scm url is invalid, could not get port value." );
 647  
 
 648  0
                     return result;
 649  0
                 }
 650  
             }
 651  
 
 652  
             // cvsroot format is :sspi:host:path
 653  0
             cvsroot = ":" + transport + ":" + host + ":";
 654  
 
 655  0
             if ( port != -1 )
 656  
             {
 657  0
                 cvsroot += port;
 658  
             }
 659  
 
 660  0
             cvsroot += path;
 661  0
         }
 662  
         else
 663  
         {
 664  4
             if ( !transport.equalsIgnoreCase( TRANSPORT_LOCAL ) )
 665  
             {
 666  1
                 String userhost = tokens[1];
 667  
 
 668  1
                 int index = userhost.indexOf( '@' );
 669  
 
 670  1
                 if ( index == -1 )
 671  
                 {
 672  0
                     host = userhost;
 673  
                 }
 674  
                 else
 675  
                 {
 676  1
                     user = userhost.substring( 0, index );
 677  
 
 678  1
                     host = userhost.substring( index + 1 );
 679  
                 }
 680  
             }
 681  
 
 682  4
             if ( transport.equals( TRANSPORT_LOCAL ) )
 683  
             {
 684  3
                 path = tokens[1];
 685  
 
 686  3
                 module = tokens[2];
 687  
 
 688  3
                 if ( module != null && module.startsWith( "/" ) )
 689  
                 {
 690  0
                     module = module.substring( 1 );
 691  
                 }
 692  
 
 693  
             }
 694  
             else
 695  
             {
 696  1
                 if ( tokens.length == 4 )
 697  
                 {
 698  1
                     path = tokens[2];
 699  
 
 700  1
                     module = tokens[3];
 701  
                 }
 702  
                 else
 703  
                 {
 704  0
                     port = new Integer( tokens[2] ).intValue();
 705  
 
 706  0
                     path = tokens[3];
 707  
 
 708  0
                     module = tokens[4];
 709  
                 }
 710  
             }
 711  
         }
 712  
 
 713  21
         if ( port == -1 )
 714  
         {
 715  4
             result.setRepository( new CvsScmProviderRepository( cvsroot, transport, user, password, host, path,
 716  
                                                                 module ) );
 717  
         }
 718  
         else
 719  
         {
 720  17
             result.setRepository( new CvsScmProviderRepository( cvsroot, transport, user, password, host, port,
 721  
                                                                 path, module ) );
 722  
         }
 723  
 
 724  21
         return result;
 725  
     }
 726  
 
 727  
     protected abstract Command getAddCommand();
 728  
 
 729  
     protected abstract Command getBranchCommand();
 730  
 
 731  
     protected abstract Command getBlameCommand();
 732  
 
 733  
     protected abstract Command getChangeLogCommand();
 734  
 
 735  
     protected abstract Command getCheckInCommand();
 736  
 
 737  
     protected abstract Command getCheckOutCommand();
 738  
 
 739  
     protected abstract Command getDiffCommand();
 740  
 
 741  
     protected abstract Command getExportCommand();
 742  
 
 743  
     protected abstract Command getListCommand();
 744  
 
 745  
     protected abstract Command getLoginCommand();
 746  
 
 747  
     protected abstract Command getRemoveCommand();
 748  
 
 749  
     protected abstract Command getStatusCommand();
 750  
 
 751  
     protected abstract Command getTagCommand();
 752  
 
 753  
     protected abstract Command getUpdateCommand();
 754  
     
 755  
     protected abstract Command getMkdirCommand();
 756  
 
 757  
     // ----------------------------------------------------------------------
 758  
     // Private methods
 759  
     // ----------------------------------------------------------------------
 760  
 
 761  
     private ScmResult executeCommand( Command command, ScmProviderRepository repository, ScmFileSet fileSet,
 762  
                                       CommandParameters parameters )
 763  
         throws ScmException
 764  
     {
 765  0
         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
 766  
 
 767  0
         command.setLogger( getLogger() );
 768  
 
 769  0
         return command.execute( repository, fileSet, parameters );
 770  
     }
 771  
 
 772  
 
 773  
     /**
 774  
      * CVS provider requires that all files in ScmFileSet must be relative to basedir
 775  
      * This function ensures and converts all absolute paths to relative paths
 776  
      *
 777  
      * @param currentFileSet
 778  
      * @return
 779  
      * @throws ScmException
 780  
      */
 781  
     private static ScmFileSet fixUpScmFileSetAbsoluteFilePath( ScmFileSet currentFileSet )
 782  
         throws ScmException
 783  
     {
 784  0
         ScmFileSet newFileSet = null;
 785  
 
 786  
         try
 787  
         {
 788  0
             File basedir = getAbsoluteFilePath( currentFileSet.getBasedir() );
 789  0
             List<File> fixedFiles = new ArrayList<File>(currentFileSet.getFileList().size());
 790  0
             for ( File file : currentFileSet.getFileList() )
 791  
             {
 792  0
                 if ( file.isAbsolute() )
 793  
                 {
 794  0
                     fixedFiles.add( new File( getRelativePath( basedir, file ) ) );
 795  
                 } else {
 796  0
                     fixedFiles.add( file );
 797  
                 }
 798  
             }
 799  
 
 800  0
             newFileSet = new ScmFileSet( basedir, fixedFiles );
 801  
         }
 802  0
         catch ( IOException e )
 803  
         {
 804  0
             throw new ScmException( "Invalid file set.", e );
 805  0
         }
 806  
 
 807  0
         return newFileSet;
 808  
     }
 809  
 
 810  
     private static File getAbsoluteFilePath( File fileOrDir )
 811  
         throws IOException
 812  
     {
 813  0
         String javaPathString = fileOrDir.getCanonicalPath().replace( '\\', '/' );
 814  
 
 815  0
         if ( javaPathString.endsWith( "/" ) )
 816  
         {
 817  0
             javaPathString = javaPathString.substring( 0, javaPathString.length() - 1 );
 818  
         }
 819  
 
 820  0
         return new File( javaPathString );
 821  
     }
 822  
 }