This project has retired. For details please refer to its Attic page.
AbstractTransactionEvent xref
View Javadoc
1   package org.apache.archiva.transaction;
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.archiva.checksum.ChecksumAlgorithm;
23  import org.apache.archiva.checksum.ChecksummedFile;
24  import org.apache.commons.io.FileUtils;
25  
26  import java.io.IOException;
27  import java.nio.charset.Charset;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.nio.file.Paths;
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.HashMap;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.stream.Stream;
38  
39  /**
40   * Abstract class for the TransactionEvents
41   *
42   *
43   */
44  public abstract class AbstractTransactionEvent
45      implements TransactionEvent
46  {
47      private Map<Path, Path> backups = new HashMap<>();
48  
49      private List<Path> createdDirs = new ArrayList<>();
50  
51      private List<Path> createdFiles = new ArrayList<>();
52  
53      private List<ChecksumAlgorithm> checksumAlgorithms;
54  
55      protected AbstractTransactionEvent()
56      {
57          this( new ArrayList<ChecksumAlgorithm>( 0 ) );
58      }
59  
60      protected AbstractTransactionEvent( List<ChecksumAlgorithm> checksumAlgorithms)
61      {
62          this.checksumAlgorithms = checksumAlgorithms;
63      }
64  
65      protected List<ChecksumAlgorithm> getChecksumAlgorithms()
66      {
67          return checksumAlgorithms;
68      }
69  
70      /**
71       * Method that creates a directory as well as all the parent directories needed
72       *
73       * @param dir The File directory to be created
74       * @throws IOException when an unrecoverable error occurred
75       */
76      protected void mkDirs( Path dir )
77          throws IOException
78      {
79          List<Path> createDirs = new ArrayList<>();
80  
81          Path parent = dir;
82          while ( !Files.exists(parent) || !Files.isDirectory(parent) )
83          {
84              createDirs.add( parent );
85  
86              parent = parent.getParent();
87          }
88  
89          while ( !createDirs.isEmpty() )
90          {
91              Path directory = createDirs.remove( createDirs.size() - 1 );
92              Files.createDirectories(directory);
93              createdDirs.add( directory );
94          }
95      }
96  
97      protected void revertMkDirs()
98          throws IOException
99      {
100         if ( createdDirs != null )
101         {
102             Collections.reverse( createdDirs );
103 
104             while ( !createdDirs.isEmpty() )
105             {
106                 Path dir = createdDirs.remove( 0 );
107 
108                 if ( Files.isDirectory(dir))
109                 {
110                     try(Stream<Path> str = Files.list(dir)) {
111                         if (str.count()==0) {
112                             org.apache.archiva.common.utils.FileUtils.deleteDirectory(dir);
113                         }
114                     }
115                 }
116                 else
117                 {
118                     //cannot rollback created directory if it still contains files
119                     break;
120                 }
121             }
122         }
123     }
124 
125     protected void revertFilesCreated()
126         throws IOException
127     {
128         Iterator<Path> it = createdFiles.iterator();
129         while ( it.hasNext() )
130         {
131             Path file = it.next();
132             Files.deleteIfExists(file);
133             it.remove();
134         }
135     }
136 
137     protected void createBackup( Path file )
138         throws IOException
139     {
140         if ( Files.exists(file) && Files.isRegularFile(file) )
141         {
142             Path backup = Files.createTempFile( "temp-", ".backup" );
143 
144             FileUtils.copyFile( file.toFile(), backup.toFile() );
145 
146             backup.toFile().deleteOnExit();
147 
148             backups.put( file, backup );
149         }
150     }
151 
152     protected void restoreBackups()
153         throws IOException
154     {
155         for ( Map.Entry<Path, Path> entry : backups.entrySet() )
156         {
157             FileUtils.copyFile( entry.getValue().toFile(), entry.getKey().toFile() );
158         }
159     }
160 
161     protected void restoreBackup( Path file )
162         throws IOException
163     {
164         Path backup = backups.get( file );
165         if ( backup != null )
166         {
167             FileUtils.copyFile( backup.toFile(), file.toFile() );
168         }
169     }
170 
171     /**
172      * Create checksums of file using all digesters defined at construction time.
173      *
174      * @param file
175      * @param force whether existing checksums should be overwritten or not
176      * @throws IOException
177      */
178     protected void createChecksums( Path file, boolean force )
179         throws IOException
180     {
181         for ( ChecksumAlgorithm checksumAlgorithm : getChecksumAlgorithms() )
182         {
183             Path checksumFile = Paths.get( file.toAbsolutePath( ) + "." + getChecksumFileExtension( checksumAlgorithm ) );
184             if ( Files.exists( checksumFile ) )
185             {
186                 if ( !force )
187                 {
188                     continue;
189                 }
190                 createBackup( checksumFile );
191             }
192             else
193             {
194                 createdFiles.add( checksumFile );
195             }
196         }
197         ChecksummedFile csFile = new ChecksummedFile( file );
198         csFile.fixChecksums( getChecksumAlgorithms() );
199     }
200 
201     /**
202      * TODO: Remove in favor of using FileUtils directly.
203      */
204     protected void writeStringToFile( Path file, String content )
205         throws IOException
206     {
207         org.apache.archiva.common.utils.FileUtils.writeStringToFile( file, Charset.defaultCharset(), content );
208     }
209 
210     /**
211      * File extension for checksums
212      * TODO should be moved to plexus-digester ?
213      */
214     protected String getChecksumFileExtension( ChecksumAlgorithm algorithm )
215     {
216         return algorithm.getExt().get(0);
217     }
218 
219 }