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 * Marc-Andre Laperle <marc-andre.laperle@ericsson.com> - Adapted to use Apache Common Compress
15 *******************************************************************************/
16 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.wizards
.importtrace
;
18 import java
.io
.IOException
;
19 import java
.io
.InputStream
;
20 import java
.util
.ArrayList
;
21 import java
.util
.Enumeration
;
22 import java
.util
.HashMap
;
23 import java
.util
.List
;
26 import org
.apache
.commons
.compress
.archivers
.tar
.TarArchiveEntry
;
27 import org
.eclipse
.core
.resources
.ResourceAttributes
;
28 import org
.eclipse
.core
.runtime
.IPath
;
29 import org
.eclipse
.core
.runtime
.Path
;
30 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
31 import org
.eclipse
.ui
.internal
.ide
.IDEWorkbenchPlugin
;
32 import org
.eclipse
.ui
.internal
.wizards
.datatransfer
.DataTransferMessages
;
33 import org
.eclipse
.ui
.internal
.wizards
.datatransfer
.ILeveledImportStructureProvider
;
36 * This class provides information regarding the context structure and content
37 * of specified tar file entry objects.
39 @SuppressWarnings("restriction")
40 public class TarLeveledStructureProvider
implements
41 ILeveledImportStructureProvider
{
42 private TarFile tarFile
;
44 private TarArchiveEntry root
= new TarArchiveEntry("/", true);//$NON-NLS-1$
46 private Map
<TarArchiveEntry
, List
<TarArchiveEntry
>> children
;
48 private Map
<IPath
, TarArchiveEntry
> directoryEntryCache
= new HashMap
<>();
50 private int stripLevel
;
53 * Creates a <code>TarFileStructureProvider</code>, which will operate on
54 * the passed tar file.
59 public TarLeveledStructureProvider(TarFile sourceFile
) {
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.
68 * @param pathName The path representing the container
69 * @return The element represented by this pathname (it may have already existed)
71 protected TarArchiveEntry
createContainer(IPath pathName
) {
72 IPath newPathName
= pathName
;
73 TarArchiveEntry existingEntry
= directoryEntryCache
.get(newPathName
);
74 if (existingEntry
!= null) {
78 TarArchiveEntry parent
;
79 if (newPathName
.segmentCount() == 1) {
82 parent
= createContainer(newPathName
.removeLastSegments(1));
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
<>();
89 children
.put(newEntry
, childList
);
91 List
<TarArchiveEntry
> parentChildList
= children
.get(parent
);
92 NonNullUtils
.checkNotNull(parentChildList
).add(newEntry
);
97 * Creates a new tar file entry with the specified name.
98 * @param entry the entry to create the file for
100 protected void createFile(TarArchiveEntry entry
) {
101 IPath pathname
= new Path(entry
.getName());
102 TarArchiveEntry parent
;
103 if (pathname
.segmentCount() == 1) {
106 parent
= directoryEntryCache
.get(pathname
107 .removeLastSegments(1));
110 List
<TarArchiveEntry
> childList
= children
.get(parent
);
111 NonNullUtils
.checkNotNull(childList
).add(entry
);
115 public List
getChildren(Object element
) {
116 if (children
== null) {
120 return (children
.get(element
));
124 public InputStream
getContents(Object element
) {
126 return tarFile
.getInputStream((TarArchiveEntry
) element
);
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 TarArchiveEntry entry
= (TarArchiveEntry
) 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(((TarArchiveEntry
) element
).getName());
150 return ArchiveUtil
.toValidNamesPath(name
).toOSString();
154 public String
getLabel(Object element
) {
155 if (element
.equals(root
)) {
156 return ((TarArchiveEntry
) element
).getName();
159 String name
= ((TarArchiveEntry
) element
).getName();
160 return stripPath(ArchiveUtil
.toValidNamesPath(name
).lastSegment());
164 * Returns the entry that this importer uses as the root sentinel.
166 * @return TarArchiveEntry 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
<TarArchiveEntry
> entries
= tarFile
.entries();
203 while (entries
.hasMoreElements()) {
204 TarArchiveEntry entry
= entries
.nextElement();
205 IPath path
= new Path(entry
.getName()).addTrailingSeparator();
207 if (entry
.isDirectory()) {
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 (((TarArchiveEntry
) element
).isDirectory());
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() {