1 package org.apache.archiva.transaction;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import org.apache.commons.io.FileUtils;
23 import org.codehaus.plexus.digest.Digester;
24 import org.codehaus.plexus.digest.DigesterException;
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;
36 * Abstract class for the TransactionEvents
40 public abstract class AbstractTransactionEvent
41 implements TransactionEvent
43 private Map<File, File> backups = new HashMap<>();
45 private List<File> createdDirs = new ArrayList<>();
47 private List<File> createdFiles = new ArrayList<>();
50 * {@link List}<{@link Digester}>
52 private List<? extends Digester> digesters;
54 protected AbstractTransactionEvent()
56 this( new ArrayList<Digester>( 0 ) );
59 protected AbstractTransactionEvent( List<? extends Digester> digesters )
61 this.digesters = digesters;
64 protected List<? extends Digester> getDigesters()
70 * Method that creates a directory as well as all the parent directories needed
72 * @param dir The File directory to be created
73 * @throws IOException when an unrecoverable error occurred
75 protected void mkDirs( File dir )
78 List<File> createDirs = new ArrayList<>();
81 while ( !parent.exists() || !parent.isDirectory() )
83 createDirs.add( parent );
85 parent = parent.getParentFile();
88 while ( !createDirs.isEmpty() )
90 File directory = createDirs.remove( createDirs.size() - 1 );
92 if ( directory.mkdir() )
94 createdDirs.add( directory );
98 throw new IOException( "Failed to create directory: " + directory.getAbsolutePath() );
103 protected void revertMkDirs()
106 if ( createdDirs != null )
108 Collections.reverse( createdDirs );
110 while ( !createdDirs.isEmpty() )
112 File dir = (File) createdDirs.remove( 0 );
114 if ( dir.isDirectory() && dir.list().length == 0 )
116 FileUtils.deleteDirectory( dir );
120 //cannot rollback created directory if it still contains files
127 protected void revertFilesCreated()
130 Iterator<File> it = createdFiles.iterator();
131 while ( it.hasNext() )
133 File file = (File) it.next();
139 protected void createBackup( File file )
142 if ( file.exists() && file.isFile() )
144 File backup = File.createTempFile( "temp-", ".backup" );
146 FileUtils.copyFile( file, backup );
148 backup.deleteOnExit();
150 backups.put( file, backup );
154 protected void restoreBackups()
157 for ( Map.Entry<File, File> entry : backups.entrySet() )
159 FileUtils.copyFile( entry.getValue(), entry.getKey() );
163 protected void restoreBackup( File file )
166 File backup = (File) backups.get( file );
167 if ( backup != null )
169 FileUtils.copyFile( backup, file );
174 * Create checksums of file using all digesters defined at construction time.
177 * @param force whether existing checksums should be overwritten or not
178 * @throws IOException
180 protected void createChecksums( File file, boolean force )
183 for ( Digester digester : getDigesters() )
185 File checksumFile = new File( file.getAbsolutePath() + "." + getDigesterFileExtension( digester ) );
186 if ( checksumFile.exists() )
192 createBackup( checksumFile );
196 createdFiles.add( checksumFile );
201 writeStringToFile( checksumFile, digester.calc( file ) );
203 catch ( DigesterException e )
205 throw (IOException) e.getCause();
211 * TODO: Remove in favor of using FileUtils directly.
213 protected void writeStringToFile( File file, String content )
216 FileUtils.writeStringToFile( file, content );
220 * File extension for checksums
221 * TODO should be moved to plexus-digester ?
223 protected String getDigesterFileExtension( Digester digester )
225 return digester.getAlgorithm().toLowerCase().replaceAll( "-", "" );