View Javadoc
1   package org.apache.maven.scm.provider.vss.commands.edit;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.maven.scm.ScmException;
28  import org.apache.maven.scm.ScmFile;
29  import org.apache.maven.scm.ScmFileSet;
30  import org.apache.maven.scm.ScmResult;
31  import org.apache.maven.scm.command.changelog.ChangeLogCommand;
32  import org.apache.maven.scm.command.edit.AbstractEditCommand;
33  import org.apache.maven.scm.command.edit.EditScmResult;
34  import org.apache.maven.scm.provider.ScmProviderRepository;
35  import org.apache.maven.scm.provider.vss.commands.VssCommandLineUtils;
36  import org.apache.maven.scm.provider.vss.commands.VssConstants;
37  import org.apache.maven.scm.provider.vss.commands.changelog.VssHistoryCommand;
38  import org.apache.maven.scm.provider.vss.repository.VssScmProviderRepository;
39  import org.codehaus.plexus.util.cli.CommandLineUtils;
40  import org.codehaus.plexus.util.cli.Commandline;
41  
42  /**
43   * @author <a href="mailto:triek@thrx.de">Thorsten Riek</a>
44   */
45  public class VssEditCommand
46      extends AbstractEditCommand
47  {
48  
49      /** {@inheritDoc} */
50      protected ScmResult executeEditCommand( ScmProviderRepository repository, ScmFileSet fileSet )
51          throws ScmException
52      {
53          if ( getLogger().isDebugEnabled() )
54          {
55              getLogger().debug( "executing checkout command..." );
56          }
57  
58          VssScmProviderRepository repo = (VssScmProviderRepository) repository;
59  
60          List<Commandline> commandLines = buildCmdLine( repo, fileSet );
61  
62          VssEditConsumer consumer = new VssEditConsumer( repo, getLogger() );
63  
64          //      TODO handle deleted files from VSS
65          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
66  
67          int exitCode;
68  
69          StringBuilder sb = new StringBuilder();
70          List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
71  
72          for ( Commandline cl : commandLines )
73          {
74  
75              if ( getLogger().isDebugEnabled() )
76              {
77                  getLogger().debug( "Executing: " + cl.getWorkingDirectory().getAbsolutePath() + ">>" + cl.toString() );
78              }
79  
80              exitCode = VssCommandLineUtils.executeCommandline( cl, consumer, stderr, getLogger() );
81  
82              if ( exitCode != 0 )
83              {
84                  String error = stderr.getOutput();
85  
86                  if ( getLogger().isDebugEnabled() )
87                  {
88                      getLogger().debug( "VSS returns error: [" + error + "] return code: [" + exitCode + "]" );
89                  }
90                  if ( error.indexOf( "A writable copy of" ) < 0 )
91                  {
92                      return new EditScmResult( cl.toString(), "The vss command failed.", error, false );
93                  }
94                  // print out the writable copy for manual handling
95                  if ( getLogger().isWarnEnabled() )
96                  {
97                      getLogger().warn( error );
98                  }
99                  break;
100             }
101 
102             sb.append( cl.toString() + '\n' );
103             updatedFiles.addAll( consumer.getUpdatedFiles() );
104 
105         }
106         return new EditScmResult( sb.toString(), updatedFiles );
107 
108     }
109 
110     public List<Commandline> buildCmdLine( VssScmProviderRepository repo, ScmFileSet fileSet )
111         throws ScmException
112     {
113         List<File> files = fileSet.getFileList();
114         List<Commandline> commands = new ArrayList<Commandline>();
115 
116         if ( files.size() > 0 )
117         {
118 
119             String base;
120             try
121             {
122                 base = fileSet.getBasedir().getCanonicalPath();
123             }
124             catch ( IOException e )
125             {
126                 throw new ScmException( "Invalid canonical path", e );
127             }
128 
129             for ( File file : files )
130             {
131 
132                 Commandline command = new Commandline();
133 
134                 try
135                 {
136                     command.addSystemEnvironment();
137                 }
138                 catch ( Exception e )
139                 {
140                     throw new ScmException( "Can't add system environment.", e );
141                 }
142 
143                 command.addEnvironment( "SSDIR", repo.getVssdir() );
144 
145                 String ssDir = VssCommandLineUtils.getSsDir();
146 
147                 command.setExecutable( ssDir + VssConstants.SS_EXE );
148 
149                 command.createArg().setValue( VssConstants.COMMAND_CHECKOUT );
150 
151                 String absolute;
152                 try
153                 {
154                     absolute = file.getCanonicalPath();
155                     String relative;
156                     int index = absolute.indexOf( base );
157                     if ( index >= 0 )
158                     {
159                         relative = absolute.substring( index + base.length() );
160                     }
161                     else
162                     {
163                         relative = file.getPath();
164                     }
165 
166                     relative = relative.replace( '\\', '/' );
167 
168                     if ( !relative.startsWith( "/" ) )
169                     {
170                         relative = '/' + relative;
171                     }
172 
173                     String relativeFolder = relative.substring( 0, relative.lastIndexOf( '/' ) );
174 
175                     command.setWorkingDirectory( new File( fileSet.getBasedir().getAbsolutePath() + File.separatorChar
176                         + relativeFolder ).getCanonicalPath() );
177 
178                     command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() + relative );
179                 }
180                 catch ( IOException e )
181                 {
182                     throw new ScmException( "Invalid canonical path", e );
183                 }
184 
185                 //User identification to get access to vss repository
186                 if ( repo.getUserPassword() != null )
187                 {
188                     command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
189                 }
190 
191                 //Ignore: Do not ask for input under any circumstances.
192                 command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
193 
194                 commands.add( command );
195 
196             }
197 
198         }
199         else
200         {
201             Commandline command = new Commandline();
202 
203             command.setWorkingDirectory( fileSet.getBasedir().getAbsolutePath() );
204 
205             try
206             {
207                 command.addSystemEnvironment();
208             }
209             catch ( Exception e )
210             {
211                 throw new ScmException( "Can't add system environment.", e );
212             }
213 
214             command.addEnvironment( "SSDIR", repo.getVssdir() );
215 
216             String ssDir = VssCommandLineUtils.getSsDir();
217 
218             command.setExecutable( ssDir + VssConstants.SS_EXE );
219 
220             command.createArg().setValue( VssConstants.COMMAND_CHECKOUT );
221 
222             command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() );
223             //Display the history of an entire project list
224             command.createArg().setValue( VssConstants.FLAG_RECURSION );
225 
226             //User identification to get access to vss repository
227             if ( repo.getUserPassword() != null )
228             {
229                 command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
230             }
231 
232             //Ignore: Do not ask for input under any circumstances.
233             command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
234 
235             commands.add( command );
236 
237         }
238 
239         return commands;
240     }
241 
242     /**
243      * @return
244      */
245     protected ChangeLogCommand getChangeLogCommand()
246     {
247         VssHistoryCommand command = new VssHistoryCommand();
248 
249         command.setLogger( getLogger() );
250 
251         return command;
252     }
253 
254 }