Coverage Report - org.apache.maven.scm.provider.jazz.command.status.JazzStatusConsumer
 
Classes in this File Line Coverage Branch Coverage Complexity
JazzStatusConsumer
77 %
73/94
80 %
32/40
3
 
 1  
 package org.apache.maven.scm.provider.jazz.command.status;
 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.ScmFile;
 23  
 import org.apache.maven.scm.ScmFileStatus;
 24  
 import org.apache.maven.scm.log.ScmLogger;
 25  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 26  
 import org.apache.maven.scm.provider.jazz.command.consumer.AbstractRepositoryConsumer;
 27  
 import org.apache.maven.scm.provider.jazz.repository.JazzScmProviderRepository;
 28  
 import org.apache.regexp.RE;
 29  
 import org.apache.regexp.RESyntaxException;
 30  
 
 31  
 import java.util.ArrayList;
 32  
 import java.util.List;
 33  
 
 34  
 /**
 35  
  * Consume the output of the scm command for the "status" operation.
 36  
  * <p/>
 37  
  * It is normally just used to build up a list of ScmFile objects that have
 38  
  * their ScmFileStatus set.
 39  
  * This class has been expanded so that the Workspace, Component and Baseline
 40  
  * are also collected and set back in the JazzScmProviderRepository.
 41  
  * The Workspace and Component names are needed for some other commands (list,
 42  
  * for example), so we can easily get this information here.
 43  
  *
 44  
  * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
 45  
  */
 46  
 public class JazzStatusConsumer
 47  
     extends AbstractRepositoryConsumer
 48  
 {
 49  
 // We have have a workspace with no flow targets (it points to itself)
 50  
 //
 51  
 //  Workspace: (1000) "BogusRepositoryWorkspace" <-> (1000) "BogusRepositoryWorkspace"
 52  
 //    Component: (1001) "BogusComponent"
 53  
 //      Baseline: (1128) 27 "BogusTestJazz-3.0.0.40"
 54  
 //      Unresolved:
 55  
 //        d-- /BogusTest/pom.xml.releaseBackup
 56  
 //        d-- /BogusTest/release.properties
 57  
 //
 58  
 // Or, we have have one that does have a flow target (ie a stream or another workspace).
 59  
 //
 60  
 //  Workspace: (1156) "GPDBWorkspace" <-> (1157) "GPDBStream"
 61  
 //    Component: (1158) "GPDB" <-> (1157) "GPDBStream"
 62  
 //      Baseline: (1159) 1 "Initial Baseline"
 63  
 //
 64  
 // Note the (%d) numbers are aliases and are only valid for the machine/instance that made the
 65  
 // remote calls to the server. They are not to be shared across machines (ie don't make them global, public
 66  
 // or persistent).
 67  
 //
 68  
 
 69  
     //  Workspace: (1000) "BogusRepositoryWorkspace" <-> (1000) "BogusRepositoryWorkspace"
 70  
     //  Workspace: (1156) "GPDBWorkspace" <-> (1157) "GPDBStream"
 71  
     private static final String WORKSPACE_PATTERN = "\\((\\d+)\\) \"(.*)\" <-> \\((\\d+)\\) \"(.*)\"";
 72  
 
 73  
     /**
 74  
      * @see #WORKSPACE_PATTERN
 75  
      */
 76  
     private RE workspaceRegExp;
 77  
 
 78  
     //  Component: (1001) "BogusComponent"
 79  
     private static final String COMPONENT_PATTERN1 = "\\((\\d+)\\) \"(.*)\"";
 80  
 
 81  
     /**
 82  
      * @see #COMPONENT_PATTERN1
 83  
      */
 84  
     private RE componentRegExp1;
 85  
 
 86  
     //  Component: (1158) "GPDB" <-> (1157) "GPDBStream"
 87  
     //  Component: (1002) "FireDragon" <-> (1005) "MavenR3Stream Workspace" (outgoing addition)
 88  
     private static final String COMPONENT_PATTERN2 = "\\((\\d+)\\) \"(.*)\" <.*>";
 89  
 
 90  
     /**
 91  
      * @see #COMPONENT_PATTERN2
 92  
      */
 93  
     private RE componentRegExp2;
 94  
 
 95  
     //  Baseline: (1128) 27 "BogusTestJazz-3.0.0.40"
 96  
     private static final String BASELINE_PATTERN = "\\((\\d+)\\) (\\d+) \"(.*)\"";
 97  
 
 98  
     /**
 99  
      * @see #BASELINE_PATTERN
 100  
      */
 101  
     private RE baselineRegExp;
 102  
 
 103  
     // Additional data we collect. (eye catchers)
 104  
 
 105  
     /**
 106  
      * The "Status" command output line that contains the "Workspace" name.
 107  
      */
 108  
     public static final String STATUS_CMD_WORKSPACE = "Workspace:";
 109  
 
 110  
     /**
 111  
      * The "Status" command output line that contains the "Component" name.
 112  
      */
 113  
     public static final String STATUS_CMD_COMPONENT = "Component:";
 114  
 
 115  
     /**
 116  
      * The "Status" command output line that contains the "Workspace" name.
 117  
      */
 118  
     public static final String STATUS_CMD_BASELINE = "Baseline:";
 119  
 
 120  
     // File Status Commands (eye catchers)
 121  
 
 122  
     /**
 123  
      * The "Status" command status flag for a resource that has been added.
 124  
      */
 125  
     public static final String STATUS_CMD_ADD_FLAG = "a-";
 126  
 
 127  
     /**
 128  
      * The "Status" command status flag for when the content or properties of
 129  
      * a file have been modified, or the properties of a directory have changed.
 130  
      */
 131  
     public static final String STATUS_CMD_CHANGE_FLAG = "-c";
 132  
 
 133  
     /**
 134  
      * The "Status" command status flag for a resource that has been deleted.
 135  
      */
 136  
     public static final String STATUS_CMD_DELETE_FLAG = "d-";
 137  
 
 138  
     /**
 139  
      * The "Status" command status flag for a resource that has been renamed or moved.
 140  
      */
 141  
     public static final String STATUS_CMD_MOVED_FLAG = "m-";
 142  
 
 143  
     /**
 144  
      * A List of ScmFile objects that have their ScmFileStatus set.
 145  
      */
 146  5
     private List<ScmFile> fChangedFiles = new ArrayList<ScmFile>();
 147  
 
 148  
     /**
 149  
      * Constructor for our "scm status" consumer.
 150  
      *
 151  
      * @param repo   The JazzScmProviderRepository being used.
 152  
      * @param logger The ScmLogger to use.
 153  
      */
 154  
     public JazzStatusConsumer( ScmProviderRepository repo, ScmLogger logger )
 155  
     {
 156  5
         super( repo, logger );
 157  
 
 158  
         try
 159  
         {
 160  5
             workspaceRegExp = new RE( WORKSPACE_PATTERN );
 161  5
             componentRegExp1 = new RE( COMPONENT_PATTERN1 );
 162  5
             componentRegExp2 = new RE( COMPONENT_PATTERN2 );
 163  5
             baselineRegExp = new RE( BASELINE_PATTERN );
 164  
         }
 165  0
         catch ( RESyntaxException ex )
 166  
         {
 167  0
             throw new RuntimeException(
 168  
                 "INTERNAL ERROR: Could not create regexp to parse jazz scm status output. This shouldn't happen. Something is probably wrong with the oro installation.",
 169  
                 ex );
 170  5
         }
 171  5
     }
 172  
 
 173  
     /**
 174  
      * Process one line of output from the execution of the "scm status" command.
 175  
      *
 176  
      * @param line The line of output from the external command that has been pumped to us.
 177  
      * @see org.codehaus.plexus.util.cli.StreamConsumer#consumeLine(java.lang.String)
 178  
      */
 179  
     public void consumeLine( String line )
 180  
     {
 181  24
         super.consumeLine( line );
 182  24
         if ( containsWorkspace( line ) )
 183  
         {
 184  4
             extractWorkspace( line );
 185  
         }
 186  24
         if ( containsComponent( line ) )
 187  
         {
 188  4
             extractComponent( line );
 189  
         }
 190  24
         if ( containsBaseline( line ) )
 191  
         {
 192  4
             extractBaseline( line );
 193  
         }
 194  24
         if ( containsStatusFlag( line ) )
 195  
         {
 196  6
             extractChangedFile( line );
 197  
         }
 198  24
     }
 199  
 
 200  
     private boolean containsWorkspace( String line )
 201  
     {
 202  24
         return line.trim().startsWith( STATUS_CMD_WORKSPACE );
 203  
     }
 204  
 
 205  
     private void extractWorkspace( String line )
 206  
     {
 207  
         // With no stream (flow target):
 208  
         //   Workspace: (1000) "BogusRepositoryWorkspace" <-> (1000) "BogusRepositoryWorkspace"
 209  
         // With a stream:
 210  
         //   Workspace: (1156) "GPDBWorkspace" <-> (1157) "GPDBStream"
 211  
 
 212  4
         if ( workspaceRegExp.match( line ) )
 213  
         {
 214  4
             JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
 215  
 
 216  4
             int workspaceAlias = Integer.parseInt( workspaceRegExp.getParen( 1 ) );
 217  4
             String workspace = workspaceRegExp.getParen( 2 );
 218  4
             int streamAlias = Integer.parseInt( workspaceRegExp.getParen( 3 ) );
 219  4
             String stream = workspaceRegExp.getParen( 4 );
 220  4
             if ( getLogger().isDebugEnabled() )
 221  
             {
 222  0
                 getLogger().debug( "Successfully parsed \"Workspace:\" line:" );
 223  0
                 getLogger().debug( "  workspaceAlias = " + workspaceAlias );
 224  0
                 getLogger().debug( "  workspace      = " + workspace );
 225  0
                 getLogger().debug( "  streamAlias    = " + streamAlias );
 226  0
                 getLogger().debug( "  stream         = " + stream );
 227  
             }
 228  4
             jazzRepository.setWorkspaceAlias( workspaceAlias );
 229  4
             jazzRepository.setWorkspace( workspace );
 230  4
             jazzRepository.setFlowTargetAlias( streamAlias );
 231  4
             jazzRepository.setFlowTarget( stream );
 232  
         }
 233  4
     }
 234  
 
 235  
     private boolean containsComponent( String line )
 236  
     {
 237  24
         return line.trim().startsWith( STATUS_CMD_COMPONENT );
 238  
     }
 239  
 
 240  
     private void extractComponent( String line )
 241  
     {
 242  
         // With no stream (flow target):
 243  
         //     Component: (1001) "BogusComponent"
 244  
         // With a stream:
 245  
         //     Component: (1158) "GPDB" <-> (1157) "GPDBStream"
 246  
         // With some additional information:
 247  
         //     Component: (1002) "FireDragon" <-> (1005) "MavenR3Stream Workspace" (outgoing addition)
 248  
 
 249  4
         if ( componentRegExp1.match( line ) )
 250  
         {
 251  
             //     Component: (1001) "BogusComponent"
 252  4
             JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
 253  4
             int componentAlias = Integer.parseInt( componentRegExp1.getParen( 1 ) );
 254  4
             String component = componentRegExp1.getParen( 2 );
 255  4
             if ( getLogger().isDebugEnabled() )
 256  
             {
 257  0
                 getLogger().debug( "Successfully parsed \"Component:\" line:" );
 258  0
                 getLogger().debug( "  componentAlias = " + componentAlias );
 259  0
                 getLogger().debug( "  component      = " + component );
 260  
             }
 261  4
             jazzRepository.setComponent( component );
 262  
         }
 263  
 
 264  4
         if ( componentRegExp2.match( line ) )
 265  
         {
 266  
             //     Component: (1158) "GPDB" <-> (1157) "GPDBStream"
 267  2
             JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
 268  2
             int componentAlias = Integer.parseInt( componentRegExp2.getParen( 1 ) );
 269  2
             String component = componentRegExp2.getParen( 2 );
 270  2
             if ( getLogger().isDebugEnabled() )
 271  
             {
 272  0
                 getLogger().debug( "Successfully parsed \"Component:\" line:" );
 273  0
                 getLogger().debug( "  componentAlias = " + componentAlias );
 274  0
                 getLogger().debug( "  component      = " + component );
 275  
             }
 276  2
             jazzRepository.setComponent( component );
 277  
         }
 278  4
     }
 279  
 
 280  
     private boolean containsBaseline( String line )
 281  
     {
 282  24
         return line.trim().startsWith( STATUS_CMD_BASELINE );
 283  
     }
 284  
 
 285  
     private void extractBaseline( String line )
 286  
     {
 287  
         // Baseline: (1128) 27 "BogusTestJazz-3.0.0.40"
 288  
 
 289  4
         if ( baselineRegExp.match( line ) )
 290  
         {
 291  4
             JazzScmProviderRepository jazzRepository = (JazzScmProviderRepository) getRepository();
 292  
 
 293  4
             int baselineAlias = Integer.parseInt( baselineRegExp.getParen( 1 ) );
 294  4
             int baselineId = Integer.parseInt( baselineRegExp.getParen( 2 ) );
 295  4
             String baseline = baselineRegExp.getParen( 3 );
 296  4
             if ( getLogger().isDebugEnabled() )
 297  
             {
 298  0
                 getLogger().debug( "Successfully parsed \"Baseline:\" line:" );
 299  0
                 getLogger().debug( "  baselineAlias = " + baselineAlias );
 300  0
                 getLogger().debug( "  baselineId    = " + baselineId );
 301  0
                 getLogger().debug( "  baseline      = " + baseline );
 302  
             }
 303  4
             jazzRepository.setBaseline( baseline );
 304  
         }
 305  4
     }
 306  
 
 307  
     private boolean containsStatusFlag( String line )
 308  
     {
 309  24
         boolean containsStatusFlag = false;
 310  
 
 311  24
         if ( line.trim().length() > 2 )
 312  
         {
 313  23
             String flag = line.trim().substring( 0, 2 );
 314  23
             if ( STATUS_CMD_ADD_FLAG.equals( flag ) ||
 315  
                 STATUS_CMD_CHANGE_FLAG.equals( flag ) ||
 316  
                 STATUS_CMD_DELETE_FLAG.equals( flag ) )
 317  
             {
 318  6
                 containsStatusFlag = true;
 319  
             }
 320  
         }
 321  24
         return containsStatusFlag;
 322  
     }
 323  
 
 324  
     private void extractChangedFile( String line )
 325  
     {
 326  6
         String flag = line.trim().substring( 0, 2 );
 327  6
         String filePath = line.trim().substring( 3 ).trim();
 328  6
         ScmFileStatus status = ScmFileStatus.UNKNOWN;
 329  
 
 330  6
         if ( STATUS_CMD_ADD_FLAG.equals( flag ) )
 331  
         {
 332  3
             status = ScmFileStatus.ADDED;
 333  
         }
 334  
 
 335  6
         if ( STATUS_CMD_CHANGE_FLAG.equals( flag ) )
 336  
         {
 337  1
             status = ScmFileStatus.MODIFIED;
 338  
         }
 339  
 
 340  6
         if ( STATUS_CMD_DELETE_FLAG.equals( flag ) )
 341  
         {
 342  2
             status = ScmFileStatus.DELETED;
 343  
         }
 344  
 
 345  6
         if ( getLogger().isDebugEnabled() )
 346  
         {
 347  0
             getLogger().debug( " Line               : '" + line + "'" );
 348  0
             getLogger().debug( " Extracted filePath : '" + filePath + "'" );
 349  0
             getLogger().debug( " Extracted     flag : '" + flag + "'" );
 350  0
             getLogger().debug( " Extracted   status : '" + status + "'" );
 351  
         }
 352  
 
 353  6
         fChangedFiles.add( new ScmFile( filePath, status ) );
 354  6
     }
 355  
 
 356  
     public List<ScmFile> getChangedFiles()
 357  
     {
 358  1
         return fChangedFiles;
 359  
     }
 360  
 }