1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.vafer.jdeb.producers;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.PushbackInputStream;
23 import java.util.zip.GZIPInputStream;
24
25 import org.apache.tools.bzip2.CBZip2InputStream;
26 import org.apache.tools.tar.TarEntry;
27 import org.apache.tools.tar.TarInputStream;
28 import org.vafer.jdeb.DataConsumer;
29 import org.vafer.jdeb.DataProducer;
30 import org.vafer.jdeb.mapping.Mapper;
31
32
33
34
35
36
37 public final class DataProducerArchive extends AbstractDataProducer implements DataProducer {
38
39 private final File archive;
40
41 public DataProducerArchive( final File pArchive, final String[] pIncludes, final String[] pExcludes, final Mapper[] pMappers ) {
42 super(pIncludes, pExcludes, pMappers);
43 archive = pArchive;
44 }
45
46 public void produce( final DataConsumer receiver ) throws IOException {
47
48 TarInputStream archiveInputStream = null;
49 try {
50 archiveInputStream = new TarInputStream(getCompressedInputStream(new FileInputStream(archive)));
51
52 while(true) {
53
54 TarEntry entry = archiveInputStream.getNextEntry();
55
56 if (entry == null) {
57 break;
58 }
59
60 if (!isIncluded(entry.getName())) {
61 continue;
62 }
63
64 entry = map(entry);
65
66 if (entry.isDirectory()) {
67 receiver.onEachDir(entry.getName(), entry.getLinkName(), entry.getUserName(), entry.getUserId(), entry.getGroupName(), entry.getGroupId(), entry.getMode(), entry.getSize());
68 continue;
69 }
70 receiver.onEachFile(archiveInputStream, entry.getName(), entry.getLinkName(), entry.getUserName(), entry.getUserId(), entry.getGroupName(), entry.getGroupId(), entry.getMode(), entry.getSize());
71 }
72
73 } finally {
74 if (archiveInputStream != null) {
75 archiveInputStream.close();
76 }
77 }
78 }
79
80
81
82
83
84 private InputStream getCompressedInputStream(InputStream in) throws IOException {
85 PushbackInputStream pin = new PushbackInputStream(in, 2);
86 byte[] header = new byte[2];
87 if (pin.read(header) != header.length) {
88 throw new IOException("Could not read header");
89 }
90
91 if (header[0] == (byte) 0x1f && header[1] == (byte) 0x8b) {
92 pin.unread(header);
93 return new GZIPInputStream(pin);
94 } else if (header[0] == 'B' && header[1] == 'Z') {
95 return new CBZip2InputStream(pin);
96 } else {
97 throw new IOException("Unsupported archive format : " + archive);
98 }
99 }
100
101 }