View Javadoc
1   package org.apache.maven.scm.provider.local.command.update;
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 org.apache.maven.scm.ScmException;
23  import org.apache.maven.scm.ScmFile;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.ScmFileStatus;
26  import org.apache.maven.scm.ScmVersion;
27  import org.apache.maven.scm.command.changelog.ChangeLogCommand;
28  import org.apache.maven.scm.command.update.AbstractUpdateCommand;
29  import org.apache.maven.scm.command.update.UpdateScmResult;
30  import org.apache.maven.scm.provider.ScmProviderRepository;
31  import org.apache.maven.scm.provider.local.command.LocalCommand;
32  import org.apache.maven.scm.provider.local.command.changelog.LocalChangeLogCommand;
33  import org.apache.maven.scm.provider.local.metadata.LocalScmMetadata;
34  import org.apache.maven.scm.provider.local.metadata.LocalScmMetadataUtils;
35  import org.apache.maven.scm.provider.local.repository.LocalScmProviderRepository;
36  import org.codehaus.plexus.util.FileUtils;
37  
38  import java.io.File;
39  import java.io.IOException;
40  import java.util.ArrayList;
41  import java.util.Iterator;
42  import java.util.List;
43  
44  /**
45   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
46   * @author Olivier Lamy
47   *
48   */
49  public class LocalUpdateCommand
50      extends AbstractUpdateCommand
51      implements LocalCommand
52  {
53      /** {@inheritDoc} */
54      protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repo, ScmFileSet fileSet, ScmVersion version )
55          throws ScmException
56      {
57          LocalScmProviderRepository repository = (LocalScmProviderRepository) repo;
58  
59          if ( version != null )
60          {
61              throw new ScmException( "The local scm doesn't support tags." );
62          }
63  
64          File root = new File( repository.getRoot() );
65  
66          String module = repository.getModule();
67  
68          File source = new File( root, module );
69  
70          File baseDestination = fileSet.getBasedir();
71  
72          if ( !baseDestination.exists() )
73          {
74              throw new ScmException(
75                  "The working directory doesn't exist (" + baseDestination.getAbsolutePath() + ")." );
76          }
77  
78          if ( !root.exists() )
79          {
80              throw new ScmException( "The base directory doesn't exist (" + root.getAbsolutePath() + ")." );
81          }
82  
83          if ( !source.exists() )
84          {
85              throw new ScmException( "The module directory doesn't exist (" + source.getAbsolutePath() + ")." );
86          }
87  
88          if ( !baseDestination.exists() && !baseDestination.isDirectory() )
89          {
90              throw new ScmException( "The destination directory isn't a directory or doesn't exist ("
91                  + baseDestination.getAbsolutePath() + ")." );
92          }
93  
94          List<ScmFile> updatedFiles;
95  
96          try
97          {
98              if ( getLogger().isInfoEnabled() )
99              {
100                 getLogger().info(
101                                   "Updating '" + baseDestination.getAbsolutePath() + "' from '"
102                                       + source.getAbsolutePath() + "'." );
103             }
104 
105             @SuppressWarnings( "unchecked" )
106             List<File> fileList = FileUtils.getFiles( source.getAbsoluteFile(), "**", null );
107             List<File> list = fileList;
108             updatedFiles = update( source, baseDestination, list );
109 
110             // process deletions in repository
111             LocalScmMetadataUtils metadataUtils = new LocalScmMetadataUtils( getLogger() );
112             LocalScmMetadata originalMetadata = metadataUtils.readMetadata( baseDestination );
113             if ( originalMetadata != null )
114             {
115                 LocalScmMetadata newMetadata = metadataUtils.buildMetadata( source );
116                 for ( Iterator<String> it = originalMetadata.getRepositoryFileNames().iterator(); it.hasNext(); )
117                 {
118                     String filename = it.next();
119                     if ( !newMetadata.getRepositoryFileNames().contains( filename ) )
120                     {
121                         File localFile = new File( baseDestination, filename );
122                         if ( localFile.exists() )
123                         {
124                             localFile.delete();
125                             updatedFiles.add( new ScmFile( "/" + filename, ScmFileStatus.UPDATED ) );
126                         }
127                     }
128                 }
129             }
130 
131             // rewrite metadata file
132             metadataUtils.writeMetadata( baseDestination, metadataUtils.buildMetadata( source ) );
133 
134         }
135         catch ( IOException ex )
136         {
137             throw new ScmException( "Error while checking out the files.", ex );
138         }
139 
140         return new LocalUpdateScmResult( null, updatedFiles );
141     }
142 
143     private List<ScmFile> update( File source, File baseDestination, List<File> files )
144         throws ScmException, IOException
145     {
146         String sourcePath = source.getAbsolutePath();
147 
148         List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
149 
150         for ( Iterator<File> i = files.iterator(); i.hasNext(); )
151         {
152             File repositoryFile = i.next();
153 
154             File repositoryDirectory = repositoryFile.getParentFile();
155 
156             // TODO: Add more excludes here
157             if ( repositoryDirectory != null && repositoryDirectory.getName().equals( "CVS" ) )
158             {
159                 continue;
160             }
161 
162             String dest = repositoryFile.getAbsolutePath().substring( sourcePath.length() + 1 );
163 
164             File destinationFile = new File( baseDestination, dest );
165 
166             String repositoryFileContents = FileUtils.fileRead( repositoryFile );
167 
168             if ( destinationFile.exists() )
169             {
170                 String destionationFileContents = FileUtils.fileRead( destinationFile );
171 
172                 if ( repositoryFileContents.equals( destionationFileContents ) )
173                 {
174                     continue;
175                 }
176             }
177 
178             File destinationDirectory = destinationFile.getParentFile();
179 
180             if ( !destinationDirectory.exists() && !destinationDirectory.mkdirs() )
181             {
182                 throw new ScmException(
183                     "Could not create destination directory '" + destinationDirectory.getAbsolutePath() + "'." );
184             }
185 
186             ScmFileStatus status;
187 
188             if ( destinationFile.exists() )
189             {
190                 status = ScmFileStatus.UPDATED;
191             }
192             else
193             {
194                 status = ScmFileStatus.ADDED;
195             }
196 
197             FileUtils.copyFileToDirectory( repositoryFile, destinationDirectory );
198 
199             int chop = baseDestination.getAbsolutePath().length();
200 
201             String fileName = "/" + destinationFile.getAbsolutePath().substring( chop + 1 );
202 
203             updatedFiles.add( new ScmFile( fileName, status ) );
204         }
205 
206         return updatedFiles;
207     }
208 
209     /** {@inheritDoc} */
210     protected ChangeLogCommand getChangeLogCommand()
211     {
212         return new LocalChangeLogCommand();
213     }
214 }