]> source.dussan.org Git - archiva.git/blob
73fabc998114745d5a46a919e7e95ba98d7a9a64
[archiva.git] /
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.commons.io.FileUtils;
23 import org.codehaus.plexus.digest.Digester;
24 import org.codehaus.plexus.digest.DigesterException;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34
35 /**
36  * Abstract class for the TransactionEvents
37  *
38  *
39  */
40 public abstract class AbstractTransactionEvent
41     implements TransactionEvent
42 {
43     private Map<File, File> backups = new HashMap<>();
44
45     private List<File> createdDirs = new ArrayList<>();
46
47     private List<File> createdFiles = new ArrayList<>();
48
49     /**
50      * {@link List}&lt;{@link Digester}&gt;
51      */
52     private List<? extends Digester> digesters;
53
54     protected AbstractTransactionEvent()
55     {
56         this( new ArrayList<Digester>( 0 ) );
57     }
58
59     protected AbstractTransactionEvent( List<? extends Digester> digesters )
60     {
61         this.digesters = digesters;
62     }
63
64     protected List<? extends Digester> getDigesters()
65     {
66         return digesters;
67     }
68
69     /**
70      * Method that creates a directory as well as all the parent directories needed
71      *
72      * @param dir The File directory to be created
73      * @throws IOException when an unrecoverable error occurred
74      */
75     protected void mkDirs( File dir )
76         throws IOException
77     {
78         List<File> createDirs = new ArrayList<>();
79
80         File parent = dir;
81         while ( !parent.exists() || !parent.isDirectory() )
82         {
83             createDirs.add( parent );
84
85             parent = parent.getParentFile();
86         }
87
88         while ( !createDirs.isEmpty() )
89         {
90             File directory = createDirs.remove( createDirs.size() - 1 );
91
92             if ( directory.mkdir() )
93             {
94                 createdDirs.add( directory );
95             }
96             else
97             {
98                 throw new IOException( "Failed to create directory: " + directory.getAbsolutePath() );
99             }
100         }
101     }
102
103     protected void revertMkDirs()
104         throws IOException
105     {
106         if ( createdDirs != null )
107         {
108             Collections.reverse( createdDirs );
109
110             while ( !createdDirs.isEmpty() )
111             {
112                 File dir = (File) createdDirs.remove( 0 );
113
114                 if ( dir.isDirectory() && dir.list().length == 0 )
115                 {
116                     FileUtils.deleteDirectory( dir );
117                 }
118                 else
119                 {
120                     //cannot rollback created directory if it still contains files
121                     break;
122                 }
123             }
124         }
125     }
126
127     protected void revertFilesCreated()
128         throws IOException
129     {
130         Iterator<File> it = createdFiles.iterator();
131         while ( it.hasNext() )
132         {
133             File file = (File) it.next();
134             file.delete();
135             it.remove();
136         }
137     }
138
139     protected void createBackup( File file )
140         throws IOException
141     {
142         if ( file.exists() && file.isFile() )
143         {
144             File backup = File.createTempFile( "temp-", ".backup" );
145
146             FileUtils.copyFile( file, backup );
147
148             backup.deleteOnExit();
149
150             backups.put( file, backup );
151         }
152     }
153
154     protected void restoreBackups()
155         throws IOException
156     {
157         for ( Map.Entry<File, File> entry : backups.entrySet() )
158         {
159             FileUtils.copyFile( entry.getValue(), entry.getKey() );
160         }
161     }
162
163     protected void restoreBackup( File file )
164         throws IOException
165     {
166         File backup = (File) backups.get( file );
167         if ( backup != null )
168         {
169             FileUtils.copyFile( backup, file );
170         }
171     }
172
173     /**
174      * Create checksums of file using all digesters defined at construction time.
175      *
176      * @param file
177      * @param force whether existing checksums should be overwritten or not
178      * @throws IOException
179      */
180     protected void createChecksums( File file, boolean force )
181         throws IOException
182     {
183         for ( Digester digester : getDigesters() )
184         {
185             File checksumFile = new File( file.getAbsolutePath() + "." + getDigesterFileExtension( digester ) );
186             if ( checksumFile.exists() )
187             {
188                 if ( !force )
189                 {
190                     continue;
191                 }
192                 createBackup( checksumFile );
193             }
194             else
195             {
196                 createdFiles.add( checksumFile );
197             }
198
199             try
200             {
201                 writeStringToFile( checksumFile, digester.calc( file ) );
202             }
203             catch ( DigesterException e )
204             {
205                 throw (IOException) e.getCause();
206             }
207         }
208     }
209
210     /**
211      * TODO: Remove in favor of using FileUtils directly.
212      */
213     protected void writeStringToFile( File file, String content )
214         throws IOException
215     {
216         FileUtils.writeStringToFile( file, content );
217     }
218
219     /**
220      * File extension for checksums
221      * TODO should be moved to plexus-digester ?
222      */
223     protected String getDigesterFileExtension( Digester digester )
224     {
225         return digester.getAlgorithm().toLowerCase().replaceAll( "-", "" );
226     }
227
228 }