View Javadoc

1   package org.apache.continuum.scm;
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  
25  import javax.annotation.Resource;
26  
27  import org.apache.commons.io.FileUtils;
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.maven.scm.ScmException;
30  import org.apache.maven.scm.ScmFileSet;
31  import org.apache.maven.scm.ScmTag;
32  import org.apache.maven.scm.ScmVersion;
33  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
34  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
35  import org.apache.maven.scm.command.update.UpdateScmResult;
36  import org.apache.maven.scm.manager.NoSuchScmProviderException;
37  import org.apache.maven.scm.manager.ScmManager;
38  import org.apache.maven.scm.repository.ScmRepository;
39  import org.apache.maven.scm.repository.ScmRepositoryException;
40  import org.springframework.stereotype.Service;
41  
42  /**
43   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
44   * @version $Id: DefaultContinuumScm.java 765340 2009-04-15 20:22:00Z evenisse $
45   * @todo consider folding some of this into Maven SCM itself
46   */
47  @Service("continuumScm")
48  public class DefaultContinuumScm
49      implements ContinuumScm
50  {
51      /**
52       * The Maven SCM manager to use.
53       */
54      @Resource
55      private ScmManager scmManager;
56  
57      public CheckOutScmResult checkout( ContinuumScmConfiguration configuration )
58          throws IOException, ScmException
59      {
60          ScmVersion scmVersion = getScmVersion( configuration );
61  
62          // TODO: probably need to base this from a working directory in the main configuration
63          File workingDirectory = configuration.getWorkingDirectory();
64  
65          ScmRepository repository = getScmRepository( configuration );
66  
67          CheckOutScmResult result;
68  
69          // TODO: synchronizing *all* checkouts is unnecessary
70          synchronized ( this )
71          {
72              if ( !workingDirectory.exists() )
73              {
74                  if ( !workingDirectory.mkdirs() )
75                  {
76                      throw new IOException( "Could not make directory: " + workingDirectory.getAbsolutePath() );
77                  }
78              }
79              else
80              {
81                  FileUtils.cleanDirectory( workingDirectory );
82              }
83  
84              ScmFileSet fileSet = new ScmFileSet( workingDirectory );
85  
86              result = scmManager.checkOut( repository, fileSet, scmVersion );
87          }
88          return result;
89      }
90  
91      private ScmVersion getScmVersion( ContinuumScmConfiguration configuration )
92      {
93          String tag = configuration.getTag();
94  
95          ScmVersion scmVersion = null;
96          if ( tag != null )
97          {
98              // TODO: differentiate between tag and branch? Allow for revision?
99              scmVersion = new ScmTag( tag );
100         }
101         return scmVersion;
102     }
103 
104     public UpdateScmResult update( ContinuumScmConfiguration configuration )
105         throws ScmException
106     {
107         ScmVersion scmVersion = getScmVersion( configuration );
108 
109         File workingDirectory = configuration.getWorkingDirectory();
110         if ( !workingDirectory.exists() )
111         {
112             // TODO: maybe we could check it out - it seems we currently rely on Continuum figuring this out
113             throw new IllegalStateException(
114                 "The working directory for the project doesn't exist " + "(" + workingDirectory.getAbsolutePath() +
115                     ")." );
116         }
117 
118         ScmRepository repository = getScmRepository( configuration );
119 
120         // Some SCM provider requires additional system properties during update
121         if ( "starteam".equals( repository.getProvider() ) )
122         {
123             // TODO: remove the use of system property - need a better way to pass provider specific configuration
124 
125             // Remove the clientspec name, so it will be recalculated between each command for each project
126             // instead of use the same for all projects
127             System.setProperty( "maven.scm.starteam.deleteLocal", "true" );
128         }
129 
130         UpdateScmResult result;
131 
132         ScmFileSet fileSet = new ScmFileSet( workingDirectory );
133 
134         // TODO: shouldn't need to synchronize this
135         synchronized ( this )
136         {
137             result = scmManager.update( repository, fileSet, scmVersion, configuration.getLatestUpdateDate() );
138         }
139 
140         return result;
141     }
142 
143     public ChangeLogScmResult changeLog( ContinuumScmConfiguration configuration )
144         throws ScmException
145     {
146         ScmVersion scmVersion = getScmVersion( configuration );
147 
148         // TODO: probably need to base this from a working directory in the main configuration
149         File workingDirectory = configuration.getWorkingDirectory();
150 
151         ScmRepository repository = getScmRepository( configuration );
152 
153         ChangeLogScmResult result;
154 
155         ScmFileSet fileSet = new ScmFileSet( workingDirectory );
156 
157         result = scmManager.changeLog( repository, fileSet, scmVersion, scmVersion );
158 
159         return result;
160     }
161 
162     /**
163      * Create a Maven SCM repository for obtaining the checkout from.
164      *
165      * @param configuration the configuration for the working copy and SCM
166      * @return the repository created
167      * @throws NoSuchScmProviderException
168      * @throws ScmRepositoryException
169      */
170     private ScmRepository getScmRepository( ContinuumScmConfiguration configuration )
171         throws ScmRepositoryException, NoSuchScmProviderException
172     {
173         ScmRepository repository = scmManager.makeScmRepository( configuration.getUrl() );
174 
175         // TODO: tie together with the clientspec change below
176         // This checkout will be retained between uses, so it remains connected to the repository
177         repository.getProviderRepository().setPersistCheckout( true );
178 
179         // TODO: should this be svnexe?
180         if ( !configuration.isUseCredentialsCache() || !"svn".equals( repository.getProvider() ) )
181         {
182             if ( !StringUtils.isEmpty( configuration.getUsername() ) )
183             {
184                 repository.getProviderRepository().setUser( configuration.getUsername() );
185 
186                 if ( !StringUtils.isEmpty( configuration.getPassword() ) )
187                 {
188                     repository.getProviderRepository().setPassword( configuration.getPassword() );
189                 }
190                 else
191                 {
192                     repository.getProviderRepository().setPassword( "" );
193                 }
194             }
195         }
196 
197         if ( "perforce".equals( repository.getProvider() ) )
198         {
199             // TODO: remove the use of system property - need a better way to pass provider specific configuration
200 
201             // Remove the clientspec name, so it will be recalculated between each command for each project
202             // instead of use the same for all projects
203             System.setProperty( "maven.scm.perforce.clientspec.name", "" );
204         }
205 
206         return repository;
207     }
208 
209     public ScmManager getScmManager()
210     {
211         return scmManager;
212     }
213 
214     public void setScmManager( ScmManager scmManager )
215     {
216         this.scmManager = scmManager;
217     }
218 
219     // TODO: add a nuke() method
220 }