Coverage Report - org.apache.maven.scm.provider.jazz.command.add.JazzAddCommand
 
Classes in this File Line Coverage Branch Coverage Complexity
JazzAddCommand
21 %
11/52
12 %
4/32
5,25
 
 1  
 package org.apache.maven.scm.provider.jazz.command.add;
 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.ScmException;
 23  
 import org.apache.maven.scm.ScmFile;
 24  
 import org.apache.maven.scm.ScmFileSet;
 25  
 import org.apache.maven.scm.ScmFileStatus;
 26  
 import org.apache.maven.scm.ScmResult;
 27  
 import org.apache.maven.scm.command.add.AbstractAddCommand;
 28  
 import org.apache.maven.scm.command.add.AddScmResult;
 29  
 import org.apache.maven.scm.command.status.StatusScmResult;
 30  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 31  
 import org.apache.maven.scm.provider.jazz.command.JazzConstants;
 32  
 import org.apache.maven.scm.provider.jazz.command.JazzScmCommand;
 33  
 import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer;
 34  
 import org.apache.maven.scm.provider.jazz.command.status.JazzStatusCommand;
 35  
 
 36  
 import java.io.File;
 37  
 import java.util.ArrayList;
 38  
 import java.util.Iterator;
 39  
 import java.util.List;
 40  
 
 41  
 // RTC does not have the equivalent of the "add" goal. The closest we have is the "share" command, however
 42  
 // that only shares directories (not individual or specific files), and it is recursive (which can not be
 43  
 // switched off!).
 44  
 //
 45  
 // The Maven SCM plugin "add" goal's job is to add files to source control, but not commit them.
 46  
 // The SVN equivalent of this is "svn add", which places a file under source control (Working Copy in svn terms)
 47  
 // but does not commit them (svn commit).
 48  
 // So, this provider will use the RTC "checkin" command for the implementation of the "add" goal.
 49  
 // This will checkin the code into a remote repository workspace. It will not deliver.
 50  
 //
 51  
 // Additionally, "svn add" does not take a message, whereas commit does. Under RTC, the only way we can preserve
 52  
 // the message, is to create a changeset. So we do that in the "checkin" goal, not the "add" goal.
 53  
 // 
 54  
 // The Maven SCM plugin "add" goal is roughly equivalent to the RTC "checkin" command.
 55  
 //
 56  
 // See the following links for additional information on the RTC "checkin" command.
 57  
 // RTC 2.0.0.2:
 58  
 // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html
 59  
 // RTC 3.0:
 60  
 // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html
 61  
 // RTC 3.0.1:
 62  
 // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html
 63  
 //
 64  
 // Currently this implementation does not use the comment message.
 65  
 // Perhaps in the future this method can be used to deliver a change-set with the given comment message.
 66  
 // However some users may want the checkin goal to only check in to the desired repository workspace.
 67  
 // While some users may want the checkin goal to both check in to the desired repository workspace and deliver it to a
 68  
 // stream.
 69  
 // Currently this implementation only checks in the unresolved changes to the repository workspace.
 70  
 //
 71  
 // See the following links for additional information on the RTC "deliver" command.
 72  
 // RTC 2.0.0.2:
 73  
 // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
 74  
 // RTC 3.0:
 75  
 // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
 76  
 // RTC 3.0.1:
 77  
 // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html
 78  
 //
 79  
 
 80  
 /**
 81  
  * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
 82  
  */
 83  1
 public class JazzAddCommand
 84  
     extends AbstractAddCommand
 85  
 {
 86  
     /**
 87  
      * {@inheritDoc}
 88  
      */
 89  
     protected ScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fileSet, String message,
 90  
                                            boolean binary )
 91  
         throws ScmException
 92  
     {
 93  0
         if ( getLogger().isDebugEnabled() )
 94  
         {
 95  0
             getLogger().debug( "Executing add command..." );
 96  
         }
 97  
 
 98  
         // The message can only be used when we create a change set, which is only done on the checkin command.
 99  
         // So that can be ignored.
 100  
         // The binary flag, is not needed for RTC.
 101  0
         return executeAddCommand( repo, fileSet );
 102  
     }
 103  
 
 104  
     public AddScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fileSet )
 105  
         throws ScmException
 106  
     {
 107  
         // NOTE: THIS IS ALSO CALLED DIRECTLY FROM THE CHECKIN COMMAND.
 108  
         //
 109  
         // The "checkin" command does not produce consumable output as to which individual files were checked in. (in
 110  
         // 2.0.0.2 at least). Since only "locally modified" changes get checked in, we call a "status" command to
 111  
         // generate a list of these files.
 112  0
         File baseDir = fileSet.getBasedir();
 113  0
         File parentFolder = ( baseDir.getParentFile() != null ) ? baseDir.getParentFile() : baseDir;
 114  
 
 115  0
         List<ScmFile> changedScmFiles = new ArrayList<ScmFile>();
 116  0
         List<File> changedFiles = new ArrayList<File>();
 117  0
         List<ScmFile> commitedFiles = new ArrayList<ScmFile>();
 118  
 
 119  0
         JazzStatusCommand statusCmd = new JazzStatusCommand();
 120  0
         statusCmd.setLogger( getLogger() );
 121  0
         StatusScmResult statusCmdResult = statusCmd.executeStatusCommand( repo, fileSet );
 122  0
         List<ScmFile> statusScmFiles = statusCmdResult.getChangedFiles();
 123  
 
 124  0
         for ( Iterator<ScmFile> it = statusScmFiles.iterator(); it.hasNext(); )
 125  
         {
 126  0
             ScmFile file = (ScmFile) it.next();
 127  0
             getLogger().debug( "Iterating over statusScmFiles: " + file );
 128  0
             if ( file.getStatus() == ScmFileStatus.ADDED ||
 129  
                 file.getStatus() == ScmFileStatus.DELETED ||
 130  
                 file.getStatus() == ScmFileStatus.MODIFIED )
 131  
             {
 132  0
                 changedScmFiles.add( new ScmFile( file.getPath(), ScmFileStatus.CHECKED_IN ) );
 133  0
                 changedFiles.add( new File( parentFolder, file.getPath() ) );
 134  
             }
 135  0
         }
 136  
 
 137  0
         List<File> files = fileSet.getFileList();
 138  0
         if ( files.size() == 0 )
 139  
         {
 140  
             // Either commit all local changes
 141  0
             commitedFiles = changedScmFiles;
 142  
         }
 143  
         else
 144  
         {
 145  
             // Or commit specific files
 146  0
             for ( int i = 0; i < files.size(); i++ )
 147  
             {
 148  0
                 if ( fileExistsInFileList( (File) ( files.get( i ) ), changedFiles ) )
 149  
                 {
 150  0
                     commitedFiles.add( new ScmFile( ( (File) files.get( i ) ).getPath(), ScmFileStatus.CHECKED_IN ) );
 151  
                 }
 152  
             }
 153  
         }
 154  
 
 155  
         // Now that we have a list of files to process, we can "add" (scm checkin) them.
 156  0
         JazzAddConsumer addConsumer = new JazzAddConsumer( repo, getLogger() );
 157  0
         ErrorConsumer errConsumer = new ErrorConsumer( getLogger() );
 158  0
         JazzScmCommand command = createAddCommand( repo, fileSet );
 159  
 
 160  0
         int status = command.execute( addConsumer, errConsumer );
 161  0
         if ( status != 0 || errConsumer.hasBeenFed() )
 162  
         {
 163  0
             return new AddScmResult( command.getCommandString(),
 164  
                                      "Error code for Jazz SCM add (checkin) command - " + status,
 165  
                                      errConsumer.getOutput(), false );
 166  
         }
 167  
 
 168  0
         return new AddScmResult( command.getCommandString(), addConsumer.getFiles() );
 169  
     }
 170  
 
 171  
     public JazzScmCommand createAddCommand( ScmProviderRepository repo, ScmFileSet fileSet )
 172  
     {
 173  1
         JazzScmCommand command =
 174  
             new JazzScmCommand( JazzConstants.CMD_CHECKIN, null, repo, false, fileSet, getLogger() );
 175  
 
 176  1
         List<File> files = fileSet.getFileList();
 177  1
         if ( files != null && !files.isEmpty() )
 178  
         {
 179  1
             Iterator<File> it = files.iterator();
 180  3
             while ( it.hasNext() )
 181  
             {
 182  2
                 File file = (File) it.next();
 183  2
                 command.addArgument( file.getPath() ); // Check in only the files specified
 184  2
             }
 185  1
         }
 186  
         else
 187  
         {
 188  0
             command.addArgument( "." ); // This will check in all local changes
 189  
         }
 190  
 
 191  1
         return command;
 192  
     }
 193  
 
 194  
     private boolean fileExistsInFileList( File file, List<File> fileList )
 195  
     {
 196  0
         boolean exists = false;
 197  0
         for ( Iterator<File> it = fileList.iterator(); it.hasNext(); )
 198  
         {
 199  0
             File changedFile = (File) it.next();
 200  0
             if ( changedFile.compareTo( file ) == 0 )
 201  
             {
 202  0
                 exists = true;
 203  0
                 break;
 204  
             }
 205  0
         }
 206  0
         return exists;
 207  
     }
 208  
 
 209  
 }