import java.io.File; import java.util.*; aspect ClassPath { private String CompilationUnit.relativeName; private String CompilationUnit.pathName; private boolean CompilationUnit.fromSource; public void CompilationUnit.setRelativeName(String name) { relativeName = name; } public void CompilationUnit.setPathName(String name) { pathName = name; } public void CompilationUnit.setFromSource(boolean value) { fromSource = value; } syn String CompilationUnit.relativeName() = relativeName; syn String CompilationUnit.pathName() = pathName; syn boolean CompilationUnit.fromSource() = fromSource; class ClassFile { private boolean exists; //private static byte[] buf; // caused problems with nested classes private byte[] buf; private int size; private boolean isSource = false; private long age; private static boolean pathsInitialized = false; public static java.util.ArrayList classPath; public static java.util.ArrayList sourcePath; private static HashSet packages = new HashSet(); public static void pushClassPath(String name) { initPaths(); sourcePath.add(new File(name)); } public static void popClassPath() { sourcePath.remove(sourcePath.size()-1); } private static void initPaths() { if(!pathsInitialized) { pathsInitialized = true; //System.err.println("Initializing class paths"); ArrayList classPaths = new ArrayList(); ArrayList sourcePaths = new ArrayList(); String[] bootclasspaths; if(Program.hasValueForOption("-bootclasspath")) bootclasspaths = Program.getValueForOption("-bootclasspath").split(File.pathSeparator); else bootclasspaths = System.getProperty("sun.boot.class.path").split(File.pathSeparator); for(int i = 0; i < bootclasspaths.length; i++) { classPaths.add(bootclasspaths[i]); //System.err.println("Adding classpath " + bootclasspaths[i]); } String[] extdirs; if(Program.hasValueForOption("-extdirs")) extdirs = Program.getValueForOption("-extdirs").split(File.pathSeparator); else extdirs = System.getProperty("java.ext.dirs").split(File.pathSeparator); for(int i = 0; i < extdirs.length; i++) { classPaths.add(extdirs[i]); //System.err.println("Adding classpath " + extdirs[i]); } String[] userClasses = null; if(Program.hasValueForOption("-classpath")) userClasses = Program.getValueForOption("-classpath").split(File.pathSeparator); else { String s = System.getProperty("java.class.path"); if(s != null && s.length() > 0) userClasses = s.split(File.pathSeparator); else userClasses = ".".split(File.pathSeparator); } if(!Program.hasValueForOption("-sourcepath")) { for(int i = 0; i < userClasses.length; i++) { classPaths.add(userClasses[i]); sourcePaths.add(userClasses[i]); //System.err.println("Adding classpath/sourcepath " + userClasses[i]); } } else { for(int i = 0; i < userClasses.length; i++) { classPaths.add(userClasses[i]); //System.err.println("Adding classpath " + userClasses[i]); } userClasses = Program.getValueForOption("-sourcepath").split(File.pathSeparator); for(int i = 0; i < userClasses.length; i++) { sourcePaths.add(userClasses[i]); //System.err.println("Adding sourcepath " + userClasses[i]); } } classPath = new ArrayList(); sourcePath = new ArrayList(); for(Iterator iter = classPaths.iterator(); iter.hasNext(); ) { String s = (String)iter.next(); File f = new File(s); if(f.isFile()) { try { ZipFile zip = new ZipFile(f); classPath.add(zip); for (Enumeration e = zip.entries() ; e.hasMoreElements() ;) { ZipEntry entry = (ZipEntry)e.nextElement(); String pathName = new File(entry.getName()).getParent(); if(!packages.contains(pathName)) { int pos = 0; while(pathName != null && -1 != (pos = pathName.indexOf(File.separatorChar, pos + 1))) { String n = pathName.substring(0, pos); if(!packages.contains(n)) { //System.out.println("Adding: " + n); packages.add(n); } } //System.out.println("Adding: " + pathName); packages.add(pathName); } } } catch (IOException e) { } } else if(f.isDirectory()) { classPath.add(f); } } for(Iterator iter = sourcePaths.iterator(); iter.hasNext(); ) { String s = (String)iter.next(); File f = new File(s); if(f.isFile()) { try { ZipFile zip = new ZipFile(f); sourcePath.add(zip); for (Enumeration e = zip.entries() ; e.hasMoreElements() ;) { ZipEntry entry = (ZipEntry)e.nextElement(); String pathName = new File(entry.getName()).getParent(); //System.out.println("Adding: " + pathName); packages.add(pathName); } } catch (IOException e) { } } else if(f.isDirectory()) { sourcePath.add(f); } } } } static boolean isPackage(String name) { name = name.replace('.', File.separatorChar); if(packages.contains(name)) { return true; } for(Iterator iter = classPath.iterator(); iter.hasNext(); ) { Object o = iter.next(); if(o instanceof File) { File classFile = new File((File)o, name); if(classFile.isDirectory()) { packages.add(name); return true; } } } for(Iterator iter = sourcePath.iterator(); iter.hasNext(); ) { Object o = iter.next(); if(o instanceof File) { File classFile = new File((File)o, name); if(classFile.isDirectory()) { packages.add(name); return true; } } } return false; } long startTime; String fullName; String pathName; String relativeName; boolean found = false; public ClassFile(String name) { initPaths(); fullName = name; startTime = System.currentTimeMillis(); String fileName = name.replace('.', File.separatorChar); name = name.replace('.', '/'); //System.out.println("Trying to load classfile " + name); exists = false; isSource = false; age = 0; try { for(Iterator iter = sourcePath.iterator(); iter.hasNext(); ) { Object o = iter.next(); if(o instanceof ZipFile) { ZipFile zip = (ZipFile)o; ZipEntry zipEntry; zipEntry = zip.getEntry(name + ".java"); if(zipEntry != null && !zipEntry.isDirectory() && zipEntry.getTime() > age) { //System.out.println("Found " + name + " in " + zip.toString() + ", size: " + zipEntry.getSize()); size = (int)zipEntry.getSize(); InputStream is = zip.getInputStream(zipEntry); fillBuf(is, size); is.close(); exists = true; isSource = true; age = zipEntry.getTime(); pathName = zip.getName(); relativeName = name; } } else if(o instanceof File) { File classFile; classFile = new File((File)o, fileName + ".java"); if(classFile.isFile() && classFile.lastModified() > age) { //System.out.println("Found " + fileName + " in " + classFile.toString() + ", size: " + classFile.length()); size = (int)classFile.length(); InputStream is = new FileInputStream(classFile); fillBuf(is, size); is.close(); exists = true; isSource = true; age = classFile.lastModified(); pathName = classFile.getPath(); relativeName = fileName; } } } for(Iterator iter = classPath.iterator(); iter.hasNext(); ) { Object o = iter.next(); if(o instanceof ZipFile) { ZipFile zip = (ZipFile)o; ZipEntry zipEntry; zipEntry = zip.getEntry(name + ".class"); if(zipEntry != null && !zipEntry.isDirectory() && zipEntry.getTime() > age) { //System.out.println("Found " + name + " in " + zip.toString() + ", size: " + zipEntry.getSize()); size = (int)zipEntry.getSize(); InputStream is = zip.getInputStream(zipEntry); fillBuf(is, size); is.close(); exists = true; isSource = false; age = zipEntry.getTime(); pathName = zip.getName(); relativeName = name; } } else if(o instanceof File) { File classFile; classFile = new File((File)o, fileName + ".class"); if(classFile.isFile() && classFile.lastModified() > age) { //System.out.println("Found " + fileName + " in " + classFile.toString() + ", size: " + classFile.length()); size = (int)classFile.length(); InputStream is = new FileInputStream(classFile); fillBuf(is, size); is.close(); exists = true; isSource = false; age = classFile.lastModified(); pathName = classFile.getPath(); relativeName = fileName; } } } } catch(IOException e) { } } private void fillBuf(InputStream is, int size) { int n = 0; try { //if(buf == null || buf.length < size) // caused problems with nested classes // buf = new byte[size]; buf = new byte[size]; while (n < size) n = n + is.read(buf, n, size - n); } catch(IOException e) { throw new Error("Could not fill buffert, error at " + n); } } public byte[] buffer() { return buf; } public int size() { return size; } public boolean exists() { return exists; } public CompilationUnit getCompilationUnit() throws Exception { if(!isSource) { if(Program.verbose()) System.out.print("Loading .class file: " + fullName + " "); CompilationUnit u = new bytecode.Parser(buffer(), size(), fullName).parse(null, null); u.setPathName(pathName); u.setRelativeName(relativeName + ".class"); u.setFromSource(false); if(Program.verbose()) System.out.println("in " + (System.currentTimeMillis() - startTime) + " ms"); return u; } else { if(Program.verbose()) System.out.print("Loading .java file: " + fullName + " "); InputStream is = new ByteArrayInputStream(buffer(), 0, size()); parser.JavaScanner scanner = new parser.JavaScanner(new parser.UnicodeEscapes(is)); parser.JavaParser parser = new parser.JavaParser(); CompilationUnit u = ((Program)parser.parse(scanner)).getCompilationUnit(0); is.close(); u.setPathName(pathName); u.setRelativeName(relativeName + ".java"); u.setFromSource(true); if(Program.verbose()) System.out.println("in " + (System.currentTimeMillis() - startTime) + " ms"); return u; } } } }