From 4eebcf650256d6190e2a68107d6ddf784ac2d940 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 29 May 2007 14:09:25 +0000 Subject: [PATCH] Moving maven-transaction to archiva-transaction git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@542526 13f79535-47bb-0310-9956-ffa450edef68 --- archiva-base/maven-transaction/pom.xml | 48 ++++ .../transaction/AbstractTransactionEvent.java | 242 ++++++++++++++++++ .../maven/transaction/CopyFileEvent.java | 119 +++++++++ .../maven/transaction/CreateFileEvent.java | 83 ++++++ .../maven/transaction/FileTransaction.java | 102 ++++++++ .../maven/transaction/TransactionEvent.java | 46 ++++ .../transaction/TransactionException.java | 51 ++++ .../transaction/AbstractFileEventTest.java | 110 ++++++++ .../maven/transaction/CopyFileEventTest.java | 180 +++++++++++++ .../transaction/CreateFileEventTest.java | 122 +++++++++ 10 files changed, 1103 insertions(+) create mode 100644 archiva-base/maven-transaction/pom.xml create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/AbstractTransactionEvent.java create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CopyFileEvent.java create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CreateFileEvent.java create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/FileTransaction.java create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionEvent.java create mode 100644 archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionException.java create mode 100644 archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/AbstractFileEventTest.java create mode 100644 archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CopyFileEventTest.java create mode 100644 archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CreateFileEventTest.java diff --git a/archiva-base/maven-transaction/pom.xml b/archiva-base/maven-transaction/pom.xml new file mode 100644 index 000000000..31cde74f1 --- /dev/null +++ b/archiva-base/maven-transaction/pom.xml @@ -0,0 +1,48 @@ + + + + 4.0.0 + + org.apache.maven.shared + maven-shared-components + 6 + + maven-transaction + 1.0-alpha-2-SNAPSHOT + Maven Transactions + API for managing transaction. + + + org.codehaus.plexus + plexus-digest + 1.0 + + + org.codehaus.plexus + plexus-utils + 1.4 + + + org.codehaus.plexus + plexus-container-default + 1.0-alpha-9 + + + diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/AbstractTransactionEvent.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/AbstractTransactionEvent.java new file mode 100644 index 000000000..e9d1409ed --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/AbstractTransactionEvent.java @@ -0,0 +1,242 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.digest.Digester; +import org.codehaus.plexus.digest.DigesterException; +import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Abstract class for the TransactionEvents + * + * @author Edwin Punzalan + * @author Carlos Sanchez + * @version $Id$ + */ +public abstract class AbstractTransactionEvent + extends AbstractLogEnabled + implements TransactionEvent +{ + private Map backups = new HashMap();; + + private List createdDirs = new ArrayList(); + + private List createdFiles = new ArrayList(); + + /** {@link List}<{@link Digester}> */ + private List digesters; + + protected AbstractTransactionEvent() + { + this( new ArrayList( 0 ) ); + } + + protected AbstractTransactionEvent( List digesters ) + { + this.digesters = digesters; + } + + protected List getDigesters() + { + return digesters; + } + + /** + * 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(); + } + + 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 ); + } + else + { + //cannot rollback created directory if it still contains files + break; + } + } + } + } + + protected void revertFilesCreated() + throws IOException + { + Iterator it = createdFiles.iterator(); + while ( it.hasNext() ) + { + File file = (File) it.next(); + file.delete(); + it.remove(); + } + } + + protected void createBackup( File file ) + throws IOException + { + if ( file.exists() && file.isFile() ) + { + File backup = File.createTempFile( "temp-", ".backup" ); + + FileUtils.copyFile( file, backup ); + + backup.deleteOnExit(); + + backups.put( file, backup ); + } + } + + protected void restoreBackups() + throws IOException + { + Iterator it = backups.entrySet().iterator(); + while ( it.hasNext() ) + { + Map.Entry entry = (Map.Entry) it.next(); + FileUtils.copyFile( (File) entry.getValue(), (File) entry.getKey() ); + } + } + + protected void restoreBackup( File file ) + throws IOException + { + File backup = (File) backups.get( file ); + if ( backup != null ) + { + FileUtils.copyFile( backup, file ); + } + } + + /** + * Create checksums of file using all digesters defined at construction time. + * + * @param file + * @param force whether existing checksums should be overwritten or not + * @throws IOException + */ + protected void createChecksums( File file, boolean force ) + throws IOException + { + Iterator it = getDigesters().iterator(); + while ( it.hasNext() ) + { + Digester digester = (Digester) it.next(); + File checksumFile = new File( file.getAbsolutePath() + "." + getDigesterFileExtension( digester ) ); + if ( checksumFile.exists() ) + { + if ( !force ) + { + continue; + } + createBackup( checksumFile ); + } + else + { + createdFiles.add( checksumFile ); + } + + try + { + writeStringToFile( checksumFile, digester.calc( file ) ); + } + catch ( DigesterException e ) + { + throw (IOException) e.getCause(); + } + } + } + + protected void writeStringToFile( File file, String content ) + throws IOException + { + FileOutputStream out = null; + try + { + out = new FileOutputStream( file ); + IOUtil.copy( content, out ); + } + finally + { + IOUtil.close( out ); + } + } + + /** + * File extension for checksums + * TODO should be moved to plexus-digester ? + */ + protected String getDigesterFileExtension( Digester digester ) + { + return digester.getAlgorithm().toLowerCase().replaceAll( "-", "" ); + } + +} diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CopyFileEvent.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CopyFileEvent.java new file mode 100644 index 000000000..c04b5e16f --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CopyFileEvent.java @@ -0,0 +1,119 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.digest.Digester; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + * Event to copy a file. + * + * @author Brett Porter + * @author Carlos Sanchez + * @version $Id$ + */ +public class CopyFileEvent + extends AbstractTransactionEvent +{ + private final File source; + + private final File destination; + + /** + * + * @param source + * @param destination + * @param digesters {@link List}<{@link Digester}> digesters to use for checksumming + */ + public CopyFileEvent( File source, File destination, List digesters ) + { + super( digesters ); + this.source = source; + this.destination = destination; + } + + public void commit() + throws IOException + { + createBackup( destination ); + + mkDirs( destination.getParentFile() ); + + FileUtils.copyFile( source, destination ); + + createChecksums( destination, true ); + copyChecksums(); + + copyChecksum( "asc" ); + } + + /** + * Copy checksums of source file with all digesters if exist + * + * @throws IOException + */ + private void copyChecksums() + throws IOException + { + Iterator it = getDigesters().iterator(); + while ( it.hasNext() ) + { + Digester digester = (Digester) it.next(); + copyChecksum( getDigesterFileExtension( digester ) ); + } + } + + /** + * Copy checksum of source file with extension provided if exists + * + * @param extension + * @return whether the checksum exists or not + * @throws IOException + */ + private boolean copyChecksum( String extension ) + throws IOException + { + File checksumSource = new File( source.getAbsolutePath() + "." + extension ); + if ( checksumSource.exists() ) + { + File checksumDestination = new File( destination.getAbsolutePath() + "." + extension ); + FileUtils.copyFile( checksumSource, checksumDestination ); + return true; + } + return false; + } + + public void rollback() + throws IOException + { + destination.delete(); + + revertFilesCreated(); + + revertMkDirs(); + + restoreBackups(); + } +} diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CreateFileEvent.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CreateFileEvent.java new file mode 100644 index 000000000..c28b4cf32 --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/CreateFileEvent.java @@ -0,0 +1,83 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.digest.Digester; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * Event for creating a file from a string content. + * + * @author Brett Porter + * @author Carlos Sanchez + * @version $Id$ + */ +public class CreateFileEvent + extends AbstractTransactionEvent +{ + private final File destination; + + private final String content; + + /** + * + * @param content + * @param destination + * @param digesters {@link List}<{@link Digester}> digesters to use for checksumming + */ + public CreateFileEvent( String content, File destination, List digesters ) + { + super( digesters ); + this.content = content; + this.destination = destination; + } + + public void commit() + throws IOException + { + createBackup( destination ); + + mkDirs( destination.getParentFile() ); + + if ( !destination.exists() && !destination.createNewFile() ) + { + throw new IOException( "Unable to create new file" ); + } + + writeStringToFile( destination, content ); + + createChecksums( destination, true ); + } + + public void rollback() + throws IOException + { + destination.delete(); + + revertFilesCreated(); + + revertMkDirs(); + + restoreBackups(); + } +} diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/FileTransaction.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/FileTransaction.java new file mode 100644 index 000000000..ffe73059c --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/FileTransaction.java @@ -0,0 +1,102 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Implement commit/rollback semantics for a set of files. + * + * @author Brett Porter + */ +public class FileTransaction +{ + private List events = new ArrayList(); + + public void commit() + throws TransactionException + { + List toRollback = new ArrayList( events.size() ); + + for ( Iterator i = events.iterator(); i.hasNext(); ) + { + TransactionEvent event = (TransactionEvent) i.next(); + + try + { + event.commit(); + + toRollback.add( event ); + } + catch ( IOException e ) + { + try + { + rollback( toRollback ); + + throw new TransactionException( "Unable to commit file transaction", e ); + } + catch ( IOException ioe ) + { + throw new TransactionException( + "Unable to commit file transaction, and rollback failed with error: '" + ioe.getMessage() + "'", + e ); + } + } + } + } + + private void rollback( List toRollback ) + throws IOException + { + for ( Iterator i = toRollback.iterator(); i.hasNext(); ) + { + TransactionEvent event = (TransactionEvent) i.next(); + + event.rollback(); + } + } + + /** + * + * @param source + * @param destination + * @param digesters {@link List}<{@link Digester}> digesters to use for checksumming + */ + public void copyFile( File source, File destination, List digesters ) + { + events.add( new CopyFileEvent( source, destination, digesters ) ); + } + + /** + * + * @param content + * @param destination + * @param digesters {@link List}<{@link Digester}> digesters to use for checksumming + */ + public void createFile( String content, File destination, List digesters ) + { + events.add( new CreateFileEvent( content, destination, digesters ) ); + } +} diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionEvent.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionEvent.java new file mode 100644 index 000000000..5be7f1e03 --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionEvent.java @@ -0,0 +1,46 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.IOException; + +/** + * Interface for individual events in a transaction. + * + * @author Brett Porter + */ +public interface TransactionEvent +{ + /** + * Commit this event. + * + * @throws IOException if an error occurred committing the change + */ + void commit() + throws IOException; + + /** + * Rollback the even already committed. + * + * @throws IOException if an error occurred reverting the change + */ + void rollback() + throws IOException; +} diff --git a/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionException.java b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionException.java new file mode 100644 index 000000000..381a6ff42 --- /dev/null +++ b/archiva-base/maven-transaction/src/main/java/org/apache/maven/transaction/TransactionException.java @@ -0,0 +1,51 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/** + * TransactionException + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class TransactionException + extends Exception +{ + + public TransactionException() + { + } + + public TransactionException( String message ) + { + super( message ); + } + + public TransactionException( Throwable cause ) + { + super( cause ); + } + + public TransactionException( String message, Throwable cause ) + { + super( message, cause ); + } + +} diff --git a/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/AbstractFileEventTest.java b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/AbstractFileEventTest.java new file mode 100644 index 000000000..479471818 --- /dev/null +++ b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/AbstractFileEventTest.java @@ -0,0 +1,110 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.digest.Digester; +import org.codehaus.plexus.util.IOUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; + +/** + * + * @author Carlos Sanchez + * @version $Id$ + */ +public abstract class AbstractFileEventTest + extends PlexusTestCase +{ + protected List digesters; + + public void setUp() + throws Exception + { + super.setUp(); + + digesters = getContainer().lookupList( Digester.class.getName() ); + } + + protected void assertChecksumExists( File file, String algorithm ) + { + assertChecksum( file, algorithm, true ); + } + + protected void assertChecksumDoesNotExist( File file, String algorithm ) + { + assertChecksum( file, algorithm, false ); + } + + private void assertChecksum( File file, String algorithm, boolean exist ) + { + String msg = exist ? "exists" : "does not exist"; + File checksumFile = new File( file.getPath() + "." + algorithm ); + assertEquals( "Test file " + algorithm + " checksum " + msg, exist, checksumFile.exists() ); + } + + protected void assertChecksumCommit( File file ) + throws IOException + { + assertChecksumExists( file, "md5" ); + assertChecksumExists( file, "sha1" ); + } + + protected void assertChecksumRollback( File file ) + throws IOException + { + assertChecksumDoesNotExist( file, "md5" ); + assertChecksumDoesNotExist( file, "sha1" ); + } + + protected String readFile( File file ) + throws IOException + { + FileInputStream in = null; + try + { + in = new FileInputStream( file ); + return IOUtil.toString( in ); + } + finally + { + IOUtil.close( in ); + } + } + + protected void writeFile( File file, String content ) + throws IOException + { + FileOutputStream out = null; + try + { + out = new FileOutputStream( file ); + IOUtil.copy( content, out ); + } + finally + { + IOUtil.close( out ); + } + } +} \ No newline at end of file diff --git a/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CopyFileEventTest.java b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CopyFileEventTest.java new file mode 100644 index 000000000..1bfc37ad9 --- /dev/null +++ b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CopyFileEventTest.java @@ -0,0 +1,180 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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; +import java.io.IOException; + +/** + * @author Edwin Punzalan + */ +public class CopyFileEventTest + extends AbstractFileEventTest +{ + private File testDir = new File( PlexusTestCase.getBasedir(), "target/transaction-tests/copy-file" ); + + private File testDest = new File( testDir, "test-file.txt" ); + + private File testSource = new File( PlexusTestCase.getBasedir(), "target/transaction-tests/test-file.txt" ); + + private File testDestChecksum; + + private String source, oldChecksum; + + public void setUp() + throws Exception + { + super.setUp(); + + testSource.getParentFile().mkdirs(); + + testSource.createNewFile(); + + writeFile( testSource, "source contents" ); + + testDestChecksum = new File( testDest.getPath() + ".sha1" ); + + testDestChecksum.getParentFile().mkdirs(); + + testDestChecksum.createNewFile(); + + writeFile( testDestChecksum, "this is the checksum" ); + + assertTrue( "Test if the source exists", testSource.exists() ); + + assertTrue( "Test if the destination checksum exists", testDestChecksum.exists() ); + + source = readFile( testSource ); + + oldChecksum = readFile( testDestChecksum ); + } + + public void testCopyCommitRollback() + throws Exception + { + CopyFileEvent event = new CopyFileEvent( testSource, testDest, digesters ); + + assertFalse( "Test that the destination is not yet created", testDest.exists() ); + + event.commit(); + + assertTrue( "Test that the destination is created", testDest.exists() ); + + assertChecksumCommit( testDest ); + + String target = readFile( testDest ); + + assertTrue( "Test that the destination contents are copied correctly", source.equals( target ) ); + + event.rollback(); + + assertFalse( "Test that the destination file has been deleted", testDest.exists() ); + + assertChecksumRollback( testDest ); + } + + public void testCopyCommitRollbackWithBackup() + throws Exception + { + testDest.getParentFile().mkdirs(); + + testDest.createNewFile(); + + writeFile( testDest, "overwritten contents" ); + + assertTrue( "Test that the destination exists", testDest.exists() ); + + CopyFileEvent event = new CopyFileEvent( testSource, testDest, digesters ); + + String target = readFile( testDest ); + + assertTrue( "Test that the destination contents have not changed", target.equals( "overwritten contents" ) ); + + event.commit(); + + target = readFile( testDest ); + + assertTrue( "Test that the destination contents are copied correctly", source.equals( target ) ); + + assertChecksumCommit( testDest ); + + event.rollback(); + + target = readFile( testDest ); + + assertTrue( "Test the destination file contents have been restored", target.equals( "overwritten contents" ) ); + + assertChecksumRollback( testDest ); + } + + public void testCreateRollbackCommit() + throws Exception + { + CopyFileEvent event = new CopyFileEvent( testSource, testDest, digesters ); + + assertFalse( "Test that the destination is not yet created", testDest.exists() ); + + event.rollback(); + + assertFalse( "Test that the destination file is not yet created", testDest.exists() ); + + event.commit(); + + assertTrue( "Test that the destination is created", testDest.exists() ); + + assertChecksumCommit( testDest ); + + String target = readFile( testDest ); + + assertTrue( "Test that the destination contents are copied correctly", source.equals( target ) ); + } + + protected void tearDown() + throws Exception + { + super.tearDown(); + + FileUtils.deleteDirectory( new File( PlexusTestCase.getBasedir(), "target/transaction-tests" ) ); + } + + protected void assertChecksumCommit( File file ) + throws IOException + { + super.assertChecksumCommit( file ); + + String target = readFile( testDestChecksum ); + + assertFalse( "Test that the destination checksum contents are created correctly", oldChecksum.equals( target ) ); + } + + protected void assertChecksumRollback( File file ) + throws IOException + { + assertChecksumDoesNotExist( file, "md5" ); + assertChecksumExists( file, "sha1" ); + + String target = readFile( testDestChecksum ); + + assertEquals( "Test that the destination checksum contents are reverted correctly", oldChecksum, target ); + } +} diff --git a/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CreateFileEventTest.java b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CreateFileEventTest.java new file mode 100644 index 000000000..22a200639 --- /dev/null +++ b/archiva-base/maven-transaction/src/test/java/org/apache/maven/transaction/CreateFileEventTest.java @@ -0,0 +1,122 @@ +package org.apache.maven.transaction; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.File; + +import org.apache.maven.transaction.CreateFileEvent; +import org.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.util.FileUtils; + +/** + * @author Edwin Punzalan + */ +public class CreateFileEventTest + extends AbstractFileEventTest +{ + 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, digesters ); + + assertFalse( "Test file is not yet created", testFile.exists() ); + + event.commit(); + + assertTrue( "Test file has been created", testFile.exists() ); + + assertChecksumCommit( testFile ); + + event.rollback(); + + assertFalse( "Test file is has been deleted after rollback", testFile.exists() ); + + assertChecksumRollback( testFile ); + + 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.getParentFile().mkdirs(); + + testFile.createNewFile(); + + writeFile( testFile, "original contents" ); + + CreateFileEvent event = new CreateFileEvent( "modified contents", testFile, digesters ); + + String contents = readFile( testFile ); + + assertEquals( "Test contents have not changed", "original contents", contents ); + + event.commit(); + + contents = readFile( testFile ); + + assertEquals( "Test contents have not changed", "modified contents", contents ); + + assertChecksumCommit( testFile ); + + event.rollback(); + + contents = readFile( testFile ); + + assertEquals( "Test contents have not changed", "original contents", contents ); + + assertChecksumRollback( testFile ); + } + + public void testCreateRollbackCommit() + throws Exception + { + File testFile = new File( testDir, "test-file.txt" ); + + CreateFileEvent event = new CreateFileEvent( "file contents", testFile, digesters ); + + 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() ); + + assertChecksumCommit( testFile ); + } + + protected void tearDown() + throws Exception + { + super.tearDown(); + + FileUtils.deleteDirectory( new File( PlexusTestCase.getBasedir(), "target/transaction-tests" ) ); + } +} -- 2.39.5