001package org.apache.maven.scm.provider.vss.commands.edit;
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
022import java.io.File;
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.List;
026
027import org.apache.maven.scm.ScmException;
028import org.apache.maven.scm.ScmFile;
029import org.apache.maven.scm.ScmFileSet;
030import org.apache.maven.scm.ScmResult;
031import org.apache.maven.scm.command.changelog.ChangeLogCommand;
032import org.apache.maven.scm.command.edit.AbstractEditCommand;
033import org.apache.maven.scm.command.edit.EditScmResult;
034import org.apache.maven.scm.provider.ScmProviderRepository;
035import org.apache.maven.scm.provider.vss.commands.VssCommandLineUtils;
036import org.apache.maven.scm.provider.vss.commands.VssConstants;
037import org.apache.maven.scm.provider.vss.commands.changelog.VssHistoryCommand;
038import org.apache.maven.scm.provider.vss.repository.VssScmProviderRepository;
039import org.codehaus.plexus.util.cli.CommandLineUtils;
040import org.codehaus.plexus.util.cli.Commandline;
041
042/**
043 * @author <a href="mailto:triek@thrx.de">Thorsten Riek</a>
044 * @version $Id: VssCheckOutCommand.java 02.06.2006 00:05:51
045 */
046public class VssEditCommand
047    extends AbstractEditCommand
048{
049
050    /** {@inheritDoc} */
051    protected ScmResult executeEditCommand( ScmProviderRepository repository, ScmFileSet fileSet )
052        throws ScmException
053    {
054        if ( getLogger().isDebugEnabled() )
055        {
056            getLogger().debug( "executing checkout command..." );
057        }
058
059        VssScmProviderRepository repo = (VssScmProviderRepository) repository;
060
061        List<Commandline> commandLines = buildCmdLine( repo, fileSet );
062
063        VssEditConsumer consumer = new VssEditConsumer( repo, getLogger() );
064
065        //      TODO handle deleted files from VSS
066        CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
067
068        int exitCode;
069
070        StringBuilder sb = new StringBuilder();
071        List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
072
073        for ( Commandline cl : commandLines )
074        {
075
076            if ( getLogger().isDebugEnabled() )
077            {
078                getLogger().debug( "Executing: " + cl.getWorkingDirectory().getAbsolutePath() + ">>" + cl.toString() );
079            }
080
081            exitCode = VssCommandLineUtils.executeCommandline( cl, consumer, stderr, getLogger() );
082
083            if ( exitCode != 0 )
084            {
085                String error = stderr.getOutput();
086
087                if ( getLogger().isDebugEnabled() )
088                {
089                    getLogger().debug( "VSS returns error: [" + error + "] return code: [" + exitCode + "]" );
090                }
091                if ( error.indexOf( "A writable copy of" ) < 0 )
092                {
093                    return new EditScmResult( cl.toString(), "The vss command failed.", error, false );
094                }
095                // print out the writable copy for manual handling
096                if ( getLogger().isWarnEnabled() )
097                {
098                    getLogger().warn( error );
099                }
100                break;
101            }
102
103            sb.append( cl.toString() + '\n' );
104            updatedFiles.addAll( consumer.getUpdatedFiles() );
105
106        }
107        return new EditScmResult( sb.toString(), updatedFiles );
108
109    }
110
111    public List<Commandline> buildCmdLine( VssScmProviderRepository repo, ScmFileSet fileSet )
112        throws ScmException
113    {
114        List<File> files = fileSet.getFileList();
115        List<Commandline> commands = new ArrayList<Commandline>();
116
117        if ( files.size() > 0 )
118        {
119
120            String base;
121            try
122            {
123                base = fileSet.getBasedir().getCanonicalPath();
124            }
125            catch ( IOException e )
126            {
127                throw new ScmException( "Invalid canonical path", e );
128            }
129
130            for ( File file : files )
131            {
132
133                Commandline command = new Commandline();
134
135                try
136                {
137                    command.addSystemEnvironment();
138                }
139                catch ( Exception e )
140                {
141                    throw new ScmException( "Can't add system environment.", e );
142                }
143
144                command.addEnvironment( "SSDIR", repo.getVssdir() );
145
146                String ssDir = VssCommandLineUtils.getSsDir();
147
148                command.setExecutable( ssDir + VssConstants.SS_EXE );
149
150                command.createArg().setValue( VssConstants.COMMAND_CHECKOUT );
151
152                String absolute;
153                try
154                {
155                    absolute = file.getCanonicalPath();
156                    String relative;
157                    int index = absolute.indexOf( base );
158                    if ( index >= 0 )
159                    {
160                        relative = absolute.substring( index + base.length() );
161                    }
162                    else
163                    {
164                        relative = file.getPath();
165                    }
166
167                    relative = relative.replace( '\\', '/' );
168
169                    if ( !relative.startsWith( "/" ) )
170                    {
171                        relative = '/' + relative;
172                    }
173
174                    String relativeFolder = relative.substring( 0, relative.lastIndexOf( '/' ) );
175
176                    command.setWorkingDirectory( new File( fileSet.getBasedir().getAbsolutePath() + File.separatorChar
177                        + relativeFolder ).getCanonicalPath() );
178
179                    command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() + relative );
180                }
181                catch ( IOException e )
182                {
183                    throw new ScmException( "Invalid canonical path", e );
184                }
185
186                //User identification to get access to vss repository
187                if ( repo.getUserPassword() != null )
188                {
189                    command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
190                }
191
192                //Ignore: Do not ask for input under any circumstances.
193                command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
194
195                commands.add( command );
196
197            }
198
199        }
200        else
201        {
202            Commandline command = new Commandline();
203
204            command.setWorkingDirectory( fileSet.getBasedir().getAbsolutePath() );
205
206            try
207            {
208                command.addSystemEnvironment();
209            }
210            catch ( Exception e )
211            {
212                throw new ScmException( "Can't add system environment.", e );
213            }
214
215            command.addEnvironment( "SSDIR", repo.getVssdir() );
216
217            String ssDir = VssCommandLineUtils.getSsDir();
218
219            command.setExecutable( ssDir + VssConstants.SS_EXE );
220
221            command.createArg().setValue( VssConstants.COMMAND_CHECKOUT );
222
223            command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() );
224            //Display the history of an entire project list
225            command.createArg().setValue( VssConstants.FLAG_RECURSION );
226
227            //User identification to get access to vss repository
228            if ( repo.getUserPassword() != null )
229            {
230                command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
231            }
232
233            //Ignore: Do not ask for input under any circumstances.
234            command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
235
236            commands.add( command );
237
238        }
239
240        return commands;
241    }
242
243    /**
244     * @return
245     */
246    protected ChangeLogCommand getChangeLogCommand()
247    {
248        VssHistoryCommand command = new VssHistoryCommand();
249
250        command.setLogger( getLogger() );
251
252        return command;
253    }
254
255}