You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kr...@apache.org on 2013/11/23 10:49:31 UTC

[08/10] Added .gitattributes to enforce proper line endings, remaining incorrect files fixed.

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/8ad9801d/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/Sandbox.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/Sandbox.java b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/Sandbox.java
index 73a1b92..2f9c301 100644
--- a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/Sandbox.java
+++ b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/Sandbox.java
@@ -1,851 +1,851 @@
-package org.apache.maven.scm.provider.integrity;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import com.mks.api.Command;
-import com.mks.api.MultiValue;
-import com.mks.api.Option;
-import com.mks.api.response.APIException;
-import com.mks.api.response.Field;
-import com.mks.api.response.Item;
-import com.mks.api.response.Response;
-import com.mks.api.response.WorkItem;
-import com.mks.api.response.WorkItemIterator;
-import com.mks.api.si.SIModelTypeName;
-import org.apache.maven.scm.ChangeFile;
-import org.apache.maven.scm.ChangeSet;
-import org.apache.maven.scm.ScmFile;
-import org.apache.maven.scm.ScmFileStatus;
-import org.apache.maven.scm.command.changelog.ChangeLogSet;
-import org.codehaus.plexus.util.StringUtils;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class represents an MKS Integrity Sandbox and provides an encapsulation
- * for executing typical Sandbox operations
- *
- * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
- * @version $Id: Sandbox.java 1.11 2011/08/22 13:06:50EDT Cletus D'Souza (dsouza) Exp  $
- * @since 1.6
- */
-public class Sandbox
-{
-    // Our date format
-    public static final SimpleDateFormat RLOG_DATEFORMAT = new SimpleDateFormat( "MMMMM d, yyyy - h:mm:ss a" );
-
-    // File Separator
-    private String fs = System.getProperty( "file.separator" );
-
-    // MKS API Session Object
-    private APISession api;
-
-    // Other sandbox specific class variables
-    private Project siProject;
-
-    private String sandboxDir;
-
-    private String cpid;
-
-    // Flag to indicate the overall add operation was successful
-    private boolean addSuccess;
-
-    // Flag to indicate the overall check-in operation was successful
-    private boolean ciSuccess;
-
-    /**
-     * Fixes the default includes/excludes patterns for compatibility with MKS Integrity's 'si viewnonmembers' command
-     *
-     * @param pattern String pattern representing the includes/excludes file/directory list
-     */
-    public static String formatFilePatterns( String pattern )
-    {
-        StringBuilder sb = new StringBuilder();
-        if ( null != pattern && pattern.length() > 0 )
-        {
-            String[] tokens = StringUtils.split( pattern, "," );
-            for ( int i = 0; i < tokens.length; i++ )
-            {
-                String tkn = tokens[i].trim();
-                if ( tkn.indexOf( "file:" ) != 0 && tkn.indexOf( "dir:" ) != 0 )
-                {
-                    sb.append( tkn.indexOf( '.' ) > 0
-                                   ? StringUtils.replaceOnce( tkn, "**/", "file:" )
-                                   : StringUtils.replaceOnce( tkn, "**/", "dir:" ) );
-                }
-                else
-                {
-                    sb.append( tkn );
-                }
-                sb.append( i < tokens.length ? "," : "" );
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * The Sandbox constructor
-     *
-     * @param api       MKS API Session object
-     * @param cmProject Project object
-     * @param dir       Absolute path to the location for the Sandbox directory
-     */
-    public Sandbox( APISession api, Project cmProject, String dir )
-    {
-        siProject = cmProject;
-        sandboxDir = dir;
-        this.api = api;
-        cpid = System.getProperty( "maven.scm.integrity.cpid" );
-        cpid = ( ( null == cpid || cpid.length() == 0 ) ? ":none" : cpid );
-        addSuccess = true;
-        ciSuccess = true;
-    }
-
-    /**
-     * Attempts to figure out if the current sandbox already exists and is valid
-     *
-     * @param sandbox The client-side fully qualified path to the sandbox pj
-     * @return true/false depending on whether or not this location has a valid sandbox
-     * @throws APIException
-     */
-    private boolean isValidSandbox( String sandbox )
-        throws APIException
-    {
-        Command cmd = new Command( Command.SI, "sandboxinfo" );
-        cmd.addOption( new Option( "sandbox", sandbox ) );
-
-        api.getLogger().debug( "Validating existing sandbox: " + sandbox );
-        Response res = api.runCommand( cmd );
-        WorkItemIterator wit = res.getWorkItems();
-        try
-        {
-            WorkItem wi = wit.next();
-            return wi.getField( "fullConfigSyntax" ).getValueAsString().equalsIgnoreCase(
-                siProject.getConfigurationPath() );
-        }
-        catch ( APIException aex )
-        {
-            ExceptionHandler eh = new ExceptionHandler( aex );
-            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
-            api.getLogger().debug( eh.getCommand() + " completed with exit code " + eh.getExitCode() );
-            return false;
-        }
-    }
-
-    /**
-     * Inspects the MKS API Response object's Item field to determine whether or nor a working file delta exists
-     *
-     * @param wfdelta MKS API Response object's Item representing the Working File Delta
-     * @return true if the working file is a delta; false otherwise
-     */
-    private boolean isDelta( Item wfdelta )
-    {
-        // Return false if there is no working file
-        if ( wfdelta.getField( "isDelta" ).getBoolean().booleanValue() )
-        {
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-
-    /**
-     * Executes a 'si add' command using the message for the description
-     *
-     * @param memberFile Full path to the new member's location
-     * @param message    Description for the new member's archive
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    private Response add( File memberFile, String message )
-        throws APIException
-    {
-        // Setup the add command
-        api.getLogger().info( "Adding member: " + memberFile.getAbsolutePath() );
-        Command siAdd = new Command( Command.SI, "add" );
-        siAdd.addOption( new Option( "onExistingArchive", "sharearchive" ) );
-        siAdd.addOption( new Option( "cpid", cpid ) );
-        if ( null != message && message.length() > 0 )
-        {
-            siAdd.addOption( new Option( "description", message ) );
-        }
-        siAdd.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        siAdd.addSelection( memberFile.getName() );
-        return api.runCommand( siAdd );
-    }
-
-    /**
-     * Executes a 'si ci' command using the relativeName for the member name and message for the description
-     *
-     * @param memberFile   Full path to the member's current sandbox location
-     * @param relativeName Relative path from the nearest subproject or project
-     * @param message      Description for checking in the new update
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    private Response checkin( File memberFile, String relativeName, String message )
-        throws APIException
-    {
-        // Setup the check-in command
-        api.getLogger().info( "Checking in member:  " + memberFile.getAbsolutePath() );
-        Command sici = new Command( Command.SI, "ci" );
-        sici.addOption( new Option( "cpid", cpid ) );
-        if ( null != message && message.length() > 0 )
-        {
-            sici.addOption( new Option( "description", message ) );
-        }
-        sici.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        sici.addSelection( relativeName );
-        return api.runCommand( sici );
-    }
-
-    /**
-     * Executes a 'si drop' command using the relativeName for the member name
-     *
-     * @param memberFile   Full path to the member's current sandbox location
-     * @param relativeName Relative path from the nearest subproject or project
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    private Response dropMember( File memberFile, String relativeName )
-        throws APIException
-    {
-        // Setup the drop command
-        api.getLogger().info( "Dropping member " + memberFile.getAbsolutePath() );
-        Command siDrop = new Command( Command.SI, "drop" );
-        siDrop.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        siDrop.addOption( new Option( "noconfirm" ) );
-        siDrop.addOption( new Option( "cpid", cpid ) );
-        siDrop.addOption( new Option( "delete" ) );
-        siDrop.addSelection( relativeName );
-        return api.runCommand( siDrop );
-    }
-
-    /**
-     * Executes a 'si diff' command to see if the working file has actually changed.  Even though the
-     * working file delta might be true, that doesn't always mean the file has actually changed.
-     *
-     * @param memberFile   Full path to the member's current sandbox location
-     * @param relativeName Relative path from the nearest subproject or project
-     * @return MKS API Response object
-     */
-    private boolean hasMemberChanged( File memberFile, String relativeName )
-    {
-        // Setup the differences command
-        Command siDiff = new Command( Command.SI, "diff" );
-        siDiff.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        siDiff.addSelection( relativeName );
-        try
-        {
-            // Run the diff command...
-            Response res = api.runCommand( siDiff );
-            try
-            {
-                // Return the changed flag...
-                return res.getWorkItems().next().getResult().getField( "resultant" ).getItem().getField(
-                    "different" ).getBoolean().booleanValue();
-            }
-            catch ( NullPointerException npe )
-            {
-                api.getLogger().warn( "Couldn't figure out differences for file: " + memberFile.getAbsolutePath() );
-                api.getLogger().warn(
-                    "Null value found along response object for WorkItem/Result/Field/Item/Field.getBoolean()" );
-                api.getLogger().warn( "Proceeding with the assumption that the file has changed!" );
-            }
-        }
-        catch ( APIException aex )
-        {
-            ExceptionHandler eh = new ExceptionHandler( aex );
-            api.getLogger().warn( "Couldn't figure out differences for file: " + memberFile.getAbsolutePath() );
-            api.getLogger().warn( eh.getMessage() );
-            api.getLogger().warn( "Proceeding with the assumption that the file has changed!" );
-            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
-        }
-        return true;
-    }
-
-    /**
-     * Returns the full path name to the current Sandbox directory
-     *
-     * @return
-     */
-    public String getSandboxDir()
-    {
-        return sandboxDir;
-    }
-
-    /**
-     * Executes a 'si lock' command using the relativeName of the file
-     *
-     * @param memberFile   Full path to the member's current sandbox location
-     * @param relativeName Relative path from the nearest subproject or project
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    public Response lock( File memberFile, String relativeName )
-        throws APIException
-    {
-        // Setup the lock command
-        api.getLogger().debug( "Locking member: " + memberFile.getAbsolutePath() );
-        Command siLock = new Command( Command.SI, "lock" );
-        siLock.addOption( new Option( "revision", ":member" ) );
-        siLock.addOption( new Option( "cpid", cpid ) );
-        siLock.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        siLock.addSelection( relativeName );
-        // Execute the lock command
-        return api.runCommand( siLock );
-    }
-
-    /**
-     * Executes a 'si unlock' command using the relativeName of the file
-     *
-     * @param memberFile   Full path to the member's current sandbox location
-     * @param relativeName Relative path from the nearest subproject or project
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    public Response unlock( File memberFile, String relativeName )
-        throws APIException
-    {
-        // Setup the unlock command
-        api.getLogger().debug( "Unlocking member: " + memberFile.getAbsolutePath() );
-        Command siUnlock = new Command( Command.SI, "unlock" );
-        siUnlock.addOption( new Option( "revision", ":member" ) );
-        siUnlock.addOption( new Option( "action", "remove" ) );
-        siUnlock.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
-        siUnlock.addSelection( relativeName );
-        // Execute the unlock command
-        return api.runCommand( siUnlock );
-    }
-
-    /**
-     * Removes the registration for the Sandbox in the user's profile
-     *
-     * @return The API Response associated with executing this command
-     * @throws APIException
-     */
-    public Response drop()
-        throws APIException
-    {
-        File project = new File( siProject.getProjectName() );
-        File sandboxpj = new File( sandboxDir + fs + project.getName() );
-
-        // Check to see if the sandbox file already exists and its OK to use
-        api.getLogger().debug( "Sandbox Project File: " + sandboxpj.getAbsolutePath() );
-        Command cmd = new Command( Command.SI, "dropsandbox" );
-        cmd.addOption( new Option( "delete", "members" ) );
-        cmd.addOption( new Option( "sandbox", sandboxpj.getAbsolutePath() ) );
-        cmd.addOption( new Option( "cwd", sandboxDir ) );
-        return api.runCommand( cmd );
-    }
-
-    /**
-     * Creates a new Sandbox in the sandboxDir specified
-     *
-     * @return true if the operation is successful; false otherwise
-     * @throws APIException
-     */
-    public boolean create()
-        throws APIException
-    {
-        File project = new File( siProject.getProjectName() );
-        File sandboxpj = new File( sandboxDir + fs + project.getName() );
-
-        // Check to see if the sandbox file already exists and its OK to use
-        api.getLogger().debug( "Sandbox Project File: " + sandboxpj.getAbsolutePath() );
-        if ( sandboxpj.isFile() )
-        {
-            // Validate this sandbox
-            if ( isValidSandbox( sandboxpj.getAbsolutePath() ) )
-            {
-                api.getLogger().debug(
-                    "Reusing existing Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
-                return true;
-            }
-            else
-            {
-                api.getLogger().error(
-                    "An invalid Sandbox exists in " + sandboxDir + ". Please provide a different location!" );
-                return false;
-            }
-        }
-        else // Create a new sandbox in the location specified
-        {
-            api.getLogger().debug(
-                "Creating Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
-            try
-            {
-                Command cmd = new Command( Command.SI, "createsandbox" );
-                cmd.addOption( new Option( "recurse" ) );
-                cmd.addOption( new Option( "nopopulate" ) );
-                cmd.addOption( new Option( "project", siProject.getConfigurationPath() ) );
-                cmd.addOption( new Option( "cwd", sandboxDir ) );
-                api.runCommand( cmd );
-            }
-            catch ( APIException aex )
-            {
-                // Check to see if this exception is due an existing sandbox registry entry
-                ExceptionHandler eh = new ExceptionHandler( aex );
-                if ( eh.getMessage().indexOf( "There is already a registered entry" ) > 0 )
-                {
-                    // This will re-validate the sandbox, if Maven blew away the old directory
-                    return create();
-                }
-                else
-                {
-                    throw aex;
-                }
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Resynchronizes an existing Sandbox
-     * Assumes that the create() call has already been made to validate this sandbox
-     *
-     * @throws APIException
-     */
-    public Response resync()
-        throws APIException
-    {
-        api.getLogger().debug(
-            "Resynchronizing Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
-        Command cmd = new Command( Command.SI, "resync" );
-        cmd.addOption( new Option( "recurse" ) );
-        cmd.addOption( new Option( "populate" ) );
-        cmd.addOption( new Option( "cwd", sandboxDir ) );
-        return api.runCommand( cmd );
-    }
-
-    /**
-     * Executes a 'si makewritable' command to allow edits to all files in the Sandbox directory
-     *
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    public Response makeWriteable()
-        throws APIException
-    {
-        api.getLogger().debug(
-            "Setting files to writeable in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
-        Command cmd = new Command( Command.SI, "makewritable" );
-        cmd.addOption( new Option( "recurse" ) );
-        cmd.addOption( new Option( "cwd", sandboxDir ) );
-        return api.runCommand( cmd );
-    }
-
-    /**
-     * Executes a 'si revert' command to roll back changes to all files in the Sandbox directory
-     *
-     * @return MKS API Response object
-     * @throws APIException
-     */
-    public Response revertMembers()
-        throws APIException
-    {
-        api.getLogger().debug(
-            "Reverting changes in sandbox " + sandboxDir + " for project " + siProject.getConfigurationPath() );
-        Command cmd = new Command( Command.SI, "revert" );
-        cmd.addOption( new Option( "recurse" ) );
-        cmd.addOption( new Option( "cwd", sandboxDir ) );
-        return api.runCommand( cmd );
-    }
-
-    /**
-     * Executes a 'si viewnonmembers' command filtering the results using the exclude and include lists
-     *
-     * @param exclude Pattern containing the exclude file list
-     * @param include Pattern containing the include file list
-     * @return List of ScmFile objects representing the new files in the Sandbox
-     * @throws APIException
-     */
-    public List<ScmFile> getNewMembers( String exclude, String include )
-        throws APIException
-    {
-        // Store a list of files that were added to the repository
-        List<ScmFile> filesAdded = new ArrayList<ScmFile>();
-        Command siViewNonMem = new Command( Command.SI, "viewnonmembers" );
-        siViewNonMem.addOption( new Option( "recurse" ) );
-        if ( null != exclude && exclude.length() > 0 )
-        {
-            siViewNonMem.addOption( new Option( "exclude", exclude ) );
-        }
-        if ( null != include && include.length() > 0 )
-        {
-            siViewNonMem.addOption( new Option( "include", include ) );
-        }
-        siViewNonMem.addOption( new Option( "noincludeFormers" ) );
-        siViewNonMem.addOption( new Option( "cwd", sandboxDir ) );
-        Response response = api.runCommand( siViewNonMem );
-        for ( WorkItemIterator wit = response.getWorkItems(); wit.hasNext(); )
-        {
-            filesAdded.add(
-                new ScmFile( wit.next().getField( "absolutepath" ).getValueAsString(), ScmFileStatus.ADDED ) );
-        }
-        return filesAdded;
-
-    }
-
-    /**
-     * Adds a list of files to the MKS Integrity SCM Project
-     *
-     * @param exclude Pattern containing the exclude file list
-     * @param include Pattern containing the include file list
-     * @param message Description for the member's archive
-     * @return
-     */
-    public List<ScmFile> addNonMembers( String exclude, String include, String message )
-    {
-        // Re-initialize the overall addSuccess to be true for now
-        addSuccess = true;
-        // Store a list of files that were actually added to the repository
-        List<ScmFile> filesAdded = new ArrayList<ScmFile>();
-        api.getLogger().debug( "Looking for new members in sandbox dir: " + sandboxDir );
-        try
-        {
-            List<ScmFile> newFileList = getNewMembers( exclude, include );
-            for ( Iterator<ScmFile> sit = newFileList.iterator(); sit.hasNext(); )
-            {
-                try
-                {
-                    ScmFile localFile = sit.next();
-                    // Attempt to add the file to the Integrity repository
-                    add( new File( localFile.getPath() ), message );
-                    // If it was a success, then add it to the list of files that were actually added
-                    filesAdded.add( localFile );
-                }
-                catch ( APIException aex )
-                {
-                    // Set the addSuccess to false, since we ran into a problem
-                    addSuccess = false;
-                    ExceptionHandler eh = new ExceptionHandler( aex );
-                    api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
-                    api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
-                }
-            }
-        }
-        catch ( APIException aex )
-        {
-            // Set the addSuccess to false, since we ran into a problem
-            addSuccess = false;
-            ExceptionHandler eh = new ExceptionHandler( aex );
-            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
-            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
-        }
-        return filesAdded;
-    }
-
-    /**
-     * Returns the overall success of the add operation
-     *
-     * @return
-     */
-    public boolean getOverallAddSuccess()
-    {
-        return addSuccess;
-    }
-
-    /**
-     * Inspects the MKS API Response object's Item field to determine whether or nor a working file exists
-     *
-     * @param wfdelta MKS API Response object's Item representing the Working File Delta
-     * @return
-     */
-    public boolean hasWorkingFile( Item wfdelta )
-    {
-        // Return false if there is no working file
-        if ( wfdelta.getField( "noWorkingFile" ).getBoolean().booleanValue() )
-        {
-            return false;
-        }
-        else
-        {
-            return true;
-        }
-    }
-
-    /**
-     * Executes a 'si viewsandbox' and parses the output for changed or dropped working files
-     *
-     * @return A list of MKS API Response WorkItem objects representing the changes in the Sandbox
-     * @throws APIException
-     */
-    public List<WorkItem> getChangeList()
-        throws APIException
-    {
-        // Store a list of files that were changed/removed to the repository
-        List<WorkItem> changedFiles = new ArrayList<WorkItem>();
-        // Setup the view sandbox command to figure out what has changed...
-        Command siViewSandbox = new Command( Command.SI, "viewsandbox" );
-        // Create the --fields option
-        MultiValue mv = new MultiValue( "," );
-        mv.add( "name" );
-        mv.add( "context" );
-        mv.add( "wfdelta" );
-        mv.add( "memberarchive" );
-        siViewSandbox.addOption( new Option( "fields", mv ) );
-        siViewSandbox.addOption( new Option( "recurse" ) );
-        siViewSandbox.addOption( new Option( "noincludeDropped" ) );
-        siViewSandbox.addOption( new Option( "filterSubs" ) );
-        siViewSandbox.addOption( new Option( "cwd", sandboxDir ) );
-
-        // Run the view sandbox command
-        Response r = api.runCommand( siViewSandbox );
-        // Check-in all changed files, drop all members with missing working files
-        for ( WorkItemIterator wit = r.getWorkItems(); wit.hasNext(); )
-        {
-            WorkItem wi = wit.next();
-            api.getLogger().debug( "Inspecting file: " + wi.getField( "name" ).getValueAsString() );
-
-            if ( wi.getModelType().equals( SIModelTypeName.MEMBER ) )
-            {
-                Item wfdeltaItem = (Item) wi.getField( "wfdelta" ).getValue();
-                // Proceed with this entry only if it is an actual working file delta
-                if ( isDelta( wfdeltaItem ) )
-                {
-                    File memberFile = new File( wi.getField( "name" ).getValueAsString() );
-                    if ( hasWorkingFile( wfdeltaItem ) )
-                    {
-                        // Only report on files that have actually changed...
-                        if ( hasMemberChanged( memberFile, wi.getId() ) )
-                        {
-                            changedFiles.add( wi );
-                        }
-                    }
-                    else
-                    {
-                        // Also report on dropped files
-                        changedFiles.add( wi );
-                    }
-                }
-            }
-        }
-        return changedFiles;
-    }
-
-    /**
-     * Wrapper function to check-in all changes and drop members associated with missing working files
-     *
-     * @param message Description for the changes
-     * @return
-     */
-    public List<ScmFile> checkInUpdates( String message )
-    {
-        // Re-initialize the overall ciSuccess to be true for now
-        ciSuccess = true;
-        // Store a list of files that were changed/removed to the repository
-        List<ScmFile> changedFiles = new ArrayList<ScmFile>();
-        api.getLogger().debug( "Looking for changed and dropped members in sandbox dir: " + sandboxDir );
-
-        try
-        {
-            // Let the list of changed files
-            List<WorkItem> changeList = getChangeList();
-            // Check-in all changed files, drop all members with missing working files
-            for ( Iterator<WorkItem> wit = changeList.iterator(); wit.hasNext(); )
-            {
-                try
-                {
-                    WorkItem wi = wit.next();
-                    File memberFile = new File( wi.getField( "name" ).getValueAsString() );
-                    // Check-in files that have actually changed...
-                    if ( hasWorkingFile( (Item) wi.getField( "wfdelta" ).getValue() ) )
-                    {
-                        // Lock each member as you go...
-                        lock( memberFile, wi.getId() );
-                        // Commit the changes...
-                        checkin( memberFile, wi.getId(), message );
-                        // Update the changed file list
-                        changedFiles.add( new ScmFile( memberFile.getAbsolutePath(), ScmFileStatus.CHECKED_IN ) );
-                    }
-                    else
-                    {
-                        // Drop the member if there is no working file
-                        dropMember( memberFile, wi.getId() );
-                        // Update the changed file list
-                        changedFiles.add( new ScmFile( memberFile.getAbsolutePath(), ScmFileStatus.DELETED ) );
-                    }
-                }
-                catch ( APIException aex )
-                {
-                    // Set the ciSuccess to false, since we ran into a problem
-                    ciSuccess = false;
-                    ExceptionHandler eh = new ExceptionHandler( aex );
-                    api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
-                    api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
-                }
-            }
-        }
-        catch ( APIException aex )
-        {
-            // Set the ciSuccess to false, since we ran into a problem
-            ciSuccess = false;
-            ExceptionHandler eh = new ExceptionHandler( aex );
-            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
-            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
-        }
-
-        return changedFiles;
-    }
-
-    /**
-     * Returns the overall success of the check-in operation
-     *
-     * @return
-     */
-    public boolean getOverallCheckInSuccess()
-    {
-        return ciSuccess;
-    }
-
-    /**
-     * Creates one subproject per directory, as required.
-     *
-     * @param dirPath A relative path structure of folders
-     * @return Response containing the result for the created subproject
-     * @throws APIException
-     */
-    public Response createSubproject( String dirPath )
-        throws APIException
-    {
-        // Setup the create subproject command
-        api.getLogger().debug( "Creating subprojects for: " + dirPath + "/project.pj" );
-        Command siCreateSubproject = new Command( Command.SI, "createsubproject" );
-        siCreateSubproject.addOption( new Option( "cpid", cpid ) );
-        siCreateSubproject.addOption( new Option( "createSubprojects" ) );
-        siCreateSubproject.addOption( new Option( "cwd", sandboxDir ) );
-        siCreateSubproject.addSelection( dirPath + "/project.pj" );
-        // Execute the create subproject command
-        return api.runCommand( siCreateSubproject );
-    }
-
-    /**
-     * Executes the 'si rlog' command to generate a list of changed revision found between startDate and endDate
-     *
-     * @param startDate The date range for the beginning of the operation
-     * @param endDate   The date range for the end of the operation
-     * @return ChangeLogSet containing a list of changes grouped by Change Pacakge ID
-     * @throws APIException
-     */
-    public ChangeLogSet getChangeLog( Date startDate, Date endDate )
-        throws APIException
-    {
-        // Initialize our return object
-        ChangeLogSet changeLog = new ChangeLogSet( startDate, endDate );
-        // By default we're going to group-by change package
-        // Non change package changes will be lumped into one big Change Set
-        Hashtable<String, ChangeSet> changeSetHash = new Hashtable<String, ChangeSet>();
-
-        // Lets prepare our si rlog command for execution
-        Command siRlog = new Command( Command.SI, "rlog" );
-        siRlog.addOption( new Option( "recurse" ) );
-        MultiValue rFilter = new MultiValue( ":" );
-        rFilter.add( "daterange" );
-        rFilter.add( "'" + RLOG_DATEFORMAT.format( startDate ) + "'-'" + RLOG_DATEFORMAT.format( endDate ) + "'" );
-        siRlog.addOption( new Option( "rfilter", rFilter ) );
-        siRlog.addOption( new Option( "cwd", sandboxDir ) );
-        // Execute the si rlog command
-        Response response = api.runCommand( siRlog );
-        for ( WorkItemIterator wit = response.getWorkItems(); wit.hasNext(); )
-        {
-            WorkItem wi = wit.next();
-            String memberName = wi.getContext();
-            // We're going to have to do a little dance to get the correct server file name
-            memberName = memberName.substring( 0, memberName.lastIndexOf( '/' ) );
-            memberName = memberName + '/' + wi.getId();
-            memberName = memberName.replace( '\\', '/' );
-            // Now lets get the revisions for this file
-            Field revisionsFld = wi.getField( "revisions" );
-            if ( null != revisionsFld && revisionsFld.getDataType().equals( Field.ITEM_LIST_TYPE )
-                && null != revisionsFld.getList() )
-            {
-                @SuppressWarnings( "unchecked" ) List<Item> revList = revisionsFld.getList();
-                for ( Iterator<Item> lit = revList.iterator(); lit.hasNext(); )
-                {
-                    Item revisionItem = lit.next();
-                    String revision = revisionItem.getId();
-                    String author = revisionItem.getField( "author" ).getItem().getId();
-                    // Attempt to get the full name, if available
-                    try
-                    {
-                        author = revisionItem.getField( "author" ).getItem().getField( "fullname" ).getValueAsString();
-                    }
-                    catch ( NullPointerException npe )
-                    { /* ignore */ }
-                    String cpid = ":none";
-                    // Attempt to get the cpid for this revision
-                    try
-                    {
-                        cpid = revisionItem.getField( "cpid" ).getItem().getId();
-                    }
-                    catch ( NullPointerException npe )
-                    { /* ignore */ }
-                    // Get the Change Package summary for this revision
-                    String comment = cpid + ": " + revisionItem.getField( "cpsummary" ).getValueAsString();
-                    // Get the date associated with this revision
-                    Date date = revisionItem.getField( "date" ).getDateTime();
-
-                    // Lets create our ChangeFile based on the information we've gathered so far
-                    ChangeFile changeFile = new ChangeFile( memberName, revision );
-
-                    // Check to see if we already have a ChangeSet grouping for this revision
-                    ChangeSet changeSet = changeSetHash.get( cpid );
-                    if ( null != changeSet )
-                    {
-                        // Set the date of the ChangeSet to the oldest entry
-                        if ( changeSet.getDate().after( date ) )
-                        {
-                            changeSet.setDate( date );
-                        }
-                        // Add the new ChangeFile
-                        changeSet.addFile( changeFile );
-                        // Update the changeSetHash
-                        changeSetHash.put( cpid, changeSet );
-                    }
-                    else // Create a new ChangeSet grouping and add the ChangeFile
-                    {
-                        List<ChangeFile> changeFileList = new ArrayList<ChangeFile>();
-                        changeFileList.add( changeFile );
-                        changeSet = new ChangeSet( date, comment, author, changeFileList );
-                        // Update the changeSetHash with an initial entry for the cpid
-                        changeSetHash.put( cpid, changeSet );
-                    }
-                }
-            }
-
-        }
-
-        // Update the Change Log with the Change Sets
-        List<ChangeSet> changeSetList = new ArrayList<ChangeSet>();
-        changeSetList.addAll( changeSetHash.values() );
-        changeLog.setChangeSets( changeSetList );
-
-        return changeLog;
-    }
+package org.apache.maven.scm.provider.integrity;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.mks.api.Command;
+import com.mks.api.MultiValue;
+import com.mks.api.Option;
+import com.mks.api.response.APIException;
+import com.mks.api.response.Field;
+import com.mks.api.response.Item;
+import com.mks.api.response.Response;
+import com.mks.api.response.WorkItem;
+import com.mks.api.response.WorkItemIterator;
+import com.mks.api.si.SIModelTypeName;
+import org.apache.maven.scm.ChangeFile;
+import org.apache.maven.scm.ChangeSet;
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileStatus;
+import org.apache.maven.scm.command.changelog.ChangeLogSet;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This class represents an MKS Integrity Sandbox and provides an encapsulation
+ * for executing typical Sandbox operations
+ *
+ * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
+ * @version $Id: Sandbox.java 1.11 2011/08/22 13:06:50EDT Cletus D'Souza (dsouza) Exp  $
+ * @since 1.6
+ */
+public class Sandbox
+{
+    // Our date format
+    public static final SimpleDateFormat RLOG_DATEFORMAT = new SimpleDateFormat( "MMMMM d, yyyy - h:mm:ss a" );
+
+    // File Separator
+    private String fs = System.getProperty( "file.separator" );
+
+    // MKS API Session Object
+    private APISession api;
+
+    // Other sandbox specific class variables
+    private Project siProject;
+
+    private String sandboxDir;
+
+    private String cpid;
+
+    // Flag to indicate the overall add operation was successful
+    private boolean addSuccess;
+
+    // Flag to indicate the overall check-in operation was successful
+    private boolean ciSuccess;
+
+    /**
+     * Fixes the default includes/excludes patterns for compatibility with MKS Integrity's 'si viewnonmembers' command
+     *
+     * @param pattern String pattern representing the includes/excludes file/directory list
+     */
+    public static String formatFilePatterns( String pattern )
+    {
+        StringBuilder sb = new StringBuilder();
+        if ( null != pattern && pattern.length() > 0 )
+        {
+            String[] tokens = StringUtils.split( pattern, "," );
+            for ( int i = 0; i < tokens.length; i++ )
+            {
+                String tkn = tokens[i].trim();
+                if ( tkn.indexOf( "file:" ) != 0 && tkn.indexOf( "dir:" ) != 0 )
+                {
+                    sb.append( tkn.indexOf( '.' ) > 0
+                                   ? StringUtils.replaceOnce( tkn, "**/", "file:" )
+                                   : StringUtils.replaceOnce( tkn, "**/", "dir:" ) );
+                }
+                else
+                {
+                    sb.append( tkn );
+                }
+                sb.append( i < tokens.length ? "," : "" );
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * The Sandbox constructor
+     *
+     * @param api       MKS API Session object
+     * @param cmProject Project object
+     * @param dir       Absolute path to the location for the Sandbox directory
+     */
+    public Sandbox( APISession api, Project cmProject, String dir )
+    {
+        siProject = cmProject;
+        sandboxDir = dir;
+        this.api = api;
+        cpid = System.getProperty( "maven.scm.integrity.cpid" );
+        cpid = ( ( null == cpid || cpid.length() == 0 ) ? ":none" : cpid );
+        addSuccess = true;
+        ciSuccess = true;
+    }
+
+    /**
+     * Attempts to figure out if the current sandbox already exists and is valid
+     *
+     * @param sandbox The client-side fully qualified path to the sandbox pj
+     * @return true/false depending on whether or not this location has a valid sandbox
+     * @throws APIException
+     */
+    private boolean isValidSandbox( String sandbox )
+        throws APIException
+    {
+        Command cmd = new Command( Command.SI, "sandboxinfo" );
+        cmd.addOption( new Option( "sandbox", sandbox ) );
+
+        api.getLogger().debug( "Validating existing sandbox: " + sandbox );
+        Response res = api.runCommand( cmd );
+        WorkItemIterator wit = res.getWorkItems();
+        try
+        {
+            WorkItem wi = wit.next();
+            return wi.getField( "fullConfigSyntax" ).getValueAsString().equalsIgnoreCase(
+                siProject.getConfigurationPath() );
+        }
+        catch ( APIException aex )
+        {
+            ExceptionHandler eh = new ExceptionHandler( aex );
+            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
+            api.getLogger().debug( eh.getCommand() + " completed with exit code " + eh.getExitCode() );
+            return false;
+        }
+    }
+
+    /**
+     * Inspects the MKS API Response object's Item field to determine whether or nor a working file delta exists
+     *
+     * @param wfdelta MKS API Response object's Item representing the Working File Delta
+     * @return true if the working file is a delta; false otherwise
+     */
+    private boolean isDelta( Item wfdelta )
+    {
+        // Return false if there is no working file
+        if ( wfdelta.getField( "isDelta" ).getBoolean().booleanValue() )
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Executes a 'si add' command using the message for the description
+     *
+     * @param memberFile Full path to the new member's location
+     * @param message    Description for the new member's archive
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    private Response add( File memberFile, String message )
+        throws APIException
+    {
+        // Setup the add command
+        api.getLogger().info( "Adding member: " + memberFile.getAbsolutePath() );
+        Command siAdd = new Command( Command.SI, "add" );
+        siAdd.addOption( new Option( "onExistingArchive", "sharearchive" ) );
+        siAdd.addOption( new Option( "cpid", cpid ) );
+        if ( null != message && message.length() > 0 )
+        {
+            siAdd.addOption( new Option( "description", message ) );
+        }
+        siAdd.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        siAdd.addSelection( memberFile.getName() );
+        return api.runCommand( siAdd );
+    }
+
+    /**
+     * Executes a 'si ci' command using the relativeName for the member name and message for the description
+     *
+     * @param memberFile   Full path to the member's current sandbox location
+     * @param relativeName Relative path from the nearest subproject or project
+     * @param message      Description for checking in the new update
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    private Response checkin( File memberFile, String relativeName, String message )
+        throws APIException
+    {
+        // Setup the check-in command
+        api.getLogger().info( "Checking in member:  " + memberFile.getAbsolutePath() );
+        Command sici = new Command( Command.SI, "ci" );
+        sici.addOption( new Option( "cpid", cpid ) );
+        if ( null != message && message.length() > 0 )
+        {
+            sici.addOption( new Option( "description", message ) );
+        }
+        sici.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        sici.addSelection( relativeName );
+        return api.runCommand( sici );
+    }
+
+    /**
+     * Executes a 'si drop' command using the relativeName for the member name
+     *
+     * @param memberFile   Full path to the member's current sandbox location
+     * @param relativeName Relative path from the nearest subproject or project
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    private Response dropMember( File memberFile, String relativeName )
+        throws APIException
+    {
+        // Setup the drop command
+        api.getLogger().info( "Dropping member " + memberFile.getAbsolutePath() );
+        Command siDrop = new Command( Command.SI, "drop" );
+        siDrop.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        siDrop.addOption( new Option( "noconfirm" ) );
+        siDrop.addOption( new Option( "cpid", cpid ) );
+        siDrop.addOption( new Option( "delete" ) );
+        siDrop.addSelection( relativeName );
+        return api.runCommand( siDrop );
+    }
+
+    /**
+     * Executes a 'si diff' command to see if the working file has actually changed.  Even though the
+     * working file delta might be true, that doesn't always mean the file has actually changed.
+     *
+     * @param memberFile   Full path to the member's current sandbox location
+     * @param relativeName Relative path from the nearest subproject or project
+     * @return MKS API Response object
+     */
+    private boolean hasMemberChanged( File memberFile, String relativeName )
+    {
+        // Setup the differences command
+        Command siDiff = new Command( Command.SI, "diff" );
+        siDiff.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        siDiff.addSelection( relativeName );
+        try
+        {
+            // Run the diff command...
+            Response res = api.runCommand( siDiff );
+            try
+            {
+                // Return the changed flag...
+                return res.getWorkItems().next().getResult().getField( "resultant" ).getItem().getField(
+                    "different" ).getBoolean().booleanValue();
+            }
+            catch ( NullPointerException npe )
+            {
+                api.getLogger().warn( "Couldn't figure out differences for file: " + memberFile.getAbsolutePath() );
+                api.getLogger().warn(
+                    "Null value found along response object for WorkItem/Result/Field/Item/Field.getBoolean()" );
+                api.getLogger().warn( "Proceeding with the assumption that the file has changed!" );
+            }
+        }
+        catch ( APIException aex )
+        {
+            ExceptionHandler eh = new ExceptionHandler( aex );
+            api.getLogger().warn( "Couldn't figure out differences for file: " + memberFile.getAbsolutePath() );
+            api.getLogger().warn( eh.getMessage() );
+            api.getLogger().warn( "Proceeding with the assumption that the file has changed!" );
+            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
+        }
+        return true;
+    }
+
+    /**
+     * Returns the full path name to the current Sandbox directory
+     *
+     * @return
+     */
+    public String getSandboxDir()
+    {
+        return sandboxDir;
+    }
+
+    /**
+     * Executes a 'si lock' command using the relativeName of the file
+     *
+     * @param memberFile   Full path to the member's current sandbox location
+     * @param relativeName Relative path from the nearest subproject or project
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    public Response lock( File memberFile, String relativeName )
+        throws APIException
+    {
+        // Setup the lock command
+        api.getLogger().debug( "Locking member: " + memberFile.getAbsolutePath() );
+        Command siLock = new Command( Command.SI, "lock" );
+        siLock.addOption( new Option( "revision", ":member" ) );
+        siLock.addOption( new Option( "cpid", cpid ) );
+        siLock.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        siLock.addSelection( relativeName );
+        // Execute the lock command
+        return api.runCommand( siLock );
+    }
+
+    /**
+     * Executes a 'si unlock' command using the relativeName of the file
+     *
+     * @param memberFile   Full path to the member's current sandbox location
+     * @param relativeName Relative path from the nearest subproject or project
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    public Response unlock( File memberFile, String relativeName )
+        throws APIException
+    {
+        // Setup the unlock command
+        api.getLogger().debug( "Unlocking member: " + memberFile.getAbsolutePath() );
+        Command siUnlock = new Command( Command.SI, "unlock" );
+        siUnlock.addOption( new Option( "revision", ":member" ) );
+        siUnlock.addOption( new Option( "action", "remove" ) );
+        siUnlock.addOption( new Option( "cwd", memberFile.getParentFile().getAbsolutePath() ) );
+        siUnlock.addSelection( relativeName );
+        // Execute the unlock command
+        return api.runCommand( siUnlock );
+    }
+
+    /**
+     * Removes the registration for the Sandbox in the user's profile
+     *
+     * @return The API Response associated with executing this command
+     * @throws APIException
+     */
+    public Response drop()
+        throws APIException
+    {
+        File project = new File( siProject.getProjectName() );
+        File sandboxpj = new File( sandboxDir + fs + project.getName() );
+
+        // Check to see if the sandbox file already exists and its OK to use
+        api.getLogger().debug( "Sandbox Project File: " + sandboxpj.getAbsolutePath() );
+        Command cmd = new Command( Command.SI, "dropsandbox" );
+        cmd.addOption( new Option( "delete", "members" ) );
+        cmd.addOption( new Option( "sandbox", sandboxpj.getAbsolutePath() ) );
+        cmd.addOption( new Option( "cwd", sandboxDir ) );
+        return api.runCommand( cmd );
+    }
+
+    /**
+     * Creates a new Sandbox in the sandboxDir specified
+     *
+     * @return true if the operation is successful; false otherwise
+     * @throws APIException
+     */
+    public boolean create()
+        throws APIException
+    {
+        File project = new File( siProject.getProjectName() );
+        File sandboxpj = new File( sandboxDir + fs + project.getName() );
+
+        // Check to see if the sandbox file already exists and its OK to use
+        api.getLogger().debug( "Sandbox Project File: " + sandboxpj.getAbsolutePath() );
+        if ( sandboxpj.isFile() )
+        {
+            // Validate this sandbox
+            if ( isValidSandbox( sandboxpj.getAbsolutePath() ) )
+            {
+                api.getLogger().debug(
+                    "Reusing existing Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
+                return true;
+            }
+            else
+            {
+                api.getLogger().error(
+                    "An invalid Sandbox exists in " + sandboxDir + ". Please provide a different location!" );
+                return false;
+            }
+        }
+        else // Create a new sandbox in the location specified
+        {
+            api.getLogger().debug(
+                "Creating Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
+            try
+            {
+                Command cmd = new Command( Command.SI, "createsandbox" );
+                cmd.addOption( new Option( "recurse" ) );
+                cmd.addOption( new Option( "nopopulate" ) );
+                cmd.addOption( new Option( "project", siProject.getConfigurationPath() ) );
+                cmd.addOption( new Option( "cwd", sandboxDir ) );
+                api.runCommand( cmd );
+            }
+            catch ( APIException aex )
+            {
+                // Check to see if this exception is due an existing sandbox registry entry
+                ExceptionHandler eh = new ExceptionHandler( aex );
+                if ( eh.getMessage().indexOf( "There is already a registered entry" ) > 0 )
+                {
+                    // This will re-validate the sandbox, if Maven blew away the old directory
+                    return create();
+                }
+                else
+                {
+                    throw aex;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Resynchronizes an existing Sandbox
+     * Assumes that the create() call has already been made to validate this sandbox
+     *
+     * @throws APIException
+     */
+    public Response resync()
+        throws APIException
+    {
+        api.getLogger().debug(
+            "Resynchronizing Sandbox in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
+        Command cmd = new Command( Command.SI, "resync" );
+        cmd.addOption( new Option( "recurse" ) );
+        cmd.addOption( new Option( "populate" ) );
+        cmd.addOption( new Option( "cwd", sandboxDir ) );
+        return api.runCommand( cmd );
+    }
+
+    /**
+     * Executes a 'si makewritable' command to allow edits to all files in the Sandbox directory
+     *
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    public Response makeWriteable()
+        throws APIException
+    {
+        api.getLogger().debug(
+            "Setting files to writeable in " + sandboxDir + " for project " + siProject.getConfigurationPath() );
+        Command cmd = new Command( Command.SI, "makewritable" );
+        cmd.addOption( new Option( "recurse" ) );
+        cmd.addOption( new Option( "cwd", sandboxDir ) );
+        return api.runCommand( cmd );
+    }
+
+    /**
+     * Executes a 'si revert' command to roll back changes to all files in the Sandbox directory
+     *
+     * @return MKS API Response object
+     * @throws APIException
+     */
+    public Response revertMembers()
+        throws APIException
+    {
+        api.getLogger().debug(
+            "Reverting changes in sandbox " + sandboxDir + " for project " + siProject.getConfigurationPath() );
+        Command cmd = new Command( Command.SI, "revert" );
+        cmd.addOption( new Option( "recurse" ) );
+        cmd.addOption( new Option( "cwd", sandboxDir ) );
+        return api.runCommand( cmd );
+    }
+
+    /**
+     * Executes a 'si viewnonmembers' command filtering the results using the exclude and include lists
+     *
+     * @param exclude Pattern containing the exclude file list
+     * @param include Pattern containing the include file list
+     * @return List of ScmFile objects representing the new files in the Sandbox
+     * @throws APIException
+     */
+    public List<ScmFile> getNewMembers( String exclude, String include )
+        throws APIException
+    {
+        // Store a list of files that were added to the repository
+        List<ScmFile> filesAdded = new ArrayList<ScmFile>();
+        Command siViewNonMem = new Command( Command.SI, "viewnonmembers" );
+        siViewNonMem.addOption( new Option( "recurse" ) );
+        if ( null != exclude && exclude.length() > 0 )
+        {
+            siViewNonMem.addOption( new Option( "exclude", exclude ) );
+        }
+        if ( null != include && include.length() > 0 )
+        {
+            siViewNonMem.addOption( new Option( "include", include ) );
+        }
+        siViewNonMem.addOption( new Option( "noincludeFormers" ) );
+        siViewNonMem.addOption( new Option( "cwd", sandboxDir ) );
+        Response response = api.runCommand( siViewNonMem );
+        for ( WorkItemIterator wit = response.getWorkItems(); wit.hasNext(); )
+        {
+            filesAdded.add(
+                new ScmFile( wit.next().getField( "absolutepath" ).getValueAsString(), ScmFileStatus.ADDED ) );
+        }
+        return filesAdded;
+
+    }
+
+    /**
+     * Adds a list of files to the MKS Integrity SCM Project
+     *
+     * @param exclude Pattern containing the exclude file list
+     * @param include Pattern containing the include file list
+     * @param message Description for the member's archive
+     * @return
+     */
+    public List<ScmFile> addNonMembers( String exclude, String include, String message )
+    {
+        // Re-initialize the overall addSuccess to be true for now
+        addSuccess = true;
+        // Store a list of files that were actually added to the repository
+        List<ScmFile> filesAdded = new ArrayList<ScmFile>();
+        api.getLogger().debug( "Looking for new members in sandbox dir: " + sandboxDir );
+        try
+        {
+            List<ScmFile> newFileList = getNewMembers( exclude, include );
+            for ( Iterator<ScmFile> sit = newFileList.iterator(); sit.hasNext(); )
+            {
+                try
+                {
+                    ScmFile localFile = sit.next();
+                    // Attempt to add the file to the Integrity repository
+                    add( new File( localFile.getPath() ), message );
+                    // If it was a success, then add it to the list of files that were actually added
+                    filesAdded.add( localFile );
+                }
+                catch ( APIException aex )
+                {
+                    // Set the addSuccess to false, since we ran into a problem
+                    addSuccess = false;
+                    ExceptionHandler eh = new ExceptionHandler( aex );
+                    api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
+                    api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
+                }
+            }
+        }
+        catch ( APIException aex )
+        {
+            // Set the addSuccess to false, since we ran into a problem
+            addSuccess = false;
+            ExceptionHandler eh = new ExceptionHandler( aex );
+            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
+            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
+        }
+        return filesAdded;
+    }
+
+    /**
+     * Returns the overall success of the add operation
+     *
+     * @return
+     */
+    public boolean getOverallAddSuccess()
+    {
+        return addSuccess;
+    }
+
+    /**
+     * Inspects the MKS API Response object's Item field to determine whether or nor a working file exists
+     *
+     * @param wfdelta MKS API Response object's Item representing the Working File Delta
+     * @return
+     */
+    public boolean hasWorkingFile( Item wfdelta )
+    {
+        // Return false if there is no working file
+        if ( wfdelta.getField( "noWorkingFile" ).getBoolean().booleanValue() )
+        {
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * Executes a 'si viewsandbox' and parses the output for changed or dropped working files
+     *
+     * @return A list of MKS API Response WorkItem objects representing the changes in the Sandbox
+     * @throws APIException
+     */
+    public List<WorkItem> getChangeList()
+        throws APIException
+    {
+        // Store a list of files that were changed/removed to the repository
+        List<WorkItem> changedFiles = new ArrayList<WorkItem>();
+        // Setup the view sandbox command to figure out what has changed...
+        Command siViewSandbox = new Command( Command.SI, "viewsandbox" );
+        // Create the --fields option
+        MultiValue mv = new MultiValue( "," );
+        mv.add( "name" );
+        mv.add( "context" );
+        mv.add( "wfdelta" );
+        mv.add( "memberarchive" );
+        siViewSandbox.addOption( new Option( "fields", mv ) );
+        siViewSandbox.addOption( new Option( "recurse" ) );
+        siViewSandbox.addOption( new Option( "noincludeDropped" ) );
+        siViewSandbox.addOption( new Option( "filterSubs" ) );
+        siViewSandbox.addOption( new Option( "cwd", sandboxDir ) );
+
+        // Run the view sandbox command
+        Response r = api.runCommand( siViewSandbox );
+        // Check-in all changed files, drop all members with missing working files
+        for ( WorkItemIterator wit = r.getWorkItems(); wit.hasNext(); )
+        {
+            WorkItem wi = wit.next();
+            api.getLogger().debug( "Inspecting file: " + wi.getField( "name" ).getValueAsString() );
+
+            if ( wi.getModelType().equals( SIModelTypeName.MEMBER ) )
+            {
+                Item wfdeltaItem = (Item) wi.getField( "wfdelta" ).getValue();
+                // Proceed with this entry only if it is an actual working file delta
+                if ( isDelta( wfdeltaItem ) )
+                {
+                    File memberFile = new File( wi.getField( "name" ).getValueAsString() );
+                    if ( hasWorkingFile( wfdeltaItem ) )
+                    {
+                        // Only report on files that have actually changed...
+                        if ( hasMemberChanged( memberFile, wi.getId() ) )
+                        {
+                            changedFiles.add( wi );
+                        }
+                    }
+                    else
+                    {
+                        // Also report on dropped files
+                        changedFiles.add( wi );
+                    }
+                }
+            }
+        }
+        return changedFiles;
+    }
+
+    /**
+     * Wrapper function to check-in all changes and drop members associated with missing working files
+     *
+     * @param message Description for the changes
+     * @return
+     */
+    public List<ScmFile> checkInUpdates( String message )
+    {
+        // Re-initialize the overall ciSuccess to be true for now
+        ciSuccess = true;
+        // Store a list of files that were changed/removed to the repository
+        List<ScmFile> changedFiles = new ArrayList<ScmFile>();
+        api.getLogger().debug( "Looking for changed and dropped members in sandbox dir: " + sandboxDir );
+
+        try
+        {
+            // Let the list of changed files
+            List<WorkItem> changeList = getChangeList();
+            // Check-in all changed files, drop all members with missing working files
+            for ( Iterator<WorkItem> wit = changeList.iterator(); wit.hasNext(); )
+            {
+                try
+                {
+                    WorkItem wi = wit.next();
+                    File memberFile = new File( wi.getField( "name" ).getValueAsString() );
+                    // Check-in files that have actually changed...
+                    if ( hasWorkingFile( (Item) wi.getField( "wfdelta" ).getValue() ) )
+                    {
+                        // Lock each member as you go...
+                        lock( memberFile, wi.getId() );
+                        // Commit the changes...
+                        checkin( memberFile, wi.getId(), message );
+                        // Update the changed file list
+                        changedFiles.add( new ScmFile( memberFile.getAbsolutePath(), ScmFileStatus.CHECKED_IN ) );
+                    }
+                    else
+                    {
+                        // Drop the member if there is no working file
+                        dropMember( memberFile, wi.getId() );
+                        // Update the changed file list
+                        changedFiles.add( new ScmFile( memberFile.getAbsolutePath(), ScmFileStatus.DELETED ) );
+                    }
+                }
+                catch ( APIException aex )
+                {
+                    // Set the ciSuccess to false, since we ran into a problem
+                    ciSuccess = false;
+                    ExceptionHandler eh = new ExceptionHandler( aex );
+                    api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
+                    api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
+                }
+            }
+        }
+        catch ( APIException aex )
+        {
+            // Set the ciSuccess to false, since we ran into a problem
+            ciSuccess = false;
+            ExceptionHandler eh = new ExceptionHandler( aex );
+            api.getLogger().error( "MKS API Exception: " + eh.getMessage() );
+            api.getLogger().debug( eh.getCommand() + " completed with exit Code " + eh.getExitCode() );
+        }
+
+        return changedFiles;
+    }
+
+    /**
+     * Returns the overall success of the check-in operation
+     *
+     * @return
+     */
+    public boolean getOverallCheckInSuccess()
+    {
+        return ciSuccess;
+    }
+
+    /**
+     * Creates one subproject per directory, as required.
+     *
+     * @param dirPath A relative path structure of folders
+     * @return Response containing the result for the created subproject
+     * @throws APIException
+     */
+    public Response createSubproject( String dirPath )
+        throws APIException
+    {
+        // Setup the create subproject command
+        api.getLogger().debug( "Creating subprojects for: " + dirPath + "/project.pj" );
+        Command siCreateSubproject = new Command( Command.SI, "createsubproject" );
+        siCreateSubproject.addOption( new Option( "cpid", cpid ) );
+        siCreateSubproject.addOption( new Option( "createSubprojects" ) );
+        siCreateSubproject.addOption( new Option( "cwd", sandboxDir ) );
+        siCreateSubproject.addSelection( dirPath + "/project.pj" );
+        // Execute the create subproject command
+        return api.runCommand( siCreateSubproject );
+    }
+
+    /**
+     * Executes the 'si rlog' command to generate a list of changed revision found between startDate and endDate
+     *
+     * @param startDate The date range for the beginning of the operation
+     * @param endDate   The date range for the end of the operation
+     * @return ChangeLogSet containing a list of changes grouped by Change Pacakge ID
+     * @throws APIException
+     */
+    public ChangeLogSet getChangeLog( Date startDate, Date endDate )
+        throws APIException
+    {
+        // Initialize our return object
+        ChangeLogSet changeLog = new ChangeLogSet( startDate, endDate );
+        // By default we're going to group-by change package
+        // Non change package changes will be lumped into one big Change Set
+        Hashtable<String, ChangeSet> changeSetHash = new Hashtable<String, ChangeSet>();
+
+        // Lets prepare our si rlog command for execution
+        Command siRlog = new Command( Command.SI, "rlog" );
+        siRlog.addOption( new Option( "recurse" ) );
+        MultiValue rFilter = new MultiValue( ":" );
+        rFilter.add( "daterange" );
+        rFilter.add( "'" + RLOG_DATEFORMAT.format( startDate ) + "'-'" + RLOG_DATEFORMAT.format( endDate ) + "'" );
+        siRlog.addOption( new Option( "rfilter", rFilter ) );
+        siRlog.addOption( new Option( "cwd", sandboxDir ) );
+        // Execute the si rlog command
+        Response response = api.runCommand( siRlog );
+        for ( WorkItemIterator wit = response.getWorkItems(); wit.hasNext(); )
+        {
+            WorkItem wi = wit.next();
+            String memberName = wi.getContext();
+            // We're going to have to do a little dance to get the correct server file name
+            memberName = memberName.substring( 0, memberName.lastIndexOf( '/' ) );
+            memberName = memberName + '/' + wi.getId();
+            memberName = memberName.replace( '\\', '/' );
+            // Now lets get the revisions for this file
+            Field revisionsFld = wi.getField( "revisions" );
+            if ( null != revisionsFld && revisionsFld.getDataType().equals( Field.ITEM_LIST_TYPE )
+                && null != revisionsFld.getList() )
+            {
+                @SuppressWarnings( "unchecked" ) List<Item> revList = revisionsFld.getList();
+                for ( Iterator<Item> lit = revList.iterator(); lit.hasNext(); )
+                {
+                    Item revisionItem = lit.next();
+                    String revision = revisionItem.getId();
+                    String author = revisionItem.getField( "author" ).getItem().getId();
+                    // Attempt to get the full name, if available
+                    try
+                    {
+                        author = revisionItem.getField( "author" ).getItem().getField( "fullname" ).getValueAsString();
+                    }
+                    catch ( NullPointerException npe )
+                    { /* ignore */ }
+                    String cpid = ":none";
+                    // Attempt to get the cpid for this revision
+                    try
+                    {
+                        cpid = revisionItem.getField( "cpid" ).getItem().getId();
+                    }
+                    catch ( NullPointerException npe )
+                    { /* ignore */ }
+                    // Get the Change Package summary for this revision
+                    String comment = cpid + ": " + revisionItem.getField( "cpsummary" ).getValueAsString();
+                    // Get the date associated with this revision
+                    Date date = revisionItem.getField( "date" ).getDateTime();
+
+                    // Lets create our ChangeFile based on the information we've gathered so far
+                    ChangeFile changeFile = new ChangeFile( memberName, revision );
+
+                    // Check to see if we already have a ChangeSet grouping for this revision
+                    ChangeSet changeSet = changeSetHash.get( cpid );
+                    if ( null != changeSet )
+                    {
+                        // Set the date of the ChangeSet to the oldest entry
+                        if ( changeSet.getDate().after( date ) )
+                        {
+                            changeSet.setDate( date );
+                        }
+                        // Add the new ChangeFile
+                        changeSet.addFile( changeFile );
+                        // Update the changeSetHash
+                        changeSetHash.put( cpid, changeSet );
+                    }
+                    else // Create a new ChangeSet grouping and add the ChangeFile
+                    {
+                        List<ChangeFile> changeFileList = new ArrayList<ChangeFile>();
+                        changeFileList.add( changeFile );
+                        changeSet = new ChangeSet( date, comment, author, changeFileList );
+                        // Update the changeSetHash with an initial entry for the cpid
+                        changeSetHash.put( cpid, changeSet );
+                    }
+                }
+            }
+
+        }
+
+        // Update the Change Log with the Change Sets
+        List<ChangeSet> changeSetList = new ArrayList<ChangeSet>();
+        changeSetList.addAll( changeSetHash.values() );
+        changeLog.setChangeSets( changeSetList );
+
+        return changeLog;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/8ad9801d/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/add/IntegrityAddCommand.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/add/IntegrityAddCommand.java b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/add/IntegrityAddCommand.java
index b215505..dd31fdd 100644
--- a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/add/IntegrityAddCommand.java
+++ b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/add/IntegrityAddCommand.java
@@ -1,71 +1,71 @@
-package org.apache.maven.scm.provider.integrity.command.add;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.scm.ScmException;
-import org.apache.maven.scm.ScmFile;
-import org.apache.maven.scm.ScmFileSet;
-import org.apache.maven.scm.ScmResult;
-import org.apache.maven.scm.command.add.AbstractAddCommand;
-import org.apache.maven.scm.command.add.AddScmResult;
-import org.apache.maven.scm.provider.ScmProviderRepository;
-import org.apache.maven.scm.provider.integrity.Sandbox;
-import org.apache.maven.scm.provider.integrity.repository.IntegrityScmProviderRepository;
-
-import java.util.List;
-
-/**
- * MKS Integrity implementation for Maven's AbstractAddCommand
- *
- * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
- * @version $Id: IntegrityAddCommand.java 1.4 2011/08/22 13:06:13EDT Cletus D'Souza (dsouza) Exp  $
- * @since 1.6
- */
-public class IntegrityAddCommand
-    extends AbstractAddCommand
-{
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public AddScmResult executeAddCommand( ScmProviderRepository repository, ScmFileSet fileSet, String message,
-                                           boolean binary )
-        throws ScmException
-    {
-        getLogger().info( "Attempting to add new files from directory " + fileSet.getBasedir().getAbsolutePath() );
-        IntegrityScmProviderRepository iRepo = (IntegrityScmProviderRepository) repository;
-        Sandbox siSandbox = iRepo.getSandbox();
-        String excludes = Sandbox.formatFilePatterns( fileSet.getExcludes() );
-        String includes = Sandbox.formatFilePatterns( fileSet.getIncludes() );
-        String msg = ( ( null == message || message.length() == 0 ) ? System.getProperty( "message" ) : message );
-        List<ScmFile> addedFiles = siSandbox.addNonMembers( excludes, includes, msg );
-        if ( siSandbox.getOverallAddSuccess() )
-        {
-            return new AddScmResult( "si add", addedFiles );
-        }
-        else
-        {
-            return new AddScmResult( addedFiles,
-                                     new ScmResult( "si add", "There was a problem adding files to the repository", "",
-                                                    false ) );
-        }
-    }
-
-}
+package org.apache.maven.scm.provider.integrity.command.add;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.add.AbstractAddCommand;
+import org.apache.maven.scm.command.add.AddScmResult;
+import org.apache.maven.scm.provider.ScmProviderRepository;
+import org.apache.maven.scm.provider.integrity.Sandbox;
+import org.apache.maven.scm.provider.integrity.repository.IntegrityScmProviderRepository;
+
+import java.util.List;
+
+/**
+ * MKS Integrity implementation for Maven's AbstractAddCommand
+ *
+ * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
+ * @version $Id: IntegrityAddCommand.java 1.4 2011/08/22 13:06:13EDT Cletus D'Souza (dsouza) Exp  $
+ * @since 1.6
+ */
+public class IntegrityAddCommand
+    extends AbstractAddCommand
+{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public AddScmResult executeAddCommand( ScmProviderRepository repository, ScmFileSet fileSet, String message,
+                                           boolean binary )
+        throws ScmException
+    {
+        getLogger().info( "Attempting to add new files from directory " + fileSet.getBasedir().getAbsolutePath() );
+        IntegrityScmProviderRepository iRepo = (IntegrityScmProviderRepository) repository;
+        Sandbox siSandbox = iRepo.getSandbox();
+        String excludes = Sandbox.formatFilePatterns( fileSet.getExcludes() );
+        String includes = Sandbox.formatFilePatterns( fileSet.getIncludes() );
+        String msg = ( ( null == message || message.length() == 0 ) ? System.getProperty( "message" ) : message );
+        List<ScmFile> addedFiles = siSandbox.addNonMembers( excludes, includes, msg );
+        if ( siSandbox.getOverallAddSuccess() )
+        {
+            return new AddScmResult( "si add", addedFiles );
+        }
+        else
+        {
+            return new AddScmResult( addedFiles,
+                                     new ScmResult( "si add", "There was a problem adding files to the repository", "",
+                                                    false ) );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/8ad9801d/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/blame/IntegrityBlameCommand.java
----------------------------------------------------------------------
diff --git a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/blame/IntegrityBlameCommand.java b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/blame/IntegrityBlameCommand.java
index 02e980e..1ecbad7 100644
--- a/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/blame/IntegrityBlameCommand.java
+++ b/maven-scm-providers/maven-scm-provider-integrity/src/main/java/org/apache/maven/scm/provider/integrity/command/blame/IntegrityBlameCommand.java
@@ -1,92 +1,92 @@
-package org.apache.maven.scm.provider.integrity.command.blame;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.scm.ScmException;
-import org.apache.maven.scm.ScmFileSet;
-import org.apache.maven.scm.ScmResult;
-import org.apache.maven.scm.command.blame.AbstractBlameCommand;
-import org.apache.maven.scm.command.blame.BlameScmResult;
-import org.apache.maven.scm.provider.ScmProviderRepository;
-import org.apache.maven.scm.provider.integrity.APISession;
-import org.apache.maven.scm.provider.integrity.repository.IntegrityScmProviderRepository;
-import org.codehaus.plexus.util.cli.CommandLineException;
-import org.codehaus.plexus.util.cli.CommandLineUtils;
-import org.codehaus.plexus.util.cli.Commandline;
-
-/**
- * MKS Integrity implementation for Maven's AbstractBlameCommand
- * <br>This class will execute a 'si annotate' command for the specified filename
- *
- * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
- * @version $Id: IntegrityBlameCommand.java 1.3 2011/08/22 13:06:15EDT Cletus D'Souza (dsouza) Exp  $
- * @since 1.6
- */
-public class IntegrityBlameCommand
-    extends AbstractBlameCommand
-{
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public BlameScmResult executeBlameCommand( ScmProviderRepository repository, ScmFileSet workingDirectory,
-                                               String filename )
-        throws ScmException
-    {
-        getLogger().info( "Attempting to display blame results for file: " + filename );
-        if ( null == filename || filename.length() == 0 )
-        {
-            throw new ScmException( "A single filename is required to execute the blame command!" );
-        }
-        BlameScmResult result;
-        IntegrityScmProviderRepository iRepo = (IntegrityScmProviderRepository) repository;
-        APISession api = iRepo.getAPISession();
-        // Since the si annotate command is not completely API ready, we will use the CLI for this command
-        Commandline shell = new Commandline();
-        shell.setWorkingDirectory( workingDirectory.getBasedir() );
-        shell.setExecutable( "si" );
-        shell.createArg().setValue( "annotate" );
-        shell.createArg().setValue( "--hostname=" + api.getHostName() );
-        shell.createArg().setValue( "--port=" + api.getPort() );
-        shell.createArg().setValue( "--user=" + api.getUserName() );
-        shell.createArg().setValue( "--fields=date,revision,author" );
-        shell.createArg().setValue( '"' + filename + '"' );
-        IntegrityBlameConsumer shellConsumer = new IntegrityBlameConsumer( getLogger() );
-
-        try
-        {
-            getLogger().debug( "Executing: " + shell.getCommandline() );
-            int exitCode = CommandLineUtils.executeCommandLine( shell, shellConsumer,
-                                                                new CommandLineUtils.StringStreamConsumer() );
-            boolean success = ( exitCode == 128 ? false : true );
-            ScmResult scmResult =
-                new ScmResult( shell.getCommandline().toString(), "", "Exit Code: " + exitCode, success );
-            return new BlameScmResult( shellConsumer.getBlameList(), scmResult );
-        }
-        catch ( CommandLineException cle )
-        {
-            getLogger().error( "Command Line Exception: " + cle.getMessage() );
-            result = new BlameScmResult( shell.getCommandline().toString(), cle.getMessage(), "", false );
-        }
-
-        return result;
-    }
-
-}
+package org.apache.maven.scm.provider.integrity.command.blame;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.blame.AbstractBlameCommand;
+import org.apache.maven.scm.command.blame.BlameScmResult;
+import org.apache.maven.scm.provider.ScmProviderRepository;
+import org.apache.maven.scm.provider.integrity.APISession;
+import org.apache.maven.scm.provider.integrity.repository.IntegrityScmProviderRepository;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * MKS Integrity implementation for Maven's AbstractBlameCommand
+ * <br>This class will execute a 'si annotate' command for the specified filename
+ *
+ * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
+ * @version $Id: IntegrityBlameCommand.java 1.3 2011/08/22 13:06:15EDT Cletus D'Souza (dsouza) Exp  $
+ * @since 1.6
+ */
+public class IntegrityBlameCommand
+    extends AbstractBlameCommand
+{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public BlameScmResult executeBlameCommand( ScmProviderRepository repository, ScmFileSet workingDirectory,
+                                               String filename )
+        throws ScmException
+    {
+        getLogger().info( "Attempting to display blame results for file: " + filename );
+        if ( null == filename || filename.length() == 0 )
+        {
+            throw new ScmException( "A single filename is required to execute the blame command!" );
+        }
+        BlameScmResult result;
+        IntegrityScmProviderRepository iRepo = (IntegrityScmProviderRepository) repository;
+        APISession api = iRepo.getAPISession();
+        // Since the si annotate command is not completely API ready, we will use the CLI for this command
+        Commandline shell = new Commandline();
+        shell.setWorkingDirectory( workingDirectory.getBasedir() );
+        shell.setExecutable( "si" );
+        shell.createArg().setValue( "annotate" );
+        shell.createArg().setValue( "--hostname=" + api.getHostName() );
+        shell.createArg().setValue( "--port=" + api.getPort() );
+        shell.createArg().setValue( "--user=" + api.getUserName() );
+        shell.createArg().setValue( "--fields=date,revision,author" );
+        shell.createArg().setValue( '"' + filename + '"' );
+        IntegrityBlameConsumer shellConsumer = new IntegrityBlameConsumer( getLogger() );
+
+        try
+        {
+            getLogger().debug( "Executing: " + shell.getCommandline() );
+            int exitCode = CommandLineUtils.executeCommandLine( shell, shellConsumer,
+                                                                new CommandLineUtils.StringStreamConsumer() );
+            boolean success = ( exitCode == 128 ? false : true );
+            ScmResult scmResult =
+                new ScmResult( shell.getCommandline().toString(), "", "Exit Code: " + exitCode, success );
+            return new BlameScmResult( shellConsumer.getBlameList(), scmResult );
+        }
+        catch ( CommandLineException cle )
+        {
+            getLogger().error( "Command Line Exception: " + cle.getMessage() );
+            result = new BlameScmResult( shell.getCommandline().toString(), cle.getMessage(), "", false );
+        }
+
+        return result;
+    }
+
+}