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