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