blob: 18b727dd3d29c661bbf31d30ed247b0d33a6e0e1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Red Hat, Inc - Was TarFileStructureProvider, performed changes from
* IImportStructureProvider to ILeveledImportStructureProvider
*******************************************************************************/
package org.eclipse.ui.internal.wizards.datatransfer;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* This class provides information regarding the context structure and content
* of specified tar file entry objects.
*
* @since 3.1
*/
public class TarLeveledStructureProvider implements
ILeveledImportStructureProvider {
private TarFile tarFile;
private TarEntry root = new TarEntry("/");//$NON-NLS-1$
private Map children;
private Map directoryEntryCache = new HashMap();
private int stripLevel;
/**
* Creates a <code>TarFileStructureProvider</code>, which will operate on
* the passed tar file.
*
* @param sourceFile
* the source TarFile
*/
public TarLeveledStructureProvider(TarFile sourceFile) {
super();
tarFile = sourceFile;
root.setFileType(TarEntry.DIRECTORY);
}
/**
* Creates a new container tar entry with the specified name, iff it has
* not already been created. If the parent of the given element does not
* already exist it will be recursively created as well.
* @param pathname The path representing the container
* @return The element represented by this pathname (it may have already existed)
*/
protected TarEntry createContainer(IPath pathname) {
TarEntry existingEntry = (TarEntry) directoryEntryCache.get(pathname);
if (existingEntry != null)
return existingEntry;
TarEntry parent;
if (pathname.segmentCount() == 1)
parent = root;
else
parent = createContainer(pathname.removeLastSegments(1));
TarEntry newEntry = new TarEntry(pathname.toString());
newEntry.setFileType(TarEntry.DIRECTORY);
directoryEntryCache.put(pathname, newEntry);
List childList = new ArrayList();
children.put(newEntry, childList);
List parentChildList = (List) children.get(parent);
parentChildList.add(newEntry);
return newEntry;
}
/**
* Creates a new tar file entry with the specified name.
*/
protected void createFile(TarEntry entry) {
IPath pathname = new Path(entry.getName());
TarEntry parent;
if (pathname.segmentCount() == 1)
parent = root;
else
parent = (TarEntry) directoryEntryCache.get(pathname
.removeLastSegments(1));
List childList = (List) children.get(parent);
childList.add(entry);
}
/*
* (non-Javadoc) Method declared on IImportStructureProvider
*/
public List getChildren(Object element) {
if (children == null)
initialize();
return ((List) children.get(element));
}
/*
* (non-Javadoc) Method declared on IImportStructureProvider
*/
public InputStream getContents(Object element) {
try {
return tarFile.getInputStream((TarEntry) element);
} catch (TarException e) {
return null;
} catch (IOException e) {
return null;
}
}
/**
* Returns the resource attributes for this file.
*
* @param element
* @return the attributes of the file
*/
public ResourceAttributes getResourceAttributes(Object element) {
ResourceAttributes attributes = new ResourceAttributes();
TarEntry entry = (TarEntry) element;
attributes.setExecutable((entry.getMode() & 0100) != 0);
attributes.setReadOnly((entry.getMode() & 0200) == 0);
return attributes;
}
/*
* (non-Javadoc) Method declared on IImportStructureProvider
*/
public String getFullPath(Object element) {
return stripPath(((TarEntry) element).getName());
}
/*
* (non-Javadoc) Method declared on IImportStructureProvider
*/
public String getLabel(Object element) {
if (element.equals(root))
return ((TarEntry) element).getName();
return stripPath(new Path(((TarEntry) element).getName()).lastSegment());
}
/**
* Returns the entry that this importer uses as the root sentinel.
*
* @return TarEntry entry
*/
public Object getRoot() {
return root;
}
/**
* Returns the tar file that this provider provides structure for.
*
* @return TarFile file
*/
public TarFile getTarFile() {
return tarFile;
}
/**
* Initializes this object's children table based on the contents of the
* specified source file.
*/
protected void initialize() {
children = new HashMap(1000);
children.put(root, new ArrayList());
Enumeration entries = tarFile.entries();
while (entries.hasMoreElements()) {
TarEntry entry = (TarEntry) entries.nextElement();
IPath path = new Path(entry.getName()).addTrailingSeparator();
if (entry.getFileType() == TarEntry.DIRECTORY)
createContainer(path);
else
{
// Ensure the container structure for all levels above this is initialized
// Once we hit a higher-level container that's already added we need go no further
int pathSegmentCount = path.segmentCount();
if (pathSegmentCount > 1)
createContainer(path.uptoSegment(pathSegmentCount - 1));
createFile(entry);
}
}
}
/*
* (non-Javadoc) Method declared on IImportStructureProvider
*/
public boolean isFolder(Object element) {
return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
}
/*
* Strip the leading directories from the path
*/
private String stripPath(String path) {
String pathOrig = new String(path);
for (int i = 0; i < stripLevel; i++) {
int firstSep = path.indexOf('/');
// If the first character was a seperator we must strip to the next
// seperator as well
if (firstSep == 0) {
path = path.substring(1);
firstSep = path.indexOf('/');
}
// No seperator wasw present so we're in a higher directory right
// now
if (firstSep == -1)
return pathOrig;
path = path.substring(firstSep);
}
return path;
}
public void setStrip(int level) {
stripLevel = level;
}
public int getStrip() {
return stripLevel;
}
}