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