001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Red Hat, Inc - Was TarFileStructureProvider, performed changes from
011: * IImportStructureProvider to ILeveledImportStructureProvider
012: *******************************************************************************/package org.eclipse.ui.internal.wizards.datatransfer;
013:
014: import java.io.IOException;
015: import java.io.InputStream;
016: import java.util.ArrayList;
017: import java.util.Enumeration;
018: import java.util.HashMap;
019: import java.util.List;
020: import java.util.Map;
021:
022: import org.eclipse.core.resources.ResourceAttributes;
023: import org.eclipse.core.runtime.IPath;
024: import org.eclipse.core.runtime.Path;
025: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
026:
027: /**
028: * This class provides information regarding the context structure and content
029: * of specified tar file entry objects.
030: *
031: * @since 3.1
032: */
033: public class TarLeveledStructureProvider implements
034: ILeveledImportStructureProvider {
035: private TarFile tarFile;
036:
037: private TarEntry root = new TarEntry("/");//$NON-NLS-1$
038:
039: private Map children;
040:
041: private Map directoryEntryCache = new HashMap();
042:
043: private int stripLevel;
044:
045: /**
046: * Creates a <code>TarFileStructureProvider</code>, which will operate on
047: * the passed tar file.
048: *
049: * @param sourceFile
050: * the source TarFile
051: */
052: public TarLeveledStructureProvider(TarFile sourceFile) {
053: super ();
054: tarFile = sourceFile;
055: root.setFileType(TarEntry.DIRECTORY);
056: }
057:
058: /**
059: * Creates a new container tar entry with the specified name, iff it has
060: * not already been created. If the parent of the given element does not
061: * already exist it will be recursively created as well.
062: * @param pathname The path representing the container
063: * @return The element represented by this pathname (it may have already existed)
064: */
065: protected TarEntry createContainer(IPath pathname) {
066: TarEntry existingEntry = (TarEntry) directoryEntryCache
067: .get(pathname);
068: if (existingEntry != null) {
069: return existingEntry;
070: }
071:
072: TarEntry parent;
073: if (pathname.segmentCount() == 1) {
074: parent = root;
075: } else {
076: parent = createContainer(pathname.removeLastSegments(1));
077: }
078: TarEntry newEntry = new TarEntry(pathname.toString());
079: newEntry.setFileType(TarEntry.DIRECTORY);
080: directoryEntryCache.put(pathname, newEntry);
081: List childList = new ArrayList();
082: children.put(newEntry, childList);
083:
084: List parentChildList = (List) children.get(parent);
085: parentChildList.add(newEntry);
086: return newEntry;
087: }
088:
089: /**
090: * Creates a new tar file entry with the specified name.
091: */
092: protected void createFile(TarEntry entry) {
093: IPath pathname = new Path(entry.getName());
094: TarEntry parent;
095: if (pathname.segmentCount() == 1) {
096: parent = root;
097: } else {
098: parent = (TarEntry) directoryEntryCache.get(pathname
099: .removeLastSegments(1));
100: }
101:
102: List childList = (List) children.get(parent);
103: childList.add(entry);
104: }
105:
106: /*
107: * (non-Javadoc) Method declared on IImportStructureProvider
108: */
109: public List getChildren(Object element) {
110: if (children == null) {
111: initialize();
112: }
113:
114: return ((List) children.get(element));
115: }
116:
117: /*
118: * (non-Javadoc) Method declared on IImportStructureProvider
119: */
120: public InputStream getContents(Object element) {
121: try {
122: return tarFile.getInputStream((TarEntry) element);
123: } catch (TarException e) {
124: IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
125: return null;
126: } catch (IOException e) {
127: IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
128: return null;
129: }
130: }
131:
132: /**
133: * Returns the resource attributes for this file.
134: *
135: * @param element
136: * @return the attributes of the file
137: */
138: public ResourceAttributes getResourceAttributes(Object element) {
139: ResourceAttributes attributes = new ResourceAttributes();
140: TarEntry entry = (TarEntry) element;
141: attributes.setExecutable((entry.getMode() & 0100) != 0);
142: attributes.setReadOnly((entry.getMode() & 0200) == 0);
143: return attributes;
144: }
145:
146: /*
147: * (non-Javadoc) Method declared on IImportStructureProvider
148: */
149: public String getFullPath(Object element) {
150: return stripPath(((TarEntry) element).getName());
151: }
152:
153: /*
154: * (non-Javadoc) Method declared on IImportStructureProvider
155: */
156: public String getLabel(Object element) {
157: if (element.equals(root)) {
158: return ((TarEntry) element).getName();
159: }
160:
161: return stripPath(new Path(((TarEntry) element).getName())
162: .lastSegment());
163: }
164:
165: /**
166: * Returns the entry that this importer uses as the root sentinel.
167: *
168: * @return TarEntry entry
169: */
170: public Object getRoot() {
171: return root;
172: }
173:
174: /**
175: * Returns the tar file that this provider provides structure for.
176: *
177: * @return TarFile file
178: */
179: public TarFile getTarFile() {
180: return tarFile;
181: }
182:
183: /*
184: * (non-Javadoc)
185: * @see org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider#closeArchive()
186: */
187: public boolean closeArchive() {
188: try {
189: getTarFile().close();
190: } catch (IOException e) {
191: IDEWorkbenchPlugin.log(
192: DataTransferMessages.ZipImport_couldNotClose
193: + getTarFile().getName(), e);
194: return false;
195: }
196: return true;
197: }
198:
199: /**
200: * Initializes this object's children table based on the contents of the
201: * specified source file.
202: */
203: protected void initialize() {
204: children = new HashMap(1000);
205:
206: children.put(root, new ArrayList());
207: Enumeration entries = tarFile.entries();
208: while (entries.hasMoreElements()) {
209: TarEntry entry = (TarEntry) entries.nextElement();
210: IPath path = new Path(entry.getName())
211: .addTrailingSeparator();
212:
213: if (entry.getFileType() == TarEntry.DIRECTORY) {
214: createContainer(path);
215: } else {
216: // Ensure the container structure for all levels above this is initialized
217: // Once we hit a higher-level container that's already added we need go no further
218: int pathSegmentCount = path.segmentCount();
219: if (pathSegmentCount > 1) {
220: createContainer(path
221: .uptoSegment(pathSegmentCount - 1));
222: }
223: createFile(entry);
224: }
225: }
226: }
227:
228: /*
229: * (non-Javadoc) Method declared on IImportStructureProvider
230: */
231: public boolean isFolder(Object element) {
232: return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
233: }
234:
235: /*
236: * Strip the leading directories from the path
237: */
238: private String stripPath(String path) {
239: String pathOrig = new String(path);
240: for (int i = 0; i < stripLevel; i++) {
241: int firstSep = path.indexOf('/');
242: // If the first character was a seperator we must strip to the next
243: // seperator as well
244: if (firstSep == 0) {
245: path = path.substring(1);
246: firstSep = path.indexOf('/');
247: }
248: // No seperator wasw present so we're in a higher directory right
249: // now
250: if (firstSep == -1) {
251: return pathOrig;
252: }
253: path = path.substring(firstSep);
254: }
255: return path;
256: }
257:
258: public void setStrip(int level) {
259: stripLevel = level;
260: }
261:
262: public int getStrip() {
263: return stripLevel;
264: }
265: }
|