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 / TarLeveledStructureProvider.java
CommitLineData
5d5f933e
MAL
1/*******************************************************************************
2 * Copyright (c) 2000, 2016 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 * Red Hat, Inc - Was TarFileStructureProvider, performed changes from
11 * IImportStructureProvider to ILeveledImportStructureProvider
12 * Mickael Istria (Red Hat Inc.) - Bug 486901
13 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Copied to Trace Compass to work around bug 501379
6120dc63 14 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Adapted to use Apache Common Compress
5d5f933e
MAL
15 *******************************************************************************/
16package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
17
18import java.io.IOException;
19import java.io.InputStream;
20import java.util.ArrayList;
21import java.util.Enumeration;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25
6120dc63 26import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
5d5f933e
MAL
27import org.eclipse.core.resources.ResourceAttributes;
28import org.eclipse.core.runtime.IPath;
29import org.eclipse.core.runtime.Path;
30import org.eclipse.tracecompass.common.core.NonNullUtils;
31import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
32import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
33import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider;
34
35/**
36 * This class provides information regarding the context structure and content
37 * of specified tar file entry objects.
38 */
39@SuppressWarnings("restriction")
40public class TarLeveledStructureProvider implements
c2750d24
MAL
41 ILeveledImportStructureProvider {
42 private TarFile tarFile;
5d5f933e 43
6120dc63 44 private TarArchiveEntry root = new TarArchiveEntry("/", true);//$NON-NLS-1$
5d5f933e 45
6120dc63 46 private Map<TarArchiveEntry, List<TarArchiveEntry>> children;
5d5f933e 47
6120dc63 48 private Map<IPath, TarArchiveEntry> directoryEntryCache = new HashMap<>();
5d5f933e 49
c2750d24 50 private int stripLevel;
5d5f933e 51
c2750d24
MAL
52 /**
53 * Creates a <code>TarFileStructureProvider</code>, which will operate on
54 * the passed tar file.
55 *
56 * @param sourceFile
57 * the source TarFile
58 */
59 public TarLeveledStructureProvider(TarFile sourceFile) {
60 super();
61 tarFile = sourceFile;
c2750d24 62 }
5d5f933e 63
c2750d24
MAL
64 /**
65 * Creates a new container tar entry with the specified name, iff it has
66 * not already been created. If the parent of the given element does not
67 * already exist it will be recursively created as well.
6120dc63 68 * @param pathName The path representing the container
c2750d24
MAL
69 * @return The element represented by this pathname (it may have already existed)
70 */
6120dc63
MAL
71 protected TarArchiveEntry createContainer(IPath pathName) {
72 IPath newPathName = pathName;
73 TarArchiveEntry existingEntry = directoryEntryCache.get(newPathName);
c2750d24
MAL
74 if (existingEntry != null) {
75 return existingEntry;
76 }
5d5f933e 77
6120dc63
MAL
78 TarArchiveEntry parent;
79 if (newPathName.segmentCount() == 1) {
c2750d24
MAL
80 parent = root;
81 } else {
6120dc63 82 parent = createContainer(newPathName.removeLastSegments(1));
c2750d24 83 }
6120dc63
MAL
84 // Add trailing / so that the entry knows it's a folder
85 newPathName = newPathName.addTrailingSeparator();
86 TarArchiveEntry newEntry = new TarArchiveEntry(newPathName.toString());
87 directoryEntryCache.put(newPathName, newEntry);
88 List<TarArchiveEntry> childList = new ArrayList<>();
c2750d24 89 children.put(newEntry, childList);
5d5f933e 90
6120dc63 91 List<TarArchiveEntry> parentChildList = children.get(parent);
c2750d24
MAL
92 NonNullUtils.checkNotNull(parentChildList).add(newEntry);
93 return newEntry;
94 }
5d5f933e 95
c2750d24
MAL
96 /**
97 * Creates a new tar file entry with the specified name.
98 * @param entry the entry to create the file for
99 */
6120dc63 100 protected void createFile(TarArchiveEntry entry) {
c2750d24 101 IPath pathname = new Path(entry.getName());
6120dc63 102 TarArchiveEntry parent;
c2750d24
MAL
103 if (pathname.segmentCount() == 1) {
104 parent = root;
105 } else {
106 parent = directoryEntryCache.get(pathname
107 .removeLastSegments(1));
108 }
5d5f933e 109
6120dc63 110 List<TarArchiveEntry> childList = children.get(parent);
c2750d24
MAL
111 NonNullUtils.checkNotNull(childList).add(entry);
112 }
5d5f933e 113
c2750d24
MAL
114 @Override
115 public List getChildren(Object element) {
116 if (children == null) {
117 initialize();
118 }
5d5f933e 119
c2750d24
MAL
120 return (children.get(element));
121 }
5d5f933e
MAL
122
123 @Override
c2750d24
MAL
124 public InputStream getContents(Object element) {
125 try {
6120dc63 126 return tarFile.getInputStream((TarArchiveEntry) element);
c2750d24
MAL
127 } catch (IOException e) {
128 IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
129 return null;
130 }
131 }
5d5f933e 132
c2750d24
MAL
133 /**
134 * Returns the resource attributes for this file.
135 *
136 * @param element the element to get the attributes from
137 * @return the attributes of the file
138 */
139 public ResourceAttributes getResourceAttributes(Object element) {
140 ResourceAttributes attributes = new ResourceAttributes();
6120dc63 141 TarArchiveEntry entry = (TarArchiveEntry) element;
c2750d24
MAL
142 attributes.setExecutable((entry.getMode() & 0100) != 0);
143 attributes.setReadOnly((entry.getMode() & 0200) == 0);
144 return attributes;
145 }
5d5f933e 146
c2750d24
MAL
147 @Override
148 public String getFullPath(Object element) {
6120dc63 149 String name = stripPath(((TarArchiveEntry) element).getName());
c2750d24
MAL
150 return ArchiveUtil.toValidNamesPath(name).toOSString();
151 }
5d5f933e 152
c2750d24
MAL
153 @Override
154 public String getLabel(Object element) {
155 if (element.equals(root)) {
6120dc63 156 return ((TarArchiveEntry) element).getName();
c2750d24 157 }
5d5f933e 158
6120dc63 159 String name = ((TarArchiveEntry) element).getName();
c2750d24
MAL
160 return stripPath(ArchiveUtil.toValidNamesPath(name).lastSegment());
161 }
5d5f933e 162
c2750d24
MAL
163 /**
164 * Returns the entry that this importer uses as the root sentinel.
165 *
6120dc63 166 * @return TarArchiveEntry entry
c2750d24
MAL
167 */
168 @Override
169 public Object getRoot() {
170 return root;
171 }
5d5f933e 172
c2750d24
MAL
173 /**
174 * Returns the tar file that this provider provides structure for.
175 *
176 * @return TarFile file
177 */
178 public TarFile getTarFile() {
179 return tarFile;
180 }
5d5f933e 181
c2750d24
MAL
182 @Override
183 public boolean closeArchive(){
184 try {
185 getTarFile().close();
186 } catch (IOException e) {
187 IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
188 + getTarFile().getName(), e);
189 return false;
190 }
191 return true;
192 }
5d5f933e 193
c2750d24
MAL
194 /**
195 * Initializes this object's children table based on the contents of the
196 * specified source file.
197 */
198 protected void initialize() {
199 children = new HashMap<>(1000);
5d5f933e 200
c2750d24 201 children.put(root, new ArrayList<>());
6120dc63 202 Enumeration<TarArchiveEntry> entries = tarFile.entries();
c2750d24 203 while (entries.hasMoreElements()) {
6120dc63 204 TarArchiveEntry entry = entries.nextElement();
c2750d24 205 IPath path = new Path(entry.getName()).addTrailingSeparator();
5d5f933e 206
6120dc63 207 if (entry.isDirectory()) {
c2750d24
MAL
208 createContainer(path);
209 } else
210 {
211 // Ensure the container structure for all levels above this is initialized
212 // Once we hit a higher-level container that's already added we need go no further
213 int pathSegmentCount = path.segmentCount();
214 if (pathSegmentCount > 1) {
215 createContainer(path.uptoSegment(pathSegmentCount - 1));
216 }
217 createFile(entry);
218 }
219 }
220 }
5d5f933e 221
c2750d24
MAL
222 @Override
223 public boolean isFolder(Object element) {
6120dc63 224 return (((TarArchiveEntry) element).isDirectory());
c2750d24 225 }
5d5f933e 226
c2750d24
MAL
227 /*
228 * Strip the leading directories from the path
229 */
230 private String stripPath(String path) {
231 String strippedPath = path;
232 String pathOrig = strippedPath;
233 for (int i = 0; i < stripLevel; i++) {
234 int firstSep = strippedPath.indexOf('/');
235 // If the first character was a seperator we must strip to the next
236 // seperator as well
237 if (firstSep == 0) {
238 strippedPath = strippedPath.substring(1);
239 firstSep = strippedPath.indexOf('/');
240 }
241 // No seperator wasw present so we're in a higher directory right
242 // now
243 if (firstSep == -1) {
244 return pathOrig;
245 }
246 strippedPath = strippedPath.substring(firstSep);
247 }
248 return strippedPath;
249 }
5d5f933e 250
c2750d24
MAL
251 @Override
252 public void setStrip(int level) {
253 stripLevel = level;
254 }
5d5f933e 255
c2750d24
MAL
256 @Override
257 public int getStrip() {
258 return stripLevel;
259 }
5d5f933e 260}
This page took 0.03758 seconds and 5 git commands to generate.