ec61df96765b1f162615e1836ea3bf9c6d39d05f
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / batch / ClasspathDirectory.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.batch;
12
13 import java.io.File;
14 import java.util.Hashtable;
15
16 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
17 import net.sourceforge.phpdt.internal.compiler.util.SuffixConstants;
18
19 public class ClasspathDirectory implements FileSystem.Classpath,
20                 SuffixConstants {
21
22         String path;
23
24         Hashtable directoryCache;
25
26         String[] missingPackageHolder = new String[1];
27
28         String encoding;
29
30         public int mode; // ability to only consider one kind of files (source
31                                                 // vs. binaries), by default use both
32
33         public static final int SOURCE = 1;
34
35         public static final int BINARY = 2;
36
37         ClasspathDirectory(File directory, String encoding, int mode) {
38                 this.mode = 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;
44         }
45
46         ClasspathDirectory(File directory, String encoding) {
47                 this(directory, encoding, SOURCE | BINARY); // by default consider both
48                                                                                                         // sources and binaries
49         }
50
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
56                                                         // jar
57                 if (dirList != null)
58                         return dirList;
59
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);
67                         while (--index > last
68                                         && !Character.isUpperCase(qualifiedPackageName
69                                                         .charAt(index))) {/* empty */
70                         }
71                         if (index > last) {
72                                 if (last == -1) {
73                                         if (!doesFileExist(qualifiedPackageName, "")) //$NON-NLS-1$ 
74                                                 break notFound;
75                                 } else {
76                                         String packageName = qualifiedPackageName
77                                                         .substring(last + 1);
78                                         String parentPackage = qualifiedPackageName.substring(0,
79                                                         last);
80                                         if (!doesFileExist(packageName, parentPackage))
81                                                 break notFound;
82                                 }
83                         }
84                         if ((dirList = dir.list()) == null)
85                                 dirList = new String[0];
86                         this.directoryCache.put(qualifiedPackageName, dirList);
87                         return dirList;
88                 }
89                 this.directoryCache
90                                 .put(qualifiedPackageName, this.missingPackageHolder);
91                 return null;
92         }
93
94         boolean doesFileExist(String fileName, String qualifiedPackageName) {
95                 String[] dirList = directoryList(qualifiedPackageName);
96                 if (dirList == null)
97                         return false; // most common case
98
99                 for (int i = dirList.length; --i >= 0;)
100                         if (fileName.equals(dirList[i]))
101                                 return true;
102                 return false;
103         }
104
105         public NameEnvironmentAnswer findClass(char[] typeName,
106                         String qualifiedPackageName, String qualifiedBinaryFileName) {
107                 if (!isPackage(qualifiedPackageName))
108                         return null; // most common case
109
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);
116                 if (sourceExists) {
117                         String fullSourcePath = this.path
118                                         + qualifiedBinaryFileName.substring(0,
119                                                         qualifiedBinaryFileName.length() - 6)
120                                         + SUFFIX_STRING_php;
121                         // if (!binaryExists)
122                         return new NameEnvironmentAnswer(new CompilationUnit(null,
123                                         fullSourcePath, this.encoding));
124
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));
131                 }
132                 // if (binaryExists) {
133                 // try {
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
139                 // }
140                 // }
141                 return null;
142         }
143
144         public boolean isPackage(String qualifiedPackageName) {
145                 return directoryList(qualifiedPackageName) != null;
146         }
147
148         public void reset() {
149                 this.directoryCache = new Hashtable(11);
150         }
151
152         public String toString() {
153                 return "ClasspathDirectory " + this.path; //$NON-NLS-1$
154         }
155 }