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
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
;
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
;
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
;
34 * This class provides information regarding the context structure and content
35 * of specified tar file entry objects.
37 @SuppressWarnings("restriction")
38 public class TarLeveledStructureProvider
implements
39 ILeveledImportStructureProvider
{
40 private TarFile tarFile
;
42 private TarEntry root
= new TarEntry("/");//$NON-NLS-1$
44 private Map
<TarEntry
, List
<TarEntry
>> children
;
46 private Map
<IPath
, TarEntry
> directoryEntryCache
= new HashMap
<>();
48 private int stripLevel
;
51 * Creates a <code>TarFileStructureProvider</code>, which will operate on
52 * the passed tar file.
57 public TarLeveledStructureProvider(TarFile sourceFile
) {
60 root
.setFileType(TarEntry
.DIRECTORY
);
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)
70 protected TarEntry
createContainer(IPath pathname
) {
71 TarEntry existingEntry
= directoryEntryCache
.get(pathname
);
72 if (existingEntry
!= null) {
77 if (pathname
.segmentCount() == 1) {
80 parent
= createContainer(pathname
.removeLastSegments(1));
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
);
88 List
<TarEntry
> parentChildList
= children
.get(parent
);
89 NonNullUtils
.checkNotNull(parentChildList
).add(newEntry
);
94 * Creates a new tar file entry with the specified name.
95 * @param entry the entry to create the file for
97 protected void createFile(TarEntry entry
) {
98 IPath pathname
= new Path(entry
.getName());
100 if (pathname
.segmentCount() == 1) {
103 parent
= directoryEntryCache
.get(pathname
104 .removeLastSegments(1));
107 List
<TarEntry
> childList
= children
.get(parent
);
108 NonNullUtils
.checkNotNull(childList
).add(entry
);
112 public List
getChildren(Object element
) {
113 if (children
== null) {
117 return (children
.get(element
));
121 public InputStream
getContents(Object element
) {
123 return tarFile
.getInputStream((TarEntry
) element
);
124 } catch (TarException e
) {
125 IDEWorkbenchPlugin
.log(e
.getLocalizedMessage(), e
);
127 } catch (IOException e
) {
128 IDEWorkbenchPlugin
.log(e
.getLocalizedMessage(), e
);
134 * Returns the resource attributes for this file.
136 * @param element the element to get the attributes from
137 * @return the attributes of the file
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);
148 public String
getFullPath(Object element
) {
149 String name
= stripPath(((TarEntry
) element
).getName());
150 return ArchiveUtil
.toValidNamesPath(name
).toOSString();
154 public String
getLabel(Object element
) {
155 if (element
.equals(root
)) {
156 return ((TarEntry
) element
).getName();
159 String name
= ((TarEntry
) element
).getName();
160 return stripPath(ArchiveUtil
.toValidNamesPath(name
).lastSegment());
164 * Returns the entry that this importer uses as the root sentinel.
166 * @return TarEntry entry
169 public Object
getRoot() {
174 * Returns the tar file that this provider provides structure for.
176 * @return TarFile file
178 public TarFile
getTarFile() {
183 public boolean closeArchive(){
185 getTarFile().close();
186 } catch (IOException e
) {
187 IDEWorkbenchPlugin
.log(DataTransferMessages
.ZipImport_couldNotClose
188 + getTarFile().getName(), e
);
195 * Initializes this object's children table based on the contents of the
196 * specified source file.
198 protected void initialize() {
199 children
= new HashMap
<>(1000);
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();
207 if (entry
.getFileType() == TarEntry
.DIRECTORY
) {
208 createContainer(path
);
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));
223 public boolean isFolder(Object element
) {
224 return (((TarEntry
) element
).getFileType() == TarEntry
.DIRECTORY
);
228 * Strip the leading directories from the path
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
238 strippedPath
= strippedPath
.substring(1);
239 firstSep
= strippedPath
.indexOf('/');
241 // No seperator wasw present so we're in a higher directory right
243 if (firstSep
== -1) {
246 strippedPath
= strippedPath
.substring(firstSep
);
252 public void setStrip(int level
) {
257 public int getStrip() {