<s> package org . eclipse . jdt . internal . core . search . indexing ; import java . io . * ; import java . util . * ; import java . util . zip . CRC32 ; import org . codehaus . jdt . groovy . integration . LanguageSupportFactory ; import org . eclipse . core . resources . * ; import org . eclipse . core . runtime . IPath ; import org . eclipse . core . runtime . IProgressMonitor ; import org . eclipse . core . runtime . OperationCanceledException ; import org . eclipse . core . runtime . Path ; import org . eclipse . jdt . core . * ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . search . * ; import org . eclipse . jdt . internal . compiler . ISourceElementRequestor ; import org . eclipse . jdt . internal . compiler . SourceElementParser ; import org . eclipse . jdt . internal . compiler . impl . CompilerOptions ; import org . eclipse . jdt . internal . compiler . problem . DefaultProblemFactory ; import org . eclipse . jdt . internal . compiler . util . SimpleLookupTable ; import org . eclipse . jdt . internal . compiler . util . SimpleSet ; import org . eclipse . jdt . internal . core . * ; import org . eclipse . jdt . internal . core . index . * ; import org . eclipse . jdt . internal . core . search . BasicSearchEngine ; import org . eclipse . jdt . internal . core . search . PatternSearchJob ; import org . eclipse . jdt . internal . core . search . processing . IJob ; import org . eclipse . jdt . internal . core . search . processing . JobManager ; import org . eclipse . jdt . internal . core . util . Messages ; import org . eclipse . jdt . internal . core . util . Util ; public class IndexManager extends JobManager implements IIndexConstants { public SimpleLookupTable indexLocations = new SimpleLookupTable ( ) ; private SimpleLookupTable indexes = new SimpleLookupTable ( ) ; private boolean needToSave = false ; private IPath javaPluginLocation = null ; private SimpleLookupTable indexStates = null ; private File savedIndexNamesFile = new File ( getSavedIndexesDirectory ( ) , "" ) ; private File participantIndexNamesFile = new File ( getSavedIndexesDirectory ( ) , "" ) ; private boolean javaLikeNamesChanged = true ; public static final Integer SAVED_STATE = new Integer ( 0 ) ; public static final Integer UPDATING_STATE = new Integer ( 1 ) ; public static final Integer UNKNOWN_STATE = new Integer ( 2 ) ; public static final Integer REBUILDING_STATE = new Integer ( 3 ) ; private SimpleLookupTable participantsContainers = null ; private boolean participantUpdated = false ; public static boolean DEBUG = false ; public synchronized void aboutToUpdateIndex ( IPath containerPath , Integer newIndexState ) { IPath indexLocation = computeIndexLocation ( containerPath ) ; Object state = getIndexStates ( ) . get ( indexLocation ) ; Integer currentIndexState = state == null ? UNKNOWN_STATE : ( Integer ) state ; if ( currentIndexState . equals ( REBUILDING_STATE ) ) return ; int compare = newIndexState . compareTo ( currentIndexState ) ; if ( compare > 0 ) { updateIndexState ( indexLocation , newIndexState ) ; } else if ( compare < 0 && this . indexes . get ( indexLocation ) == null ) { rebuildIndex ( indexLocation , containerPath ) ; } } public void addBinary ( IFile resource , IPath containerPath ) { if ( JavaCore . getPlugin ( ) == null ) return ; SearchParticipant participant = SearchEngine . getDefaultSearchParticipant ( ) ; SearchDocument document = participant . getDocument ( resource . getFullPath ( ) . toString ( ) ) ; IPath indexLocation = computeIndexLocation ( containerPath ) ; scheduleDocumentIndexing ( document , containerPath , indexLocation , participant ) ; } public void addSource ( IFile resource , IPath containerPath , SourceElementParser parser ) { if ( JavaCore . getPlugin ( ) == null ) return ; SearchParticipant participant = SearchEngine . getDefaultSearchParticipant ( ) ; SearchDocument document = participant . getDocument ( resource . getFullPath ( ) . toString ( ) ) ; document . setParser ( parser ) ; IPath indexLocation = computeIndexLocation ( containerPath ) ; scheduleDocumentIndexing ( document , containerPath , indexLocation , participant ) ; } public void cleanUpIndexes ( ) { SimpleSet knownPaths = new SimpleSet ( ) ; IJavaSearchScope scope = BasicSearchEngine . createWorkspaceScope ( ) ; PatternSearchJob job = new PatternSearchJob ( null , SearchEngine . getDefaultSearchParticipant ( ) , scope , null ) ; Index [ ] selectedIndexes = job . getIndexes ( null ) ; for ( int i = 0 , l = selectedIndexes . length ; i < l ; i ++ ) { String path = selectedIndexes [ i ] . getIndexFile ( ) . getAbsolutePath ( ) ; knownPaths . add ( path ) ; } if ( this . indexStates != null ) { Object [ ] keys = this . indexStates . keyTable ; IPath [ ] locations = new IPath [ this . indexStates . elementSize ] ; int count = 0 ; for ( int i = 0 , l = keys . length ; i < l ; i ++ ) { IPath key = ( IPath ) keys [ i ] ; if ( key != null && ! knownPaths . includes ( key . toOSString ( ) ) ) locations [ count ++ ] = key ; } if ( count > 0 ) removeIndexesState ( locations ) ; } deleteIndexFiles ( knownPaths ) ; } public synchronized IPath computeIndexLocation ( IPath containerPath ) { IPath indexLocation = ( IPath ) this . indexLocations . get ( containerPath ) ; if ( indexLocation == null ) { String pathString = containerPath . toOSString ( ) ; CRC32 checksumCalculator = new CRC32 ( ) ; checksumCalculator . update ( pathString . getBytes ( ) ) ; String fileName = Long . toString ( checksumCalculator . getValue ( ) ) + ".index" ; if ( VERBOSE ) Util . verbose ( "" + pathString + " is " + fileName ) ; indexLocation = ( IPath ) getIndexStates ( ) . getKey ( getJavaPluginWorkingLocation ( ) . append ( fileName ) ) ; this . indexLocations . put ( containerPath , indexLocation ) ; } return indexLocation ; } public void deleteIndexFiles ( ) { if ( DEBUG ) Util . verbose ( "" ) ; this . savedIndexNamesFile . delete ( ) ; deleteIndexFiles ( null ) ; } private void deleteIndexFiles ( SimpleSet pathsToKeep ) { File [ ] indexesFiles = getSavedIndexesDirectory ( ) . listFiles ( ) ; if ( indexesFiles == null ) return ; for ( int i = 0 , l = indexesFiles . length ; i < l ; i ++ ) { String fileName = indexesFiles [ i ] . getAbsolutePath ( ) ; if ( pathsToKeep != null && pathsToKeep . includes ( fileName ) ) continue ; String suffix = ".index" ; if ( fileName . regionMatches ( true , fileName . length ( ) - suffix . length ( ) , suffix , 0 , suffix . length ( ) ) ) { if ( VERBOSE || DEBUG ) Util . verbose ( "" + indexesFiles [ i ] ) ; indexesFiles [ i ] . delete ( ) ; } } } public synchronized void ensureIndexExists ( IPath indexLocation , IPath containerPath ) { SimpleLookupTable states = getIndexStates ( ) ; Object state = states . get ( indexLocation ) ; if ( state == null ) { updateIndexState ( indexLocation , REBUILDING_STATE ) ; getIndex ( containerPath , indexLocation , true , true ) ; } } public SourceElementParser getSourceElementParser ( IJavaProject project , ISourceElementRequestor requestor ) { Map options = project . getOptions ( true ) ; options . put ( JavaCore . COMPILER_TASK_TAGS , "" ) ; SourceElementParser parser = LanguageSupportFactory . getIndexingParser ( requestor , new DefaultProblemFactory ( Locale . getDefault ( ) ) , new CompilerOptions ( options ) , true , true , false ) ; parser . reportOnlyOneSyntaxError = true ; parser . javadocParser . checkDocComment = true ; parser . javadocParser . reportProblems = false ; return parser ; } public synchronized Index getIndex ( IPath indexLocation ) { return ( Index ) this . indexes . get ( indexLocation ) ; } public synchronized Index getIndex ( IPath containerPath , boolean reuseExistingFile , boolean createIfMissing ) { IPath indexLocation = computeIndexLocation ( containerPath ) ; return getIndex ( containerPath , indexLocation , reuseExistingFile , createIfMissing ) ; } public synchronized Index getIndex ( IPath containerPath , IPath indexLocation , boolean reuseExistingFile , boolean createIfMissing ) { Index index = getIndex ( indexLocation ) ; if ( index == null ) { Object state = getIndexStates ( ) . get ( indexLocation ) ; Integer currentIndexState = state == null ? UNKNOWN_STATE : ( Integer ) state ; if ( currentIndexState == UNKNOWN_STATE ) { rebuildIndex ( indexLocation , containerPath ) ; return null ; } String containerPathString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; String indexLocationString = indexLocation . toOSString ( ) ; if ( reuseExistingFile ) { File indexFile = new File ( indexLocationString ) ; if ( indexFile . exists ( ) ) { try { index = new Index ( indexLocationString , containerPathString , true ) ; this . indexes . put ( indexLocation , index ) ; return index ; } catch ( IOException e ) { if ( currentIndexState != REBUILDING_STATE ) { if ( VERBOSE ) Util . verbose ( "" + indexLocationString + " path: " + containerPathString ) ; rebuildIndex ( indexLocation , containerPath ) ; return null ; } } } if ( currentIndexState == SAVED_STATE ) { rebuildIndex ( indexLocation , containerPath ) ; return null ; } } if ( createIfMissing ) { try { if ( VERBOSE ) Util . verbose ( "" + indexLocationString + " path: " + containerPathString ) ; index = new Index ( indexLocationString , containerPathString , false ) ; this . indexes . put ( indexLocation , index ) ; return index ; } catch ( IOException e ) { if ( VERBOSE ) Util . verbose ( "" + indexLocationString + " path: " + containerPathString ) ; return null ; } } } return index ; } public Index [ ] getIndexes ( IPath [ ] locations , IProgressMonitor progressMonitor ) { int length = locations . length ; Index [ ] locatedIndexes = new Index [ length ] ; int count = 0 ; if ( this . javaLikeNamesChanged ) { this . javaLikeNamesChanged = hasJavaLikeNamesChanged ( ) ; } for ( int i = 0 ; i < length ; i ++ ) { if ( progressMonitor != null && progressMonitor . isCanceled ( ) ) { throw new OperationCanceledException ( ) ; } IPath indexLocation = locations [ i ] ; Index index = getIndex ( indexLocation ) ; if ( index == null ) { IPath containerPath = ( IPath ) this . indexLocations . keyForValue ( indexLocation ) ; if ( containerPath != null ) { index = getIndex ( containerPath , indexLocation , true , false ) ; if ( index != null && this . javaLikeNamesChanged && ! index . isIndexForJar ( ) ) { File indexFile = index . getIndexFile ( ) ; if ( indexFile . exists ( ) ) { if ( DEBUG ) Util . verbose ( "" + containerPath ) ; indexFile . delete ( ) ; } this . indexes . put ( indexLocation , null ) ; rebuildIndex ( indexLocation , containerPath ) ; index = null ; } } else { if ( ! getJavaPluginWorkingLocation ( ) . isPrefixOf ( indexLocation ) ) { if ( indexLocation . toFile ( ) . exists ( ) ) { try { IPath container = getParticipantsContainer ( indexLocation ) ; if ( container != null ) { index = new Index ( indexLocation . toOSString ( ) , container . toOSString ( ) , true ) ; this . indexes . put ( indexLocation , index ) ; } } catch ( IOException e ) { } } } } } if ( index != null ) locatedIndexes [ count ++ ] = index ; } if ( this . javaLikeNamesChanged ) { writeJavaLikeNamesFile ( ) ; this . javaLikeNamesChanged = false ; } if ( count < length ) { System . arraycopy ( locatedIndexes , 0 , locatedIndexes = new Index [ count ] , 0 , count ) ; } return locatedIndexes ; } public synchronized Index getIndexForUpdate ( IPath containerPath , boolean reuseExistingFile , boolean createIfMissing ) { IPath indexLocation = computeIndexLocation ( containerPath ) ; if ( getIndexStates ( ) . get ( indexLocation ) == REBUILDING_STATE ) return getIndex ( containerPath , indexLocation , reuseExistingFile , createIfMissing ) ; return null ; } private SimpleLookupTable getIndexStates ( ) { if ( this . indexStates != null ) return this . indexStates ; this . indexStates = new SimpleLookupTable ( ) ; IPath indexesDirectoryPath = getJavaPluginWorkingLocation ( ) ; char [ ] [ ] savedNames = readIndexState ( indexesDirectoryPath . toOSString ( ) ) ; if ( savedNames != null ) { for ( int i = 1 , l = savedNames . length ; i < l ; i ++ ) { char [ ] savedName = savedNames [ i ] ; if ( savedName . length > 0 ) { IPath indexLocation = indexesDirectoryPath . append ( new String ( savedName ) ) ; if ( VERBOSE ) Util . verbose ( "" + indexLocation ) ; this . indexStates . put ( indexLocation , SAVED_STATE ) ; } } } else { writeJavaLikeNamesFile ( ) ; this . javaLikeNamesChanged = false ; deleteIndexFiles ( ) ; } return this . indexStates ; } private IPath getParticipantsContainer ( IPath indexLocation ) { if ( this . participantsContainers == null ) { readParticipantsIndexNamesFile ( ) ; } return ( IPath ) this . participantsContainers . get ( indexLocation ) ; } private IPath getJavaPluginWorkingLocation ( ) { if ( this . javaPluginLocation != null ) return this . javaPluginLocation ; IPath stateLocation = JavaCore . getPlugin ( ) . getStateLocation ( ) ; return this . javaPluginLocation = stateLocation ; } private File getSavedIndexesDirectory ( ) { return new File ( getJavaPluginWorkingLocation ( ) . toOSString ( ) ) ; } private boolean hasJavaLikeNamesChanged ( ) { char [ ] [ ] currentNames = Util . getJavaLikeExtensions ( ) ; int current = currentNames . length ; char [ ] [ ] prevNames = readJavaLikeNamesFile ( ) ; if ( prevNames == null ) { if ( VERBOSE && current != 1 ) Util . verbose ( "" , System . err ) ; return ( current != 1 ) ; } int prev = prevNames . length ; if ( current != prev ) { if ( VERBOSE ) Util . verbose ( "" , System . err ) ; return true ; } if ( current > 1 ) { System . arraycopy ( currentNames , 0 , currentNames = new char [ current ] [ ] , 0 , current ) ; Util . sort ( currentNames ) ; } for ( int i = 0 ; i < current ; i ++ ) { if ( ! CharOperation . equals ( currentNames [ i ] , prevNames [ i ] ) ) { if ( VERBOSE ) Util . verbose ( "" , System . err ) ; return true ; } } return false ; } public void indexDocument ( SearchDocument searchDocument , SearchParticipant searchParticipant , Index index , IPath indexLocation ) { try { searchDocument . setIndex ( index ) ; searchParticipant . indexDocument ( searchDocument , indexLocation ) ; } finally { searchDocument . setIndex ( null ) ; } } public void indexAll ( IProject project ) { if ( JavaCore . getPlugin ( ) == null ) return ; try { JavaModel model = JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) ; JavaProject javaProject = ( JavaProject ) model . getJavaProject ( project ) ; IClasspathEntry [ ] entries = javaProject . getResolvedClasspath ( ) ; for ( int i = 0 ; i < entries . length ; i ++ ) { IClasspathEntry entry = entries [ i ] ; if ( entry . getEntryKind ( ) == IClasspathEntry . CPE_LIBRARY ) indexLibrary ( entry . getPath ( ) , project ) ; } } catch ( JavaModelException e ) { } IndexRequest request = new IndexAllProject ( project , this ) ; if ( ! isJobWaiting ( request ) ) request ( request ) ; } public void indexLibrary ( IPath path , IProject requestingProject ) { if ( JavaCore . getPlugin ( ) == null ) return ; Object target = JavaModel . getTarget ( path , true ) ; IndexRequest request = null ; if ( target instanceof IFile ) { request = new AddJarFileToIndex ( ( IFile ) target , this ) ; } else if ( target instanceof File ) { request = new AddJarFileToIndex ( path , this ) ; } else if ( target instanceof IContainer ) { request = new IndexBinaryFolder ( ( IContainer ) target , this ) ; } else { return ; } if ( ! isJobWaiting ( request ) ) request ( request ) ; } public void indexSourceFolder ( JavaProject javaProject , IPath sourceFolder , char [ ] [ ] inclusionPatterns , char [ ] [ ] exclusionPatterns ) { IProject project = javaProject . getProject ( ) ; if ( this . jobEnd > this . jobStart ) { IndexRequest request = new IndexAllProject ( project , this ) ; if ( isJobWaiting ( request ) ) return ; } request ( new AddFolderToIndex ( sourceFolder , project , inclusionPatterns , exclusionPatterns , this ) ) ; } public synchronized void jobWasCancelled ( IPath containerPath ) { IPath indexLocation = computeIndexLocation ( containerPath ) ; Index index = getIndex ( indexLocation ) ; if ( index != null ) { index . monitor = null ; this . indexes . removeKey ( indexLocation ) ; } updateIndexState ( indexLocation , UNKNOWN_STATE ) ; } protected synchronized void moveToNextJob ( ) { this . needToSave = true ; super . moveToNextJob ( ) ; } protected void notifyIdle ( long idlingTime ) { if ( idlingTime > 1000 && this . needToSave ) saveIndexes ( ) ; } public String processName ( ) { return Messages . process_name ; } private char [ ] [ ] readJavaLikeNamesFile ( ) { try { String pathName = getJavaPluginWorkingLocation ( ) . toOSString ( ) ; File javaLikeNamesFile = new File ( pathName , "" ) ; if ( ! javaLikeNamesFile . exists ( ) ) return null ; char [ ] javaLikeNames = org . eclipse . jdt . internal . compiler . util . Util . getFileCharContent ( javaLikeNamesFile , null ) ; if ( javaLikeNames . length > 0 ) { char [ ] [ ] names = CharOperation . splitOn ( '\n' , javaLikeNames ) ; return names ; } } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" ) ; } return null ; } private void rebuildIndex ( IPath indexLocation , IPath containerPath ) { Object target = JavaModel . getTarget ( containerPath , true ) ; if ( target == null ) return ; if ( VERBOSE ) Util . verbose ( "" + indexLocation + " path: " + containerPath ) ; updateIndexState ( indexLocation , REBUILDING_STATE ) ; IndexRequest request = null ; if ( target instanceof IProject ) { IProject p = ( IProject ) target ; if ( JavaProject . hasJavaNature ( p ) ) request = new IndexAllProject ( p , this ) ; } else if ( target instanceof IFolder ) { request = new IndexBinaryFolder ( ( IFolder ) target , this ) ; } else if ( target instanceof IFile ) { request = new AddJarFileToIndex ( ( IFile ) target , this ) ; } else if ( target instanceof File ) { request = new AddJarFileToIndex ( containerPath , this ) ; } if ( request != null ) request ( request ) ; } public synchronized Index recreateIndex ( IPath containerPath ) { String containerPathString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; try { IPath indexLocation = computeIndexLocation ( containerPath ) ; Index index = getIndex ( indexLocation ) ; ReadWriteMonitor monitor = index == null ? null : index . monitor ; if ( VERBOSE ) Util . verbose ( "" + indexLocation + " for path: " + containerPathString ) ; index = new Index ( indexLocation . toOSString ( ) , containerPathString , false ) ; this . indexes . put ( indexLocation , index ) ; index . monitor = monitor ; return index ; } catch ( IOException e ) { if ( VERBOSE ) { Util . verbose ( "" + containerPathString ) ; e . printStackTrace ( ) ; } return null ; } } public void remove ( String containerRelativePath , IPath indexedContainer ) { request ( new RemoveFromIndex ( containerRelativePath , indexedContainer , this ) ) ; } public synchronized void removeIndex ( IPath containerPath ) { if ( VERBOSE || DEBUG ) Util . verbose ( "" + containerPath ) ; IPath indexLocation = computeIndexLocation ( containerPath ) ; Index index = getIndex ( indexLocation ) ; File indexFile = null ; if ( index != null ) { index . monitor = null ; indexFile = index . getIndexFile ( ) ; } if ( indexFile == null ) indexFile = new File ( indexLocation . toOSString ( ) ) ; if ( indexFile . exists ( ) ) { if ( DEBUG ) Util . verbose ( "" + indexFile ) ; indexFile . delete ( ) ; } this . indexes . removeKey ( indexLocation ) ; updateIndexState ( indexLocation , null ) ; } public synchronized void removeIndexPath ( IPath path ) { if ( VERBOSE || DEBUG ) Util . verbose ( "" + path ) ; Object [ ] keyTable = this . indexes . keyTable ; Object [ ] valueTable = this . indexes . valueTable ; IPath [ ] locations = null ; int max = this . indexes . elementSize ; int count = 0 ; for ( int i = 0 , l = keyTable . length ; i < l ; i ++ ) { IPath indexLocation = ( IPath ) keyTable [ i ] ; if ( indexLocation == null ) continue ; if ( path . isPrefixOf ( indexLocation ) ) { Index index = ( Index ) valueTable [ i ] ; index . monitor = null ; if ( locations == null ) locations = new IPath [ max ] ; locations [ count ++ ] = indexLocation ; File indexFile = index . getIndexFile ( ) ; if ( indexFile . exists ( ) ) { if ( DEBUG ) Util . verbose ( "" + indexFile ) ; indexFile . delete ( ) ; } } else { max -- ; } } if ( locations != null ) { for ( int i = 0 ; i < count ; i ++ ) this . indexes . removeKey ( locations [ i ] ) ; removeIndexesState ( locations ) ; if ( this . participantsContainers != null && this . participantsContainers . get ( path . toOSString ( ) ) != null ) { this . participantsContainers . removeKey ( path . toOSString ( ) ) ; writeParticipantsIndexNamesFile ( ) ; } } } public synchronized void removeIndexFamily ( IPath path ) { ArrayList toRemove = null ; Object [ ] containerPaths = this . indexLocations . keyTable ; for ( int i = 0 , length = containerPaths . length ; i < length ; i ++ ) { IPath containerPath = ( IPath ) containerPaths [ i ] ; if ( containerPath == null ) continue ; if ( path . isPrefixOf ( containerPath ) ) { if ( toRemove == null ) toRemove = new ArrayList ( ) ; toRemove . add ( containerPath ) ; } } if ( toRemove != null ) for ( int i = 0 , length = toRemove . size ( ) ; i < length ; i ++ ) removeIndex ( ( IPath ) toRemove . get ( i ) ) ; } public void removeSourceFolderFromIndex ( JavaProject javaProject , IPath sourceFolder , char [ ] [ ] inclusionPatterns , char [ ] [ ] exclusionPatterns ) { IProject project = javaProject . getProject ( ) ; if ( this . jobEnd > this . jobStart ) { IndexRequest request = new IndexAllProject ( project , this ) ; if ( isJobWaiting ( request ) ) return ; } request ( new RemoveFolderFromIndex ( sourceFolder , inclusionPatterns , exclusionPatterns , project , this ) ) ; } public synchronized void reset ( ) { super . reset ( ) ; if ( this . indexes != null ) { this . indexes = new SimpleLookupTable ( ) ; this . indexStates = null ; } this . indexLocations = new SimpleLookupTable ( ) ; this . javaPluginLocation = null ; } public synchronized boolean resetIndex ( IPath containerPath ) { String containerPathString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; try { IPath indexLocation = computeIndexLocation ( containerPath ) ; Index index = getIndex ( indexLocation ) ; if ( VERBOSE ) { Util . verbose ( "" + indexLocation + " for path: " + containerPathString ) ; } if ( index == null ) { return recreateIndex ( containerPath ) != null ; } index . reset ( ) ; return true ; } catch ( IOException e ) { if ( VERBOSE ) { Util . verbose ( "" + containerPathString ) ; e . printStackTrace ( ) ; } return false ; } } public void saveIndex ( Index index ) throws IOException { if ( index . hasChanged ( ) ) { if ( VERBOSE ) Util . verbose ( "" + index . getIndexFile ( ) ) ; index . save ( ) ; } synchronized ( this ) { IPath containerPath = new Path ( index . containerPath ) ; if ( this . jobEnd > this . jobStart ) { for ( int i = this . jobEnd ; i > this . jobStart ; i -- ) { IJob job = this . awaitingJobs [ i ] ; if ( job instanceof IndexRequest ) if ( ( ( IndexRequest ) job ) . containerPath . equals ( containerPath ) ) return ; } } IPath indexLocation = computeIndexLocation ( containerPath ) ; updateIndexState ( indexLocation , SAVED_STATE ) ; } } public void saveIndexes ( ) { ArrayList toSave = new ArrayList ( ) ; synchronized ( this ) { Object [ ] valueTable = this . indexes . valueTable ; for ( int i = 0 , l = valueTable . length ; i < l ; i ++ ) { Index index = ( Index ) valueTable [ i ] ; if ( index != null ) toSave . add ( index ) ; } } boolean allSaved = true ; for ( int i = 0 , length = toSave . size ( ) ; i < length ; i ++ ) { Index index = ( Index ) toSave . get ( i ) ; ReadWriteMonitor monitor = index . monitor ; if ( monitor == null ) continue ; try { monitor . enterRead ( ) ; if ( index . hasChanged ( ) ) { if ( monitor . exitReadEnterWrite ( ) ) { try { saveIndex ( index ) ; } catch ( IOException e ) { if ( VERBOSE ) { Util . verbose ( "" , System . err ) ; e . printStackTrace ( ) ; } allSaved = false ; } finally { monitor . exitWriteEnterRead ( ) ; } } else { allSaved = false ; } } } finally { monitor . exitRead ( ) ; } } if ( this . participantsContainers != null && this . participantUpdated ) { writeParticipantsIndexNamesFile ( ) ; this . participantUpdated = false ; } this . needToSave = ! allSaved ; } public void scheduleDocumentIndexing ( final SearchDocument searchDocument , IPath container , final IPath indexLocation , final SearchParticipant searchParticipant ) { request ( new IndexRequest ( container , this ) { public boolean execute ( IProgressMonitor progressMonitor ) { if ( this . isCancelled || progressMonitor != null && progressMonitor . isCanceled ( ) ) return true ; Index index = getIndex ( this . containerPath , indexLocation , true , true ) ; if ( index == null ) return true ; ReadWriteMonitor monitor = index . monitor ; if ( monitor == null ) return true ; try { monitor . enterWrite ( ) ; indexDocument ( searchDocument , searchParticipant , index , indexLocation ) ; } finally { monitor . exitWrite ( ) ; } return true ; } public String toString ( ) { return "indexing " + searchDocument . getPath ( ) ; } } ) ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( 10 ) ; buffer . append ( super . toString ( ) ) ; buffer . append ( "" ) ; int count = 0 ; Object [ ] valueTable = this . indexes . valueTable ; for ( int i = 0 , l = valueTable . length ; i < l ; i ++ ) { Index index = ( Index ) valueTable [ i ] ; if ( index != null ) buffer . append ( ++ count ) . append ( " - " ) . append ( index . toString ( ) ) . append ( '\n' ) ; } return buffer . toString ( ) ; } private char [ ] [ ] readIndexState ( String dirOSString ) { try { char [ ] savedIndexNames = org . eclipse . jdt . internal . compiler . util . Util . getFileCharContent ( this . savedIndexNamesFile , null ) ; if ( savedIndexNames . length > 0 ) { char [ ] [ ] names = CharOperation . splitOn ( '\n' , savedIndexNames ) ; if ( names . length > 1 ) { String savedSignature = DiskIndex . SIGNATURE + "+" + dirOSString ; if ( savedSignature . equals ( new String ( names [ 0 ] ) ) ) return names ; } } } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" ) ; } return null ; } private void readParticipantsIndexNamesFile ( ) { SimpleLookupTable containers = new SimpleLookupTable ( 3 ) ; try { char [ ] participantIndexNames = org . eclipse . jdt . internal . compiler . util . Util . getFileCharContent ( this . participantIndexNamesFile , null ) ; if ( participantIndexNames . length > 0 ) { char [ ] [ ] names = CharOperation . splitOn ( '\n' , participantIndexNames ) ; if ( names . length >= 3 ) { if ( DiskIndex . SIGNATURE . equals ( new String ( names [ 0 ] ) ) ) { for ( int i = 1 , l = names . length - 1 ; i < l ; i += 2 ) { containers . put ( new Path ( new String ( names [ i ] ) ) , new Path ( new String ( names [ i + 1 ] ) ) ) ; } } } } } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" ) ; } this . participantsContainers = containers ; return ; } private synchronized void removeIndexesState ( IPath [ ] locations ) { getIndexStates ( ) ; int length = locations . length ; boolean changed = false ; for ( int i = 0 ; i < length ; i ++ ) { if ( locations [ i ] == null ) continue ; if ( ( this . indexStates . removeKey ( locations [ i ] ) != null ) ) { changed = true ; if ( VERBOSE ) { Util . verbose ( "" + locations [ i ] ) ; } } } if ( ! changed ) return ; writeSavedIndexNamesFile ( ) ; } private synchronized void updateIndexState ( IPath indexLocation , Integer indexState ) { if ( indexLocation . isEmpty ( ) ) throw new IllegalArgumentException ( ) ; getIndexStates ( ) ; if ( indexState != null ) { if ( indexState . equals ( this . indexStates . get ( indexLocation ) ) ) return ; this . indexStates . put ( indexLocation , indexState ) ; } else { if ( ! this . indexStates . containsKey ( indexLocation ) ) return ; this . indexStates . removeKey ( indexLocation ) ; } writeSavedIndexNamesFile ( ) ; if ( VERBOSE ) { if ( indexState == null ) { Util . verbose ( "" + indexLocation ) ; } else { String state = "?" ; if ( indexState == SAVED_STATE ) state = "SAVED" ; else if ( indexState == UPDATING_STATE ) state = "UPDATING" ; else if ( indexState == UNKNOWN_STATE ) state = "UNKNOWN" ; else if ( indexState == REBUILDING_STATE ) state = "REBUILDING" ; Util . verbose ( "" + state + " for: " + indexLocation ) ; } } } public void updateParticipant ( IPath indexLocation , IPath containerPath ) { if ( this . participantsContainers == null ) { readParticipantsIndexNamesFile ( ) ; } if ( this . participantsContainers . get ( indexLocation ) == null ) { this . participantsContainers . put ( indexLocation , containerPath ) ; this . participantUpdated = true ; } } private void writeJavaLikeNamesFile ( ) { BufferedWriter writer = null ; String pathName = getJavaPluginWorkingLocation ( ) . toOSString ( ) ; try { char [ ] [ ] currentNames = Util . getJavaLikeExtensions ( ) ; int length = currentNames . length ; if ( length > 1 ) { System . arraycopy ( currentNames , 0 , currentNames = new char [ length ] [ ] , 0 , length ) ; Util . sort ( currentNames ) ; } File javaLikeNamesFile = new File ( pathName , "" ) ; writer = new BufferedWriter ( new FileWriter ( javaLikeNamesFile ) ) ; for ( int i = 0 ; i < length - 1 ; i ++ ) { writer . write ( currentNames [ i ] ) ; writer . write ( '\n' ) ; } if ( length > 0 ) writer . write ( currentNames [ length - 1 ] ) ; } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" , System . err ) ; } finally { if ( writer != null ) { try { writer . close ( ) ; } catch ( IOException e ) { } } } } private void writeParticipantsIndexNamesFile ( ) { BufferedWriter writer = null ; try { writer = new BufferedWriter ( new FileWriter ( this . participantIndexNamesFile ) ) ; writer . write ( DiskIndex . SIGNATURE ) ; writer . write ( '\n' ) ; Object [ ] indexFiles = this . participantsContainers . keyTable ; Object [ ] containers = this . participantsContainers . valueTable ; for ( int i = 0 , l = indexFiles . length ; i < l ; i ++ ) { IPath indexFile = ( IPath ) indexFiles [ i ] ; if ( indexFile != null ) { writer . write ( indexFile . toOSString ( ) ) ; writer . write ( '\n' ) ; writer . write ( ( ( IPath ) containers [ i ] ) . toOSString ( ) ) ; writer . write ( '\n' ) ; } } } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" , System . err ) ; } finally { if ( writer != null ) { try { writer . close ( ) ; } catch ( IOException e ) { } } } } private void writeSavedIndexNamesFile ( ) { BufferedWriter writer = null ; try { writer = new BufferedWriter ( new FileWriter ( this . savedIndexNamesFile ) ) ; writer . write ( DiskIndex . SIGNATURE ) ; writer . write ( '+' ) ; writer . write ( getJavaPluginWorkingLocation ( ) . toOSString ( ) ) ; writer . write ( '\n' ) ; Object [ ] keys = this . indexStates . keyTable ; Object [ ] states = this . indexStates . valueTable ; for ( int i = 0 , l = states . length ; i < l ; i ++ ) { IPath key = ( IPath ) keys [ i ] ; if ( key != null && ! key . isEmpty ( ) && states [ i ] == SAVED_STATE ) { writer . write ( key . lastSegment ( ) ) ; writer . write ( '\n' ) ; } } } catch ( IOException ignored ) { if ( VERBOSE ) Util . verbose ( "" , System . err ) ; } finally { if ( writer != null ) { try { writer . close ( ) ; } catch ( IOException e ) { } } } } } </s>