1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.batch;
14 import java.io.IOException;
15 import java.util.zip.ZipFile;
17 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
18 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
19 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
21 public class FileSystem implements INameEnvironment {
22 Classpath[] classpaths;
23 String[] knownFileNames;
26 NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName);
27 boolean isPackage(String qualifiedPackageName);
29 * This method resets the environment. The resulting state is equivalent to
30 * a new name environment without creating a new object.
35 classPathNames is a collection is Strings representing the full path of each class path
36 initialFileNames is a collection is Strings, the trailing '.java' will be removed if its not already.
39 public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding) {
40 this(classpathNames, initialFileNames, encoding, null);
42 public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding, int[] classpathDirectoryModes) {
43 int classpathSize = classpathNames.length;
44 classpaths = new Classpath[classpathSize];
45 String[] pathNames = new String[classpathSize];
46 int problemsOccured = 0;
47 for (int i = 0; i < classpathSize; i++) {
49 File file = new File(convertPathSeparators(classpathNames[i]));
50 if (file.isDirectory()) {
52 if (classpathDirectoryModes == null){
53 classpaths[i] = new ClasspathDirectory(file, encoding);
55 classpaths[i] = new ClasspathDirectory(file, encoding, classpathDirectoryModes[i]);
57 pathNames[i] = ((ClasspathDirectory) classpaths[i]).path;
59 } else if (classpathNames[i].endsWith(".jar") | (classpathNames[i].endsWith(".zip"))) { //$NON-NLS-2$ //$NON-NLS-1$
60 classpaths[i] = this.getClasspathJar(file); // will throw an IOException if file does not exist
61 pathNames[i] = classpathNames[i].substring(0, classpathNames[i].lastIndexOf('.'));
63 } catch (IOException e) {
66 if (classpaths[i] == null)
69 if (problemsOccured > 0) {
70 Classpath[] newPaths = new Classpath[classpathSize - problemsOccured];
71 String[] newNames = new String[classpathSize - problemsOccured];
72 for (int i = 0, current = 0; i < classpathSize; i++)
73 if (classpaths[i] != null) {
74 newPaths[current] = classpaths[i];
75 newNames[current++] = pathNames[i];
77 classpathSize = newPaths.length;
78 classpaths = newPaths;
82 knownFileNames = new String[initialFileNames.length];
83 for (int i = initialFileNames.length; --i >= 0;) {
84 String fileName = initialFileNames[i];
85 String matchingPathName = null;
86 if (fileName.lastIndexOf(".") != -1) //$NON-NLS-1$
87 fileName = fileName.substring(0, fileName.lastIndexOf('.')); // remove trailing ".java"
89 fileName = convertPathSeparators(fileName);
90 for (int j = 0; j < classpathSize; j++)
91 if (fileName.startsWith(pathNames[j]))
92 matchingPathName = pathNames[j];
93 if (matchingPathName == null)
94 knownFileNames[i] = fileName; // leave as is...
96 knownFileNames[i] = fileName.substring(matchingPathName.length());
99 public void cleanup() {
100 for (int i = 0, max = classpaths.length; i < max; i++)
101 classpaths[i].reset();
103 private String convertPathSeparators(String path) {
104 return File.separatorChar == '/'
105 ? path.replace('\\', '/')
106 : path.replace('/', '\\');
108 private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName){
109 for (int i = 0, length = knownFileNames.length; i < length; i++)
110 if (qualifiedTypeName.equals(knownFileNames[i]))
111 return null; // looking for a file which we know was provided at the beginning of the compilation
113 String qualifiedBinaryFileName = qualifiedTypeName + ".class"; //$NON-NLS-1$
114 String qualifiedPackageName =
115 qualifiedTypeName.length() == typeName.length
117 : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1);
118 String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
119 if (qualifiedPackageName == qp2) {
120 for (int i = 0, length = classpaths.length; i < length; i++) {
121 NameEnvironmentAnswer answer = classpaths[i].findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName);
122 if (answer != null) return answer;
125 String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar);
126 for (int i = 0, length = classpaths.length; i < length; i++) {
127 Classpath p = classpaths[i];
128 NameEnvironmentAnswer answer = (p instanceof ClasspathJar)
129 ? p.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)
130 : p.findClass(typeName, qp2, qb2);
131 if (answer != null) return answer;
136 public NameEnvironmentAnswer findType(char[][] compoundName) {
137 if (compoundName != null)
139 new String(CharOperation.concatWith(compoundName, '/')),
140 compoundName[compoundName.length - 1]);
143 public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
144 if (typeName != null)
146 new String(CharOperation.concatWith(packageName, typeName, '/')),
150 public ClasspathJar getClasspathJar(File file) throws IOException {
151 return new ClasspathJar(new ZipFile(file), true);
153 public boolean isPackage(char[][] compoundName, char[] packageName) {
154 String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
155 String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
156 if (qualifiedPackageName == qp2) {
157 for (int i = 0, length = classpaths.length; i < length; i++)
158 if (classpaths[i].isPackage(qualifiedPackageName))
161 for (int i = 0, length = classpaths.length; i < length; i++) {
162 Classpath p = classpaths[i];
163 if ((p instanceof ClasspathJar) ? p.isPackage(qualifiedPackageName) : p.isPackage(qp2))