001    package 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    
022    import java.io.File;
023    import java.io.IOException;
024    import java.util.ArrayList;
025    import java.util.List;
026    
027    import org.apache.maven.scm.ScmException;
028    import org.apache.maven.scm.ScmFile;
029    import org.apache.maven.scm.ScmFileSet;
030    import org.apache.maven.scm.ScmResult;
031    import org.apache.maven.scm.command.changelog.ChangeLogCommand;
032    import org.apache.maven.scm.command.edit.AbstractEditCommand;
033    import org.apache.maven.scm.command.edit.EditScmResult;
034    import org.apache.maven.scm.provider.ScmProviderRepository;
035    import org.apache.maven.scm.provider.vss.commands.VssCommandLineUtils;
036    import org.apache.maven.scm.provider.vss.commands.VssConstants;
037    import org.apache.maven.scm.provider.vss.commands.changelog.VssHistoryCommand;
038    import org.apache.maven.scm.provider.vss.repository.VssScmProviderRepository;
039    import org.codehaus.plexus.util.cli.CommandLineUtils;
040    import 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     */
046    public 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    }