View Javadoc
1   package org.codehaus.plexus.archiver.zip;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.util.Arrays;
6   import java.util.HashMap;
7   import java.util.Map;
8   import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
9   import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
10  import org.apache.commons.compress.archivers.zip.ZipFile;
11  import org.codehaus.plexus.archiver.ArchiveFile;
12  import org.codehaus.plexus.util.IOUtil;
13  import org.junit.Assert;
14  
15  /**
16   * A utility class, which allows to compare archive files.
17   */
18  public class ArchiveFileComparator
19  {
20  
21      public interface TarArchiveEntryConsumer
22      {
23  
24          void accept( TarArchiveEntry entry ) throws IOException;
25  
26      }
27  
28      public static void forEachTarArchiveEntry( ArchiveFile file, TarArchiveEntryConsumer consumer )
29          throws IOException
30      {
31          for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); )
32          {
33              TarArchiveEntry ze = (TarArchiveEntry) en.nextElement();
34              if ( !ze.isDirectory() )
35              {
36                  consumer.accept( ze );
37              }
38          }
39      }
40  
41      /**
42       * Creates a map with the archive files contents. The map keys
43       * are the names of file entries in the archive file. The map
44       * values are the respective archive entries.
45       */
46      private static Map<String, TarArchiveEntry> getFileEntries( ArchiveFile file )
47          throws IOException
48      {
49          final Map map = new HashMap();
50          for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); )
51          {
52              TarArchiveEntry ze = (TarArchiveEntry) en.nextElement();
53              if ( ze.isDirectory() )
54              {
55                  continue;
56              }
57              if ( map.put( ze.getName(), ze ) != null )
58              {
59                  Assert.fail( "Multiple archive file entries named " + ze.getName() + " found." );
60              }
61          }
62          return map;
63      }
64  
65      private static Map getFileEntries( ZipFile file )
66          throws IOException
67      {
68          final Map map = new HashMap();
69          for ( java.util.Enumeration en = file.getEntries(); en.hasMoreElements(); )
70          {
71              ZipArchiveEntry ze = (ZipArchiveEntry) en.nextElement();
72              if ( ze.isDirectory() )
73              {
74                  continue;
75              }
76              if ( map.put( ze.getName(), ze ) != null )
77              {
78                  Assert.fail( "Multiple archive file entries named " + ze.getName() + " found." );
79              }
80          }
81          return map;
82      }
83  
84      /**
85       * Called to compare the given archive entries.
86       */
87      private static void assertEquals( ArchiveFile file1, TarArchiveEntry entry1,
88                                        ArchiveFile file2, TarArchiveEntry entry2 )
89          throws IOException
90      {
91          Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() );
92          Assert.assertEquals( entry1.isSymbolicLink(), entry2.isSymbolicLink() );
93          Assert.assertEquals( entry1.getModTime().getTime(), entry2.getModTime().getTime() );
94  
95          final InputStream is1 = file1.getInputStream( entry1 );
96          final InputStream is2 = file2.getInputStream( entry2 );
97          final byte[] bytes1 = IOUtil.toByteArray( is1 );
98          final byte[] bytes2 = IOUtil.toByteArray( is2 );
99          Assert.assertTrue( Arrays.equals( bytes1, bytes2 ) );
100         is1.close();
101         is2.close();
102     }
103 
104     private static void assertEquals( ArchiveFile file1, TarArchiveEntry entry1,
105                                       ZipFile file2, ZipArchiveEntry entry2 )
106         throws IOException
107     {
108         Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() );
109 
110         final InputStream is1 = file1.getInputStream( entry1 );
111         final InputStream is2 = file2.getInputStream( entry2 );
112         final byte[] bytes1 = IOUtil.toByteArray( is1 );
113         final byte[] bytes2 = IOUtil.toByteArray( is2 );
114         Assert.assertTrue( Arrays.equals( bytes1, bytes2 ) );
115         is1.close();
116         is2.close();
117     }
118 
119     private static void assertEquals( ZipFile file1, ZipArchiveEntry entry1,
120                                       ZipFile file2, ZipArchiveEntry entry2 )
121         throws Exception
122     {
123         Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() );
124         Assert.assertEquals( entry1.isUnixSymlink(), entry2.isUnixSymlink() );
125         long timeDelta = entry1.getLastModifiedDate().getTime() - entry2.getLastModifiedDate().getTime();
126         Assert.assertTrue( Math.abs( timeDelta ) <= 1000 );
127 
128         final InputStream is1 = file1.getInputStream( entry1 );
129         final InputStream is2 = file2.getInputStream( entry2 );
130         final byte[] bytes1 = IOUtil.toByteArray( is1 );
131         final byte[] bytes2 = IOUtil.toByteArray( is2 );
132         Assert.assertTrue( Arrays.equals( bytes1, bytes2 ) );
133         is1.close();
134         is2.close();
135     }
136 
137     /**
138      * Called to compare the given archive files.
139      */
140     public static void assertEquals( final ArchiveFile file1, final ArchiveFile file2, final String prefix )
141         throws Exception
142     {
143 
144         final Map<String, TarArchiveEntry> map2 = getFileEntries( file2 );
145         forEachTarArchiveEntry( file1, new TarArchiveEntryConsumer()
146         {
147 
148             public void accept( TarArchiveEntry ze1 )
149                 throws IOException
150             {
151                 final String name1 = ze1.getName();
152                 final String name2 = prefix == null ? name1 : ( prefix + name1 );
153                 TarArchiveEntry ze2 = map2.remove( name2 );
154                 Assert.assertNotNull( ze2 );
155                 assertEquals( file1, ze1, file2, ze2 );
156 
157             }
158 
159         } );
160         Assert.assertTrue( map2.isEmpty() );
161     }
162 
163     public static void assertEquals( final ArchiveFile file1, final ZipFile file2, final String prefix )
164         throws Exception
165     {
166         final Map<String, ZipArchiveEntry> map2 = getFileEntries( file2 );
167         forEachTarArchiveEntry( file1, new TarArchiveEntryConsumer()
168         {
169 
170             public void accept( TarArchiveEntry ze1 )
171                 throws IOException
172             {
173                 final String name1 = ze1.getName();
174                 final String name2 = prefix == null ? name1 : ( prefix + name1 );
175                 ZipArchiveEntry ze2 = map2.remove( name2 );
176                 Assert.assertNotNull( ze2 );
177                 assertEquals( file1, ze1, file2, ze2 );
178             }
179 
180         } );
181         Assert.assertTrue( map2.isEmpty() );
182     }
183 
184     public static void assertEquals( org.apache.commons.compress.archivers.zip.ZipFile file1,
185                                      org.apache.commons.compress.archivers.zip.ZipFile file2, String prefix )
186         throws Exception
187     {
188         final Map map1 = getFileEntries( file1 );
189         final Map map2 = getFileEntries( file2 );
190         for ( Object o : map1.keySet() )
191         {
192             final String name1 = (String) o;
193             final String name2 = prefix == null ? name1 : ( prefix + name1 );
194             ZipArchiveEntry ze1 = (ZipArchiveEntry) map1.get( name1 );
195             ZipArchiveEntry ze2 = (ZipArchiveEntry) map2.remove( name2 );
196             Assert.assertNotNull( "Missing " + name1 + "in file 2", ze2 );
197             assertEquals( file1, ze1, file2, ze2 );
198         }
199         Assert.assertTrue( map2.isEmpty() );
200     }
201 
202 }