Merged xdebug from 1.3.x
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / batch / FileSystem.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
15 import net.sourceforge.phpdt.core.compiler.CharOperation;
16 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
17 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
18 import net.sourceforge.phpdt.internal.compiler.util.SuffixConstants;
19
20 public class FileSystem implements INameEnvironment, SuffixConstants {
21         Classpath[] classpaths;
22
23         String[] knownFileNames;
24
25         interface Classpath {
26                 NameEnvironmentAnswer findClass(char[] typeName,
27                                 String qualifiedPackageName, String qualifiedBinaryFileName);
28
29                 boolean isPackage(String qualifiedPackageName);
30
31                 /**
32                  * This method resets the environment. The resulting state is equivalent
33                  * to a new name environment without creating a new object.
34                  */
35                 void reset();
36         }
37
38         /*
39          * classPathNames is a collection is Strings representing the full path of
40          * each class path initialFileNames is a collection is Strings, the trailing
41          * '.java' will be removed if its not already.
42          */
43
44         public FileSystem(String[] classpathNames, String[] initialFileNames,
45                         String encoding) {
46                 this(classpathNames, initialFileNames, encoding, null);
47         }
48
49         public FileSystem(String[] classpathNames, String[] initialFileNames,
50                         String encoding, int[] classpathDirectoryModes) {
51                 int classpathSize = classpathNames.length;
52                 this.classpaths = new Classpath[classpathSize];
53                 String[] pathNames = new String[classpathSize];
54                 int problemsOccured = 0;
55                 for (int i = 0; i < classpathSize; i++) {
56                         // try {
57                         File file = new File(convertPathSeparators(classpathNames[i]));
58                         if (file.isDirectory()) {
59                                 if (file.exists()) {
60                                         if (classpathDirectoryModes == null) {
61                                                 this.classpaths[i] = new ClasspathDirectory(file,
62                                                                 encoding);
63                                         } else {
64                                                 this.classpaths[i] = new ClasspathDirectory(file,
65                                                                 encoding, classpathDirectoryModes[i]);
66                                         }
67                                         pathNames[i] = ((ClasspathDirectory) this.classpaths[i]).path;
68                                 }
69                         } else {
70                                 String lowercaseClasspathName = classpathNames[i].toLowerCase();
71                                 // if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar)
72                                 // || lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) {
73                                 // this.classpaths[i] = this.getClasspathJar(file); // will
74                                 // throw an IOException if file does not exist
75                                 // pathNames[i] = classpathNames[i].substring(0,
76                                 // classpathNames[i].lastIndexOf('.'));
77                                 // }
78                         }
79                         // } catch (IOException e) {
80                         // this.classpaths[i] = null;
81                         // }
82                         if (this.classpaths[i] == null)
83                                 problemsOccured++;
84                 }
85                 if (problemsOccured > 0) {
86                         Classpath[] newPaths = new Classpath[classpathSize
87                                         - problemsOccured];
88                         String[] newNames = new String[classpathSize - problemsOccured];
89                         for (int i = 0, current = 0; i < classpathSize; i++)
90                                 if (this.classpaths[i] != null) {
91                                         newPaths[current] = this.classpaths[i];
92                                         newNames[current++] = pathNames[i];
93                                 }
94                         classpathSize = newPaths.length;
95                         this.classpaths = newPaths;
96                         pathNames = newNames;
97                 }
98
99                 this.knownFileNames = new String[initialFileNames.length];
100                 for (int i = initialFileNames.length; --i >= 0;) {
101                         String fileName = initialFileNames[i];
102                         String matchingPathName = null;
103                         if (fileName.lastIndexOf(".") != -1) //$NON-NLS-1$
104                                 fileName = fileName.substring(0, fileName.lastIndexOf('.')); // remove
105                                                                                                                                                                 // trailing
106                                                                                                                                                                 // ".java"
107
108                         fileName = convertPathSeparators(fileName);
109                         for (int j = 0; j < classpathSize; j++)
110                                 if (fileName.startsWith(pathNames[j]))
111                                         matchingPathName = pathNames[j];
112                         if (matchingPathName == null)
113                                 this.knownFileNames[i] = fileName; // leave as is...
114                         else
115                                 this.knownFileNames[i] = fileName.substring(matchingPathName
116                                                 .length());
117                 }
118         }
119
120         public void cleanup() {
121                 for (int i = 0, max = this.classpaths.length; i < max; i++)
122                         this.classpaths[i].reset();
123         }
124
125         private String convertPathSeparators(String path) {
126                 return File.separatorChar == '/' ? path.replace('\\', '/') : path
127                                 .replace('/', '\\');
128         }
129
130         // private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[]
131         // typeName){
132         // for (int i = 0, length = this.knownFileNames.length; i < length; i++)
133         // if (qualifiedTypeName.equals(this.knownFileNames[i]))
134         // return null; // looking for a file which we know was provided at the
135         // beginning of the compilation
136         //
137         // String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
138         // String qualifiedPackageName =
139         // qualifiedTypeName.length() == typeName.length
140         // ? "" //$NON-NLS-1$
141         // : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() -
142         // typeName.length - 1);
143         // String qp2 = File.separatorChar == '/' ? qualifiedPackageName :
144         // qualifiedPackageName.replace('/', File.separatorChar);
145         // if (qualifiedPackageName == qp2) {
146         // for (int i = 0, length = this.classpaths.length; i < length; i++) {
147         // NameEnvironmentAnswer answer = this.classpaths[i].findClass(typeName,
148         // qualifiedPackageName, qualifiedBinaryFileName);
149         // if (answer != null) return answer;
150         // }
151         // } else {
152         // String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar);
153         // for (int i = 0, length = this.classpaths.length; i < length; i++) {
154         // Classpath p = this.classpaths[i];
155         // NameEnvironmentAnswer answer = (p instanceof ClasspathJar)
156         // ? p.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)
157         // : p.findClass(typeName, qp2, qb2);
158         // if (answer != null) return answer;
159         // }
160         // }
161         // return null;
162         // }
163         public NameEnvironmentAnswer findType(char[][] compoundName) {
164                 // if (compoundName != null)
165                 // return findClass(
166                 // new String(CharOperation.concatWith(compoundName, '/')),
167                 // compoundName[compoundName.length - 1]);
168                 return null;
169         }
170
171         public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
172                 // if (typeName != null)
173                 // return findClass(
174                 // new String(CharOperation.concatWith(packageName, typeName, '/')),
175                 // typeName);
176                 return null;
177         }
178
179         // public ClasspathJar getClasspathJar(File file) throws IOException {
180         // return new ClasspathJar(new ZipFile(file), true);
181         // }
182         public boolean isPackage(char[][] compoundName, char[] packageName) {
183                 String qualifiedPackageName = new String(CharOperation.concatWith(
184                                 compoundName, packageName, '/'));
185                 String qp2 = File.separatorChar == '/' ? qualifiedPackageName
186                                 : qualifiedPackageName.replace('/', File.separatorChar);
187                 if (qualifiedPackageName == qp2) {
188                         for (int i = 0, length = this.classpaths.length; i < length; i++)
189                                 if (this.classpaths[i].isPackage(qualifiedPackageName))
190                                         return true;
191                 }
192                 // else {
193                 // for (int i = 0, length = this.classpaths.length; i < length; i++) {
194                 // Classpath p = this.classpaths[i];
195                 // if ((p instanceof ClasspathJar) ? p.isPackage(qualifiedPackageName) :
196                 // p.isPackage(qp2))
197                 // return true;
198                 // }
199                 // }
200                 return false;
201         }
202 }