1 11 package org.eclipse.jdt.internal.compiler.batch; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import java.util.ArrayList ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.Set ; 19 20 import org.eclipse.jdt.core.compiler.CharOperation; 21 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; 22 import org.eclipse.jdt.internal.compiler.env.INameEnvironment; 23 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; 24 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 25 import org.eclipse.jdt.internal.compiler.util.Util; 26 27 public class FileSystem implements INameEnvironment, SuffixConstants { 28 public interface Classpath { 29 char[][][] findTypeNames(String qualifiedPackageName); 30 NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName); 31 NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly); 32 boolean isPackage(String qualifiedPackageName); 33 37 void reset(); 38 44 char[] normalizedPath(); 45 51 String getPath(); 52 55 void initialize() throws IOException ; 56 } 57 58 62 public static class ClasspathNormalizer { 63 71 public static ArrayList normalize(ArrayList classpaths) { 72 ArrayList normalizedClasspath = new ArrayList (); 73 HashSet cache = new HashSet (); 74 for (Iterator iterator = classpaths.iterator(); iterator.hasNext(); ) { 75 FileSystem.Classpath classpath = (FileSystem.Classpath) iterator.next(); 76 String path = classpath.getPath(); 77 if (!cache.contains(path)) { 78 normalizedClasspath.add(classpath); 79 cache.add(path); 80 } 81 } 82 return normalizedClasspath; 83 } 84 } 85 86 Classpath[] classpaths; 87 Set knownFileNames; 88 89 93 public FileSystem(String [] classpathNames, String [] initialFileNames, String encoding) { 94 final int classpathSize = classpathNames.length; 95 this.classpaths = new Classpath[classpathSize]; 96 int counter = 0; 97 for (int i = 0; i < classpathSize; i++) { 98 Classpath classpath = getClasspath(classpathNames[i], encoding, null); 99 try { 100 classpath.initialize(); 101 this.classpaths[counter++] = classpath; 102 } catch (IOException e) { 103 } 105 } 106 if (counter != classpathSize) { 107 System.arraycopy(this.classpaths, 0, (this.classpaths = new Classpath[counter]), 0, counter); 108 } 109 initializeKnownFileNames(initialFileNames); 110 } 111 FileSystem(Classpath[] paths, String [] initialFileNames) { 112 final int length = paths.length; 113 int counter = 0; 114 this.classpaths = new FileSystem.Classpath[length]; 115 for (int i = 0; i < length; i++) { 116 final Classpath classpath = paths[i]; 117 try { 118 classpath.initialize(); 119 this.classpaths[counter++] = classpath; 120 } catch(IOException exception) { 121 } 123 } 124 if (counter != length) { 125 System.arraycopy(this.classpaths, 0, (this.classpaths = new FileSystem.Classpath[counter]), 0, counter); 127 } 128 initializeKnownFileNames(initialFileNames); 129 } 130 public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) { 131 return getClasspath(classpathName, encoding, false, accessRuleSet, null); 132 } 133 public static Classpath getClasspath(String classpathName, String encoding, 134 boolean isSourceOnly, AccessRuleSet accessRuleSet, 135 String destinationPath) { 136 Classpath result = null; 137 File file = new File (convertPathSeparators(classpathName)); 138 if (file.isDirectory()) { 139 if (file.exists()) { 140 result = new ClasspathDirectory(file, encoding, 141 isSourceOnly ? ClasspathLocation.SOURCE : 142 ClasspathLocation.SOURCE | ClasspathLocation.BINARY, 143 accessRuleSet, 144 destinationPath == null || destinationPath == Main.NONE ? 145 destinationPath : convertPathSeparators(destinationPath)); 147 } 148 } else { 149 String lowercaseClasspathName = classpathName.toLowerCase(); 150 if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar) 151 || lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) { 152 if (isSourceOnly) { 153 result = new ClasspathSourceJar(file, true, accessRuleSet, 155 encoding, 156 destinationPath == null || destinationPath == Main.NONE ? 157 destinationPath : convertPathSeparators(destinationPath)); 159 } else if (destinationPath == null) { 160 result = new ClasspathJar(file, true, accessRuleSet, null); 162 } 163 } 164 } 165 return result; 166 } 167 private void initializeKnownFileNames(String [] initialFileNames) { 168 if (initialFileNames == null) { 169 this.knownFileNames = new HashSet (0); 170 return; 171 } 172 this.knownFileNames = new HashSet (initialFileNames.length * 2); 173 for (int i = initialFileNames.length; --i >= 0;) { 174 char[] fileName = initialFileNames[i].toCharArray(); 175 char[] matchingPathName = null; 176 final int lastIndexOf = CharOperation.lastIndexOf('.', fileName); 177 if (lastIndexOf != -1) { 178 fileName = CharOperation.subarray(fileName, 0, lastIndexOf); 179 } 180 CharOperation.replace(fileName, '\\', '/'); 181 for (int j = 0; j < classpaths.length; j++){ 182 char[] matchCandidate = this.classpaths[j].normalizedPath(); 183 if (this.classpaths[j] instanceof ClasspathDirectory && 184 CharOperation.prefixEquals(matchCandidate, fileName) && 185 (matchingPathName == null || 186 matchCandidate.length < matchingPathName.length)) 187 matchingPathName = matchCandidate; 188 } 189 if (matchingPathName == null) { 190 this.knownFileNames.add(new String (fileName)); } else { 192 this.knownFileNames.add(new String (CharOperation.subarray(fileName, matchingPathName.length, fileName.length))); 193 } 194 matchingPathName = null; 195 } 196 } 197 public void cleanup() { 198 for (int i = 0, max = this.classpaths.length; i < max; i++) 199 this.classpaths[i].reset(); 200 } 201 private static String convertPathSeparators(String path) { 202 return File.separatorChar == '/' 203 ? path.replace('\\', '/') 204 : path.replace('/', '\\'); 205 } 206 private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly){ 207 if (this.knownFileNames.contains(qualifiedTypeName)) return null; 209 String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class; 210 String qualifiedPackageName = 211 qualifiedTypeName.length() == typeName.length 212 ? Util.EMPTY_STRING 213 : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1); 214 String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar); 215 NameEnvironmentAnswer suggestedAnswer = null; 216 if (qualifiedPackageName == qp2) { 217 for (int i = 0, length = this.classpaths.length; i < length; i++) { 218 NameEnvironmentAnswer answer = this.classpaths[i].findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly); 219 if (answer != null) { 220 if (!answer.ignoreIfBetter()) { 221 if (answer.isBetter(suggestedAnswer)) 222 return answer; 223 } else if (answer.isBetter(suggestedAnswer)) 224 suggestedAnswer = answer; 226 } 227 } 228 } else { 229 String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar); 230 for (int i = 0, length = this.classpaths.length; i < length; i++) { 231 Classpath p = this.classpaths[i]; 232 NameEnvironmentAnswer answer = (p instanceof ClasspathJar) 233 ? p.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly) 234 : p.findClass(typeName, qp2, qb2, asBinaryOnly); 235 if (answer != null) { 236 if (!answer.ignoreIfBetter()) { 237 if (answer.isBetter(suggestedAnswer)) 238 return answer; 239 } else if (answer.isBetter(suggestedAnswer)) 240 suggestedAnswer = answer; 242 } 243 } 244 } 245 if (suggestedAnswer != null) 246 return suggestedAnswer; 248 return null; 249 } 250 public NameEnvironmentAnswer findType(char[][] compoundName) { 251 if (compoundName != null) 252 return findClass( 253 new String (CharOperation.concatWith(compoundName, '/')), 254 compoundName[compoundName.length - 1], 255 false); 256 return null; 257 } 258 public char[][][] findTypeNames(char[][] packageName) { 259 char[][][] result = null; 260 if (packageName != null) { 261 String qualifiedPackageName = new String (CharOperation.concatWith(packageName, '/')); 262 String qualifiedPackageName2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar); 263 if (qualifiedPackageName == qualifiedPackageName2) { 264 for (int i = 0, length = this.classpaths.length; i < length; i++) { 265 char[][][] answers = this.classpaths[i].findTypeNames(qualifiedPackageName); 266 if (answers != null) { 267 if (result == null) { 269 result = answers; 270 } else { 271 int resultLength = result.length; 272 int answersLength = answers.length; 273 System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength); 274 System.arraycopy(answers, 0, result, resultLength, answersLength); 275 } 276 } 277 } 278 } else { 279 for (int i = 0, length = this.classpaths.length; i < length; i++) { 280 Classpath p = this.classpaths[i]; 281 char[][][] answers = (p instanceof ClasspathJar) 282 ? p.findTypeNames(qualifiedPackageName) 283 : p.findTypeNames(qualifiedPackageName2); 284 if (answers != null) { 285 if (result == null) { 287 result = answers; 288 } else { 289 int resultLength = result.length; 290 int answersLength = answers.length; 291 System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength); 292 System.arraycopy(answers, 0, result, resultLength, answersLength); 293 } 294 } 295 } 296 } 297 } 298 return result; 299 } 300 public NameEnvironmentAnswer findType(char[][] compoundName, boolean asBinaryOnly) { 301 if (compoundName != null) 302 return findClass( 303 new String (CharOperation.concatWith(compoundName, '/')), 304 compoundName[compoundName.length - 1], 305 asBinaryOnly); 306 return null; 307 } 308 public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { 309 if (typeName != null) 310 return findClass( 311 new String (CharOperation.concatWith(packageName, typeName, '/')), 312 typeName, 313 false); 314 return null; 315 } 316 public boolean isPackage(char[][] compoundName, char[] packageName) { 317 String qualifiedPackageName = new String (CharOperation.concatWith(compoundName, packageName, '/')); 318 String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar); 319 if (qualifiedPackageName == qp2) { 320 for (int i = 0, length = this.classpaths.length; i < length; i++) 321 if (this.classpaths[i].isPackage(qualifiedPackageName)) 322 return true; 323 } else { 324 for (int i = 0, length = this.classpaths.length; i < length; i++) { 325 Classpath p = this.classpaths[i]; 326 if ((p instanceof ClasspathJar) ? p.isPackage(qualifiedPackageName) : p.isPackage(qp2)) 327 return true; 328 } 329 } 330 return false; 331 } 332 } 333 | Popular Tags |