/** * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.navigator; import java.io.File; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeSet; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.runtime.Assert; import org.python.pydev.core.log.Log; import org.python.pydev.shared_core.string.StringUtils; /** * Helper to get a structure from a zip file */ public class ZipStructure { private Map<Integer, TreeSet<String>> levelToContents = new HashMap<Integer, TreeSet<String>>(); public final File file; /*package*/ ZipStructure() { //just for testing this.file = null; } /** * @param file the file that's treated as a zip * @param zipFile the zip wrapping of the passed file */ public ZipStructure(File file, ZipFile zipFile) { this.file = file; Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { String name; try { ZipEntry element = entries.nextElement(); name = element.getName(); } catch (Exception e) { Log.log(e); continue; } final List<String> split = StringUtils.split(name, '/'); int size = split.size(); int level = size - 1; TreeSet<String> treeSet = levelToContents.get(level); if (treeSet == null) { treeSet = new TreeSet<String>(); levelToContents.put(level, treeSet); } treeSet.add(name); //Add for parent entries (it's possible to have an entry folder/entry.py and the folder/ //wouldn't appear in our structure). if (size == 1) { continue; } String[] array = split.toArray(new String[size]); for (int i = 0; i < size - 1; i++) { name = StringUtils.join("/", array, 0, i + 1) + "/"; level = i; treeSet = levelToContents.get(level); if (treeSet == null) { treeSet = new TreeSet<String>(); levelToContents.put(level, treeSet); } treeSet.add(name); } } } /*package*/Map<Integer, TreeSet<String>> getLevelToContents() { return levelToContents; } /** * In this method we'll get the contents within the zip file for the passed directory * * @param string: Must be a directory within the zip file or an empty string to get the root contents */ public List<String> contents(String name) { ArrayList<String> ret = new ArrayList<String>(); int level; int length = name.length(); if (length == 0) { level = 0; } else { Assert.isTrue(StringUtils.endsWith(name, '/')); //must be a directory level = StringUtils.count(name, '/'); } TreeSet<String> treeSet = levelToContents.get(level); if (treeSet != null) { if (length == 0) { ret.addAll(treeSet); } else { for (String s : treeSet.tailSet(name)) { if (s.startsWith(name)) { ret.add(s); } } } } return ret; } }