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,
24 Hashtable directoryCache;
26 String[] missingPackageHolder = new String[1];
30 public int mode; // ability to only consider one kind of files (source
31 // vs. binaries), by default use both
33 public static final int SOURCE = 1;
35 public static final int BINARY = 2;
37 ClasspathDirectory(File directory, String encoding, int mode) {
39 this.path = directory.getAbsolutePath();
40 if (!this.path.endsWith(File.separator))
41 this.path += File.separator;
42 this.directoryCache = new Hashtable(11);
43 this.encoding = encoding;
46 ClasspathDirectory(File directory, String encoding) {
47 this(directory, encoding, SOURCE | BINARY); // by default consider both
48 // sources and binaries
51 String[] directoryList(String qualifiedPackageName) {
52 String[] dirList = (String[]) this.directoryCache
53 .get(qualifiedPackageName);
54 if (dirList == this.missingPackageHolder)
55 return null; // package exists in another classpath directory or
60 File dir = new File(this.path + qualifiedPackageName);
61 notFound: if (dir != null && dir.isDirectory()) {
62 // must protect against a case insensitive File call
63 // walk the qualifiedPackageName backwards looking for an uppercase
64 // character before the '/'
65 int index = qualifiedPackageName.length();
66 int last = qualifiedPackageName.lastIndexOf(File.separatorChar);
68 && !Character.isUpperCase(qualifiedPackageName
69 .charAt(index))) {/* empty */
73 if (!doesFileExist(qualifiedPackageName, "")) //$NON-NLS-1$
76 String packageName = qualifiedPackageName
78 String parentPackage = qualifiedPackageName.substring(0,
80 if (!doesFileExist(packageName, parentPackage))
84 if ((dirList = dir.list()) == null)
85 dirList = new String[0];
86 this.directoryCache.put(qualifiedPackageName, dirList);
90 .put(qualifiedPackageName, this.missingPackageHolder);
94 boolean doesFileExist(String fileName, String qualifiedPackageName) {
95 String[] dirList = directoryList(qualifiedPackageName);
97 return false; // most common case
99 for (int i = dirList.length; --i >= 0;)
100 if (fileName.equals(dirList[i]))
105 public NameEnvironmentAnswer findClass(char[] typeName,
106 String qualifiedPackageName, String qualifiedBinaryFileName) {
107 if (!isPackage(qualifiedPackageName))
108 return null; // most common case
110 String fileName = new String(typeName);
111 // boolean binaryExists = ((this.mode & BINARY) != 0) &&
112 // doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName);
113 boolean sourceExists = ((this.mode & SOURCE) != 0)
114 && doesFileExist(fileName + SUFFIX_STRING_php,
115 qualifiedPackageName);
117 String fullSourcePath = this.path
118 + qualifiedBinaryFileName.substring(0,
119 qualifiedBinaryFileName.length() - 6)
121 // if (!binaryExists)
122 return new NameEnvironmentAnswer(new CompilationUnit(null,
123 fullSourcePath, this.encoding));
125 // String fullBinaryPath = this.path + qualifiedBinaryFileName;
126 // long binaryModified = new File(fullBinaryPath).lastModified();
127 // long sourceModified = new File(fullSourcePath).lastModified();
128 // if (sourceModified > binaryModified)
129 // return new NameEnvironmentAnswer(new CompilationUnit(null,
130 // fullSourcePath, this.encoding));
132 // if (binaryExists) {
134 // ClassFileReader reader = ClassFileReader.read(this.path +
135 // qualifiedBinaryFileName);
136 // if (reader != null) return new NameEnvironmentAnswer(reader);
137 // } catch (Exception e) {
138 // // treat as if file is missing
144 public boolean isPackage(String qualifiedPackageName) {
145 return directoryList(qualifiedPackageName) != null;
148 public void reset() {
149 this.directoryCache = new Hashtable(11);
152 public String toString() {
153 return "ClasspathDirectory " + this.path; //$NON-NLS-1$