1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.batch;
14 import java.util.Hashtable;
16 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
17 import net.sourceforge.phpdt.internal.compiler.util.SuffixConstants;
19 public class ClasspathDirectory implements FileSystem.Classpath, SuffixConstants {
22 Hashtable directoryCache;
23 String[] missingPackageHolder = new String[1];
25 public int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
27 public static final int SOURCE = 1;
28 public static final int BINARY = 2;
30 ClasspathDirectory(File directory, String encoding, int mode) {
32 this.path = directory.getAbsolutePath();
33 if (!this.path.endsWith(File.separator))
34 this.path += File.separator;
35 this.directoryCache = new Hashtable(11);
36 this.encoding = encoding;
39 ClasspathDirectory(File directory, String encoding) {
40 this(directory, encoding, SOURCE | BINARY); // by default consider both sources and binaries
43 String[] directoryList(String qualifiedPackageName) {
44 String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
45 if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
46 if (dirList != null) return dirList;
48 File dir = new File(this.path + qualifiedPackageName);
49 notFound : if (dir != null && dir.isDirectory()) {
50 // must protect against a case insensitive File call
51 // walk the qualifiedPackageName backwards looking for an uppercase character before the '/'
52 int index = qualifiedPackageName.length();
53 int last = qualifiedPackageName.lastIndexOf(File.separatorChar);
54 while (--index > last && !Character.isUpperCase(qualifiedPackageName.charAt(index))){/*empty*/}
57 if (!doesFileExist(qualifiedPackageName, "")) //$NON-NLS-1$
60 String packageName = qualifiedPackageName.substring(last + 1);
61 String parentPackage = qualifiedPackageName.substring(0, last);
62 if (!doesFileExist(packageName, parentPackage))
66 if ((dirList = dir.list()) == null)
67 dirList = new String[0];
68 this.directoryCache.put(qualifiedPackageName, dirList);
71 this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
74 boolean doesFileExist(String fileName, String qualifiedPackageName) {
75 String[] dirList = directoryList(qualifiedPackageName);
76 if (dirList == null) return false; // most common case
78 for (int i = dirList.length; --i >= 0;)
79 if (fileName.equals(dirList[i]))
83 public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
84 if (!isPackage(qualifiedPackageName)) return null; // most common case
86 String fileName = new String(typeName);
87 // boolean binaryExists = ((this.mode & BINARY) != 0) && doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName);
88 boolean sourceExists = ((this.mode & SOURCE) != 0) && doesFileExist(fileName + SUFFIX_STRING_php, qualifiedPackageName);
90 String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_php;
92 return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding));
94 // String fullBinaryPath = this.path + qualifiedBinaryFileName;
95 // long binaryModified = new File(fullBinaryPath).lastModified();
96 // long sourceModified = new File(fullSourcePath).lastModified();
97 // if (sourceModified > binaryModified)
98 // return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding));
100 // if (binaryExists) {
102 // ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
103 // if (reader != null) return new NameEnvironmentAnswer(reader);
104 // } catch (Exception e) {
105 // // treat as if file is missing
110 public boolean isPackage(String qualifiedPackageName) {
111 return directoryList(qualifiedPackageName) != null;
113 public void reset() {
114 this.directoryCache = new Hashtable(11);
116 public String toString() {
117 return "ClasspathDirectory " + this.path; //$NON-NLS-1$