<s> package org . eclipse . jdt . internal . core ; import java . io . BufferedInputStream ; import java . io . BufferedOutputStream ; import java . io . DataInputStream ; import java . io . DataOutputStream ; import java . io . File ; import java . io . FileInputStream ; import java . io . FileOutputStream ; import java . io . IOException ; import java . util . * ; import org . eclipse . core . resources . * ; import org . eclipse . core . runtime . * ; import org . eclipse . jdt . core . * ; import org . eclipse . jdt . internal . core . JavaModelManager . PerProjectInfo ; import org . eclipse . jdt . internal . core . util . Util ; public class DeltaProcessingState implements IResourceChangeListener { public IElementChangedListener [ ] elementChangedListeners = new IElementChangedListener [ 5 ] ; public int [ ] elementChangedListenerMasks = new int [ 5 ] ; public int elementChangedListenerCount = 0 ; public IResourceChangeListener [ ] preResourceChangeListeners = new IResourceChangeListener [ 1 ] ; public int [ ] preResourceChangeEventMasks = new int [ 1 ] ; public int preResourceChangeListenerCount = 0 ; private ThreadLocal deltaProcessors = new ThreadLocal ( ) ; public void doNotUse ( ) { this . deltaProcessors . set ( null ) ; } public HashMap roots = new HashMap ( ) ; public HashMap otherRoots = new HashMap ( ) ; public HashMap oldRoots = new HashMap ( ) ; public HashMap oldOtherRoots = new HashMap ( ) ; public HashMap sourceAttachments = new HashMap ( ) ; public HashMap projectDependencies = new HashMap ( ) ; public boolean rootsAreStale = true ; private Set initializingThreads = Collections . synchronizedSet ( new HashSet ( ) ) ; public Hashtable externalTimeStamps ; private HashMap classpathChanges = new HashMap ( ) ; private HashMap classpathValidations = new HashMap ( ) ; private HashMap projectReferenceChanges = new HashMap ( ) ; private HashMap externalFolderChanges = new HashMap ( ) ; private HashSet javaProjectNamesCache ; private HashSet externalElementsToRefresh ; public synchronized void addElementChangedListener ( IElementChangedListener listener , int eventMask ) { for ( int i = 0 ; i < this . elementChangedListenerCount ; i ++ ) { if ( this . elementChangedListeners [ i ] == listener ) { int cloneLength = this . elementChangedListenerMasks . length ; System . arraycopy ( this . elementChangedListenerMasks , 0 , this . elementChangedListenerMasks = new int [ cloneLength ] , 0 , cloneLength ) ; this . elementChangedListenerMasks [ i ] |= eventMask ; return ; } } int length ; if ( ( length = this . elementChangedListeners . length ) == this . elementChangedListenerCount ) { System . arraycopy ( this . elementChangedListeners , 0 , this . elementChangedListeners = new IElementChangedListener [ length * 2 ] , 0 , length ) ; System . arraycopy ( this . elementChangedListenerMasks , 0 , this . elementChangedListenerMasks = new int [ length * 2 ] , 0 , length ) ; } this . elementChangedListeners [ this . elementChangedListenerCount ] = listener ; this . elementChangedListenerMasks [ this . elementChangedListenerCount ] = eventMask ; this . elementChangedListenerCount ++ ; } public synchronized void addForRefresh ( IJavaElement externalElement ) { if ( this . externalElementsToRefresh == null ) { this . externalElementsToRefresh = new HashSet ( ) ; } this . externalElementsToRefresh . add ( externalElement ) ; } public synchronized void addPreResourceChangedListener ( IResourceChangeListener listener , int eventMask ) { for ( int i = 0 ; i < this . preResourceChangeListenerCount ; i ++ ) { if ( this . preResourceChangeListeners [ i ] == listener ) { this . preResourceChangeEventMasks [ i ] |= eventMask ; return ; } } int length ; if ( ( length = this . preResourceChangeListeners . length ) == this . preResourceChangeListenerCount ) { System . arraycopy ( this . preResourceChangeListeners , 0 , this . preResourceChangeListeners = new IResourceChangeListener [ length * 2 ] , 0 , length ) ; System . arraycopy ( this . preResourceChangeEventMasks , 0 , this . preResourceChangeEventMasks = new int [ length * 2 ] , 0 , length ) ; } this . preResourceChangeListeners [ this . preResourceChangeListenerCount ] = listener ; this . preResourceChangeEventMasks [ this . preResourceChangeListenerCount ] = eventMask ; this . preResourceChangeListenerCount ++ ; } public DeltaProcessor getDeltaProcessor ( ) { DeltaProcessor deltaProcessor = ( DeltaProcessor ) this . deltaProcessors . get ( ) ; if ( deltaProcessor != null ) return deltaProcessor ; deltaProcessor = new DeltaProcessor ( this , JavaModelManager . getJavaModelManager ( ) ) ; this . deltaProcessors . set ( deltaProcessor ) ; return deltaProcessor ; } public synchronized ClasspathChange addClasspathChange ( IProject project , IClasspathEntry [ ] oldRawClasspath , IPath oldOutputLocation , IClasspathEntry [ ] oldResolvedClasspath ) { ClasspathChange change = ( ClasspathChange ) this . classpathChanges . get ( project ) ; if ( change == null ) { change = new ClasspathChange ( ( JavaProject ) JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) . getJavaProject ( project ) , oldRawClasspath , oldOutputLocation , oldResolvedClasspath ) ; this . classpathChanges . put ( project , change ) ; } else { if ( change . oldRawClasspath == null ) change . oldRawClasspath = oldRawClasspath ; if ( change . oldOutputLocation == null ) change . oldOutputLocation = oldOutputLocation ; if ( change . oldResolvedClasspath == null ) change . oldResolvedClasspath = oldResolvedClasspath ; } return change ; } public synchronized ClasspathChange getClasspathChange ( IProject project ) { return ( ClasspathChange ) this . classpathChanges . get ( project ) ; } public synchronized HashMap removeAllClasspathChanges ( ) { HashMap result = this . classpathChanges ; this . classpathChanges = new HashMap ( result . size ( ) ) ; return result ; } public synchronized ClasspathValidation addClasspathValidation ( JavaProject project ) { ClasspathValidation validation = ( ClasspathValidation ) this . classpathValidations . get ( project ) ; if ( validation == null ) { validation = new ClasspathValidation ( project ) ; this . classpathValidations . put ( project , validation ) ; } return validation ; } public synchronized void addExternalFolderChange ( JavaProject project , IClasspathEntry [ ] oldResolvedClasspath ) { ExternalFolderChange change = ( ExternalFolderChange ) this . externalFolderChanges . get ( project ) ; if ( change == null ) { change = new ExternalFolderChange ( project , oldResolvedClasspath ) ; this . externalFolderChanges . put ( project , change ) ; } } public synchronized void addProjectReferenceChange ( JavaProject project , IClasspathEntry [ ] oldResolvedClasspath ) { ProjectReferenceChange change = ( ProjectReferenceChange ) this . projectReferenceChanges . get ( project ) ; if ( change == null ) { change = new ProjectReferenceChange ( project , oldResolvedClasspath ) ; this . projectReferenceChanges . put ( project , change ) ; } } public void initializeRoots ( boolean initAfterLoad ) { HashMap [ ] rootInfos = null ; if ( this . rootsAreStale ) { Thread currentThread = Thread . currentThread ( ) ; boolean addedCurrentThread = false ; try { if ( ! this . initializingThreads . add ( currentThread ) ) return ; addedCurrentThread = true ; JavaModelManager . getJavaModelManager ( ) . forceBatchInitializations ( initAfterLoad ) ; rootInfos = getRootInfos ( false ) ; } finally { if ( addedCurrentThread ) { this . initializingThreads . remove ( currentThread ) ; } } } synchronized ( this ) { this . oldRoots = this . roots ; this . oldOtherRoots = this . otherRoots ; if ( this . rootsAreStale && rootInfos != null ) { this . roots = rootInfos [ 0 ] ; this . otherRoots = rootInfos [ 1 ] ; this . sourceAttachments = rootInfos [ 2 ] ; this . projectDependencies = rootInfos [ 3 ] ; this . rootsAreStale = false ; } } } synchronized void initializeRootsWithPreviousSession ( ) { HashMap [ ] rootInfos = getRootInfos ( true ) ; if ( rootInfos != null ) { this . roots = rootInfos [ 0 ] ; this . otherRoots = rootInfos [ 1 ] ; this . sourceAttachments = rootInfos [ 2 ] ; this . projectDependencies = rootInfos [ 3 ] ; this . rootsAreStale = false ; } } private HashMap [ ] getRootInfos ( boolean usePreviousSession ) { HashMap newRoots = new HashMap ( ) ; HashMap newOtherRoots = new HashMap ( ) ; HashMap newSourceAttachments = new HashMap ( ) ; HashMap newProjectDependencies = new HashMap ( ) ; IJavaModel model = JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) ; IJavaProject [ ] projects ; try { projects = model . getJavaProjects ( ) ; } catch ( JavaModelException e ) { return null ; } for ( int i = 0 , length = projects . length ; i < length ; i ++ ) { JavaProject project = ( JavaProject ) projects [ i ] ; IClasspathEntry [ ] classpath ; try { if ( usePreviousSession ) { PerProjectInfo perProjectInfo = project . getPerProjectInfo ( ) ; project . resolveClasspath ( perProjectInfo , true , false ) ; classpath = perProjectInfo . resolvedClasspath ; } else { classpath = project . getResolvedClasspath ( ) ; } } catch ( JavaModelException e ) { continue ; } for ( int j = 0 , classpathLength = classpath . length ; j < classpathLength ; j ++ ) { IClasspathEntry entry = classpath [ j ] ; if ( entry . getEntryKind ( ) == IClasspathEntry . CPE_PROJECT ) { IJavaProject key = model . getJavaProject ( entry . getPath ( ) . segment ( 0 ) ) ; IJavaProject [ ] dependents = ( IJavaProject [ ] ) newProjectDependencies . get ( key ) ; if ( dependents == null ) { dependents = new IJavaProject [ ] { project } ; } else { int dependentsLength = dependents . length ; System . arraycopy ( dependents , 0 , dependents = new IJavaProject [ dependentsLength + 1 ] , 0 , dependentsLength ) ; dependents [ dependentsLength ] = project ; } newProjectDependencies . put ( key , dependents ) ; continue ; } IPath path = entry . getPath ( ) ; if ( newRoots . get ( path ) == null ) { newRoots . put ( path , new DeltaProcessor . RootInfo ( project , path , ( ( ClasspathEntry ) entry ) . fullInclusionPatternChars ( ) , ( ( ClasspathEntry ) entry ) . fullExclusionPatternChars ( ) , entry . getEntryKind ( ) ) ) ; } else { ArrayList rootList = ( ArrayList ) newOtherRoots . get ( path ) ; if ( rootList == null ) { rootList = new ArrayList ( ) ; newOtherRoots . put ( path , rootList ) ; } rootList . add ( new DeltaProcessor . RootInfo ( project , path , ( ( ClasspathEntry ) entry ) . fullInclusionPatternChars ( ) , ( ( ClasspathEntry ) entry ) . fullExclusionPatternChars ( ) , entry . getEntryKind ( ) ) ) ; } if ( entry . getEntryKind ( ) != IClasspathEntry . CPE_LIBRARY ) continue ; String propertyString = null ; try { propertyString = Util . getSourceAttachmentProperty ( path ) ; } catch ( JavaModelException e ) { e . printStackTrace ( ) ; } IPath sourceAttachmentPath ; if ( propertyString != null ) { int index = propertyString . lastIndexOf ( PackageFragmentRoot . ATTACHMENT_PROPERTY_DELIMITER ) ; sourceAttachmentPath = ( index < 0 ) ? new Path ( propertyString ) : new Path ( propertyString . substring ( 0 , index ) ) ; } else { sourceAttachmentPath = entry . getSourceAttachmentPath ( ) ; } if ( sourceAttachmentPath != null ) { newSourceAttachments . put ( sourceAttachmentPath , path ) ; } } } return new HashMap [ ] { newRoots , newOtherRoots , newSourceAttachments , newProjectDependencies } ; } public synchronized ClasspathValidation [ ] removeClasspathValidations ( ) { int length = this . classpathValidations . size ( ) ; if ( length == 0 ) return null ; ClasspathValidation [ ] validations = new ClasspathValidation [ length ] ; this . classpathValidations . values ( ) . toArray ( validations ) ; this . classpathValidations . clear ( ) ; return validations ; } public synchronized ExternalFolderChange [ ] removeExternalFolderChanges ( ) { int length = this . externalFolderChanges . size ( ) ; if ( length == 0 ) return null ; ExternalFolderChange [ ] updates = new ExternalFolderChange [ length ] ; this . externalFolderChanges . values ( ) . toArray ( updates ) ; this . externalFolderChanges . clear ( ) ; return updates ; } public synchronized ProjectReferenceChange [ ] removeProjectReferenceChanges ( ) { int length = this . projectReferenceChanges . size ( ) ; if ( length == 0 ) return null ; ProjectReferenceChange [ ] updates = new ProjectReferenceChange [ length ] ; this . projectReferenceChanges . values ( ) . toArray ( updates ) ; this . projectReferenceChanges . clear ( ) ; return updates ; } public synchronized HashSet removeExternalElementsToRefresh ( ) { HashSet result = this . externalElementsToRefresh ; this . externalElementsToRefresh = null ; return result ; } public synchronized void removeElementChangedListener ( IElementChangedListener listener ) { for ( int i = 0 ; i < this . elementChangedListenerCount ; i ++ ) { if ( this . elementChangedListeners [ i ] == listener ) { int length = this . elementChangedListeners . length ; IElementChangedListener [ ] newListeners = new IElementChangedListener [ length ] ; System . arraycopy ( this . elementChangedListeners , 0 , newListeners , 0 , i ) ; int [ ] newMasks = new int [ length ] ; System . arraycopy ( this . elementChangedListenerMasks , 0 , newMasks , 0 , i ) ; int trailingLength = this . elementChangedListenerCount - i - 1 ; if ( trailingLength > 0 ) { System . arraycopy ( this . elementChangedListeners , i + 1 , newListeners , i , trailingLength ) ; System . arraycopy ( this . elementChangedListenerMasks , i + 1 , newMasks , i , trailingLength ) ; } this . elementChangedListeners = newListeners ; this . elementChangedListenerMasks = newMasks ; this . elementChangedListenerCount -- ; return ; } } } public synchronized void removePreResourceChangedListener ( IResourceChangeListener listener ) { for ( int i = 0 ; i < this . preResourceChangeListenerCount ; i ++ ) { if ( this . preResourceChangeListeners [ i ] == listener ) { int length = this . preResourceChangeListeners . length ; IResourceChangeListener [ ] newListeners = new IResourceChangeListener [ length ] ; int [ ] newEventMasks = new int [ length ] ; System . arraycopy ( this . preResourceChangeListeners , 0 , newListeners , 0 , i ) ; System . arraycopy ( this . preResourceChangeEventMasks , 0 , newEventMasks , 0 , i ) ; int trailingLength = this . preResourceChangeListenerCount - i - 1 ; if ( trailingLength > 0 ) { System . arraycopy ( this . preResourceChangeListeners , i + 1 , newListeners , i , trailingLength ) ; System . arraycopy ( this . preResourceChangeEventMasks , i + 1 , newEventMasks , i , trailingLength ) ; } this . preResourceChangeListeners = newListeners ; this . preResourceChangeEventMasks = newEventMasks ; this . preResourceChangeListenerCount -- ; return ; } } } public void resourceChanged ( final IResourceChangeEvent event ) { for ( int i = 0 ; i < this . preResourceChangeListenerCount ; i ++ ) { final IResourceChangeListener listener = this . preResourceChangeListeners [ i ] ; if ( ( this . preResourceChangeEventMasks [ i ] & event . getType ( ) ) != 0 ) SafeRunner . run ( new ISafeRunnable ( ) { public void handleException ( Throwable exception ) { Util . log ( exception , "" ) ; } public void run ( ) throws Exception { listener . resourceChanged ( event ) ; } } ) ; } try { getDeltaProcessor ( ) . resourceChanged ( event ) ; } finally { if ( event . getType ( ) == IResourceChangeEvent . POST_CHANGE ) { this . deltaProcessors . set ( null ) ; } else { getDeltaProcessor ( ) . overridenEventType = - 1 ; } } } public Hashtable getExternalLibTimeStamps ( ) { if ( this . externalTimeStamps == null ) { Hashtable timeStamps = new Hashtable ( ) ; File timestampsFile = getTimeStampsFile ( ) ; DataInputStream in = null ; try { in = new DataInputStream ( new BufferedInputStream ( new FileInputStream ( timestampsFile ) ) ) ; int size = in . readInt ( ) ; while ( size -- > 0 ) { String key = in . readUTF ( ) ; long timestamp = in . readLong ( ) ; timeStamps . put ( Path . fromPortableString ( key ) , new Long ( timestamp ) ) ; } } catch ( IOException e ) { if ( timestampsFile . exists ( ) ) Util . log ( e , "" ) ; } finally { if ( in != null ) { try { in . close ( ) ; } catch ( IOException e ) { } } } this . externalTimeStamps = timeStamps ; } return this . externalTimeStamps ; } public IJavaProject findJavaProject ( String name ) { if ( getOldJavaProjecNames ( ) . contains ( name ) ) return JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) . getJavaProject ( name ) ; return null ; } public synchronized HashSet getOldJavaProjecNames ( ) { if ( this . javaProjectNamesCache == null ) { HashSet result = new HashSet ( ) ; IJavaProject [ ] projects ; try { projects = JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) . getJavaProjects ( ) ; } catch ( JavaModelException e ) { return this . javaProjectNamesCache ; } for ( int i = 0 , length = projects . length ; i < length ; i ++ ) { IJavaProject project = projects [ i ] ; result . add ( project . getElementName ( ) ) ; } return this . javaProjectNamesCache = result ; } return this . javaProjectNamesCache ; } public synchronized void resetOldJavaProjectNames ( ) { this . javaProjectNamesCache = null ; } private File getTimeStampsFile ( ) { return JavaCore . getPlugin ( ) . getStateLocation ( ) . append ( "" ) . toFile ( ) ; } public void saveExternalLibTimeStamps ( ) throws CoreException { if ( this . externalTimeStamps == null ) return ; HashSet toRemove = new HashSet ( ) ; if ( this . roots != null ) { Enumeration keys = this . externalTimeStamps . keys ( ) ; while ( keys . hasMoreElements ( ) ) { Object key = keys . nextElement ( ) ; if ( this . roots . get ( key ) == null ) { toRemove . add ( key ) ; } } } File timestamps = getTimeStampsFile ( ) ; DataOutputStream out = null ; try { out = new DataOutputStream ( new BufferedOutputStream ( new FileOutputStream ( timestamps ) ) ) ; out . writeInt ( this . externalTimeStamps . size ( ) - toRemove . size ( ) ) ; Iterator entries = this . externalTimeStamps . entrySet ( ) . iterator ( ) ; while ( entries . hasNext ( ) ) { Map . Entry entry = ( Map . Entry ) entries . next ( ) ; IPath key = ( IPath ) entry . getKey ( ) ; if ( ! toRemove . contains ( key ) ) { out . writeUTF ( key . toPortableString ( ) ) ; Long timestamp = ( Long ) entry . getValue ( ) ; out . writeLong ( timestamp . longValue ( ) ) ; } } } catch ( IOException e ) { IStatus status = new Status ( IStatus . ERROR , JavaCore . PLUGIN_ID , IStatus . ERROR , "" , e ) ; throw new CoreException ( status ) ; } finally { if ( out != null ) { try { out . close ( ) ; } catch ( IOException e ) { } } } } public synchronized void updateRoots ( IPath containerPath , IResourceDelta containerDelta , DeltaProcessor deltaProcessor ) { Map updatedRoots ; Map otherUpdatedRoots ; if ( containerDelta . getKind ( ) == IResourceDelta . REMOVED ) { updatedRoots = this . oldRoots ; otherUpdatedRoots = this . oldOtherRoots ; } else { updatedRoots = this . roots ; otherUpdatedRoots = this . otherRoots ; } int containerSegmentCount = containerPath . segmentCount ( ) ; boolean containerIsProject = containerSegmentCount == 1 ; Iterator iterator = updatedRoots . entrySet ( ) . iterator ( ) ; while ( iterator . hasNext ( ) ) { Map . Entry entry = ( Map . Entry ) iterator . next ( ) ; IPath path = ( IPath ) entry . getKey ( ) ; if ( containerPath . isPrefixOf ( path ) && ! containerPath . equals ( path ) ) { IResourceDelta rootDelta = containerDelta . findMember ( path . removeFirstSegments ( containerSegmentCount ) ) ; if ( rootDelta == null ) continue ; DeltaProcessor . RootInfo rootInfo = ( DeltaProcessor . RootInfo ) entry . getValue ( ) ; if ( ! containerIsProject || ! rootInfo . project . getPath ( ) . isPrefixOf ( path ) ) { deltaProcessor . updateCurrentDeltaAndIndex ( rootDelta , IJavaElement . PACKAGE_FRAGMENT_ROOT , rootInfo ) ; } ArrayList rootList = ( ArrayList ) otherUpdatedRoots . get ( path ) ; if ( rootList != null ) { Iterator otherProjects = rootList . iterator ( ) ; while ( otherProjects . hasNext ( ) ) { rootInfo = ( DeltaProcessor . RootInfo ) otherProjects . next ( ) ; if ( ! containerIsProject || ! rootInfo . project . getPath ( ) . isPrefixOf ( path ) ) { deltaProcessor . updateCurrentDeltaAndIndex ( rootDelta , IJavaElement . PACKAGE_FRAGMENT_ROOT , rootInfo ) ; } } } } } } } </s>