View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.compress.archivers;
20  
21  import static org.junit.Assert.*;
22  
23  import java.io.BufferedInputStream;
24  import java.io.ByteArrayOutputStream;
25  import java.io.File;
26  import java.io.FileInputStream;
27  import java.io.FileOutputStream;
28  import java.io.InputStream;
29  import java.io.OutputStream;
30  
31  import org.apache.commons.compress.AbstractTestCase;
32  import org.apache.commons.compress.archivers.ar.ArArchiveEntry;
33  import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
34  import org.apache.commons.compress.archivers.ar.ArArchiveOutputStream;
35  import org.apache.commons.compress.utils.IOUtils;
36  import org.junit.Ignore;
37  import org.junit.Test;
38  
39  public final class ArTestCase extends AbstractTestCase {
40  
41      @Test
42      public void testArArchiveCreation() throws Exception {
43          final File output = new File(dir, "bla.ar");
44  
45          final File file1 = getFile("test1.xml");
46          final File file2 = getFile("test2.xml");
47  
48          final OutputStream out = new FileOutputStream(output);
49          final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("ar", out);
50          os.putArchiveEntry(new ArArchiveEntry("test1.xml", file1.length()));
51          IOUtils.copy(new FileInputStream(file1), os);
52          os.closeArchiveEntry();
53  
54          os.putArchiveEntry(new ArArchiveEntry("test2.xml", file2.length()));
55          IOUtils.copy(new FileInputStream(file2), os);
56          os.closeArchiveEntry();
57  
58          os.close();
59      }
60  
61      @Test
62      public void testArUnarchive() throws Exception {
63          final File output = new File(dir, "bla.ar");
64          {
65              final File file1 = getFile("test1.xml");
66              final File file2 = getFile("test2.xml");
67  
68              final OutputStream out = new FileOutputStream(output);
69              final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("ar", out);
70              os.putArchiveEntry(new ArArchiveEntry("test1.xml", file1.length()));
71              IOUtils.copy(new FileInputStream(file1), os);
72              os.closeArchiveEntry();
73  
74              os.putArchiveEntry(new ArArchiveEntry("test2.xml", file2.length()));
75              IOUtils.copy(new FileInputStream(file2), os);
76              os.closeArchiveEntry();
77              os.close();
78              out.close();
79          }
80  
81          // UnArArchive Operation
82          final File input = output;
83          try (final InputStream is = new FileInputStream(input);
84                  final ArchiveInputStream in = new ArchiveStreamFactory()
85                          .createArchiveInputStream(new BufferedInputStream(is))) {
86              final ArArchiveEntry entry = (ArArchiveEntry) in.getNextEntry();
87  
88              final File target = new File(dir, entry.getName());
89              try (final OutputStream out = new FileOutputStream(target)) {
90                  IOUtils.copy(in, out);
91              }
92          }
93      }
94  
95      @Test
96      public void testArDelete() throws Exception {
97          final File output = new File(dir, "bla.ar");
98  
99          final File file1 = getFile("test1.xml");
100         final File file2 = getFile("test2.xml");
101         {
102             // create
103 
104             final OutputStream out = new FileOutputStream(output);
105             final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("ar", out);
106             os.putArchiveEntry(new ArArchiveEntry("test1.xml", file1.length()));
107             IOUtils.copy(new FileInputStream(file1), os);
108             os.closeArchiveEntry();
109 
110             os.putArchiveEntry(new ArArchiveEntry("test2.xml", file2.length()));
111             IOUtils.copy(new FileInputStream(file2), os);
112             os.closeArchiveEntry();
113             os.close();
114             out.close();
115         }
116 
117         assertEquals(8
118                      + 60 + file1.length() + (file1.length() % 2)
119                      + 60 + file2.length() + (file2.length() % 2),
120                      output.length());
121 
122         final File output2 = new File(dir, "bla2.ar");
123 
124         int copied = 0;
125         int deleted = 0;
126 
127         {
128             // remove all but one file
129 
130             final InputStream is = new FileInputStream(output);
131             final OutputStream os = new FileOutputStream(output2);
132             final ArchiveOutputStream aos = new ArchiveStreamFactory().createArchiveOutputStream("ar", os);
133             final ArchiveInputStream ais = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(is));
134             while(true) {
135                 final ArArchiveEntry entry = (ArArchiveEntry)ais.getNextEntry();
136                 if (entry == null) {
137                     break;
138                 }
139 
140                 if ("test1.xml".equals(entry.getName())) {
141                     aos.putArchiveEntry(entry);
142                     IOUtils.copy(ais, aos);
143                     aos.closeArchiveEntry();
144                     copied++;
145                 } else {
146                     IOUtils.copy(ais, new ByteArrayOutputStream());
147                     deleted++;
148                 }
149 
150             }
151             ais.close();
152             aos.close();
153             is.close();
154             os.close();
155         }
156 
157         assertEquals(1, copied);
158         assertEquals(1, deleted);
159         assertEquals(8
160                      + 60 + file1.length() + (file1.length() % 2),
161                      output2.length());
162 
163         long files = 0;
164         long sum = 0;
165 
166         {
167             final InputStream is = new FileInputStream(output2);
168             final ArchiveInputStream ais = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(is));
169             while(true) {
170                 final ArArchiveEntry entry = (ArArchiveEntry)ais.getNextEntry();
171                 if (entry == null) {
172                     break;
173                 }
174 
175                 IOUtils.copy(ais, new ByteArrayOutputStream());
176 
177                 sum +=  entry.getLength();
178                 files++;
179             }
180             ais.close();
181             is.close();
182         }
183 
184         assertEquals(1, files);
185         assertEquals(file1.length(), sum);
186 
187     }
188 
189     // TODO: revisit - does AR not support storing directories?
190     @Ignore
191     @Test
192     public void XtestDirectoryEntryFromFile() throws Exception {
193         final File[] tmp = createTempDirAndFile();
194         File archive = null;
195         ArArchiveOutputStream aos = null;
196         ArArchiveInputStream ais = null;
197         try {
198             archive = File.createTempFile("test.", ".ar", tmp[0]);
199             archive.deleteOnExit();
200             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
201             final long beforeArchiveWrite = tmp[0].lastModified();
202             final ArArchiveEntry in = new ArArchiveEntry(tmp[0], "foo");
203             aos.putArchiveEntry(in);
204             aos.closeArchiveEntry();
205             aos.close();
206             aos = null;
207             ais = new ArArchiveInputStream(new FileInputStream(archive));
208             final ArArchiveEntry out = ais.getNextArEntry();
209             ais.close();
210             ais = null;
211             assertNotNull(out);
212             assertEquals("foo/", out.getName());
213             assertEquals(0, out.getSize());
214             // AR stores time with a granularity of 1 second
215             assertEquals(beforeArchiveWrite / 1000,
216                          out.getLastModifiedDate().getTime() / 1000);
217             assertTrue(out.isDirectory());
218         } finally {
219             if (ais != null) {
220                 ais.close();
221             }
222             if (aos != null) {
223                 aos.close();
224             }
225             tryHardToDelete(archive);
226             tryHardToDelete(tmp[1]);
227             rmdir(tmp[0]);
228         }
229     }
230 
231     // TODO: revisit - does AR not support storing directories?
232     @Ignore
233     @Test
234     public void XtestExplicitDirectoryEntry() throws Exception {
235         final File[] tmp = createTempDirAndFile();
236         File archive = null;
237         ArArchiveOutputStream aos = null;
238         ArArchiveInputStream ais = null;
239         try {
240             archive = File.createTempFile("test.", ".ar", tmp[0]);
241             archive.deleteOnExit();
242             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
243             final long beforeArchiveWrite = tmp[0].lastModified();
244             final ArArchiveEntry in = new ArArchiveEntry("foo", 0, 0, 0, 0,
245                                                    tmp[1].lastModified() / 1000);
246             aos.putArchiveEntry(in);
247             aos.closeArchiveEntry();
248             aos.close();
249             aos = null;
250             ais = new ArArchiveInputStream(new FileInputStream(archive));
251             final ArArchiveEntry out = ais.getNextArEntry();
252             ais.close();
253             ais = null;
254             assertNotNull(out);
255             assertEquals("foo/", out.getName());
256             assertEquals(0, out.getSize());
257             assertEquals(beforeArchiveWrite / 1000,
258                          out.getLastModifiedDate().getTime() / 1000);
259             assertTrue(out.isDirectory());
260         } finally {
261             if (ais != null) {
262                 ais.close();
263             }
264             if (aos != null) {
265                 aos.close();
266             }
267             tryHardToDelete(archive);
268             tryHardToDelete(tmp[1]);
269             rmdir(tmp[0]);
270         }
271     }
272 
273     @Test
274     public void testFileEntryFromFile() throws Exception {
275         final File[] tmp = createTempDirAndFile();
276         File archive = null;
277         ArArchiveOutputStream aos = null;
278         ArArchiveInputStream ais = null;
279         FileInputStream fis = null;
280         try {
281             archive = File.createTempFile("test.", ".ar", tmp[0]);
282             archive.deleteOnExit();
283             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
284             final ArArchiveEntry in = new ArArchiveEntry(tmp[1], "foo");
285             aos.putArchiveEntry(in);
286             final byte[] b = new byte[(int) tmp[1].length()];
287             fis = new FileInputStream(tmp[1]);
288             while (fis.read(b) > 0) {
289                 aos.write(b);
290             }
291             fis.close();
292             fis = null;
293             aos.closeArchiveEntry();
294             aos.close();
295             aos = null;
296             ais = new ArArchiveInputStream(new FileInputStream(archive));
297             final ArArchiveEntry out = ais.getNextArEntry();
298             ais.close();
299             ais = null;
300             assertNotNull(out);
301             assertEquals("foo", out.getName());
302             assertEquals(tmp[1].length(), out.getSize());
303             // AR stores time with a granularity of 1 second
304             assertEquals(tmp[1].lastModified() / 1000,
305                          out.getLastModifiedDate().getTime() / 1000);
306             assertFalse(out.isDirectory());
307         } finally {
308             if (ais != null) {
309                 ais.close();
310             }
311             if (aos != null) {
312                 aos.close();
313             }
314             tryHardToDelete(archive);
315             if (fis != null) {
316                 fis.close();
317             }
318             tryHardToDelete(tmp[1]);
319             rmdir(tmp[0]);
320         }
321     }
322 
323     @Test
324     public void testExplicitFileEntry() throws Exception {
325         final File[] tmp = createTempDirAndFile();
326         File archive = null;
327         ArArchiveOutputStream aos = null;
328         ArArchiveInputStream ais = null;
329         FileInputStream fis = null;
330         try {
331             archive = File.createTempFile("test.", ".ar", tmp[0]);
332             archive.deleteOnExit();
333             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
334             final ArArchiveEntry in = new ArArchiveEntry("foo", tmp[1].length(),
335                                                    0, 0, 0,
336                                                    tmp[1].lastModified() / 1000);
337             aos.putArchiveEntry(in);
338             final byte[] b = new byte[(int) tmp[1].length()];
339             fis = new FileInputStream(tmp[1]);
340             while (fis.read(b) > 0) {
341                 aos.write(b);
342             }
343             fis.close();
344             fis = null;
345             aos.closeArchiveEntry();
346             aos.close();
347             aos = null;
348             ais = new ArArchiveInputStream(new FileInputStream(archive));
349             final ArArchiveEntry out = ais.getNextArEntry();
350             ais.close();
351             ais = null;
352             assertNotNull(out);
353             assertEquals("foo", out.getName());
354             assertEquals(tmp[1].length(), out.getSize());
355             assertEquals(tmp[1].lastModified() / 1000,
356                          out.getLastModifiedDate().getTime() / 1000);
357             assertFalse(out.isDirectory());
358         } finally {
359             if (ais != null) {
360                 ais.close();
361             }
362             if (aos != null) {
363                 aos.close();
364             }
365             tryHardToDelete(archive);
366             if (fis != null) {
367                 fis.close();
368             }
369             tryHardToDelete(tmp[1]);
370             rmdir(tmp[0]);
371         }
372     }
373 }