KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > frontend > SourceLoader


1 package polyglot.frontend;
2
3 import java.io.*;
4 import java.util.*;
5 import polyglot.main.Report;
6 import polyglot.util.InternalCompilerError;
7
8 /** A <code>SourceLoader</code> is responsible for loading source files. */
9 public class SourceLoader
10 {
11     protected ExtensionInfo sourceExt;
12     protected Collection sourcePath;
13
14     /** 0 if unknown, 1 if case insensitive, -1 if not. */
15     protected int caseInsensitive;
16
17     /** Set of sources already loaded. An attempt to load a source
18       * already loaded will cause an IOException. */

19     protected Set loadedSources;
20
21     /**
22      * This is a map from Files (of directories) to Set[String]s, which
23      * records the first level of contents of the directory. This cache
24      * is used to avoid a number of File.exists() calls.
25      */

26     protected Map directoryContentsCache;
27
28     public SourceLoader(ExtensionInfo sourceExt, Collection sourcePath) {
29     this.sourcePath = sourcePath;
30     this.sourceExt = sourceExt;
31         this.directoryContentsCache = new HashMap();
32         this.caseInsensitive = 0;
33         this.loadedSources = new HashSet();
34     }
35
36     /** Load a source from a specific file. */
37     public FileSource fileSource(String JavaDoc fileName) throws IOException {
38         // If we haven't done so already,
39
// determine if the file system is case insensitive
40
setCaseInsensitive(fileName);
41
42     File sourceFile = new File(fileName);
43
44     if (! sourceFile.exists()) {
45         throw new FileNotFoundException(fileName);
46     }
47
48         if (loadedSources.contains(fileKey(sourceFile))) {
49         throw new FileNotFoundException(fileName);
50         }
51
52         loadedSources.add(fileKey(sourceFile));
53
54         String JavaDoc[] exts = sourceExt.fileExtensions();
55         boolean ok = false;
56
57         for (int i = 0; i < exts.length; i++) {
58             String JavaDoc ext = exts[i];
59
60             if (fileName.endsWith("." + ext)) {
61                 ok = true;
62                 break;
63             }
64         }
65
66         if (! ok) {
67             String JavaDoc extString = "";
68
69             for (int i = 0; i < exts.length; i++) {
70                 if (exts.length == 2 && i == exts.length-1) {
71                     extString += " or ";
72                 }
73                 else if (exts.length != 1 && i == exts.length-1) {
74                     extString += ", or ";
75                 }
76                 else if (i != 0) {
77                     extString += ", ";
78                 }
79                 extString = extString + "\"." + exts[i] + "\"";
80             }
81
82             if (exts.length == 1) {
83                 throw new IOException("Source \"" + fileName +
84                                       "\" does not have the extension "
85                                       + extString + ".");
86             }
87             else {
88                 throw new IOException("Source \"" + fileName +
89                                       "\" does not have any of the extensions "
90                                       + extString + ".");
91             }
92         }
93
94     if (Report.should_report(Report.frontend, 2))
95         Report.report(2, "Loading class from " + sourceFile);
96
97     return new FileSource(sourceFile);
98     }
99
100     /**
101      * The current user directory. We make it static so we don't need to
102      * keep on making copies of it.
103      */

104     static File current_dir = null;
105
106     /**
107      * The current user directory.
108      */

109     protected static File current_dir() {
110         if (current_dir == null) {
111             current_dir = new File(System.getProperty("user.dir"));
112         }
113         return current_dir;
114     }
115
116     /** Check if a directory for a package exists. */
117     public boolean packageExists(String JavaDoc name) {
118         String JavaDoc fileName = name.replace('.', File.separatorChar);
119
120     /* Search the source path. */
121         for (Iterator i = sourcePath.iterator(); i.hasNext(); ) {
122             File directory = (File) i.next();
123
124             File f = new File(directory, fileName);
125
126             if (f.exists() && f.isDirectory()) {
127                 return true;
128             }
129         }
130
131         return false;
132     }
133     
134     /** Load the source file for the given class name using the source path. */
135     public FileSource classSource(String JavaDoc className) {
136     /* Search the source path. */
137         String JavaDoc[] exts = sourceExt.fileExtensions();
138
139         for (int k = 0; k < exts.length; k++) {
140             String JavaDoc fileName = className.replace('.', File.separatorChar) +
141                                       "." + exts[k];
142
143             for (Iterator i = sourcePath.iterator(); i.hasNext(); ) {
144                 File directory = (File) i.next();
145                 Set dirContents = (Set)directoryContentsCache.get(directory);
146                 if (dirContents == null) {
147                     dirContents = new HashSet();
148                     directoryContentsCache.put(directory, dirContents);
149                     if (directory.exists()) {
150                         String JavaDoc[] contents = directory.list();
151                         for (int j = 0; j < contents.length; j++) {
152                             dirContents.add(contents[j]);
153                         }
154                     }
155                 }
156
157                 // check if the source file exists in the directory
158
int index = fileName.indexOf(File.separatorChar);
159                 if (index < 0) index = fileName.length();
160                 String JavaDoc firstPart = fileName.substring(0, index);
161
162                 if (dirContents.contains(firstPart)) {
163                     // the directory contains at least the first part of the
164
// file path. We will check if this file exists.
165
File sourceFile;
166                     
167                     if (directory != null && directory.equals(current_dir())) {
168                         sourceFile = new File(fileName);
169                     }
170                     else {
171                         sourceFile = new File(directory, fileName);
172                     }
173                     
174                     // Skip it if already loaded
175
if (loadedSources.contains(fileKey(sourceFile))) {
176                         continue;
177                     }
178
179                     try {
180                         if (Report.should_report(Report.frontend, 2))
181                             Report.report(2, "Loading " + className + " from " + sourceFile);
182                         FileSource s = new FileSource(sourceFile);
183                         loadedSources.add(fileKey(sourceFile));
184                         return s;
185                     }
186                     catch (IOException e) {
187                     }
188                 }
189             }
190         }
191
192         return null;
193     }
194
195     public Object JavaDoc fileKey(File file) {
196         setCaseInsensitive(file.getAbsolutePath());
197         if (caseInsensitive()) {
198             return file.getAbsolutePath().toLowerCase();
199         }
200         return file.getAbsolutePath();
201     }
202
203     /** Is the file system case insensitive. */
204     public boolean caseInsensitive() {
205         if (caseInsensitive == 0) {
206             throw new InternalCompilerError("unknown case sensitivity");
207         }
208         return caseInsensitive == 1;
209     }
210
211     protected void setCaseInsensitive(String JavaDoc fileName) {
212         if (caseInsensitive != 0) {
213             return;
214         }
215
216         // File.equals doesn't work correctly on the Mac.
217
// So, get the list of files in the same directory
218
// as sourceFile. Check if the sourceFile with two
219
// different cases exists but only appears in the list once.
220
File f1 = new File(fileName.toUpperCase());
221         File f2 = new File(fileName.toLowerCase());
222
223         if (f1.equals(f2)) {
224             caseInsensitive = 1;
225         }
226         else if (f1.exists() && f2.exists()) {
227             boolean f1Exists = false;
228             boolean f2Exists = false;
229
230             File dir;
231
232             if (f1.getParent() != null) {
233                 dir = new File(f1.getParent());
234             }
235             else {
236                 dir = current_dir();
237             }
238
239             File[] ls = dir.listFiles();
240             for (int i = 0; i < ls.length; i++) {
241                 if (f1.equals(ls[i])) {
242                     f1Exists = true;
243                 }
244                 if (f2.equals(ls[i])) {
245                     f2Exists = true;
246                 }
247             }
248
249             if (! f1Exists || ! f2Exists) {
250                 caseInsensitive = 1;
251             }
252             else {
253                 // There are two files.
254
caseInsensitive = -1;
255             }
256         }
257         else {
258             caseInsensitive = -1;
259         }
260     }
261
262     protected String JavaDoc canonicalize(String JavaDoc fileName) {
263         return fileName;
264     }
265 }
266
Popular Tags