001    package org.apache.maven.scm.provider.perforce.command.update;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.scm.CommandParameter;
023    import org.apache.maven.scm.CommandParameters;
024    import org.apache.maven.scm.ScmException;
025    import org.apache.maven.scm.ScmFileSet;
026    import org.apache.maven.scm.ScmVersion;
027    import org.apache.maven.scm.command.changelog.ChangeLogCommand;
028    import org.apache.maven.scm.command.checkout.CheckOutScmResult;
029    import org.apache.maven.scm.command.update.AbstractUpdateCommand;
030    import org.apache.maven.scm.command.update.UpdateScmResult;
031    import org.apache.maven.scm.command.update.UpdateScmResultWithRevision;
032    import org.apache.maven.scm.provider.ScmProviderRepository;
033    import org.apache.maven.scm.provider.perforce.PerforceScmProvider;
034    import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
035    import org.apache.maven.scm.provider.perforce.command.PerforceCommand;
036    import org.apache.maven.scm.provider.perforce.command.changelog.PerforceChangeLogCommand;
037    import org.apache.maven.scm.provider.perforce.command.checkout.PerforceCheckOutCommand;
038    
039    import org.codehaus.plexus.util.cli.CommandLineException;
040    import org.codehaus.plexus.util.cli.CommandLineUtils;
041    import org.codehaus.plexus.util.cli.Commandline;
042    
043    import java.io.File;
044    
045    /**
046     * @author Mike Perham
047     * @version $Id: PerforceUpdateCommand.java 1306867 2012-03-29 13:45:10Z olamy $
048     */
049    public class PerforceUpdateCommand
050        extends AbstractUpdateCommand
051        implements PerforceCommand
052    {
053        /** {@inheritDoc} */
054        protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repo, ScmFileSet files,
055                                                        ScmVersion scmVersion )
056            throws ScmException
057        {
058            // In Perforce, there is no difference between update and checkout.
059            // Here we just run the checkout command and map the result onto an
060            // UpdateScmResult.
061            PerforceCheckOutCommand command = new PerforceCheckOutCommand();
062            command.setLogger( getLogger() );
063            CommandParameters params = new CommandParameters();
064            params.setScmVersion( CommandParameter.SCM_VERSION, scmVersion );
065    
066            CheckOutScmResult cosr = (CheckOutScmResult) command.execute( repo, files, params );
067            if ( !cosr.isSuccess() )
068            {
069                return new UpdateScmResult( cosr.getCommandLine(), cosr.getProviderMessage(), cosr.getCommandOutput(),
070                                            false );
071            }
072    
073            PerforceScmProviderRepository p4repo = (PerforceScmProviderRepository) repo;
074            String clientspec = PerforceScmProvider.getClientspecName( getLogger(), p4repo, files.getBasedir() );
075            Commandline cl = createCommandLine( p4repo, files.getBasedir(), clientspec );
076    
077            @SuppressWarnings( "unused" )
078            String location = PerforceScmProvider.getRepoPath( getLogger(), p4repo, files.getBasedir() );
079            PerforceHaveConsumer consumer =
080                new PerforceHaveConsumer( getLogger() );
081    
082            try
083            {
084                if ( getLogger().isDebugEnabled() )
085                {
086                    getLogger().debug( PerforceScmProvider.clean( "Executing " + cl.toString() ) );
087                }
088    
089                CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
090                int exitCode = CommandLineUtils.executeCommandLine( cl, consumer, err );
091    
092                if ( exitCode != 0 )
093                {
094                    String cmdLine = CommandLineUtils.toString( cl.getCommandline() );
095    
096                    StringBuilder msg = new StringBuilder( "Exit code: " + exitCode + " - " + err.getOutput() );
097                    msg.append( '\n' );
098                    msg.append( "Command line was:" + cmdLine );
099    
100                    throw new CommandLineException( msg.toString() );
101                }
102            }
103            catch ( CommandLineException e )
104            {
105                if ( getLogger().isErrorEnabled() )
106                {
107                    getLogger().error( "CommandLineException " + e.getMessage(), e );
108                }
109            }
110    
111            return new UpdateScmResultWithRevision( cosr.getCommandLine(), cosr.getCheckedOutFiles(),
112                                                    String.valueOf( consumer.getHave() ) );
113        }
114    
115        /** {@inheritDoc} */
116        protected ChangeLogCommand getChangeLogCommand()
117        {
118            PerforceChangeLogCommand command = new PerforceChangeLogCommand();
119            command.setLogger( getLogger() );
120            return command;
121        }
122    
123        public static Commandline createCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
124                                                     String clientspec )
125        {
126            Commandline command = PerforceScmProvider.createP4Command( repo, workingDirectory );
127    
128            if ( clientspec != null )
129            {
130                command.createArg().setValue( "-c" );
131                command.createArg().setValue( clientspec );
132            }
133            command.createArg().setValue( "changes" );
134            command.createArg().setValue( "-m1" );
135            command.createArg().setValue( "-ssubmitted" );
136            command.createArg().setValue( "//" + clientspec + "/...#have" );
137    
138            return command;
139        }
140    }