028473adb77d8122cb7da326e143a547b9bcb21b
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / TarFile.java
1 /*******************************************************************************
2 * Copyright (c) 2004, 2015 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 243347 TarFile should not throw NPE in finalize()
11 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Bug 463633
12 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Copied to Trace Compass to work around bug 501379
13 *******************************************************************************/
14
15 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
16
17 import java.io.File;
18 import java.io.FileInputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.Enumeration;
22 import java.util.zip.GZIPInputStream;
23
24
25 /**
26 * Reads a .tar or .tar.gz archive file, providing an index enumeration
27 * and allows for accessing an InputStream for arbitrary files in the
28 * archive.
29 */
30 public class TarFile {
31 private File file;
32 private TarInputStream entryEnumerationStream;
33 private TarEntry curEntry;
34 private TarInputStream entryStream;
35
36 private InputStream internalEntryStream;
37 // This field is just to prevent try with resources error and keep the code
38 // similar to the original
39 private InputStream fInputStream;
40
41 /**
42 * Create a new TarFile for the given file.
43 *
44 * @param file the file
45 * @throws TarException on Tar error (bad format, etc)
46 * @throws IOException on i/o error
47 */
48 public TarFile(File file) throws TarException, IOException {
49 this.file = file;
50
51 fInputStream = new FileInputStream(file);
52 // First, check if it's a GZIPInputStream.
53 try {
54 fInputStream = new GZIPInputStream(fInputStream);
55 } catch(IOException e) {
56 //If it is not compressed we close
57 //the old one and recreate
58 fInputStream.close();
59 fInputStream = new FileInputStream(file);
60 }
61 try {
62 entryEnumerationStream = new TarInputStream(fInputStream);
63 } catch (TarException | IOException ex) {
64 fInputStream.close();
65 throw ex;
66 }
67 curEntry = entryEnumerationStream.getNextEntry();
68 }
69
70 /**
71 * Close the tar file input stream.
72 *
73 * @throws IOException if the file cannot be successfully closed
74 */
75 public void close() throws IOException {
76 if (entryEnumerationStream != null) {
77 entryEnumerationStream.close();
78 }
79 if (internalEntryStream != null) {
80 internalEntryStream.close();
81 }
82 }
83
84 /**
85 * Create a new TarFile for the given path name.
86 *
87 * @param filename the file name to create the TarFile from
88 * @throws TarException on Tar error (bad format, etc)
89 * @throws IOException on i/o error
90 */
91 public TarFile(String filename) throws TarException, IOException {
92 this(new File(filename));
93 }
94
95 /**
96 * Returns an enumeration cataloguing the tar archive.
97 *
98 * @return enumeration of all files in the archive
99 */
100 public Enumeration<TarEntry> entries() {
101 return new Enumeration<TarEntry>() {
102 @Override
103 public boolean hasMoreElements() {
104 return (curEntry != null);
105 }
106
107 @Override
108 public TarEntry nextElement() {
109 TarEntry oldEntry = curEntry;
110 try {
111 curEntry = entryEnumerationStream.getNextEntry();
112 } catch(TarException e) {
113 curEntry = null;
114 } catch(IOException e) {
115 curEntry = null;
116 }
117 return oldEntry;
118 }
119 };
120 }
121
122 /**
123 * Returns a new InputStream for the given file in the tar archive.
124 *
125 * @param entry the entry to get the InputStream from
126 * @return an input stream for the given file
127 * @throws TarException on Tar error (bad format, etc)
128 * @throws IOException on i/o error
129 */
130 public InputStream getInputStream(TarEntry entry) throws TarException, IOException {
131 if(entryStream == null || !entryStream.skipToEntry(entry)) {
132 if (internalEntryStream != null) {
133 internalEntryStream.close();
134 }
135 internalEntryStream = new FileInputStream(file);
136 // First, check if it's a GZIPInputStream.
137 try {
138 internalEntryStream = new GZIPInputStream(internalEntryStream);
139 } catch(IOException e) {
140 //If it is not compressed we close
141 //the old one and recreate
142 internalEntryStream.close();
143 internalEntryStream = new FileInputStream(file);
144 }
145 entryStream = new TarInputStream(internalEntryStream, entry) {
146 @Override
147 public void close() {
148 // Ignore close() since we want to reuse the stream.
149 }
150 };
151 }
152 return entryStream;
153 }
154
155 /**
156 * Returns the path name of the file this archive represents.
157 *
158 * @return path
159 */
160 public String getName() {
161 return file.getPath();
162 }
163
164 @Override
165 protected void finalize() throws Throwable {
166 close();
167 }
168 }
This page took 0.037818 seconds and 4 git commands to generate.