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             updatedFiles = update( source, baseDestination, fileList );
108 
109             // process deletions in repository
110             LocalScmMetadataUtils metadataUtils = new LocalScmMetadataUtils( getLogger() );
111             LocalScmMetadata originalMetadata = metadataUtils.readMetadata( baseDestination );
112             if ( originalMetadata != null )
113             {
114                 LocalScmMetadata newMetadata = metadataUtils.buildMetadata( source );
115                 for ( Iterator<String> it = originalMetadata.getRepositoryFileNames().iterator(); it.hasNext(); )
116                 {
117                     String filename = it.next();
118                     if ( !newMetadata.getRepositoryFileNames().contains( filename ) )
119                     {
120                         File localFile = new File( baseDestination, filename );
121                         if ( localFile.exists() )
122                         {
123                             localFile.delete();
124                             updatedFiles.add( new ScmFile( "/" + filename, ScmFileStatus.UPDATED ) );
125                         }
126                     }
127                 }
128             }
129 
130             // rewrite metadata file
131             metadataUtils.writeMetadata( baseDestination, metadataUtils.buildMetadata( source ) );
132 
133         }
134         catch ( IOException ex )
135         {
136             throw new ScmException( "Error while checking out the files.", ex );
137         }
138 
139         return new LocalUpdateScmResult( null, updatedFiles );
140     }
141 
142     private List<ScmFile> update( File source, File baseDestination, List<File> files )
143         throws ScmException, IOException
144     {
145         String sourcePath = source.getAbsolutePath();
146 
147         List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
148 
149         for ( Iterator<File> i = files.iterator(); i.hasNext(); )
150         {
151             File repositoryFile = i.next();
152 
153             File repositoryDirectory = repositoryFile.getParentFile();
154 
155             String dest = repositoryFile.getAbsolutePath().substring( sourcePath.length() + 1 );
156 
157             File destinationFile = new File( baseDestination, dest );
158 
159             String repositoryFileContents = FileUtils.fileRead( repositoryFile );
160 
161             if ( destinationFile.exists() )
162             {
163                 String destionationFileContents = FileUtils.fileRead( destinationFile );
164 
165                 if ( repositoryFileContents.equals( destionationFileContents ) )
166                 {
167                     continue;
168                 }
169             }
170 
171             File destinationDirectory = destinationFile.getParentFile();
172 
173             if ( !destinationDirectory.exists() && !destinationDirectory.mkdirs() )
174             {
175                 throw new ScmException(
176                     "Could not create destination directory '" + destinationDirectory.getAbsolutePath() + "'." );
177             }
178 
179             ScmFileStatus status;
180 
181             if ( destinationFile.exists() )
182             {
183                 status = ScmFileStatus.UPDATED;
184             }
185             else
186             {
187                 status = ScmFileStatus.ADDED;
188             }
189 
190             FileUtils.copyFileToDirectory( repositoryFile, destinationDirectory );
191 
192             int chop = baseDestination.getAbsolutePath().length();
193 
194             String fileName = "/" + destinationFile.getAbsolutePath().substring( chop + 1 );
195 
196             updatedFiles.add( new ScmFile( fileName, status ) );
197         }
198 
199         return updatedFiles;
200     }
201 
202     /** {@inheritDoc} */
203     protected ChangeLogCommand getChangeLogCommand()
204     {
205         return new LocalChangeLogCommand();
206     }
207 }