<s> package org . eclipse . jdt . internal . compiler . batch ; import java . io . File ; import java . io . IOException ; import java . util . ArrayList ; import java . util . HashSet ; import java . util . Iterator ; import java . util . List ; import java . util . Set ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . env . AccessRuleSet ; import org . eclipse . jdt . internal . compiler . env . INameEnvironment ; import org . eclipse . jdt . internal . compiler . env . NameEnvironmentAnswer ; import org . eclipse . jdt . internal . compiler . util . SuffixConstants ; import org . eclipse . jdt . internal . compiler . util . Util ; public class FileSystem implements INameEnvironment , SuffixConstants { public interface Classpath { char [ ] [ ] [ ] findTypeNames ( String qualifiedPackageName ) ; NameEnvironmentAnswer findClass ( char [ ] typeName , String qualifiedPackageName , String qualifiedBinaryFileName ) ; NameEnvironmentAnswer findClass ( char [ ] typeName , String qualifiedPackageName , String qualifiedBinaryFileName , boolean asBinaryOnly ) ; boolean isPackage ( String qualifiedPackageName ) ; List fetchLinkedJars ( ClasspathSectionProblemReporter problemReporter ) ; void reset ( ) ; char [ ] normalizedPath ( ) ; String getPath ( ) ; void initialize ( ) throws IOException ; } public interface ClasspathSectionProblemReporter { void invalidClasspathSection ( String jarFilePath ) ; void multipleClasspathSections ( String jarFilePath ) ; } public static class ClasspathNormalizer { public static ArrayList normalize ( ArrayList classpaths ) { ArrayList normalizedClasspath = new ArrayList ( ) ; HashSet cache = new HashSet ( ) ; for ( Iterator iterator = classpaths . iterator ( ) ; iterator . hasNext ( ) ; ) { FileSystem . Classpath classpath = ( FileSystem . Classpath ) iterator . next ( ) ; if ( ! cache . contains ( classpath ) ) { normalizedClasspath . add ( classpath ) ; cache . add ( classpath ) ; } } return normalizedClasspath ; } } Classpath [ ] classpaths ; Set knownFileNames ; public FileSystem ( String [ ] classpathNames , String [ ] initialFileNames , String encoding ) { final int classpathSize = classpathNames . length ; this . classpaths = new Classpath [ classpathSize ] ; int counter = 0 ; for ( int i = 0 ; i < classpathSize ; i ++ ) { Classpath classpath = getClasspath ( classpathNames [ i ] , encoding , null ) ; try { classpath . initialize ( ) ; this . classpaths [ counter ++ ] = classpath ; } catch ( IOException e ) { } } if ( counter != classpathSize ) { System . arraycopy ( this . classpaths , 0 , ( this . classpaths = new Classpath [ counter ] ) , 0 , counter ) ; } initializeKnownFileNames ( initialFileNames ) ; } protected FileSystem ( Classpath [ ] paths , String [ ] initialFileNames ) { final int length = paths . length ; int counter = 0 ; this . classpaths = new FileSystem . Classpath [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { final Classpath classpath = paths [ i ] ; try { classpath . initialize ( ) ; this . classpaths [ counter ++ ] = classpath ; } catch ( IOException exception ) { } } if ( counter != length ) { System . arraycopy ( this . classpaths , 0 , ( this . classpaths = new FileSystem . Classpath [ counter ] ) , 0 , counter ) ; } initializeKnownFileNames ( initialFileNames ) ; } public static Classpath getClasspath ( String classpathName , String encoding , AccessRuleSet accessRuleSet ) { return getClasspath ( classpathName , encoding , false , accessRuleSet , null ) ; } public static Classpath getClasspath ( String classpathName , String encoding , boolean isSourceOnly , AccessRuleSet accessRuleSet , String destinationPath ) { Classpath result = null ; File file = new File ( convertPathSeparators ( classpathName ) ) ; if ( file . isDirectory ( ) ) { if ( file . exists ( ) ) { result = new ClasspathDirectory ( file , encoding , isSourceOnly ? ClasspathLocation . SOURCE : ClasspathLocation . SOURCE | ClasspathLocation . BINARY , accessRuleSet , destinationPath == null || destinationPath == Main . NONE ? destinationPath : convertPathSeparators ( destinationPath ) ) ; } } else { if ( Util . isPotentialZipArchive ( classpathName ) ) { if ( isSourceOnly ) { result = new ClasspathSourceJar ( file , true , accessRuleSet , encoding , destinationPath == null || destinationPath == Main . NONE ? destinationPath : convertPathSeparators ( destinationPath ) ) ; } else if ( destinationPath == null ) { result = new ClasspathJar ( file , true , accessRuleSet , null ) ; } } } return result ; } private void initializeKnownFileNames ( String [ ] initialFileNames ) { if ( initialFileNames == null ) { this . knownFileNames = new HashSet ( 0 ) ; return ; } this . knownFileNames = new HashSet ( initialFileNames . length * 2 ) ; for ( int i = initialFileNames . length ; -- i >= 0 ; ) { File compilationUnitFile = new File ( initialFileNames [ i ] ) ; char [ ] fileName = null ; try { fileName = compilationUnitFile . getCanonicalPath ( ) . toCharArray ( ) ; } catch ( IOException e ) { continue ; } char [ ] matchingPathName = null ; final int lastIndexOf = CharOperation . lastIndexOf ( '.' , fileName ) ; if ( lastIndexOf != - 1 ) { fileName = CharOperation . subarray ( fileName , 0 , lastIndexOf ) ; } CharOperation . replace ( fileName , '\\' , '/' ) ; boolean globalPathMatches = false ; for ( int j = 0 , max = this . classpaths . length ; j < max ; j ++ ) { char [ ] matchCandidate = this . classpaths [ j ] . normalizedPath ( ) ; boolean currentPathMatch = false ; if ( this . classpaths [ j ] instanceof ClasspathDirectory && CharOperation . prefixEquals ( matchCandidate , fileName ) ) { currentPathMatch = true ; if ( matchingPathName == null ) { matchingPathName = matchCandidate ; } else { if ( currentPathMatch ) { if ( matchCandidate . length > matchingPathName . length ) { matchingPathName = matchCandidate ; } } else { if ( ! globalPathMatches && matchCandidate . length < matchingPathName . length ) { matchingPathName = matchCandidate ; } } } if ( currentPathMatch ) { globalPathMatches = true ; } } } if ( matchingPathName == null ) { this . knownFileNames . add ( new String ( fileName ) ) ; } else { this . knownFileNames . add ( new String ( CharOperation . subarray ( fileName , matchingPathName . length , fileName . length ) ) ) ; } matchingPathName = null ; } } public void cleanup ( ) { for ( int i = 0 , max = this . classpaths . length ; i < max ; i ++ ) this . classpaths [ i ] . reset ( ) ; } private static String convertPathSeparators ( String path ) { return File . separatorChar == '/' ? path . replace ( '\\' , '/' ) : path . replace ( '/' , '\\' ) ; } private NameEnvironmentAnswer findClass ( String qualifiedTypeName , char [ ] typeName , boolean asBinaryOnly ) { if ( this . knownFileNames . contains ( qualifiedTypeName ) ) return null ; String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class ; String qualifiedPackageName = qualifiedTypeName . length ( ) == typeName . length ? Util . EMPTY_STRING : qualifiedBinaryFileName . substring ( 0 , qualifiedTypeName . length ( ) - typeName . length - 1 ) ; String qp2 = File . separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName . replace ( '/' , File . separatorChar ) ; NameEnvironmentAnswer suggestedAnswer = null ; if ( qualifiedPackageName == qp2 ) { for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) { NameEnvironmentAnswer answer = this . classpaths [ i ] . findClass ( typeName , qualifiedPackageName , qualifiedBinaryFileName , asBinaryOnly ) ; if ( answer != null ) { if ( ! answer . ignoreIfBetter ( ) ) { if ( answer . isBetter ( suggestedAnswer ) ) return answer ; } else if ( answer . isBetter ( suggestedAnswer ) ) suggestedAnswer = answer ; } } } else { String qb2 = qualifiedBinaryFileName . replace ( '/' , File . separatorChar ) ; for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) { Classpath p = this . classpaths [ i ] ; NameEnvironmentAnswer answer = ( p instanceof ClasspathJar ) ? p . findClass ( typeName , qualifiedPackageName , qualifiedBinaryFileName , asBinaryOnly ) : p . findClass ( typeName , qp2 , qb2 , asBinaryOnly ) ; if ( answer != null ) { if ( ! answer . ignoreIfBetter ( ) ) { if ( answer . isBetter ( suggestedAnswer ) ) return answer ; } else if ( answer . isBetter ( suggestedAnswer ) ) suggestedAnswer = answer ; } } } if ( suggestedAnswer != null ) return suggestedAnswer ; return null ; } public NameEnvironmentAnswer findType ( char [ ] [ ] compoundName ) { if ( compoundName != null ) return findClass ( new String ( CharOperation . concatWith ( compoundName , '/' ) ) , compoundName [ compoundName . length - 1 ] , false ) ; return null ; } public char [ ] [ ] [ ] findTypeNames ( char [ ] [ ] packageName ) { char [ ] [ ] [ ] result = null ; if ( packageName != null ) { String qualifiedPackageName = new String ( CharOperation . concatWith ( packageName , '/' ) ) ; String qualifiedPackageName2 = File . separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName . replace ( '/' , File . separatorChar ) ; if ( qualifiedPackageName == qualifiedPackageName2 ) { for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) { char [ ] [ ] [ ] answers = this . classpaths [ i ] . findTypeNames ( qualifiedPackageName ) ; if ( answers != null ) { if ( result == null ) { result = answers ; } else { int resultLength = result . length ; int answersLength = answers . length ; System . arraycopy ( result , 0 , ( result = new char [ answersLength + resultLength ] [ ] [ ] ) , 0 , resultLength ) ; System . arraycopy ( answers , 0 , result , resultLength , answersLength ) ; } } } } else { for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) { Classpath p = this . classpaths [ i ] ; char [ ] [ ] [ ] answers = ( p instanceof ClasspathJar ) ? p . findTypeNames ( qualifiedPackageName ) : p . findTypeNames ( qualifiedPackageName2 ) ; if ( answers != null ) { if ( result == null ) { result = answers ; } else { int resultLength = result . length ; int answersLength = answers . length ; System . arraycopy ( result , 0 , ( result = new char [ answersLength + resultLength ] [ ] [ ] ) , 0 , resultLength ) ; System . arraycopy ( answers , 0 , result , resultLength , answersLength ) ; } } } } } return result ; } public NameEnvironmentAnswer findType ( char [ ] [ ] compoundName , boolean asBinaryOnly ) { if ( compoundName != null ) return findClass ( new String ( CharOperation . concatWith ( compoundName , '/' ) ) , compoundName [ compoundName . length - 1 ] , asBinaryOnly ) ; return null ; } public NameEnvironmentAnswer findType ( char [ ] typeName , char [ ] [ ] packageName ) { if ( typeName != null ) return findClass ( new String ( CharOperation . concatWith ( packageName , typeName , '/' ) ) , typeName , false ) ; return null ; } public boolean isPackage ( char [ ] [ ] compoundName , char [ ] packageName ) { String qualifiedPackageName = new String ( CharOperation . concatWith ( compoundName , packageName , '/' ) ) ; String qp2 = File . separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName . replace ( '/' , File . separatorChar ) ; if ( qualifiedPackageName == qp2 ) { for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) if ( this . classpaths [ i ] . isPackage ( qualifiedPackageName ) ) return true ; } else { for ( int i = 0 , length = this . classpaths . length ; i < length ; i ++ ) { Classpath p = this . classpaths [ i ] ; if ( ( p instanceof ClasspathJar ) ? p . isPackage ( qualifiedPackageName ) : p . isPackage ( qp2 ) ) return true ; } } return false ; } } </s>