View Javadoc
1   package org.apache.maven.scm.provider.vss.commands.checkin;
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.ScmVersion;
31  import org.apache.maven.scm.command.checkin.AbstractCheckInCommand;
32  import org.apache.maven.scm.command.checkin.CheckInScmResult;
33  import org.apache.maven.scm.provider.ScmProviderRepository;
34  import org.apache.maven.scm.provider.vss.commands.VssCommandLineUtils;
35  import org.apache.maven.scm.provider.vss.commands.VssConstants;
36  import org.apache.maven.scm.provider.vss.repository.VssScmProviderRepository;
37  import org.codehaus.plexus.util.cli.CommandLineUtils;
38  import org.codehaus.plexus.util.cli.Commandline;
39  
40  /**
41   * @author <a href="mailto:matpimenta@gmail.com">Mateus Pimenta</a>
42   * @author Olivier Lamy
43   * @since 1.3
44   * @version $Id
45   * 
46   */
47  public class VssCheckInCommand
48      extends AbstractCheckInCommand
49  {
50  
51      /**
52       * (non-Javadoc)
53       * 
54       * @see org.apache.maven.scm.command.checkin.AbstractCheckInCommand# executeCheckInCommand
55       * (org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet,
56       * java.lang.String, org.apache.maven.scm.ScmVersion)
57       */
58      protected CheckInScmResult executeCheckInCommand( ScmProviderRepository repository, ScmFileSet fileSet,
59                                                        String message, ScmVersion scmVersion )
60          throws ScmException
61      {
62          if ( getLogger().isDebugEnabled() )
63          {
64              getLogger().debug( "executing checkin command..." );
65          }
66  
67          VssScmProviderRepository repo = (VssScmProviderRepository) repository;
68  
69          List<Commandline> commandLines = buildCmdLine( repo, fileSet, scmVersion );
70  
71          VssCheckInConsumer consumer = new VssCheckInConsumer( repo, getLogger() );
72  
73          //      TODO handle deleted files from VSS
74          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
75  
76          int exitCode;
77  
78          StringBuilder sb = new StringBuilder();
79          for ( Commandline cl : commandLines )
80          {
81  
82              if ( getLogger().isDebugEnabled() )
83              {
84                  getLogger().debug( "Executing: " + cl.getWorkingDirectory().getAbsolutePath() + ">>" + cl.toString() );
85              }
86  
87              exitCode = VssCommandLineUtils.executeCommandline( cl, consumer, stderr, getLogger() );
88  
89              if ( exitCode != 0 )
90              {
91                  String error = stderr.getOutput();
92  
93                  if ( getLogger().isDebugEnabled() )
94                  {
95                      getLogger().debug( "VSS returns error: [" + error + "] return code: [" + exitCode + "]" );
96                  }
97                  if ( error.indexOf( "A writable copy of" ) < 0 )
98                  {
99                      return new CheckInScmResult( cl.toString(), "The vss command failed.", error, false );
100                 }
101                 // print out the writable copy for manual handling
102                 if ( getLogger().isWarnEnabled() )
103                 {
104                     getLogger().warn( error );
105                 }
106             }
107 
108         }
109         return new CheckInScmResult( sb.toString(), new ArrayList<ScmFile>() );
110     }
111 
112     public List<Commandline> buildCmdLine( VssScmProviderRepository repo, ScmFileSet fileSet, ScmVersion version )
113         throws ScmException
114     {
115 
116         List<File> files = fileSet.getFileList();
117         List<Commandline> commands = new ArrayList<Commandline>();
118 
119         if ( files.size() > 0 )
120         {
121 
122             String base;
123             try
124             {
125                 base = fileSet.getBasedir().getCanonicalPath();
126             }
127             catch ( IOException e )
128             {
129                 throw new ScmException( "Invalid canonical path", e );
130             }
131 
132             for ( File file : files )
133             {
134 
135                 Commandline command = new Commandline();
136 
137                 try
138                 {
139                     command.addSystemEnvironment();
140                 }
141                 catch ( Exception e )
142                 {
143                     throw new ScmException( "Can't add system environment.", e );
144                 }
145 
146                 command.addEnvironment( "SSDIR", repo.getVssdir() );
147 
148                 String ssDir = VssCommandLineUtils.getSsDir();
149 
150                 command.setExecutable( ssDir + VssConstants.SS_EXE );
151 
152                 command.createArg().setValue( VssConstants.COMMAND_CHECKIN );
153 
154                 String absolute;
155                 try
156                 {
157                     absolute = file.getCanonicalPath();
158                     String relative;
159                     int index = absolute.indexOf( base );
160                     if ( index >= 0 )
161                     {
162                         relative = absolute.substring( index + base.length() );
163                     }
164                     else
165                     {
166                         relative = file.getPath();
167                     }
168 
169                     relative = relative.replace( '\\', '/' );
170 
171                     if ( !relative.startsWith( "/" ) )
172                     {
173                         relative = '/' + relative;
174                     }
175 
176                     String relativeFolder = relative.substring( 0, relative.lastIndexOf( '/' ) );
177 
178                     command.setWorkingDirectory( new File( fileSet.getBasedir().getAbsolutePath() + File.separatorChar
179                         + relativeFolder ).getCanonicalPath() );
180 
181                     command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() + relative );
182                 }
183                 catch ( IOException e )
184                 {
185                     throw new ScmException( "Invalid canonical path", e );
186                 }
187 
188                 //User identification to get access to vss repository
189                 if ( repo.getUserPassword() != null )
190                 {
191                     command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
192                 }
193 
194                 // Ignore: Do not ask for input under any circumstances.
195                 command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
196 
197                 // Ignore: Do not touch local writable files.
198                 command.createArg().setValue( VssConstants.FLAG_REPLACE_WRITABLE );
199 
200                 commands.add( command );
201 
202             }
203 
204         }
205         else
206         {
207             Commandline command = new Commandline();
208 
209             command.setWorkingDirectory( fileSet.getBasedir().getAbsolutePath() );
210 
211             try
212             {
213                 command.addSystemEnvironment();
214             }
215             catch ( Exception e )
216             {
217                 throw new ScmException( "Can't add system environment.", e );
218             }
219 
220             command.addEnvironment( "SSDIR", repo.getVssdir() );
221 
222             String ssDir = VssCommandLineUtils.getSsDir();
223 
224             command.setExecutable( ssDir + VssConstants.SS_EXE );
225 
226             command.createArg().setValue( VssConstants.COMMAND_CHECKIN );
227 
228             command.createArg().setValue( VssConstants.PROJECT_PREFIX + repo.getProject() );
229             //Display the history of an entire project list
230             command.createArg().setValue( VssConstants.FLAG_RECURSION );
231 
232             //User identification to get access to vss repository
233             if ( repo.getUserPassword() != null )
234             {
235                 command.createArg().setValue( VssConstants.FLAG_LOGIN + repo.getUserPassword() );
236             }
237 
238             // Ignore: Do not ask for input under any circumstances.
239             command.createArg().setValue( VssConstants.FLAG_AUTORESPONSE_DEF );
240 
241             // Ignore: Do not touch local writable files.
242             command.createArg().setValue( VssConstants.FLAG_REPLACE_WRITABLE );
243 
244             commands.add( command );
245 
246         }
247 
248         return commands;
249 
250     }
251 }