From: Edwin L. Punzalan Date: Thu, 8 Jun 2006 13:32:13 +0000 (+0000) Subject: Implemented the rollback() method for the TransactionEvents X-Git-Tag: archiva-0.9-alpha-1~828 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c2cb417afb8fb1eeaa3cf3bb406d998b624540d6;p=archiva.git Implemented the rollback() method for the TransactionEvents git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@412747 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/DefaultRepositoryConverter.java b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/DefaultRepositoryConverter.java index 3c8a5b998..e946355c2 100644 --- a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/DefaultRepositoryConverter.java +++ b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/DefaultRepositoryConverter.java @@ -376,7 +376,6 @@ public class DefaultRepositoryConverter boolean result = true; if ( file.exists() ) { - // TODO: utility methods in the model converter File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( pom ) ); String contents = null; diff --git a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/AbstractTransactionEvent.java b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/AbstractTransactionEvent.java new file mode 100644 index 000000000..521930a28 --- /dev/null +++ b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/AbstractTransactionEvent.java @@ -0,0 +1,120 @@ +package org.apache.maven.repository.converter.transaction; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +/** + * Abstract class for the TransactionEvents + * + * @author Edwin Punzalan + */ +public abstract class AbstractTransactionEvent + implements TransactionEvent +{ + private File backup; + + private List createdDirs; + + /** + * Method that creates a directory as well as all the parent directories needed + * + * @param dir The File directory to be created + * @throws IOException when an unrecoverable error occurred + */ + protected void mkDirs( File dir ) + throws IOException + { + List createDirs = new ArrayList(); + + File parent = dir; + while( !parent.exists() || !parent.isDirectory() ) + { + createDirs.add( parent ); + + parent = parent.getParentFile(); + } + + createdDirs = new ArrayList(); + + while ( !createDirs.isEmpty() ) + { + File directory = (File) createDirs.remove( createDirs.size() - 1 ); + + if ( directory.mkdir() ) + { + createdDirs.add( directory ); + } + else + { + throw new IOException( "Failed to create directory: " + directory.getAbsolutePath() ); + } + } + } + + protected void revertMkDirs() + throws IOException + { + if ( createdDirs != null ) + { + Collections.reverse( createdDirs ); + + while( !createdDirs.isEmpty() ) + { + File dir = (File) createdDirs.remove( 0 ); + + if ( dir.isDirectory() && dir.list().length == 0 ) + { + FileUtils.deleteDirectory( dir.getAbsolutePath() ); + } + else + { + //cannot rollback created directory if it still contains files + break; + } + } + } + } + + protected void createBackup( File file ) + throws IOException + { + if ( file.exists() && file.isFile() ) + { + backup = File.createTempFile( "temp-", ".backup" ); + + FileUtils.copyFile( file, backup ); + + backup.deleteOnExit(); + } + } + + protected void restoreBackup( File file ) + throws IOException + { + if ( backup != null ) + { + FileUtils.copyFile( backup, file ); + } + } +} diff --git a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CopyFileEvent.java b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CopyFileEvent.java index 996aabd93..cddc854cc 100644 --- a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CopyFileEvent.java +++ b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CopyFileEvent.java @@ -27,7 +27,7 @@ import java.io.IOException; * @author Brett Porter */ public class CopyFileEvent - implements TransactionEvent + extends AbstractTransactionEvent { private final File source; @@ -42,7 +42,9 @@ public class CopyFileEvent public void commit() throws IOException { - destination.getParentFile().mkdirs(); + createBackup( destination ); + + mkDirs( destination.getParentFile() ); FileUtils.copyFile( source, destination ); } @@ -50,6 +52,10 @@ public class CopyFileEvent public void rollback() throws IOException { - // TODO: revert to backup/delete if was created + FileUtils.fileDelete( destination.getAbsolutePath() ); + + revertMkDirs(); + + restoreBackup( destination ); } } diff --git a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CreateFileEvent.java b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CreateFileEvent.java index 79644a37d..283ee60fd 100644 --- a/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CreateFileEvent.java +++ b/maven-repository-converter/src/main/java/org/apache/maven/repository/converter/transaction/CreateFileEvent.java @@ -27,7 +27,7 @@ import java.io.IOException; * @author Brett Porter */ public class CreateFileEvent - implements TransactionEvent + extends AbstractTransactionEvent { private final File destination; @@ -42,7 +42,14 @@ public class CreateFileEvent public void commit() throws IOException { - destination.getParentFile().mkdirs(); + createBackup( destination ); + + mkDirs( destination.getParentFile() ); + + if ( !destination.exists() && !destination.createNewFile() ) + { + throw new IOException( "Unable to create new file" ); + } FileUtils.fileWrite( destination.getAbsolutePath(), content ); } @@ -50,6 +57,10 @@ public class CreateFileEvent public void rollback() throws IOException { - // TODO: revert to backup/delete if was created + FileUtils.fileDelete( destination.getAbsolutePath() ); + + revertMkDirs(); + + restoreBackup( destination ); } } diff --git a/maven-repository-converter/src/test/java/org/apache/maven/repository/converter/transaction/CreateFileEventTest.java b/maven-repository-converter/src/test/java/org/apache/maven/repository/converter/transaction/CreateFileEventTest.java new file mode 100644 index 000000000..5a1008e35 --- /dev/null +++ b/maven-repository-converter/src/test/java/org/apache/maven/repository/converter/transaction/CreateFileEventTest.java @@ -0,0 +1,103 @@ +package org.apache.maven.repository.converter.transaction; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; + +/** + * @author Edwin Punzalan + */ +public class CreateFileEventTest + extends PlexusTestCase +{ + private File testDir = new File( PlexusTestCase.getBasedir(), "target/transaction-tests/create-file" ); + + public void testCreateCommitRollback() + throws Exception + { + File testFile = new File( testDir, "test-file.txt" ); + + CreateFileEvent event = new CreateFileEvent( "file contents", testFile ); + + assertFalse( "Test file is not yet created", testFile.exists() ); + + event.commit(); + + assertTrue( "Test file is not yet created", testFile.exists() ); + + event.rollback(); + + assertFalse( "Test file is has been deleted after rollback", testFile.exists() ); + assertFalse( "Test file parent directories has been rolledback too", testDir.exists() ); + assertTrue( "target directory still exists", new File( PlexusTestCase.getBasedir(), "target" ).exists() ); + } + + public void testCreateCommitRollbackWithBackup() + throws Exception + { + File testFile = new File( testDir, "test-file.txt" ); + + testFile.createNewFile(); + + FileUtils.fileWrite( testFile.getAbsolutePath(), "original contents" ); + + CreateFileEvent event = new CreateFileEvent( "modified contents", testFile ); + + String contents = FileUtils.fileRead( testFile.getAbsolutePath() ); + + assertEquals( "Test contents have not changed", "original contents", contents ); + + event.commit(); + + assertTrue( "Test file is not yet created", testFile.exists() ); + + event.rollback(); + + assertFalse( "Test file is has been deleted after rollback", testFile.exists() ); + assertFalse( "Test file parent directories has been rolledback too", testDir.exists() ); + assertTrue( "target directory still exists", new File( PlexusTestCase.getBasedir(), "target" ).exists() ); + } + + public void testCreateRollbackCommit() + throws Exception + { + File testFile = new File( testDir, "test-file.txt" ); + + CreateFileEvent event = new CreateFileEvent( "file contents", testFile ); + + assertFalse( "Test file is not yet created", testFile.exists() ); + + event.rollback(); + + assertFalse( "Test file is not yet created", testFile.exists() ); + + event.commit(); + + assertTrue( "Test file is not yet created", testFile.exists() ); + } + + protected void tearDown() + throws Exception + { + super.tearDown(); + + FileUtils.deleteDirectory( new File( testDir, "target/transaction-tests" ).getAbsolutePath() ); + } +}