137f1aa544e547e477f58a36a025c3b04efb0cb9
[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 return stripPath(((TarEntry) element).getName());
150 }
151
152 @Override
153 public String getLabel(Object element) {
154 if (element.equals(root)) {
155 return ((TarEntry) element).getName();
156 }
157
158 return stripPath(new Path(((TarEntry) element).getName()).lastSegment());
159 }
160
161 /**
162 * Returns the entry that this importer uses as the root sentinel.
163 *
164 * @return TarEntry entry
165 */
166 @Override
167 public Object getRoot() {
168 return root;
169 }
170
171 /**
172 * Returns the tar file that this provider provides structure for.
173 *
174 * @return TarFile file
175 */
176 public TarFile getTarFile() {
177 return tarFile;
178 }
179
180 @Override
181 public boolean closeArchive(){
182 try {
183 getTarFile().close();
184 } catch (IOException e) {
185 IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
186 + getTarFile().getName(), e);
187 return false;
188 }
189 return true;
190 }
191
192 /**
193 * Initializes this object's children table based on the contents of the
194 * specified source file.
195 */
196 protected void initialize() {
197 children = new HashMap<>(1000);
198
199 children.put(root, new ArrayList<>());
200 Enumeration<TarEntry> entries = tarFile.entries();
201 while (entries.hasMoreElements()) {
202 TarEntry entry = entries.nextElement();
203 IPath path = new Path(entry.getName()).addTrailingSeparator();
204
205 if (entry.getFileType() == TarEntry.DIRECTORY) {
206 createContainer(path);
207 } else
208 {
209 // Ensure the container structure for all levels above this is initialized
210 // Once we hit a higher-level container that's already added we need go no further
211 int pathSegmentCount = path.segmentCount();
212 if (pathSegmentCount > 1) {
213 createContainer(path.uptoSegment(pathSegmentCount - 1));
214 }
215 createFile(entry);
216 }
217 }
218 }
219
220 @Override
221 public boolean isFolder(Object element) {
222 return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
223 }
224
225 /*
226 * Strip the leading directories from the path
227 */
228 private String stripPath(String path) {
229 String strippedPath = path;
230 String pathOrig = strippedPath;
231 for (int i = 0; i < stripLevel; i++) {
232 int firstSep = strippedPath.indexOf('/');
233 // If the first character was a seperator we must strip to the next
234 // seperator as well
235 if (firstSep == 0) {
236 strippedPath = strippedPath.substring(1);
237 firstSep = strippedPath.indexOf('/');
238 }
239 // No seperator wasw present so we're in a higher directory right
240 // now
241 if (firstSep == -1) {
242 return pathOrig;
243 }
244 strippedPath = strippedPath.substring(firstSep);
245 }
246 return strippedPath;
247 }
248
249 @Override
250 public void setStrip(int level) {
251 stripLevel = level;
252 }
253
254 @Override
255 public int getStrip() {
256 return stripLevel;
257 }
258 }
This page took 0.036012 seconds and 4 git commands to generate.