📄 pythonpathhelper.java
字号:
/*
* Created on Nov 12, 2004
*
* @author Fabio Zadrozny
*/
package org.python.pydev.editor.codecompletion.revisited;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.python.pydev.core.FullRepIterable;
import org.python.pydev.core.REF;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.plugin.PydevPlugin;
/**
* This is not a singleton because we may have a different pythonpath for each project (even though
* we have a default one as the original pythonpath).
*
* @author Fabio Zadrozny
*/
public class PythonPathHelper implements Serializable{
private static final long serialVersionUID = 1L;
/**
* This is a list of Files containg the pythonpath.
*/
private volatile List<String> pythonpath = new ArrayList<String>();
/**
* Returns the default path given from the string.
* @param str
* @param acceptPoint says if we can have dots in the str that has the path to be analyzed
* @return a trimmed string with all the '\' converted to '/'
*/
public String getDefaultPathStr(String str){
//this check is no longer done... could result in other problems
// if(acceptPoint == false && str.indexOf(".") == 0){ //cannot start with a dot
// throw new RuntimeException("The pythonpath can only have absolute paths (cannot start with '.', therefore, the path: '"+str+"' is not valid.");
// }
return StringUtils.replaceAllSlashes(str.trim());
}
/**
* This method returns all modules that can be obtained from a root File.
* @param monitor
* @return the files in position 0 and folders in position 1.
*/
public List<File>[] getModulesBelow(File root, IProgressMonitor monitor){
if(!root.exists()){
return null;
}
if(root.isDirectory()){
FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
if(pathname.isFile()){
return isValidFileMod(REF.getFileAbsolutePath(pathname));
}else if(pathname.isDirectory()){
return isFileOrFolderWithInit(pathname);
}else{
return false;
}
}
};
return PydevPlugin.getPyFilesBelow(root, filter, monitor, true);
}
return null;
}
/**
* @param root the zip file to analyze
* @param monitor the monitor, to keep track of what is happening
* @return a list with the name of the found modules in the jar
*/
public static List<String> getFromJar(File root, IProgressMonitor monitor){
String fileName = root.getName();
if(root.isFile() && (fileName.endsWith(".jar") || fileName.endsWith(".zip"))){ //ok, it may be a jar file, so let's get its contents and get the available modules
Set<String> folders = new HashSet<String>();
try {
String zipFileName = root.getName();
ZipFile zipFile = new ZipFile(root);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
//ok, now that we have the zip entries, let's map them to modules
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
String name = entry.getName();
if(!entry.isDirectory()){
//it is a file... we will ignore them, as java files do not map to actual modules as python, but to classes.
//and will only add its parent folder...
IPath path = new Path(name);
String fileExtension = path.getFileExtension();
if(fileExtension != null && fileExtension.equals("class")){
path = path.removeFileExtension().removeLastSegments(1); //remove the class and the public class name
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < path.segmentCount(); i++) {
buffer.append(path.segment(i));
String modName = buffer.toString();
folders.add(modName);
if(i+1 < path.segmentCount()){
buffer.append("."); //not the last one...
}
}
monitor.setTaskName("Found in "+zipFileName+" module "+buffer);
}
}
}
return new ArrayList<String>(folders);
} catch (Exception e) {
//that's ok, it is probably not a zip file after all...
PydevPlugin.log(e);
}
}
return null;
}
/**
*
* @param path the path we want to analyze
* @return if the path passed belongs to a valid python compiled extension
*/
public static boolean isValidDll(String path){
if( path.endsWith(".pyd") ||
path.endsWith(".so") ||
path.endsWith(".dll")){
return true;
}
return false;
}
public final static String[] WILDCARD_VALID_SOURCE_FILES = new String[]{"*.py", "*.pyw"};
public final static String[] DOTTED_VALID_SOURCE_FILES = new String[]{".py", ".pyw"};
public final static String[] VALID_SOURCE_FILES = new String[]{"py", "pyw"};
public final static String[] getDottedValidSourceFiles() {
return DOTTED_VALID_SOURCE_FILES;
}
public final static String[] getValidSourceFiles() {
return VALID_SOURCE_FILES;
}
public final static String getDefaultDottedPythonExtension(){
return ".py";
}
/**
* @return if the path passed belongs to a valid python source file (checks for the extension)
*/
public static boolean isValidSourceFile(String path) {
path = path.toLowerCase();
for(String end : getDottedValidSourceFiles()){
if(path.endsWith(end)){
return true;
}
}
return false;
}
/**
* @return whether an IFile is a valid source file given its extension
*/
public static boolean isValidSourceFile(IFile file) {
String ext = file.getFileExtension();
if(ext == null){ // no extension
return false;
}
ext = ext.toLowerCase();
for(String end : getValidSourceFiles()){
if(ext.equals(end)){
return true;
}
}
return false;
}
/**
* @return if the paths maps to a valid python module (depending on its extension).
*/
public static boolean isValidFileMod(String path){
boolean ret = false;
if( isValidSourceFile(path)){
ret = true;
} else if(isValidDll(path)){
ret = true;
}
return ret;
}
public String resolveModule(String fullPath){
return resolveModule(fullPath, false);
}
/**
* DAMN... when I started thinking this up, it seemed much better... (and easier)
*
* @param module - this is the full path of the module. Only for directories or py,pyd,dll,pyo files.
* @return a String with the module that the file or folder should represent. E.g.: compiler.ast
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -