📄 cachedjarspackagemanager.java
字号:
// Copyright (c) Corporation for National Research Initiatives// Copyright 2000 Samuele Pedronipackage org.python.core;import java.util.Hashtable;import java.util.Vector;import java.util.Enumeration;import java.util.zip.ZipInputStream;import java.util.zip.ZipEntry;import java.io.*;import java.net.URL;import java.net.URLConnection;//import java.net.URLDecoder;import java.lang.reflect.Modifier;/** Abstract package manager that gathers info about statically known classes * from a set of jars. This info can be eventually cached. * Off-the-shelf this class offers a local file-system based cache impl. */public abstract class CachedJarsPackageManager extends PackageManager { /** Message log method - hook. This default impl does nothing. * @param msg message text */ protected void message(String msg) { } /** Warning log method - hook. This default impl does nothing. * @param warn warning text */ protected void warning(String warn) { } /** Comment log method - hook. This default impl does nothing. * @param msg message text */ protected void comment(String msg) { } /** Debug log method - hook. This default impl does nothing. * @param msg message text */ protected void debug(String msg) { } /** Filter class/pkg by name helper method - hook. * The default impl. is used by {@link #addJarToPackages} in order * to filter out classes whose name contains '$' (e.g. inner classes,...). * Should be used or overriden by derived classes too. * Also to be used in {@link #doDir}. * @param name class/pkg name * @param pkg if true, name refers to a pkg * @return true if name must be filtered out */ protected boolean filterByName(String name,boolean pkg) { return name.indexOf('$') != -1; } /** Filter class by access perms helper method - hook. * The default impl. is used by {@link #addJarToPackages} in order * to filter out non-public classes. * Should be used or overriden by derived classes too. * Also to be used in {@link #doDir}. * Access perms can be read with {@link #checkAccess}. * @param name class name * @param acc class access permissions as int * @return true if name must be filtered out */ protected boolean filterByAccess(String name,int acc) { return (acc & Modifier.PUBLIC) != Modifier.PUBLIC; } private boolean indexModified; private Hashtable jarfiles; private static String vectorToString(Vector vec) { int n = vec.size(); StringBuffer ret = new StringBuffer(); for(int i=0; i<n; i++) { ret.append((String)vec.elementAt(i)); if (i<n-1) ret.append(","); } return ret.toString(); } // Add a single class from zipFile to zipPackages // Only add valid, public classes private void addZipEntry(Hashtable zipPackages, ZipEntry entry, ZipInputStream zip) throws IOException { String name = entry.getName(); //System.err.println("entry: "+name); if (!name.endsWith(".class")) return; char sep = '/'; int breakPoint = name.lastIndexOf(sep); if (breakPoint == -1) { breakPoint = name.lastIndexOf('\\'); sep = '\\'; } String packageName; if (breakPoint == -1) { packageName = ""; } else { packageName = name.substring(0,breakPoint).replace(sep, '.'); } String className = name.substring(breakPoint+1, name.length()-6); if (filterByName(className,false)) return; Vector[] vec = (Vector[])zipPackages.get(packageName); if (vec == null) { vec = new Vector[] { new Vector(), new Vector() }; zipPackages.put(packageName, vec); } int access = checkAccess(zip); if ((access != -1) && !filterByAccess(name,access)) { vec[0].addElement(className); } else { vec[1].addElement(className); } } // Extract all of the packages in a single jarfile private Hashtable getZipPackages(InputStream jarin) throws IOException { Hashtable zipPackages = new Hashtable(); ZipInputStream zip=new ZipInputStream(jarin); ZipEntry entry; while ((entry = zip.getNextEntry()) != null) { addZipEntry(zipPackages, entry, zip); zip.closeEntry(); } // Turn each vector into a comma-separated String for (Enumeration e = zipPackages.keys() ; e.hasMoreElements() ;) { Object key = e.nextElement(); Vector[] vec = (Vector[])zipPackages.get(key); String classes = vectorToString(vec[0]); if (vec[1].size() > 0) { classes += '@' + vectorToString(vec[1]); } zipPackages.put(key, classes); } return zipPackages; } /** Gathers classes info from jar specified by jarurl URL. * Eventually just using previously cached info. * Eventually updated info is not cached. * Persistent cache storage access goes through * inOpenCacheFile() and outCreateCacheFile(). */ public void addJarToPackages(java.net.URL jarurl) { addJarToPackages(jarurl,null,false); } /** Gathers classes info from jar specified by jarurl URL. * Eventually just using previously cached info. * Eventually updated info is (re-)cached if param cache is true. * Persistent cache storage access goes through * inOpenCacheFile() and outCreateCacheFile(). */ public void addJarToPackages(URL jarurl,boolean cache) { addJarToPackages(jarurl,null,cache); } /** Gathers classes info from jar specified by File jarfile. * Eventually just using previously cached info. * Eventually updated info is not cached. * Persistent cache storage access goes through * inOpenCacheFile() and outCreateCacheFile(). */ public void addJarToPackages(File jarfile) { addJarToPackages(null,jarfile,false); } /** Gathers classes info from jar specified by File jarfile. * Eventually just using previously cached info. * Eventually updated info is (re-)cached if param cache is true. * Persistent cache storage access goes through * inOpenCacheFile() and outCreateCacheFile(). */ public void addJarToPackages(File jarfile,boolean cache) { addJarToPackages(null,jarfile,cache); } private void addJarToPackages(URL jarurl,File jarfile,boolean cache) { try { boolean caching = jarfiles!=null; URLConnection jarconn = null; boolean localfile = true; if (jarfile == null) { jarconn = jarurl.openConnection(); // This is necessary because 'file:' url-connections // return always 0 through getLastModified (bug?). // And in order to handle localfiles (from urls too) // uniformly. if(jarconn.getURL().getProtocol().equals("file")) { // ??pending: need to use java2 URLDecoder.decode? // but under 1.1 this is absent and should be simulated. String jarfilename = jarurl.getFile(); jarfilename = jarfilename.replace('/',File.separatorChar); jarfile = new File(jarfilename); } else localfile = false; } if (localfile && !jarfile.exists()) return; Hashtable zipPackages = null; long mtime = 0; String jarcanon = null; JarXEntry entry = null; boolean brandNew = false; if(caching) { if(localfile) { mtime = jarfile.lastModified(); jarcanon = jarfile.getCanonicalPath(); } else { mtime = jarconn.getLastModified(); jarcanon = jarurl.toString(); } entry = (JarXEntry)jarfiles.get(jarcanon); if (entry == null && cache) { message("processing new jar, '"+ jarcanon+"'"); String jarname; if(localfile) { jarname = jarfile.getName(); } else { jarname = jarurl.getFile(); int slash = jarname.lastIndexOf('/'); if (slash != -1) jarname=jarname.substring(slash+1); } jarname=jarname.substring(0,jarname.length()-4); entry = new JarXEntry(jarname); jarfiles.put(jarcanon, entry); brandNew = true; } if (mtime != 0 && entry != null && entry.mtime == mtime) { zipPackages = readCacheFile(entry, jarcanon); } } if (zipPackages == null) { caching = caching && cache; if(caching) { indexModified = true; if (entry.mtime != 0) { message("processing modified jar, '"+ jarcanon+"'"); } entry.mtime = mtime; } InputStream jarin; if (jarconn == null) jarin = new BufferedInputStream( new FileInputStream(jarfile)); else jarin = jarconn.getInputStream();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -