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          final InputStream is = new FileInputStream(input);
84          final ArchiveInputStream in = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(is));
85          final ArArchiveEntry entry = (ArArchiveEntry)in.getNextEntry();
86  
87          File target = new File(dir, entry.getName());
88          final OutputStream out = new FileOutputStream(target);
89  
90          IOUtils.copy(in, out);
91  
92          out.close();
93          in.close();
94          is.close();
95      }
96  
97      @Test
98      public void testArDelete() throws Exception {
99          final File output = new File(dir, "bla.ar");
100 
101         final File file1 = getFile("test1.xml");
102         final File file2 = getFile("test2.xml");
103         {
104             // create
105 
106             final OutputStream out = new FileOutputStream(output);
107             final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("ar", out);
108             os.putArchiveEntry(new ArArchiveEntry("test1.xml", file1.length()));
109             IOUtils.copy(new FileInputStream(file1), os);
110             os.closeArchiveEntry();
111 
112             os.putArchiveEntry(new ArArchiveEntry("test2.xml", file2.length()));
113             IOUtils.copy(new FileInputStream(file2), os);
114             os.closeArchiveEntry();
115             os.close();
116             out.close();
117         }
118 
119         assertEquals(8
120                      + 60 + file1.length() + (file1.length() % 2)
121                      + 60 + file2.length() + (file2.length() % 2),
122                      output.length());
123 
124         final File output2 = new File(dir, "bla2.ar");
125 
126         int copied = 0;
127         int deleted = 0;
128 
129         {
130             // remove all but one file
131 
132             final InputStream is = new FileInputStream(output);
133             final OutputStream os = new FileOutputStream(output2);
134             final ArchiveOutputStream aos = new ArchiveStreamFactory().createArchiveOutputStream("ar", os);
135             final ArchiveInputStream ais = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(is));
136             while(true) {
137                 final ArArchiveEntry entry = (ArArchiveEntry)ais.getNextEntry();
138                 if (entry == null) {
139                     break;
140                 }
141 
142                 if ("test1.xml".equals(entry.getName())) {
143                     aos.putArchiveEntry(entry);
144                     IOUtils.copy(ais, aos);
145                     aos.closeArchiveEntry();
146                     copied++;
147                 } else {
148                     IOUtils.copy(ais, new ByteArrayOutputStream());
149                     deleted++;
150                 }
151 
152             }
153             ais.close();
154             aos.close();
155             is.close();
156             os.close();
157         }
158 
159         assertEquals(1, copied);
160         assertEquals(1, deleted);
161         assertEquals(8
162                      + 60 + file1.length() + (file1.length() % 2),
163                      output2.length());
164 
165         long files = 0;
166         long sum = 0;
167 
168         {
169             final InputStream is = new FileInputStream(output2);
170             final ArchiveInputStream ais = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(is));
171             while(true) {
172                 final ArArchiveEntry entry = (ArArchiveEntry)ais.getNextEntry();
173                 if (entry == null) {
174                     break;
175                 }
176 
177                 IOUtils.copy(ais, new ByteArrayOutputStream());
178 
179                 sum +=  entry.getLength();
180                 files++;
181             }
182             ais.close();
183             is.close();
184         }
185 
186         assertEquals(1, files);
187         assertEquals(file1.length(), sum);
188 
189     }
190 
191     // TODO: revisit - does AR not support storing directories?
192     @Ignore
193     @Test
194     public void XtestDirectoryEntryFromFile() throws Exception {
195         File[] tmp = createTempDirAndFile();
196         File archive = null;
197         ArArchiveOutputStream aos = null;
198         ArArchiveInputStream ais = null;
199         try {
200             archive = File.createTempFile("test.", ".ar", tmp[0]);
201             archive.deleteOnExit();
202             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
203             long beforeArchiveWrite = tmp[0].lastModified();
204             ArArchiveEntry in = new ArArchiveEntry(tmp[0], "foo");
205             aos.putArchiveEntry(in);
206             aos.closeArchiveEntry();
207             aos.close();
208             aos = null;
209             ais = new ArArchiveInputStream(new FileInputStream(archive));
210             ArArchiveEntry out = ais.getNextArEntry();
211             ais.close();
212             ais = null;
213             assertNotNull(out);
214             assertEquals("foo/", out.getName());
215             assertEquals(0, out.getSize());
216             // AR stores time with a granularity of 1 second
217             assertEquals(beforeArchiveWrite / 1000,
218                          out.getLastModifiedDate().getTime() / 1000);
219             assertTrue(out.isDirectory());
220         } finally {
221             if (ais != null) {
222                 ais.close();
223             }
224             if (aos != null) {
225                 aos.close();
226             }
227             tryHardToDelete(archive);
228             tryHardToDelete(tmp[1]);
229             rmdir(tmp[0]);
230         }
231     }
232 
233     // TODO: revisit - does AR not support storing directories?
234     @Ignore
235     @Test
236     public void XtestExplicitDirectoryEntry() throws Exception {
237         File[] tmp = createTempDirAndFile();
238         File archive = null;
239         ArArchiveOutputStream aos = null;
240         ArArchiveInputStream ais = null;
241         try {
242             archive = File.createTempFile("test.", ".ar", tmp[0]);
243             archive.deleteOnExit();
244             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
245             long beforeArchiveWrite = tmp[0].lastModified();
246             ArArchiveEntry in = new ArArchiveEntry("foo", 0, 0, 0, 0,
247                                                    tmp[1].lastModified() / 1000);
248             aos.putArchiveEntry(in);
249             aos.closeArchiveEntry();
250             aos.close();
251             aos = null;
252             ais = new ArArchiveInputStream(new FileInputStream(archive));
253             ArArchiveEntry out = ais.getNextArEntry();
254             ais.close();
255             ais = null;
256             assertNotNull(out);
257             assertEquals("foo/", out.getName());
258             assertEquals(0, out.getSize());
259             assertEquals(beforeArchiveWrite / 1000,
260                          out.getLastModifiedDate().getTime() / 1000);
261             assertTrue(out.isDirectory());
262         } finally {
263             if (ais != null) {
264                 ais.close();
265             }
266             if (aos != null) {
267                 aos.close();
268             }
269             tryHardToDelete(archive);
270             tryHardToDelete(tmp[1]);
271             rmdir(tmp[0]);
272         }
273     }
274 
275     @Test
276     public void testFileEntryFromFile() throws Exception {
277         File[] tmp = createTempDirAndFile();
278         File archive = null;
279         ArArchiveOutputStream aos = null;
280         ArArchiveInputStream ais = null;
281         FileInputStream fis = null;
282         try {
283             archive = File.createTempFile("test.", ".ar", tmp[0]);
284             archive.deleteOnExit();
285             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
286             ArArchiveEntry in = new ArArchiveEntry(tmp[1], "foo");
287             aos.putArchiveEntry(in);
288             byte[] b = new byte[(int) tmp[1].length()];
289             fis = new FileInputStream(tmp[1]);
290             while (fis.read(b) > 0) {
291                 aos.write(b);
292             }
293             fis.close();
294             fis = null;
295             aos.closeArchiveEntry();
296             aos.close();
297             aos = null;
298             ais = new ArArchiveInputStream(new FileInputStream(archive));
299             ArArchiveEntry out = ais.getNextArEntry();
300             ais.close();
301             ais = null;
302             assertNotNull(out);
303             assertEquals("foo", out.getName());
304             assertEquals(tmp[1].length(), out.getSize());
305             // AR stores time with a granularity of 1 second
306             assertEquals(tmp[1].lastModified() / 1000,
307                          out.getLastModifiedDate().getTime() / 1000);
308             assertFalse(out.isDirectory());
309         } finally {
310             if (ais != null) {
311                 ais.close();
312             }
313             if (aos != null) {
314                 aos.close();
315             }
316             tryHardToDelete(archive);
317             if (fis != null) {
318                 fis.close();
319             }
320             tryHardToDelete(tmp[1]);
321             rmdir(tmp[0]);
322         }
323     }
324 
325     @Test
326     public void testExplicitFileEntry() throws Exception {
327         File[] tmp = createTempDirAndFile();
328         File archive = null;
329         ArArchiveOutputStream aos = null;
330         ArArchiveInputStream ais = null;
331         FileInputStream fis = null;
332         try {
333             archive = File.createTempFile("test.", ".ar", tmp[0]);
334             archive.deleteOnExit();
335             aos = new ArArchiveOutputStream(new FileOutputStream(archive));
336             ArArchiveEntry in = new ArArchiveEntry("foo", tmp[1].length(),
337                                                    0, 0, 0,
338                                                    tmp[1].lastModified() / 1000);
339             aos.putArchiveEntry(in);
340             byte[] b = new byte[(int) tmp[1].length()];
341             fis = new FileInputStream(tmp[1]);
342             while (fis.read(b) > 0) {
343                 aos.write(b);
344             }
345             fis.close();
346             fis = null;
347             aos.closeArchiveEntry();
348             aos.close();
349             aos = null;
350             ais = new ArArchiveInputStream(new FileInputStream(archive));
351             ArArchiveEntry out = ais.getNextArEntry();
352             ais.close();
353             ais = null;
354             assertNotNull(out);
355             assertEquals("foo", out.getName());
356             assertEquals(tmp[1].length(), out.getSize());
357             assertEquals(tmp[1].lastModified() / 1000,
358                          out.getLastModifiedDate().getTime() / 1000);
359             assertFalse(out.isDirectory());
360         } finally {
361             if (ais != null) {
362                 ais.close();
363             }
364             if (aos != null) {
365                 aos.close();
366             }
367             tryHardToDelete(archive);
368             if (fis != null) {
369                 fis.close();
370             }
371             tryHardToDelete(tmp[1]);
372             rmdir(tmp[0]);
373         }
374     }
375 }