685657865291bffc05283d4f5f6498492636ab38
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / TarLeveledStructureProvider.java
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
14 *******************************************************************************/
15 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.ArrayList;
20 import java.util.Enumeration;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.eclipse.core.resources.ResourceAttributes;
26 import org.eclipse.core.runtime.IPath;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.tracecompass.common.core.NonNullUtils;
29 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
30 import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
31 import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider;
32
33 /**
34 * This class provides information regarding the context structure and content
35 * of specified tar file entry objects.
36 */
37 @SuppressWarnings("restriction")
38 public class TarLeveledStructureProvider implements
39 ILeveledImportStructureProvider {
40 private TarFile tarFile;
41
42 private TarEntry root = new TarEntry("/");//$NON-NLS-1$
43
44 private Map<TarEntry, List<TarEntry>> children;
45
46 private Map<IPath, TarEntry> directoryEntryCache = new HashMap<>();
47
48 private int stripLevel;
49
50 /**
51 * Creates a <code>TarFileStructureProvider</code>, which will operate on
52 * the passed tar file.
53 *
54 * @param sourceFile
55 * the source TarFile
56 */
57 public TarLeveledStructureProvider(TarFile sourceFile) {
58 super();
59 tarFile = sourceFile;
60 root.setFileType(TarEntry.DIRECTORY);
61 }
62
63 /**
64 * Creates a new container tar entry with the specified name, iff it has
65 * not already been created. If the parent of the given element does not
66 * already exist it will be recursively created as well.
67 * @param pathname The path representing the container
68 * @return The element represented by this pathname (it may have already existed)
69 */
70 protected TarEntry createContainer(IPath pathname) {
71 TarEntry existingEntry = directoryEntryCache.get(pathname);
72 if (existingEntry != null) {
73 return existingEntry;
74 }
75
76 TarEntry parent;
77 if (pathname.segmentCount() == 1) {
78 parent = root;
79 } else {
80 parent = createContainer(pathname.removeLastSegments(1));
81 }
82 TarEntry newEntry = new TarEntry(pathname.toString());
83 newEntry.setFileType(TarEntry.DIRECTORY);
84 directoryEntryCache.put(pathname, newEntry);
85 List<TarEntry> childList = new ArrayList<>();
86 children.put(newEntry, childList);
87
88 List<TarEntry> parentChildList = children.get(parent);
89 NonNullUtils.checkNotNull(parentChildList).add(newEntry);
90 return newEntry;
91 }
92
93 /**
94 * Creates a new tar file entry with the specified name.
95 * @param entry the entry to create the file for
96 */
97 protected void createFile(TarEntry entry) {
98 IPath pathname = new Path(entry.getName());
99 TarEntry parent;
100 if (pathname.segmentCount() == 1) {
101 parent = root;
102 } else {
103 parent = directoryEntryCache.get(pathname
104 .removeLastSegments(1));
105 }
106
107 List<TarEntry> childList = children.get(parent);
108 NonNullUtils.checkNotNull(childList).add(entry);
109 }
110
111 @Override
112 public List getChildren(Object element) {
113 if (children == null) {
114 initialize();
115 }
116
117 return (children.get(element));
118 }
119
120 @Override
121 public InputStream getContents(Object element) {
122 try {
123 return tarFile.getInputStream((TarEntry) element);
124 } catch (TarException e) {
125 IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
126 return null;
127 } catch (IOException e) {
128 IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
129 return null;
130 }
131 }
132
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();
141 TarEntry entry = (TarEntry) element;
142 attributes.setExecutable((entry.getMode() & 0100) != 0);
143 attributes.setReadOnly((entry.getMode() & 0200) == 0);
144 return attributes;
145 }
146
147 @Override
148 public String getFullPath(Object element) {
149 String name = stripPath(((TarEntry) element).getName());
150 return ArchiveUtil.toValidNamesPath(name).toOSString();
151 }
152
153 @Override
154 public String getLabel(Object element) {
155 if (element.equals(root)) {
156 return ((TarEntry) element).getName();
157 }
158
159 String name = ((TarEntry) element).getName();
160 return stripPath(ArchiveUtil.toValidNamesPath(name).lastSegment());
161 }
162
163 /**
164 * Returns the entry that this importer uses as the root sentinel.
165 *
166 * @return TarEntry entry
167 */
168 @Override
169 public Object getRoot() {
170 return root;
171 }
172
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 }
181
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 }
193
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);
200
201 children.put(root, new ArrayList<>());
202 Enumeration<TarEntry> entries = tarFile.entries();
203 while (entries.hasMoreElements()) {
204 TarEntry entry = entries.nextElement();
205 IPath path = new Path(entry.getName()).addTrailingSeparator();
206
207 if (entry.getFileType() == TarEntry.DIRECTORY) {
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 }
221
222 @Override
223 public boolean isFolder(Object element) {
224 return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
225 }
226
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 }
250
251 @Override
252 public void setStrip(int level) {
253 stripLevel = level;
254 }
255
256 @Override
257 public int getStrip() {
258 return stripLevel;
259 }
260 }
This page took 0.041281 seconds and 4 git commands to generate.