/**
* Copyright (c) 2005-2011 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.editor.codecompletion.revisited;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.python.pydev.core.docutils.StringUtils;
import com.aptana.shared_core.string.FastStringBuffer;
/**
* This class contains all the information we need from the folders beneath the pythonpath.
*
* @author Fabio
*/
public class ModulesFoundStructure {
public static final boolean DEBUG_ZIP = false;
/**
* Inner class to contain what we found within a zip file.
*
* @author Fabio
*/
public static class ZipContents {
public ZipContents(File zipFile) {
this.zipFile = zipFile;
}
public static int ZIP_CONTENTS_TYPE_JAR = 1;
public static int ZIP_CONTENTS_TYPE_PY_ZIP = 2;
/**
* See constants.
*
* Basically it must be one type or the other... if it has .java or .class, it's considered a jar.
*
* Now, if it has any .py it is considered a py zip.
*
* That's because the handling of that file can be very different from one situation to the other:
* - If it's a jar, we're going to rely on JDT, which should not be a requisite for those that don't use jython
* - If it has .py files, we're going to do the handling without any dependency
*/
public int zipContentsType;
/**
* May be any zip file (.zip, .jar, .egg, etc)
*/
public File zipFile;
/**
* These are the paths found within the zip file that are valid to be in the pythonpath.
*
* If it is a jar file, those are the .class files.
* If it is a zip file with .py files, those are the actual .py files (or .pyd files -- dlls)
*
* Does not support mixing both
*/
public Set<String> foundFileZipPaths = new HashSet<String>();
/**
* These are the paths for the folders for the files found to be in the pythonpath.
*/
public Set<String> foundFolderZipPaths = new HashSet<String>();
//these are only 'temporarily' filled if it's not a Jar. Note that these contains the contents for the whole zip,
//and not only the ones that are in the pythonpath
//They are cleared when consolidatePythonpathInfo is called.
public TreeMap<String, String> pyFilesLowerToRegular = new TreeMap<String, String>(); //.py / .pyd / .class
public TreeSet<String> pyfoldersLower = new TreeSet<String>(); //folders
public TreeSet<String> pyInitFilesLowerWithoutExtension = new TreeSet<String>(); //__init__.py (full path in zip)
/**
* Given the temporary info found, goes on to fill the actual found modules.
*/
public void consolidatePythonpathInfo(IProgressMonitor monitor) {
int i = 0;
FastStringBuffer buffer = new FastStringBuffer();
for (Map.Entry<String, String> entry : pyFilesLowerToRegular.entrySet()) {
if (i % 15 == 0) {
if (monitor.isCanceled()) {
break;
}
monitor.setTaskName("Updating zips info...");
monitor.worked(1);
}
String key = entry.getKey();
int index = StringUtils.rFind(key, '/');
boolean add = true;
if (index != -1) {
//If it's in the root, we don't need to check for __init__
buffer.clear();
buffer.append(key.substring(0, index));
if (zipContentsType == ZIP_CONTENTS_TYPE_PY_ZIP) {
//we don't need to check for __init__ if we have a jar
if (buffer.length() > 0) {
buffer.append("/");
buffer.append("__init__");
add = pyInitFilesLowerWithoutExtension.contains(buffer.toString());
}
}
}
if (add) {
String filePath = entry.getValue();
if (DEBUG_ZIP) {
System.out.println("Zip: Found in pythonpath:" + filePath);
}
foundFileZipPaths.add(filePath);
foundFolderZipPaths.add(StringUtils.stripFromLastSlash(filePath));
}
i++;
}
pyFilesLowerToRegular = null;
pyfoldersLower = null;
pyInitFilesLowerWithoutExtension = null;
}
}
/**
* Contains: file found -> module name it was found with.
*/
public Map<File, String> regularModules = new HashMap<File, String>();
/**
* For each zip, there should be one entry.
*/
public List<ZipContents> zipContents = new ArrayList<ZipContents>();
}