1 package org.codehaus.plexus.archiver.tar;
2
3 import java.io.File;
4 import java.io.FilterInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.lang.reflect.UndeclaredThrowableException;
8 import java.util.Enumeration;
9 import java.util.NoSuchElementException;
10
11 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
12 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
13 import org.codehaus.plexus.archiver.ArchiveFile;
14 import org.codehaus.plexus.archiver.util.Streams;
15
16 import static org.codehaus.plexus.archiver.util.Streams.bufferedInputStream;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class TarFile implements ArchiveFile {
40
41 private final java.io.File file;
42
43 private TarArchiveInputStream inputStream;
44
45 private TarArchiveEntry currentEntry;
46
47
48
49
50 public TarFile(File file) {
51 this.file = file;
52 }
53
54
55
56
57
58
59
60
61 @Override
62 public Enumeration<org.apache.commons.compress.archivers.ArchiveEntry> getEntries() throws IOException {
63 if (inputStream != null) {
64 close();
65 }
66 open();
67 return new Enumeration<org.apache.commons.compress.archivers.ArchiveEntry>() {
68
69 boolean currentEntryValid;
70
71 @Override
72 public boolean hasMoreElements() {
73 if (!currentEntryValid) {
74 try {
75 currentEntry = inputStream.getNextTarEntry();
76 } catch (IOException e) {
77 throw new UndeclaredThrowableException(e);
78 }
79 }
80 return currentEntry != null;
81 }
82
83 @Override
84 public org.apache.commons.compress.archivers.ArchiveEntry nextElement() {
85 if (currentEntry == null) {
86 throw new NoSuchElementException();
87 }
88 currentEntryValid = false;
89 return currentEntry;
90 }
91 };
92 }
93
94 public void close() throws IOException {
95 if (inputStream != null) {
96 inputStream.close();
97 inputStream = null;
98 }
99 }
100
101 @Override
102 public InputStream getInputStream(org.apache.commons.compress.archivers.ArchiveEntry entry) throws IOException {
103 return getInputStream(new TarArchiveEntry(entry.getName()));
104 }
105
106
107
108
109
110
111
112 public InputStream getInputStream(TarArchiveEntry entry) throws IOException {
113 if (entry.equals((Object) currentEntry) && inputStream != null) {
114 return new FilterInputStream(inputStream) {
115
116 public void close() throws IOException {
117
118 }
119 };
120 }
121 return getInputStream(entry, currentEntry);
122 }
123
124 protected InputStream getInputStream(File file) throws IOException {
125 return Streams.fileInputStream(file);
126 }
127
128 private InputStream getInputStream(TarArchiveEntry entry, TarArchiveEntry currentEntry) throws IOException {
129 if (currentEntry == null || inputStream == null) {
130
131 if (inputStream != null) {
132 close();
133 }
134 open();
135 if (!findEntry(entry, null)) {
136 throw new IOException("Unknown entry: " + entry.getName());
137 }
138 } else {
139
140 if (findEntry(entry, null)) {
141 return getInputStream(entry);
142 }
143 close();
144 open();
145 if (!findEntry(entry, currentEntry)) {
146 throw new IOException("No such entry: " + entry.getName());
147 }
148 }
149 return getInputStream(entry);
150 }
151
152 private void open() throws IOException {
153 inputStream = new TarArchiveInputStream(bufferedInputStream(getInputStream(file)), "UTF8");
154 }
155
156 private boolean findEntry(TarArchiveEntry entry, TarArchiveEntry currentEntry) throws IOException {
157 for (; ; ) {
158 this.currentEntry = inputStream.getNextTarEntry();
159 if (this.currentEntry == null || (currentEntry != null && this.currentEntry.equals(currentEntry))) {
160 return false;
161 }
162 if (this.currentEntry.equals(entry)) {
163 return true;
164 }
165 }
166 }
167 }