Coverage Report - org.apache.maven.scm.provider.clearcase.repository.ClearCaseScmProviderRepository
 
Classes in this File Line Coverage Branch Coverage Complexity
ClearCaseScmProviderRepository
80 %
84/105
64 %
22/34
2,333
 
 1  
 package org.apache.maven.scm.provider.clearcase.repository;
 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.scm.log.ScmLogger;
 23  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 24  
 import org.apache.maven.scm.providers.clearcase.settings.Settings;
 25  
 import org.apache.maven.scm.repository.ScmRepositoryException;
 26  
 
 27  
 import java.io.File;
 28  
 import java.net.InetAddress;
 29  
 import java.net.MalformedURLException;
 30  
 import java.net.URI;
 31  
 import java.net.URISyntaxException;
 32  
 import java.net.URL;
 33  
 import java.net.UnknownHostException;
 34  
 import java.util.StringTokenizer;
 35  
 
 36  
 /**
 37  
  * Provider Repository for ClearCase (standard, LT, UCM)
 38  
  * <p />
 39  
  * Url format for ClearCase and ClearCaseLT : <br />
 40  
  * [view_name]:[configspec] or [view_name]|[configspec]
 41  
  * <p />
 42  
  * Url format for ClearCaseUCM : <br />
 43  
  * [view_name]|[configspec]|[vob_name]|[stream_name] or [view_name]:[configspec]:[vob_name]:[stream_name]
 44  
  * <p />
 45  
  * [configspec] can be used in two different ways:
 46  
  * <ul>
 47  
  * <li>Path to a config spec file that is
 48  
  * used when creating the snapshot view, e.g.
 49  
  * "\\myserver\clearcase\configspecs\my_module.txt", or:</li>
 50  
  * <li>A load rule that is used to automatically create a config spec, e.g. "load /MY_VOB/my/project/dir"</li>
 51  
  * </ul>
 52  
  * Notice that checking out from a tag is currently only supported when the second option is used.
 53  
  *
 54  
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 55  
  * @version $Id: ClearCaseScmProviderRepository.java 483105 2006-12-06 15:07:54Z
 56  
  *          evenisse $
 57  
  */
 58  
 public class ClearCaseScmProviderRepository
 59  
     extends ScmProviderRepository
 60  
 {
 61  
     private ScmLogger logger;
 62  
 
 63  11
     private boolean viewNameGivenByUser = false;
 64  
 
 65  
     private String viewName;
 66  
 
 67  
     /**
 68  
      * The user-specified config spec; may be null.
 69  
      */
 70  
     private File configSpec;
 71  
 
 72  
     /**
 73  
      * The directory to be loaded, when auto-generating the config spec.
 74  
      */
 75  
     private String loadDirectory;
 76  
 
 77  
     /**
 78  
      * Describe the stream linked to the view. Only used with ClearCaseUCM
 79  
      */
 80  
     private String streamName;
 81  
 
 82  
     /**
 83  
      * Describe the vob containing the stream. Only used with ClearCaseUCM
 84  
      */
 85  
     private String vobName;
 86  
 
 87  
     /**
 88  
      * Provider configuration settings
 89  
      */
 90  
     private Settings settings;
 91  
 
 92  
     /**
 93  
      * Describe the Element Name
 94  
      */
 95  
     private String elementName;
 96  
 
 97  
     /**
 98  
      * Define the flag used in the clearcase-settings.xml when using ClearCaseLT
 99  
      */
 100  
     public static final String CLEARCASE_LT = "LT";
 101  
 
 102  
     /**
 103  
      * Define the flag used in the clearcase-settings.xml when using ClearCaseUCM
 104  
      */
 105  
     public static final String CLEARCASE_UCM = "UCM";
 106  
 
 107  
     /**
 108  
      * Define the default value from the clearcase-settings.xml when using ClearCase
 109  
      */
 110  1
     public static final String CLEARCASE_DEFAULT = null;
 111  
 
 112  
     public ClearCaseScmProviderRepository( ScmLogger logger, String url, Settings settings )
 113  
         throws ScmRepositoryException
 114  11
     {
 115  11
         this.logger = logger;
 116  11
         this.settings = settings;
 117  
         try
 118  
         {
 119  11
             parseUrl( url );
 120  
         }
 121  0
         catch ( MalformedURLException e )
 122  
         {
 123  0
             throw new ScmRepositoryException( "Illegal URL: " + url + "(" + e.getMessage() + ")" );
 124  
         }
 125  0
         catch ( URISyntaxException e )
 126  
         {
 127  0
             throw new ScmRepositoryException( "Illegal URL: " + url + "(" + e.getMessage() + ")" );
 128  
         }
 129  0
         catch ( UnknownHostException e )
 130  
         {
 131  0
             throw new ScmRepositoryException( "Illegal URL: " + url + "(" + e.getMessage() + ")" );
 132  11
         }
 133  11
     }
 134  
 
 135  
     private void parseUrl( String url )
 136  
         throws MalformedURLException, URISyntaxException, UnknownHostException
 137  
     {
 138  11
         if ( url.indexOf( '|' ) != -1 )
 139  
         {
 140  5
             StringTokenizer tokenizer = new StringTokenizer( url, "|" );
 141  5
             fillInProperties( tokenizer );
 142  5
         }
 143  
         else
 144  
         {
 145  6
             StringTokenizer tokenizer = new StringTokenizer( url, ":" );
 146  6
             fillInProperties( tokenizer );
 147  
         }
 148  11
     }
 149  
 
 150  
     private void fillInProperties( StringTokenizer tokenizer )
 151  
         throws UnknownHostException, URISyntaxException, MalformedURLException
 152  
     {
 153  11
         String configSpecString = null;
 154  
 
 155  11
         if ( CLEARCASE_UCM.equals( settings.getClearcaseType() ) )
 156  
         {
 157  5
             configSpecString = fillUCMProperties( tokenizer );
 158  
         }
 159  
         else
 160  
         {
 161  6
             configSpecString = fillDefaultProperties( tokenizer );
 162  
         }
 163  
 
 164  11
         if ( !configSpecString.startsWith( "load " ) )
 165  
         {
 166  6
             configSpec = createConfigSpecFile( configSpecString );
 167  6
             loadDirectory = null;
 168  
         }
 169  
         else
 170  
         {
 171  5
             configSpec = null;
 172  5
             loadDirectory = configSpecString.substring( 5 );
 173  
 
 174  
         }
 175  11
     }
 176  
 
 177  
     private String fillDefaultProperties( StringTokenizer tokenizer )
 178  
         throws UnknownHostException
 179  
     {
 180  6
         int tokenNumber = tokenizer.countTokens();
 181  
         String configSpecString;
 182  6
         if ( tokenNumber == 1 )
 183  
         {
 184  
             // No view name was given
 185  2
             viewName = getDefaultViewName();
 186  2
             configSpecString = tokenizer.nextToken();
 187  
         }
 188  
         else
 189  
         {
 190  4
             configSpecString = checkViewName( tokenizer );
 191  4
             checkUnexpectedParameter( tokenizer, tokenNumber, 2 );
 192  
         }
 193  6
         if ( logger.isDebugEnabled() )
 194  
         {
 195  0
             logger.debug( "viewName = '" + viewName + "' ; configSpec = '" + configSpecString + "'" );
 196  
         }
 197  6
         return configSpecString;
 198  
     }
 199  
 
 200  
     private String fillUCMProperties( StringTokenizer tokenizer )
 201  
         throws UnknownHostException, MalformedURLException
 202  
     {
 203  5
         int tokenNumber = tokenizer.countTokens();
 204  5
         if ( tokenNumber <= 2 )
 205  
         {
 206  0
             throw new MalformedURLException( "ClearCaseUCM need more parameters. Expected url format : "
 207  
                 + "[view_name]|[configspec]|[vob_name]|[stream_name]" );
 208  
         }
 209  
 
 210  
         String configSpecString;
 211  5
         if ( tokenNumber == 3 )
 212  
         {
 213  
             // No view name was given
 214  2
             viewName = getDefaultViewName();
 215  2
             configSpecString = tokenizer.nextToken();
 216  2
             vobName = tokenizer.nextToken();
 217  2
             streamName = tokenizer.nextToken();
 218  
         }
 219  3
         else if ( tokenNumber == 4 )
 220  
         {
 221  3
             String[] tokens = new String[4];
 222  3
             tokens[0] = tokenizer.nextToken();
 223  3
             tokens[1] = tokenizer.nextToken();
 224  3
             tokens[2] = tokenizer.nextToken();
 225  3
             tokens[3] = tokenizer.nextToken();
 226  
 
 227  3
             if ( tokens[3].startsWith( "/main/" ) )
 228  
             {
 229  2
                 viewName = getDefaultViewName();
 230  2
                 configSpecString = tokens[0];
 231  2
                 vobName = tokens[1];
 232  2
                 streamName = tokens[2];
 233  2
                 elementName = tokens[3];
 234  
             }
 235  
             else
 236  
             {
 237  1
                 viewName = tokens[0];
 238  1
                 viewNameGivenByUser = true;
 239  1
                 configSpecString = tokens[1];
 240  1
                 vobName = tokens[2];
 241  1
                 streamName = tokens[3];
 242  
             }
 243  3
         }
 244  
         else
 245  
         {
 246  0
             configSpecString = checkViewName( tokenizer );
 247  0
             vobName = tokenizer.nextToken();
 248  0
             streamName = tokenizer.nextToken();
 249  0
             elementName = tokenizer.nextToken();
 250  0
             checkUnexpectedParameter( tokenizer, tokenNumber, 5 );
 251  
         }
 252  
 
 253  5
         if ( logger.isInfoEnabled() )
 254  
         {
 255  5
             logger.info( "viewName = '" + viewName + "' ; configSpec = '" + configSpecString + "' ; vobName = '"
 256  
                 + vobName + "' ; streamName = '" + streamName + "' ; elementName = '" + elementName + "'" );
 257  
         }
 258  
 
 259  5
         return configSpecString;
 260  
     }
 261  
 
 262  
     private String checkViewName( StringTokenizer tokenizer )
 263  
         throws UnknownHostException
 264  
     {
 265  4
         viewName = tokenizer.nextToken();
 266  4
         if ( viewName.length() > 0 )
 267  
         {
 268  4
             viewNameGivenByUser = true;
 269  
         }
 270  
         else
 271  
         {
 272  0
             viewName = getDefaultViewName();
 273  
         }
 274  
 
 275  4
         return tokenizer.nextToken();
 276  
     }
 277  
 
 278  
     private void checkUnexpectedParameter( StringTokenizer tokenizer, int tokenNumber, int maxTokenNumber )
 279  
     {
 280  4
         if ( tokenNumber > maxTokenNumber )
 281  
         {
 282  0
             String unexpectedToken = tokenizer.nextToken();
 283  0
             if ( logger.isInfoEnabled() )
 284  
             {
 285  0
                 logger.info( "The SCM URL contains unused parameter : " + unexpectedToken );
 286  
             }
 287  
         }
 288  4
     }
 289  
 
 290  
     private File createConfigSpecFile( String spec )
 291  
         throws URISyntaxException, MalformedURLException
 292  
     {
 293  
         File result;
 294  6
         if ( spec.indexOf( ':' ) == -1 )
 295  
         {
 296  6
             result = new File( spec );
 297  
         }
 298  
         else
 299  
         {
 300  0
             result = new File( new URI( new URL( spec ).toString() ) );
 301  
         }
 302  6
         return result;
 303  
     }
 304  
 
 305  
     /**
 306  
      * Default: ${hostname}-{user.name}-maven
 307  
      *
 308  
      * @return the default view name
 309  
      */
 310  
     private String getDefaultViewName()
 311  
         throws UnknownHostException
 312  
     {
 313  6
         String username = System.getProperty( "user.name", "nouser" );
 314  6
         String hostname = getHostName();
 315  6
         return username + "-" + hostname + "-maven";
 316  
     }
 317  
 
 318  
     private String getHostName()
 319  
         throws UnknownHostException
 320  
     {
 321  6
         return InetAddress.getLocalHost().getHostName();
 322  
     }
 323  
 
 324  
     /**
 325  
      * Returns the name of the view. If it is defined in the scm url, then it is returned as defined there.
 326  
      * If it is the default name, then the uniqueId is added
 327  
      *
 328  
      * @param uniqueId
 329  
      * @return the name of the view
 330  
      */
 331  
     public String getViewName( String uniqueId )
 332  
     {
 333  
         String result;
 334  13
         if ( viewNameGivenByUser )
 335  
         {
 336  5
             result = viewName;
 337  
         }
 338  
         else
 339  
         {
 340  8
             result = viewName + "-" + uniqueId;
 341  
         }
 342  
 
 343  13
         return result;
 344  
     }
 345  
 
 346  
     /**
 347  
      * Returns the user-supplied config spec or <code>null</code> in case it
 348  
      * should be automatically generated
 349  
      *
 350  
      * @return File or <code>null</code>
 351  
      * @see #isAutoConfigSpec()
 352  
      */
 353  
     public File getConfigSpec()
 354  
     {
 355  11
         return configSpec;
 356  
     }
 357  
 
 358  
     /**
 359  
      * Returns true when the config spec has not been supplied by the user, but
 360  
      * instead should automatically be generated by the plugin
 361  
      *
 362  
      * @return true if auto config spec
 363  
      */
 364  
     public boolean isAutoConfigSpec()
 365  
     {
 366  5
         return configSpec == null;
 367  
     }
 368  
 
 369  
     /**
 370  
      * Returns the VOB directory to be loaded when auto-generating the config
 371  
      * spec.
 372  
      *
 373  
      * @return <code>null</code> when isAutoConfigSpec() returns false;
 374  
      *         otherwise the VOB directory
 375  
      */
 376  
     public String getLoadDirectory()
 377  
     {
 378  11
         return loadDirectory;
 379  
     }
 380  
 
 381  
     public String getStreamName()
 382  
     {
 383  11
         return streamName;
 384  
     }
 385  
 
 386  
     public String getVobName()
 387  
     {
 388  11
         return vobName;
 389  
     }
 390  
 
 391  
     public String getElementName()
 392  
     {
 393  2
         return elementName;
 394  
     }
 395  
 
 396  
     public boolean hasElements()
 397  
     {
 398  0
         if ( elementName == null )
 399  
         {
 400  0
             return false;
 401  
         }
 402  
 
 403  0
         return true;
 404  
     }
 405  
 }