// Copyright (c) Corporation for National Research Initiatives // Copyright 2000 Samuele Pedroni package org.python.core; import java.io.*; import java.lang.reflect.Modifier; /** Path package manager. Gathering classes info dynamically * from a set of directories in path {@link #searchPath}, and * statically from a set of jars, like {@link CachedJarsPackageManager}. */ public abstract class PathPackageManager extends CachedJarsPackageManager { public PyList searchPath; public PathPackageManager() { searchPath = new PyList(); } /** Helper for {@link #packageExists(java.lang.String,java.lang.String)}. * Scans for package pkg.name the directories in path. * */ protected boolean packageExists(PyList path,String pkg,String name) { String child = pkg.replace('.',File.separatorChar) + File.separator + name; for (int i=0; i < path.__len__(); i++) { String dir = path.get(i).__str__().toString(); if (dir.length() == 0) dir = null; File f = new File(dir,child); if (f.isDirectory() && imp.caseok(f, name, name.length())) { return true; } } return false; } /** Helper for {@link #doDir(PyJavaPackage,boolean,boolean)}. * Scans for package jpkg content over the directories in path. * Add to ret the founded classes/pkgs. * Filter out classes using {@link #filterByName},{@link #filterByAccess}. */ protected void doDir(PyList path, PyList ret, PyJavaPackage jpkg, boolean instantiate,boolean exclpkgs) { String child=jpkg.__name__.replace('.',File.separatorChar); for (int i=0; i < path.__len__(); i++) { String dir = path.get(i).__str__().toString(); if (dir.length() == 0) dir = null; File childFile = new File(dir,child); String[] list=childFile.list(); if(list == null) continue; doList: for (int j=0; j < list.length; j++) { String jname = list[j]; File cand = new File(childFile, jname); int jlen = jname.length(); boolean pkgCand=false; if (cand.isDirectory()) { if (!instantiate && exclpkgs) continue; pkgCand = true; } else { if(!jname.endsWith(".class")) continue; jlen-=6; } jname = jname.substring(0,jlen); PyString name = new PyString(jname); if (filterByName(jname,pkgCand)) continue; // for opt maybe we should some hash-set for ret if (jpkg.__dict__.has_key(name) || jpkg.clsSet.has_key(name) || ret.__contains__(name)) { continue; } if (!Character.isJavaIdentifierStart(jname.charAt(0))) continue; for (int k = 1; k < jlen; k++) { if (!Character.isJavaIdentifierPart(jname.charAt(k))) continue doList; } if(!pkgCand) { try { int acc = checkAccess(new BufferedInputStream( new FileInputStream(cand))); if ((acc == -1) || filterByAccess(jname, acc)) continue; } catch(IOException e) { continue; } } if (instantiate) { if (pkgCand) jpkg.addPackage(jname); else jpkg.addLazyClass(jname); } ret.append(name); } } } /** Add directory dir (if exists) to {@link #searchPath}. */ public void addDirectory(File dir) { try { if (dir.getPath().length() == 0) searchPath.append(Py.EmptyString); else searchPath.append(new PyString(dir.getCanonicalPath())); } catch(IOException e) { warning("skipping bad directory, '" +dir+ "'"); } } // ??pending: // Uses simply split and not a StringTokenizer+trim to adhere to // sun jvm parsing of classpath. // E.g. "a;" is parsed by sun jvm as a, ""; the latter is interpreted // as cwd. jview trims and cwd is per default in classpath. // The logic here should work for both(...). Need to distinguish? // This code does not avoid duplicates in searchPath. // Should cause no problem (?). /** Adds "classpath" entry. Calls {@link #addDirectory} if path * refers to a dir, {@link #addJarToPackages(java.io.File, boolean)} * with param cache true if path refers to a jar. */ public void addClassPath(String path) { PyList paths = new PyString(path).split(java.io.File.pathSeparator); for (int i = 0; i < paths.__len__(); i++) { String entry = paths.get(i).toString(); if (entry.endsWith(".jar") || entry.endsWith(".zip")) { addJarToPackages(new File(entry),true); } else { File dir = new File(entry); if (entry.length() == 0 || dir.isDirectory()) addDirectory(dir); } } } public PyList doDir(PyJavaPackage jpkg, boolean instantiate, boolean exclpkgs) { PyList basic = basicDoDir(jpkg,instantiate,exclpkgs); PyList ret = new PyList(); doDir(searchPath,ret,jpkg,instantiate,exclpkgs); return merge(basic,ret); } public boolean packageExists(String pkg,String name) { return packageExists(searchPath,pkg,name); } }