View Javadoc
1   package org.apache.maven.scm.provider.starteam;
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.CommandParameters;
28  import org.apache.maven.scm.ScmException;
29  import org.apache.maven.scm.ScmFileSet;
30  import org.apache.maven.scm.command.add.AddScmResult;
31  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
32  import org.apache.maven.scm.command.checkin.CheckInScmResult;
33  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
34  import org.apache.maven.scm.command.diff.DiffScmResult;
35  import org.apache.maven.scm.command.edit.EditScmResult;
36  import org.apache.maven.scm.command.remove.RemoveScmResult;
37  import org.apache.maven.scm.command.status.StatusScmResult;
38  import org.apache.maven.scm.command.tag.TagScmResult;
39  import org.apache.maven.scm.command.unedit.UnEditScmResult;
40  import org.apache.maven.scm.command.update.UpdateScmResult;
41  import org.apache.maven.scm.provider.AbstractScmProvider;
42  import org.apache.maven.scm.provider.ScmProviderRepository;
43  import org.apache.maven.scm.provider.starteam.command.add.StarteamAddCommand;
44  import org.apache.maven.scm.provider.starteam.command.changelog.StarteamChangeLogCommand;
45  import org.apache.maven.scm.provider.starteam.command.checkin.StarteamCheckInCommand;
46  import org.apache.maven.scm.provider.starteam.command.checkout.StarteamCheckOutCommand;
47  import org.apache.maven.scm.provider.starteam.command.diff.StarteamDiffCommand;
48  import org.apache.maven.scm.provider.starteam.command.edit.StarteamEditCommand;
49  import org.apache.maven.scm.provider.starteam.command.remove.StarteamRemoveCommand;
50  import org.apache.maven.scm.provider.starteam.command.status.StarteamStatusCommand;
51  import org.apache.maven.scm.provider.starteam.command.tag.StarteamTagCommand;
52  import org.apache.maven.scm.provider.starteam.command.unedit.StarteamUnEditCommand;
53  import org.apache.maven.scm.provider.starteam.command.update.StarteamUpdateCommand;
54  import org.apache.maven.scm.provider.starteam.repository.StarteamScmProviderRepository;
55  import org.apache.maven.scm.repository.ScmRepositoryException;
56  import org.codehaus.plexus.util.StringUtils;
57  
58  /**
59   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
60   *
61   * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="starteam"
62   */
63  public class StarteamScmProvider
64      extends AbstractScmProvider
65  {
66      public static final String STARTEAM_URL_FORMAT =
67          "[username[:password]@]hostname:port:/projectName/[viewName/][folderHiearchy/]";
68  
69      // ----------------------------------------------------------------------
70      // ScmProvider Implementation
71      // ----------------------------------------------------------------------
72  
73      /** {@inheritDoc} */
74      public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
75          throws ScmRepositoryException
76      {
77          String user = null;
78  
79          String password = null;
80  
81          int index = scmSpecificUrl.indexOf( '@' );
82  
83          String rest = scmSpecificUrl;
84  
85          if ( index != -1 )
86          {
87              String userAndPassword = scmSpecificUrl.substring( 0, index );
88  
89              rest = scmSpecificUrl.substring( index + 1 );
90  
91              index = userAndPassword.indexOf( ':' );
92  
93              if ( index != -1 )
94              {
95                  user = userAndPassword.substring( 0, index );
96  
97                  password = userAndPassword.substring( index + 1 );
98              }
99              else
100             {
101                 user = userAndPassword;
102             }
103         }
104 
105         String[] tokens = StringUtils.split( rest, Character.toString( delimiter ) );
106 
107         String host;
108 
109         int port;
110 
111         String path;
112 
113         if ( tokens.length == 3 )
114         {
115             host = tokens[0];
116 
117             port = Integer.valueOf( tokens[1] ).intValue();
118 
119             path = tokens[2];
120         }
121         else if ( tokens.length == 2 )
122         {
123             if ( getLogger().isWarnEnabled() )
124             {
125                 getLogger().warn(
126                                   "Your scm URL use a deprecated format. The new format is :"
127                                       + STARTEAM_URL_FORMAT );
128             }
129 
130             host = tokens[0];
131 
132             if ( tokens[1].indexOf( '/' ) == -1 )
133             {
134                 throw new ScmRepositoryException(
135                     "Invalid SCM URL: The url has to be on the form: " + STARTEAM_URL_FORMAT );
136             }
137 
138             int at = tokens[1].indexOf( '/' );
139 
140             port = new Integer( tokens[1].substring( 0, at ) ).intValue();
141 
142             path = tokens[1].substring( at );
143         }
144         else
145         {
146             throw new ScmRepositoryException(
147                 "Invalid SCM URL: The url has to be on the form: " + STARTEAM_URL_FORMAT );
148         }
149 
150         try
151         {
152             return new StarteamScmProviderRepository( user, password, host, port, path );
153         }
154         catch ( Exception e )
155         {
156             throw new ScmRepositoryException(
157                 "Invalid SCM URL: The url has to be on the form: " + STARTEAM_URL_FORMAT );
158         }
159     }
160 
161     public String getScmType()
162     {
163         return "starteam";
164     }
165 
166     /** {@inheritDoc} */
167     public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
168         throws ScmException
169     {
170         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
171 
172         StarteamAddCommand command = new StarteamAddCommand();
173 
174         command.setLogger( getLogger() );
175 
176         return (AddScmResult) command.execute( repository, fileSet, parameters );
177     }
178 
179     /** {@inheritDoc} */
180     public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
181                                          CommandParameters parameters )
182         throws ScmException
183     {
184         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
185 
186         StarteamChangeLogCommand command = new StarteamChangeLogCommand();
187 
188         command.setLogger( getLogger() );
189 
190         return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
191     }
192 
193     /** {@inheritDoc} */
194     public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
195                                      CommandParameters parameters )
196         throws ScmException
197     {
198         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
199 
200         StarteamCheckInCommand command = new StarteamCheckInCommand();
201 
202         command.setLogger( getLogger() );
203 
204         return (CheckInScmResult) command.execute( repository, fileSet, parameters );
205     }
206 
207     /** {@inheritDoc} */
208     public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
209                                        CommandParameters parameters )
210         throws ScmException
211     {
212         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
213 
214         StarteamCheckOutCommand command = new StarteamCheckOutCommand();
215 
216         command.setLogger( getLogger() );
217 
218         return (CheckOutScmResult) command.execute( repository, fileSet, parameters );
219     }
220 
221     /** {@inheritDoc} */
222     public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
223         throws ScmException
224     {
225         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
226 
227         StarteamDiffCommand command = new StarteamDiffCommand();
228 
229         command.setLogger( getLogger() );
230 
231         return (DiffScmResult) command.execute( repository, fileSet, parameters );
232     }
233 
234     /** {@inheritDoc} */
235     public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
236         throws ScmException
237     {
238         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
239 
240         StarteamStatusCommand command = new StarteamStatusCommand();
241 
242         command.setLogger( getLogger() );
243 
244         return (StatusScmResult) command.execute( repository, fileSet, parameters );
245     }
246 
247     /** {@inheritDoc} */
248     public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
249         throws ScmException
250     {
251         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
252 
253         StarteamTagCommand command = new StarteamTagCommand();
254 
255         command.setLogger( getLogger() );
256 
257         return (TagScmResult) command.execute( repository, fileSet, parameters );
258     }
259 
260     /** {@inheritDoc} */
261     public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
262         throws ScmException
263     {
264         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
265 
266         StarteamUpdateCommand command = new StarteamUpdateCommand();
267 
268         command.setLogger( getLogger() );
269 
270         return (UpdateScmResult) command.execute( repository, fileSet, parameters );
271     }
272 
273     /** {@inheritDoc} */
274     protected EditScmResult edit( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
275         throws ScmException
276     {
277         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
278 
279         StarteamEditCommand command = new StarteamEditCommand();
280 
281         command.setLogger( getLogger() );
282 
283         return (EditScmResult) command.execute( repository, fileSet, parameters );
284     }
285 
286     /** {@inheritDoc} */
287     protected UnEditScmResult unedit( ScmProviderRepository repository, ScmFileSet fileSet,
288                                       CommandParameters parameters )
289         throws ScmException
290     {
291         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
292 
293         StarteamUnEditCommand command = new StarteamUnEditCommand();
294 
295         command.setLogger( getLogger() );
296 
297         return (UnEditScmResult) command.execute( repository, fileSet, parameters );
298     }
299 
300     /** {@inheritDoc} */
301     public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
302         throws ScmException
303     {
304         fileSet = fixUpScmFileSetAbsoluteFilePath( fileSet );
305 
306         StarteamRemoveCommand command = new StarteamRemoveCommand();
307 
308         command.setLogger( getLogger() );
309 
310         return (RemoveScmResult) command.execute( repository, fileSet, parameters );
311     }
312 
313     /**
314      * Starteam provider requires that all files in ScmFileSet must be relative to basedir
315      * This function ensures and converts all absolute paths to relative paths
316      *
317      * @param currentFileSet
318      * @return
319      * @throws ScmException
320      */
321     private static ScmFileSet fixUpScmFileSetAbsoluteFilePath( ScmFileSet currentFileSet )
322         throws ScmException
323     {
324         ScmFileSet newFileSet = null;
325         
326         try
327         {
328             File basedir = getAbsoluteFilePath( currentFileSet.getBasedir() );
329 
330             List<File> files = currentFileSet.getFileList();
331 
332             List<File> relPathFiles = new ArrayList<File>(files.size());
333             
334             for ( File file : files )
335             {
336                 if ( file.isAbsolute() )
337                 {
338                     relPathFiles.add( new File( getRelativePath( basedir, file ) ));
339                 } else {
340                     relPathFiles.add( file );
341                 }
342                 
343             }
344 
345             newFileSet = new ScmFileSet( basedir, relPathFiles );
346         }
347         catch ( IOException e )
348         {
349             throw new ScmException( "Invalid file set.", e );
350         }
351 
352         return newFileSet;
353     }
354 
355     public static String getRelativePath( File basedir, File f )
356         throws ScmException, IOException
357     {
358         File fileOrDir = getAbsoluteFilePath( f );
359 
360         if ( !fileOrDir.getCanonicalPath().startsWith( basedir.getCanonicalPath() ) )
361         {
362             throw new ScmException( fileOrDir.getPath() + " was not contained in " + basedir.getPath() );
363         }
364 
365         if ( basedir.getCanonicalFile().equals(basedir.getAbsoluteFile()) )
366         {
367             return fileOrDir.getPath().substring( basedir.getPath().length() + 1, fileOrDir.getPath().length() );
368         }
369         return fileOrDir.getPath().substring( basedir.getCanonicalPath().length() + 1, fileOrDir.getPath().length() );
370     }
371 
372     private static File getAbsoluteFilePath( File fileOrDir )
373         throws IOException
374     {
375         String javaPathString = fileOrDir.getCanonicalPath().replace( '\\', '/' );
376 
377         if ( javaPathString.endsWith( "/" ) )
378         {
379             javaPathString = javaPathString.substring( 0, javaPathString.length() - 1 );
380         }
381 
382         return new File( javaPathString );
383     }
384 }