/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.batch; import java.io.File; import java.util.Hashtable; import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; import net.sourceforge.phpdt.internal.compiler.util.SuffixConstants; public class ClasspathDirectory implements FileSystem.Classpath, SuffixConstants { String path; Hashtable directoryCache; String[] missingPackageHolder = new String[1]; String encoding; public int mode; // ability to only consider one kind of files (source vs. binaries), by default use both public static final int SOURCE = 1; public static final int BINARY = 2; ClasspathDirectory(File directory, String encoding, int mode) { this.mode = mode; this.path = directory.getAbsolutePath(); if (!this.path.endsWith(File.separator)) this.path += File.separator; this.directoryCache = new Hashtable(11); this.encoding = encoding; } ClasspathDirectory(File directory, String encoding) { this(directory, encoding, SOURCE | BINARY); // by default consider both sources and binaries } String[] directoryList(String qualifiedPackageName) { String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName); if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar if (dirList != null) return dirList; File dir = new File(this.path + qualifiedPackageName); notFound : if (dir != null && dir.isDirectory()) { // must protect against a case insensitive File call // walk the qualifiedPackageName backwards looking for an uppercase character before the '/' int index = qualifiedPackageName.length(); int last = qualifiedPackageName.lastIndexOf(File.separatorChar); while (--index > last && !Character.isUpperCase(qualifiedPackageName.charAt(index))){/*empty*/} if (index > last) { if (last == -1) { if (!doesFileExist(qualifiedPackageName, "")) //$NON-NLS-1$ break notFound; } else { String packageName = qualifiedPackageName.substring(last + 1); String parentPackage = qualifiedPackageName.substring(0, last); if (!doesFileExist(packageName, parentPackage)) break notFound; } } if ((dirList = dir.list()) == null) dirList = new String[0]; this.directoryCache.put(qualifiedPackageName, dirList); return dirList; } this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder); return null; } boolean doesFileExist(String fileName, String qualifiedPackageName) { String[] dirList = directoryList(qualifiedPackageName); if (dirList == null) return false; // most common case for (int i = dirList.length; --i >= 0;) if (fileName.equals(dirList[i])) return true; return false; } public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) { if (!isPackage(qualifiedPackageName)) return null; // most common case String fileName = new String(typeName); // boolean binaryExists = ((this.mode & BINARY) != 0) && doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName); boolean sourceExists = ((this.mode & SOURCE) != 0) && doesFileExist(fileName + SUFFIX_STRING_php, qualifiedPackageName); if (sourceExists) { String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_php; // if (!binaryExists) return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding)); // String fullBinaryPath = this.path + qualifiedBinaryFileName; // long binaryModified = new File(fullBinaryPath).lastModified(); // long sourceModified = new File(fullSourcePath).lastModified(); // if (sourceModified > binaryModified) // return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding)); } // if (binaryExists) { // try { // ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName); // if (reader != null) return new NameEnvironmentAnswer(reader); // } catch (Exception e) { // // treat as if file is missing // } // } return null; } public boolean isPackage(String qualifiedPackageName) { return directoryList(qualifiedPackageName) != null; } public void reset() { this.directoryCache = new Hashtable(11); } public String toString() { return "ClasspathDirectory " + this.path; //$NON-NLS-1$ } }