tmf: Use Apache Common Compress for importing from archive
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / ArchiveUtil.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
14
15 import java.io.File;
16 import java.io.IOException;
17
18 import org.apache.commons.compress.archivers.zip.ZipFile;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.core.runtime.Path;
21 import org.eclipse.swt.widgets.Shell;
22 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceCoreUtils;
23 import org.eclipse.tracecompass.tmf.core.util.Pair;
24 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
25
26 /**
27 * Various utilities for dealing with archives in the context of importing
28 * traces.
29 */
30 public class ArchiveUtil {
31
32 /**
33 * Returns whether or not the source file is an archive file (Zip, tar,
34 * tar.gz, gz).
35 *
36 * @param sourceFile
37 * the source file
38 * @return whether or not the source file is an archive file
39 */
40 public static boolean isArchiveFile(File sourceFile) {
41 String absolutePath = sourceFile.getAbsolutePath();
42 return isTarFile(absolutePath) || isZipFile(absolutePath) || isGzipFile(absolutePath);
43 }
44
45 private static boolean isZipFile(String fileName) {
46 ZipFile specifiedZipSourceFile = getSpecifiedZipSourceFile(fileName);
47 if (specifiedZipSourceFile != null) {
48 try {
49 specifiedZipSourceFile.close();
50 return true;
51 } catch (IOException e) {
52 // ignore
53 }
54 }
55
56 return false;
57 }
58
59 private static boolean isTarFile(String fileName) {
60 TarFile specifiedTarSourceFile = getSpecifiedTarSourceFile(fileName);
61 if (specifiedTarSourceFile != null) {
62 try {
63 specifiedTarSourceFile.close();
64 return true;
65 } catch (IOException e) {
66 // ignore
67 }
68 }
69 return false;
70 }
71
72 private static boolean isGzipFile(String fileName) {
73 if (!fileName.isEmpty()) {
74 try (GzipFile specifiedTarSourceFile = new GzipFile(fileName);) {
75 return true;
76 } catch (IOException e) {
77 }
78 }
79 return false;
80 }
81
82 private static ZipFile getSpecifiedZipSourceFile(String fileName) {
83 if (fileName.length() == 0) {
84 return null;
85 }
86
87 File file = new File(fileName);
88 if (file.isDirectory()) {
89 return null;
90 }
91
92 try {
93 return new ZipFile(file);
94 } catch (IOException e) {
95 // ignore
96 }
97
98 return null;
99 }
100
101 private static TarFile getSpecifiedTarSourceFile(String fileName) {
102 if (fileName.length() == 0) {
103 return null;
104 }
105
106 // FIXME: Work around Bug 463633. Remove this block once we move to Eclipse 4.5.
107 if (new File(fileName).length() < 512) {
108 return null;
109 }
110
111 try {
112 return new TarFile(fileName);
113 } catch (IOException e) {
114 // ignore
115 }
116
117 return null;
118 }
119
120 static boolean ensureZipSourceIsValid(String archivePath) {
121 ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath);
122 if (specifiedFile == null) {
123 return false;
124 }
125 return closeZipFile(specifiedFile);
126 }
127
128 static boolean closeZipFile(ZipFile file) {
129 try {
130 file.close();
131 } catch (IOException e) {
132 return false;
133 }
134
135 return true;
136 }
137
138 static boolean ensureTarSourceIsValid(String archivePath) {
139 TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath);
140 if (specifiedFile == null) {
141 return false;
142 }
143 return closeTarFile(specifiedFile);
144 }
145
146 static boolean ensureGzipSourceIsValid(String archivePath) {
147 return isGzipFile(archivePath);
148 }
149
150 static boolean closeTarFile(TarFile file) {
151 try {
152 file.close();
153 } catch (IOException e) {
154 return false;
155 }
156
157 return true;
158 }
159
160 /**
161 * Get the root file system object and it's associated import provider for
162 * the specified source file. A shell is used to display messages in case of
163 * errors.
164 *
165 * @param sourceFile
166 * the source file
167 * @param shell
168 * the parent shell to use to display error messages
169 * @return the root file system object and it's associated import provider
170 */
171 @SuppressWarnings("resource")
172 public static Pair<IFileSystemObject, FileSystemObjectImportStructureProvider> getRootObjectAndProvider(File sourceFile, Shell shell) {
173 if (sourceFile == null) {
174 return null;
175 }
176
177 IFileSystemObject rootElement = null;
178 FileSystemObjectImportStructureProvider importStructureProvider = null;
179
180 // Import from directory
181 if (!isArchiveFile(sourceFile)) {
182 importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
183 rootElement = importStructureProvider.getIFileSystemObject(sourceFile);
184 } else {
185 // Import from archive
186 FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null;
187 String archivePath = sourceFile.getAbsolutePath();
188 if (isTarFile(archivePath)) {
189 if (ensureTarSourceIsValid(archivePath)) {
190 // We close the file when we dispose the import provider,
191 // see disposeSelectionGroupRoot
192 TarFile tarFile = getSpecifiedTarSourceFile(archivePath);
193 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath);
194 }
195 } else if (ensureZipSourceIsValid(archivePath)) {
196 // We close the file when we dispose the import provider, see
197 // disposeSelectionGroupRoot
198 ZipFile zipFile = getSpecifiedZipSourceFile(archivePath);
199 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath);
200 } else if (ensureGzipSourceIsValid(archivePath)) {
201 // We close the file when we dispose the import provider, see
202 // disposeSelectionGroupRoot
203 GzipFile zipFile = null;
204 try {
205 zipFile = new GzipFile(archivePath);
206 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new GzipLeveledStructureProvider(zipFile), archivePath);
207 } catch (IOException e) {
208 // do nothing
209 }
210 }
211 if (leveledImportStructureProvider == null) {
212 return null;
213 }
214 rootElement = leveledImportStructureProvider.getRoot();
215 importStructureProvider = leveledImportStructureProvider;
216 }
217
218 if (rootElement == null) {
219 return null;
220 }
221
222 return new Pair<>(rootElement, importStructureProvider);
223 }
224
225 /**
226 * Convert a string path to a path containing valid names. See
227 * {@link TmfTraceCoreUtils#validateName(String)}.
228 *
229 * @param path
230 * the string path to convert
231 * @return the path contains valid segment names
232 */
233 public static IPath toValidNamesPath(String path) {
234 IPath newSafePath = TmfTraceCoreUtils.newSafePath(path);
235 IPath newFullPath = newSafePath;
236 String[] segments = newSafePath.segments();
237 for (int i = 0; i < segments.length; i++) {
238 String segment = TmfTraceCoreUtils.validateName(TmfTraceCoreUtils.safePathToString(segments[i]));
239 if (i == 0) {
240 newFullPath = new Path(segment);
241 } else {
242 newFullPath = newFullPath.append(segment);
243 }
244 }
245 return newFullPath;
246 }
247 }
This page took 0.037268 seconds and 5 git commands to generate.