package org.codehaus.plexus.archiver.zip; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.zip.*; import org.codehaus.plexus.archiver.ArchiveFile; import org.codehaus.plexus.util.IOUtil; import org.junit.Assert; /** * A utility class, which allows to compare archive files. */ public class ArchiveFileComparator { public interface TarArchiveEntryConsumer { void accept(TarArchiveEntry entry) throws IOException; } public static void forEachTarArchiveEntry( ArchiveFile file, TarArchiveEntryConsumer consumer ) throws IOException { for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); ) { TarArchiveEntry ze = (TarArchiveEntry) en.nextElement(); if ( !ze.isDirectory() ) { consumer.accept( ze ); } } } /** * Creates a map with the archive files contents. The map keys * are the names of file entries in the archive file. The map * values are the respective archive entries. */ private static Map<String, TarArchiveEntry> getFileEntries( ArchiveFile file ) throws IOException { final Map map = new HashMap(); for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); ) { TarArchiveEntry ze = (TarArchiveEntry) en.nextElement(); if ( ze.isDirectory() ) { continue; } if ( map.put( ze.getName(), ze ) != null ) { Assert.fail( "Multiple archive file entries named " + ze.getName() + " found." ); } } return map; } private static Map getFileEntries( ZipFile file ) throws IOException { final Map map = new HashMap(); for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); ) { ZipArchiveEntry ze = (ZipArchiveEntry) en.nextElement(); if ( ze.isDirectory() ) { continue; } if ( map.put( ze.getName(), ze ) != null ) { Assert.fail( "Multiple archive file entries named " + ze.getName() + " found." ); } } return map; } /** * Called to compare the given archive entries. */ private static void assertEquals( ArchiveFile file1, TarArchiveEntry entry1, ArchiveFile file2, TarArchiveEntry entry2 ) throws IOException { Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() ); Assert.assertEquals( entry1.getModTime().getTime(), entry2.getModTime().getTime() ); final InputStream is1 = file1.getInputStream( entry1 ); final InputStream is2 = file2.getInputStream( entry2 ); final byte[] bytes1 = IOUtil.toByteArray( is1 ); final byte[] bytes2 = IOUtil.toByteArray( is2 ); Assert.assertTrue( Arrays.equals( bytes1, bytes2 ) ); is1.close(); is2.close(); } private static void assertEquals( ZipFile file1, ZipArchiveEntry entry1, ZipFile file2, ZipArchiveEntry entry2 ) throws Exception { Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() ); Assert.assertEquals( entry1.getLastModifiedDate().getTime(), entry2.getLastModifiedDate().getTime() ); final InputStream is1 = file1.getInputStream( entry1 ); final InputStream is2 = file2.getInputStream( entry2 ); final byte[] bytes1 = IOUtil.toByteArray( is1 ); final byte[] bytes2 = IOUtil.toByteArray( is2 ); Assert.assertTrue( Arrays.equals( bytes1, bytes2 ) ); is1.close(); is2.close(); } /** * Called to compare the given archive files. */ public static void assertEquals( final ArchiveFile file1, final ArchiveFile file2, final String prefix ) throws Exception { final Map<String,TarArchiveEntry> map2 = getFileEntries( file2 ); forEachTarArchiveEntry( file1, new TarArchiveEntryConsumer() { public void accept( TarArchiveEntry ze1 ) throws IOException { final String name1 = ze1.getName(); final String name2 = prefix == null ? name1 : (prefix + name1); TarArchiveEntry ze2 = map2.remove(name2); Assert.assertNotNull(ze2); assertEquals(file1, ze1, file2, ze2); } } ); Assert.assertTrue( map2.isEmpty() ); } public static void assertEquals( org.apache.commons.compress.archivers.zip.ZipFile file1, org.apache.commons.compress.archivers.zip.ZipFile file2, String prefix ) throws Exception { final Map map1 = getFileEntries( file1 ); final Map map2 = getFileEntries( file2 ); for (Object o : map1.keySet()) { final String name1 = (String) o; final String name2 = prefix == null ? name1 : (prefix + name1); ZipArchiveEntry ze1 = (ZipArchiveEntry) map1.get(name1); ZipArchiveEntry ze2 = (ZipArchiveEntry) map2.remove(name2); Assert.assertNotNull("Missing " + name1 + "in file 2", ze2); assertEquals(file1, ze1, file2, ze2); } Assert.assertTrue( map2.isEmpty() ); } }