<s> package org . eclipse . jdt . internal . core ; import java . io . File ; import java . util . * ; import org . eclipse . core . resources . IContainer ; import org . eclipse . core . resources . IFile ; import org . eclipse . core . resources . IFolder ; import org . eclipse . core . resources . IProject ; import org . eclipse . core . resources . IResource ; import org . eclipse . core . resources . IResourceChangeEvent ; import org . eclipse . core . resources . IResourceDelta ; import org . eclipse . core . resources . IResourceDeltaVisitor ; import org . eclipse . core . resources . IWorkspace ; import org . eclipse . core . resources . IWorkspaceRoot ; import org . eclipse . core . resources . IWorkspaceRunnable ; import org . eclipse . core . resources . ResourcesPlugin ; import org . eclipse . core . resources . WorkspaceJob ; import org . eclipse . core . runtime . * ; import org . eclipse . jdt . core . * ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . SourceElementParser ; import org . eclipse . jdt . internal . core . JavaModelManager . PerProjectInfo ; import org . eclipse . jdt . internal . core . builder . JavaBuilder ; import org . eclipse . jdt . internal . core . hierarchy . TypeHierarchy ; import org . eclipse . jdt . internal . core . search . AbstractSearchScope ; import org . eclipse . jdt . internal . core . search . JavaWorkspaceScope ; import org . eclipse . jdt . internal . core . search . indexing . IndexManager ; import org . eclipse . jdt . internal . core . util . Messages ; import org . eclipse . jdt . internal . core . util . Util ; public class DeltaProcessor { static class OutputsInfo { int outputCount ; IPath [ ] paths ; int [ ] traverseModes ; OutputsInfo ( IPath [ ] paths , int [ ] traverseModes , int outputCount ) { this . paths = paths ; this . traverseModes = traverseModes ; this . outputCount = outputCount ; } public String toString ( ) { if ( this . paths == null ) return "<none>" ; StringBuffer buffer = new StringBuffer ( ) ; for ( int i = 0 ; i < this . outputCount ; i ++ ) { buffer . append ( "path=" ) ; buffer . append ( this . paths [ i ] . toString ( ) ) ; buffer . append ( "n->traverse=" ) ; switch ( this . traverseModes [ i ] ) { case BINARY : buffer . append ( "BINARY" ) ; break ; case IGNORE : buffer . append ( "IGNORE" ) ; break ; case SOURCE : buffer . append ( "SOURCE" ) ; break ; default : buffer . append ( "<unknown>" ) ; } if ( i + 1 < this . outputCount ) { buffer . append ( '\n' ) ; } } return buffer . toString ( ) ; } } public static class RootInfo { char [ ] [ ] inclusionPatterns ; char [ ] [ ] exclusionPatterns ; public JavaProject project ; IPath rootPath ; int entryKind ; IPackageFragmentRoot root ; IPackageFragmentRoot cache ; RootInfo ( JavaProject project , IPath rootPath , char [ ] [ ] inclusionPatterns , char [ ] [ ] exclusionPatterns , int entryKind ) { this . project = project ; this . rootPath = rootPath ; this . inclusionPatterns = inclusionPatterns ; this . exclusionPatterns = exclusionPatterns ; this . entryKind = entryKind ; this . cache = getPackageFragmentRoot ( ) ; } public IPackageFragmentRoot getPackageFragmentRoot ( ) { IPackageFragmentRoot tRoot = null ; Object target = JavaModel . getTarget ( this . rootPath , false ) ; if ( target instanceof IResource ) { tRoot = this . project . getPackageFragmentRoot ( ( IResource ) target ) ; } else { tRoot = this . project . getPackageFragmentRoot ( this . rootPath . toOSString ( ) ) ; } return tRoot ; } public IPackageFragmentRoot getPackageFragmentRoot ( IResource resource ) { if ( this . root == null ) { if ( resource != null ) { this . root = this . project . getPackageFragmentRoot ( resource ) ; } else { this . root = getPackageFragmentRoot ( ) ; } } if ( this . root != null ) this . cache = this . root ; return this . root ; } boolean isRootOfProject ( IPath path ) { return this . rootPath . equals ( path ) && this . project . getProject ( ) . getFullPath ( ) . isPrefixOf ( path ) ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( "project=" ) ; if ( this . project == null ) { buffer . append ( "null" ) ; } else { buffer . append ( this . project . getElementName ( ) ) ; } buffer . append ( "npath=" ) ; if ( this . rootPath == null ) { buffer . append ( "null" ) ; } else { buffer . append ( this . rootPath . toString ( ) ) ; } buffer . append ( "nincluding=" ) ; if ( this . inclusionPatterns == null ) { buffer . append ( "null" ) ; } else { for ( int i = 0 , length = this . inclusionPatterns . length ; i < length ; i ++ ) { buffer . append ( new String ( this . inclusionPatterns [ i ] ) ) ; if ( i < length - 1 ) { buffer . append ( "|" ) ; } } } buffer . append ( "nexcluding=" ) ; if ( this . exclusionPatterns == null ) { buffer . append ( "null" ) ; } else { for ( int i = 0 , length = this . exclusionPatterns . length ; i < length ; i ++ ) { buffer . append ( new String ( this . exclusionPatterns [ i ] ) ) ; if ( i < length - 1 ) { buffer . append ( "|" ) ; } } } return buffer . toString ( ) ; } } private final static int IGNORE = 0 ; private final static int SOURCE = 1 ; private final static int BINARY = 2 ; private final static String EXTERNAL_JAR_ADDED = "" ; private final static String EXTERNAL_JAR_CHANGED = "" ; private final static String EXTERNAL_JAR_REMOVED = "" ; private final static String EXTERNAL_JAR_UNCHANGED = "" ; private final static String INTERNAL_JAR_IGNORE = "" ; private final static int NON_JAVA_RESOURCE = - 1 ; public static boolean DEBUG = false ; public static boolean VERBOSE = false ; public static boolean PERF = false ; public static final int DEFAULT_CHANGE_EVENT = 0 ; public static long getTimeStamp ( File file ) { return file . lastModified ( ) + file . length ( ) ; } private DeltaProcessingState state ; JavaModelManager manager ; private JavaElementDelta currentDelta ; private Openable currentElement ; public ArrayList javaModelDeltas = new ArrayList ( ) ; public HashMap reconcileDeltas = new HashMap ( ) ; private boolean isFiring = true ; private final ModelUpdater modelUpdater = new ModelUpdater ( ) ; public HashSet projectCachesToReset = new HashSet ( ) ; public Map oldRoots ; public int overridenEventType = - 1 ; private SourceElementParser sourceElementParserCache ; public DeltaProcessor ( DeltaProcessingState state , JavaModelManager manager ) { this . state = state ; this . manager = manager ; } private void addDependentProjects ( IJavaProject project , HashMap projectDependencies , HashSet result ) { IJavaProject [ ] dependents = ( IJavaProject [ ] ) projectDependencies . get ( project ) ; if ( dependents == null ) return ; for ( int i = 0 , length = dependents . length ; i < length ; i ++ ) { IJavaProject dependent = dependents [ i ] ; if ( result . contains ( dependent ) ) continue ; result . add ( dependent ) ; addDependentProjects ( dependent , projectDependencies , result ) ; } } private void addToParentInfo ( Openable child ) { Openable parent = ( Openable ) child . getParent ( ) ; if ( parent != null && parent . isOpen ( ) ) { try { OpenableElementInfo info = ( OpenableElementInfo ) parent . getElementInfo ( ) ; if ( child instanceof IPackageFragmentRoot ) addPackageFragmentRoot ( info , ( IPackageFragmentRoot ) child ) ; else info . addChild ( child ) ; } catch ( JavaModelException e ) { } } } private void addPackageFragmentRoot ( OpenableElementInfo parent , IPackageFragmentRoot child ) throws JavaModelException { IJavaElement [ ] roots = parent . getChildren ( ) ; if ( roots . length > 0 ) { IClasspathEntry [ ] resolvedClasspath = ( ( JavaProject ) child . getJavaProject ( ) ) . getResolvedClasspath ( ) ; IPath currentEntryPath = child . getResolvedClasspathEntry ( ) . getPath ( ) ; int indexToInsert = - 1 ; int lastComparedIndex = - 1 ; int i = 0 , j = 0 ; for ( ; i < roots . length && j < resolvedClasspath . length ; ) { IClasspathEntry classpathEntry = resolvedClasspath [ j ] ; if ( lastComparedIndex != j && currentEntryPath . equals ( classpathEntry . getPath ( ) ) ) { indexToInsert = i ; break ; } lastComparedIndex = j ; IClasspathEntry rootEntry = ( ( IPackageFragmentRoot ) roots [ i ] ) . getResolvedClasspathEntry ( ) ; if ( rootEntry . getPath ( ) . equals ( classpathEntry . getPath ( ) ) ) i ++ ; else j ++ ; } for ( ; i < roots . length ; i ++ ) { if ( roots [ i ] . equals ( child ) ) { return ; } if ( ! ( ( IPackageFragmentRoot ) roots [ i ] ) . getResolvedClasspathEntry ( ) . getPath ( ) . equals ( currentEntryPath ) ) break ; } if ( indexToInsert >= 0 ) { int newSize = roots . length + 1 ; IPackageFragmentRoot [ ] newChildren = new IPackageFragmentRoot [ newSize ] ; if ( indexToInsert > 0 ) System . arraycopy ( roots , 0 , newChildren , 0 , indexToInsert ) ; newChildren [ indexToInsert ] = child ; System . arraycopy ( roots , indexToInsert , newChildren , indexToInsert + 1 , ( newSize - indexToInsert - 1 ) ) ; parent . setChildren ( newChildren ) ; return ; } } parent . addChild ( child ) ; } private void checkProjectsAndClasspathChanges ( IResourceDelta delta ) { IResource resource = delta . getResource ( ) ; IResourceDelta [ ] children = null ; switch ( resource . getType ( ) ) { case IResource . ROOT : this . state . getOldJavaProjecNames ( ) ; children = delta . getAffectedChildren ( ) ; break ; case IResource . PROJECT : IProject project = ( IProject ) resource ; JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : this . manager . forceBatchInitializations ( false ) ; this . projectCachesToReset . add ( javaProject ) ; if ( JavaProject . hasJavaNature ( project ) ) { addToParentInfo ( javaProject ) ; readRawClasspath ( javaProject ) ; checkProjectReferenceChange ( project , javaProject ) ; checkExternalFolderChange ( project , javaProject ) ; } this . state . rootsAreStale = true ; break ; case IResourceDelta . CHANGED : if ( ( delta . getFlags ( ) & IResourceDelta . OPEN ) != 0 ) { this . manager . forceBatchInitializations ( false ) ; this . projectCachesToReset . add ( javaProject ) ; if ( project . isOpen ( ) ) { if ( JavaProject . hasJavaNature ( project ) ) { addToParentInfo ( javaProject ) ; readRawClasspath ( javaProject ) ; checkProjectReferenceChange ( project , javaProject ) ; checkExternalFolderChange ( project , javaProject ) ; } } else { try { javaProject . close ( ) ; } catch ( JavaModelException e ) { } removeFromParentInfo ( javaProject ) ; this . manager . removePerProjectInfo ( javaProject , false ) ; this . manager . containerRemove ( javaProject ) ; } this . state . rootsAreStale = true ; } else if ( ( delta . getFlags ( ) & IResourceDelta . DESCRIPTION ) != 0 ) { boolean wasJavaProject = this . state . findJavaProject ( project . getName ( ) ) != null ; boolean isJavaProject = JavaProject . hasJavaNature ( project ) ; if ( wasJavaProject != isJavaProject ) { this . manager . forceBatchInitializations ( false ) ; this . projectCachesToReset . add ( javaProject ) ; if ( isJavaProject ) { addToParentInfo ( javaProject ) ; readRawClasspath ( javaProject ) ; checkProjectReferenceChange ( project , javaProject ) ; checkExternalFolderChange ( project , javaProject ) ; } else { this . manager . removePerProjectInfo ( javaProject , true ) ; this . manager . containerRemove ( javaProject ) ; try { javaProject . close ( ) ; } catch ( JavaModelException e ) { } removeFromParentInfo ( javaProject ) ; } this . state . rootsAreStale = true ; } else { if ( isJavaProject ) { addToParentInfo ( javaProject ) ; children = delta . getAffectedChildren ( ) ; } } } else { if ( JavaProject . hasJavaNature ( project ) ) { addToParentInfo ( javaProject ) ; children = delta . getAffectedChildren ( ) ; } } break ; case IResourceDelta . REMOVED : this . manager . forceBatchInitializations ( false ) ; this . manager . removePerProjectInfo ( javaProject , true ) ; this . manager . containerRemove ( javaProject ) ; this . state . rootsAreStale = true ; break ; } break ; case IResource . FOLDER : if ( delta . getKind ( ) == IResourceDelta . CHANGED ) { children = delta . getAffectedChildren ( ) ; } break ; case IResource . FILE : IFile file = ( IFile ) resource ; int kind = delta . getKind ( ) ; RootInfo rootInfo ; if ( file . getName ( ) . equals ( JavaProject . CLASSPATH_FILENAME ) ) { this . manager . forceBatchInitializations ( false ) ; switch ( kind ) { case IResourceDelta . CHANGED : int flags = delta . getFlags ( ) ; if ( ( flags & IResourceDelta . CONTENT ) == 0 && ( flags & IResourceDelta . ENCODING ) == 0 && ( flags & IResourceDelta . MOVED_FROM ) == 0 ) { break ; } case IResourceDelta . ADDED : case IResourceDelta . REMOVED : javaProject = ( JavaProject ) JavaCore . create ( file . getProject ( ) ) ; readRawClasspath ( javaProject ) ; break ; } this . state . rootsAreStale = true ; } else if ( ( rootInfo = rootInfo ( file . getFullPath ( ) , kind ) ) != null && rootInfo . entryKind == IClasspathEntry . CPE_LIBRARY ) { javaProject = ( JavaProject ) JavaCore . create ( file . getProject ( ) ) ; javaProject . resetResolvedClasspath ( ) ; this . state . rootsAreStale = true ; } break ; } if ( children != null ) { for ( int i = 0 ; i < children . length ; i ++ ) { checkProjectsAndClasspathChanges ( children [ i ] ) ; } } } private void checkExternalFolderChange ( IProject project , JavaProject javaProject ) { ClasspathChange change = this . state . getClasspathChange ( project ) ; this . state . addExternalFolderChange ( javaProject , change == null ? null : change . oldResolvedClasspath ) ; } private void checkProjectReferenceChange ( IProject project , JavaProject javaProject ) { ClasspathChange change = this . state . getClasspathChange ( project ) ; this . state . addProjectReferenceChange ( javaProject , change == null ? null : change . oldResolvedClasspath ) ; } private void readRawClasspath ( JavaProject javaProject ) { try { PerProjectInfo perProjectInfo = javaProject . getPerProjectInfo ( ) ; if ( ! perProjectInfo . writtingRawClasspath ) perProjectInfo . readAndCacheClasspath ( javaProject ) ; } catch ( JavaModelException e ) { if ( VERBOSE ) { e . printStackTrace ( ) ; } } } private void checkSourceAttachmentChange ( IResourceDelta delta , IResource res ) { IPath rootPath = ( IPath ) this . state . sourceAttachments . get ( externalPath ( res ) ) ; if ( rootPath != null ) { RootInfo rootInfo = rootInfo ( rootPath , delta . getKind ( ) ) ; if ( rootInfo != null ) { IJavaProject projectOfRoot = rootInfo . project ; IPackageFragmentRoot root = null ; try { root = projectOfRoot . findPackageFragmentRoot ( rootPath ) ; if ( root != null ) { root . close ( ) ; } } catch ( JavaModelException e ) { } if ( root == null ) return ; switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : currentDelta ( ) . sourceAttached ( root ) ; break ; case IResourceDelta . CHANGED : currentDelta ( ) . sourceDetached ( root ) ; currentDelta ( ) . sourceAttached ( root ) ; break ; case IResourceDelta . REMOVED : currentDelta ( ) . sourceDetached ( root ) ; break ; } } } } private void close ( Openable element ) { try { element . close ( ) ; } catch ( JavaModelException e ) { } } private void contentChanged ( Openable element ) { boolean isPrimary = false ; boolean isPrimaryWorkingCopy = false ; if ( element . getElementType ( ) == IJavaElement . COMPILATION_UNIT ) { CompilationUnit cu = ( CompilationUnit ) element ; isPrimary = cu . isPrimary ( ) ; isPrimaryWorkingCopy = isPrimary && cu . isWorkingCopy ( ) ; } if ( isPrimaryWorkingCopy ) { currentDelta ( ) . changed ( element , IJavaElementDelta . F_PRIMARY_RESOURCE ) ; } else { close ( element ) ; int flags = IJavaElementDelta . F_CONTENT ; if ( element instanceof JarPackageFragmentRoot ) { flags |= IJavaElementDelta . F_ARCHIVE_CONTENT_CHANGED ; this . projectCachesToReset . add ( element . getJavaProject ( ) ) ; } if ( isPrimary ) { flags |= IJavaElementDelta . F_PRIMARY_RESOURCE ; } currentDelta ( ) . changed ( element , flags ) ; } } private Openable createElement ( IResource resource , int elementType , RootInfo rootInfo ) { if ( resource == null ) return null ; IPath path = resource . getFullPath ( ) ; IJavaElement element = null ; switch ( elementType ) { case IJavaElement . JAVA_PROJECT : if ( resource instanceof IProject ) { popUntilPrefixOf ( path ) ; if ( this . currentElement != null && this . currentElement . getElementType ( ) == IJavaElement . JAVA_PROJECT && ( ( IJavaProject ) this . currentElement ) . getProject ( ) . equals ( resource ) ) { return this . currentElement ; } if ( rootInfo != null && rootInfo . project . getProject ( ) . equals ( resource ) ) { element = rootInfo . project ; break ; } IProject proj = ( IProject ) resource ; if ( JavaProject . hasJavaNature ( proj ) ) { element = JavaCore . create ( proj ) ; } else { element = this . state . findJavaProject ( proj . getName ( ) ) ; } } break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : element = rootInfo == null ? JavaCore . create ( resource ) : rootInfo . getPackageFragmentRoot ( resource ) ; break ; case IJavaElement . PACKAGE_FRAGMENT : if ( rootInfo != null ) { if ( rootInfo . project . contains ( resource ) ) { PackageFragmentRoot root = ( PackageFragmentRoot ) rootInfo . getPackageFragmentRoot ( null ) ; IPath pkgPath = path . removeFirstSegments ( root . resource ( ) . getFullPath ( ) . segmentCount ( ) ) ; String [ ] pkgName = pkgPath . segments ( ) ; element = root . getPackageFragment ( pkgName ) ; } } else { popUntilPrefixOf ( path ) ; if ( this . currentElement == null ) { element = JavaCore . create ( resource ) ; } else { PackageFragmentRoot root = this . currentElement . getPackageFragmentRoot ( ) ; if ( root == null ) { element = JavaCore . create ( resource ) ; } else if ( ( ( JavaProject ) root . getJavaProject ( ) ) . contains ( resource ) ) { IPath pkgPath = path . removeFirstSegments ( root . getPath ( ) . segmentCount ( ) ) ; String [ ] pkgName = pkgPath . segments ( ) ; element = root . getPackageFragment ( pkgName ) ; } } } break ; case IJavaElement . COMPILATION_UNIT : case IJavaElement . CLASS_FILE : popUntilPrefixOf ( path ) ; if ( this . currentElement == null ) { element = rootInfo == null ? JavaCore . create ( resource ) : JavaModelManager . create ( resource , rootInfo . project ) ; } else { IPackageFragment pkgFragment = null ; switch ( this . currentElement . getElementType ( ) ) { case IJavaElement . PACKAGE_FRAGMENT_ROOT : PackageFragmentRoot root = ( PackageFragmentRoot ) this . currentElement ; IPath rootPath = root . getPath ( ) ; IPath pkgPath = path . removeLastSegments ( 1 ) ; String [ ] pkgName = pkgPath . removeFirstSegments ( rootPath . segmentCount ( ) ) . segments ( ) ; pkgFragment = root . getPackageFragment ( pkgName ) ; break ; case IJavaElement . PACKAGE_FRAGMENT : Openable pkg = this . currentElement ; if ( pkg . getPath ( ) . equals ( path . removeLastSegments ( 1 ) ) ) { pkgFragment = ( IPackageFragment ) pkg ; } break ; case IJavaElement . COMPILATION_UNIT : case IJavaElement . CLASS_FILE : pkgFragment = ( IPackageFragment ) this . currentElement . getParent ( ) ; break ; } if ( pkgFragment == null ) { element = rootInfo == null ? JavaCore . create ( resource ) : JavaModelManager . create ( resource , rootInfo . project ) ; } else { if ( elementType == IJavaElement . COMPILATION_UNIT ) { String fileName = path . lastSegment ( ) ; element = pkgFragment . getCompilationUnit ( fileName ) ; } else { String fileName = path . lastSegment ( ) ; element = pkgFragment . getClassFile ( fileName ) ; } } } break ; } if ( element == null ) return null ; this . currentElement = ( Openable ) element ; return this . currentElement ; } public void checkExternalArchiveChanges ( IJavaElement [ ] elementsScope , IProgressMonitor monitor ) throws JavaModelException { checkExternalArchiveChanges ( elementsScope , false , monitor ) ; } private void checkExternalArchiveChanges ( IJavaElement [ ] elementsScope , boolean asynchronous , IProgressMonitor monitor ) throws JavaModelException { if ( monitor != null && monitor . isCanceled ( ) ) throw new OperationCanceledException ( ) ; try { if ( monitor != null ) monitor . beginTask ( "" , 1 ) ; boolean hasExternalWorkingCopyProject = false ; for ( int i = 0 , length = elementsScope . length ; i < length ; i ++ ) { IJavaElement element = elementsScope [ i ] ; this . state . addForRefresh ( elementsScope [ i ] ) ; if ( element . getElementType ( ) == IJavaElement . JAVA_MODEL ) { HashSet projects = JavaModelManager . getJavaModelManager ( ) . getExternalWorkingCopyProjects ( ) ; if ( projects != null ) { hasExternalWorkingCopyProject = true ; Iterator iterator = projects . iterator ( ) ; while ( iterator . hasNext ( ) ) { JavaProject project = ( JavaProject ) iterator . next ( ) ; project . resetCaches ( ) ; } } } } HashSet elementsToRefresh = this . state . removeExternalElementsToRefresh ( ) ; boolean hasDelta = elementsToRefresh != null && createExternalArchiveDelta ( elementsToRefresh , monitor ) ; if ( hasDelta ) { IJavaElementDelta [ ] projectDeltas = this . currentDelta . getAffectedChildren ( ) ; final int length = projectDeltas . length ; final IProject [ ] projectsToTouch = new IProject [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { IJavaElementDelta delta = projectDeltas [ i ] ; JavaProject javaProject = ( JavaProject ) delta . getElement ( ) ; projectsToTouch [ i ] = javaProject . getProject ( ) ; } if ( projectsToTouch . length > 0 ) { if ( asynchronous ) { WorkspaceJob touchJob = new WorkspaceJob ( Messages . updating_external_archives_jobName ) { public IStatus runInWorkspace ( IProgressMonitor progressMonitor ) throws CoreException { try { if ( progressMonitor != null ) progressMonitor . beginTask ( "" , projectsToTouch . length ) ; touchProjects ( projectsToTouch , progressMonitor ) ; } finally { if ( progressMonitor != null ) progressMonitor . done ( ) ; } return Status . OK_STATUS ; } public boolean belongsTo ( Object family ) { return ResourcesPlugin . FAMILY_MANUAL_REFRESH == family ; } } ; touchJob . schedule ( ) ; } else { IWorkspaceRunnable runnable = new IWorkspaceRunnable ( ) { public void run ( IProgressMonitor progressMonitor ) throws CoreException { for ( int i = 0 ; i < projectsToTouch . length ; i ++ ) { IProject project = projectsToTouch [ i ] ; if ( JavaBuilder . DEBUG ) System . out . println ( "" + project . getName ( ) + "" ) ; project . touch ( progressMonitor ) ; } } } ; try { ResourcesPlugin . getWorkspace ( ) . run ( runnable , monitor ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } } if ( this . currentDelta != null ) { fire ( this . currentDelta , DEFAULT_CHANGE_EVENT ) ; } } else if ( hasExternalWorkingCopyProject ) { JavaModelManager . getJavaModelManager ( ) . resetJarTypeCache ( ) ; } } finally { this . currentDelta = null ; if ( monitor != null ) monitor . done ( ) ; } } protected void touchProjects ( final IProject [ ] projectsToTouch , IProgressMonitor progressMonitor ) throws CoreException { for ( int i = 0 ; i < projectsToTouch . length ; i ++ ) { IProgressMonitor monitor = progressMonitor == null ? null : new SubProgressMonitor ( progressMonitor , 1 ) ; IProject project = projectsToTouch [ i ] ; if ( JavaBuilder . DEBUG ) System . out . println ( "" + project . getName ( ) + "" ) ; project . touch ( monitor ) ; } } private boolean createExternalArchiveDelta ( HashSet refreshedElements , IProgressMonitor monitor ) { HashMap externalArchivesStatus = new HashMap ( ) ; boolean hasDelta = false ; HashSet archivePathsToRefresh = new HashSet ( ) ; Iterator iterator = refreshedElements . iterator ( ) ; while ( iterator . hasNext ( ) ) { IJavaElement element = ( IJavaElement ) iterator . next ( ) ; switch ( element . getElementType ( ) ) { case IJavaElement . PACKAGE_FRAGMENT_ROOT : archivePathsToRefresh . add ( element . getPath ( ) ) ; break ; case IJavaElement . JAVA_PROJECT : JavaProject javaProject = ( JavaProject ) element ; if ( ! JavaProject . hasJavaNature ( javaProject . getProject ( ) ) ) { break ; } IClasspathEntry [ ] classpath ; try { classpath = javaProject . getResolvedClasspath ( ) ; for ( int j = 0 , cpLength = classpath . length ; j < cpLength ; j ++ ) { if ( classpath [ j ] . getEntryKind ( ) == IClasspathEntry . CPE_LIBRARY ) { archivePathsToRefresh . add ( classpath [ j ] . getPath ( ) ) ; } } } catch ( JavaModelException e ) { } break ; case IJavaElement . JAVA_MODEL : Iterator projectNames = this . state . getOldJavaProjecNames ( ) . iterator ( ) ; while ( projectNames . hasNext ( ) ) { String projectName = ( String ) projectNames . next ( ) ; IProject project = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) . getProject ( projectName ) ; if ( ! JavaProject . hasJavaNature ( project ) ) { continue ; } javaProject = ( JavaProject ) JavaCore . create ( project ) ; try { classpath = javaProject . getResolvedClasspath ( ) ; for ( int k = 0 , cpLength = classpath . length ; k < cpLength ; k ++ ) { if ( classpath [ k ] . getEntryKind ( ) == IClasspathEntry . CPE_LIBRARY ) { archivePathsToRefresh . add ( classpath [ k ] . getPath ( ) ) ; } } } catch ( JavaModelException e2 ) { continue ; } } break ; } } Iterator projectNames = this . state . getOldJavaProjecNames ( ) . iterator ( ) ; IWorkspaceRoot wksRoot = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; while ( projectNames . hasNext ( ) ) { if ( monitor != null && monitor . isCanceled ( ) ) break ; String projectName = ( String ) projectNames . next ( ) ; IProject project = wksRoot . getProject ( projectName ) ; if ( ! JavaProject . hasJavaNature ( project ) ) { continue ; } JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; IClasspathEntry [ ] entries ; try { entries = javaProject . getResolvedClasspath ( ) ; } catch ( JavaModelException e1 ) { continue ; } for ( int j = 0 ; j < entries . length ; j ++ ) { if ( entries [ j ] . getEntryKind ( ) == IClasspathEntry . CPE_LIBRARY ) { IPath entryPath = entries [ j ] . getPath ( ) ; if ( ! archivePathsToRefresh . contains ( entryPath ) ) continue ; String status = ( String ) externalArchivesStatus . get ( entryPath ) ; if ( status == null ) { Object targetLibrary = JavaModel . getTarget ( entryPath , true ) ; if ( targetLibrary == null ) { if ( this . state . getExternalLibTimeStamps ( ) . remove ( entryPath ) != null && this . state . roots . get ( entryPath ) != null ) { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_REMOVED ) ; this . manager . indexManager . removeIndex ( entryPath ) ; } } else if ( targetLibrary instanceof File ) { File externalFile = ( File ) targetLibrary ; Long oldTimestamp = ( Long ) this . state . getExternalLibTimeStamps ( ) . get ( entryPath ) ; long newTimeStamp = getTimeStamp ( externalFile ) ; if ( oldTimestamp != null ) { if ( newTimeStamp == 0 ) { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_REMOVED ) ; this . state . getExternalLibTimeStamps ( ) . remove ( entryPath ) ; this . manager . indexManager . removeIndex ( entryPath ) ; } else if ( oldTimestamp . longValue ( ) != newTimeStamp ) { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_CHANGED ) ; this . state . getExternalLibTimeStamps ( ) . put ( entryPath , new Long ( newTimeStamp ) ) ; this . manager . indexManager . removeIndex ( entryPath ) ; this . manager . indexManager . indexLibrary ( entryPath , project . getProject ( ) ) ; } else { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_UNCHANGED ) ; } } else { if ( newTimeStamp == 0 ) { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_UNCHANGED ) ; } else { externalArchivesStatus . put ( entryPath , EXTERNAL_JAR_ADDED ) ; this . state . getExternalLibTimeStamps ( ) . put ( entryPath , new Long ( newTimeStamp ) ) ; this . manager . indexManager . removeIndex ( entryPath ) ; this . manager . indexManager . indexLibrary ( entryPath , project . getProject ( ) ) ; } } } else { externalArchivesStatus . put ( entryPath , INTERNAL_JAR_IGNORE ) ; } } status = ( String ) externalArchivesStatus . get ( entryPath ) ; if ( status != null ) { if ( status == EXTERNAL_JAR_ADDED ) { PackageFragmentRoot root = ( PackageFragmentRoot ) javaProject . getPackageFragmentRoot ( entryPath . toString ( ) ) ; if ( VERBOSE ) { System . out . println ( "" + root . getElementName ( ) ) ; } elementAdded ( root , null , null ) ; javaProject . resetResolvedClasspath ( ) ; this . state . addClasspathValidation ( javaProject ) ; hasDelta = true ; } else if ( status == EXTERNAL_JAR_CHANGED ) { PackageFragmentRoot root = ( PackageFragmentRoot ) javaProject . getPackageFragmentRoot ( entryPath . toString ( ) ) ; if ( VERBOSE ) { System . out . println ( "" + root . getElementName ( ) ) ; } contentChanged ( root ) ; javaProject . resetResolvedClasspath ( ) ; hasDelta = true ; } else if ( status == EXTERNAL_JAR_REMOVED ) { PackageFragmentRoot root = ( PackageFragmentRoot ) javaProject . getPackageFragmentRoot ( entryPath . toString ( ) ) ; if ( VERBOSE ) { System . out . println ( "" + root . getElementName ( ) ) ; } elementRemoved ( root , null , null ) ; javaProject . resetResolvedClasspath ( ) ; this . state . addClasspathValidation ( javaProject ) ; hasDelta = true ; } } } } } JavaModel . flushExternalFileCache ( ) ; if ( hasDelta ) { JavaModelManager . getJavaModelManager ( ) . resetJarTypeCache ( ) ; } return hasDelta ; } private JavaElementDelta currentDelta ( ) { if ( this . currentDelta == null ) { this . currentDelta = new JavaElementDelta ( this . manager . getJavaModel ( ) ) ; } return this . currentDelta ; } private void deleting ( IProject project ) { try { this . manager . indexManager . discardJobs ( project . getName ( ) ) ; JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; if ( this . oldRoots == null ) { this . oldRoots = new HashMap ( ) ; } if ( javaProject . isOpen ( ) ) { this . oldRoots . put ( javaProject , javaProject . getPackageFragmentRoots ( ) ) ; } else { this . oldRoots . put ( javaProject , javaProject . computePackageFragmentRoots ( javaProject . getResolvedClasspath ( ) , false , null ) ) ; } javaProject . close ( ) ; this . state . getOldJavaProjecNames ( ) ; removeFromParentInfo ( javaProject ) ; this . manager . resetProjectPreferences ( javaProject ) ; } catch ( JavaModelException e ) { } } private void elementAdded ( Openable element , IResourceDelta delta , RootInfo rootInfo ) { int elementType = element . getElementType ( ) ; if ( elementType == IJavaElement . JAVA_PROJECT ) { IProject project ; if ( delta != null && JavaProject . hasJavaNature ( project = ( IProject ) delta . getResource ( ) ) ) { addToParentInfo ( element ) ; this . manager . getPerProjectInfo ( project , true ) . rememberExternalLibTimestamps ( ) ; if ( ( delta . getFlags ( ) & IResourceDelta . MOVED_FROM ) != 0 ) { Openable movedFromElement = ( Openable ) element . getJavaModel ( ) . getJavaProject ( delta . getMovedFromPath ( ) . lastSegment ( ) ) ; currentDelta ( ) . movedTo ( element , movedFromElement ) ; } else { close ( element ) ; currentDelta ( ) . added ( element ) ; } this . state . updateRoots ( element . getPath ( ) , delta , this ) ; this . projectCachesToReset . add ( element ) ; } } else { if ( delta == null || ( delta . getFlags ( ) & IResourceDelta . MOVED_FROM ) == 0 ) { if ( isPrimaryWorkingCopy ( element , elementType ) ) { currentDelta ( ) . changed ( element , IJavaElementDelta . F_PRIMARY_RESOURCE ) ; } else { addToParentInfo ( element ) ; close ( element ) ; currentDelta ( ) . added ( element ) ; } } else { addToParentInfo ( element ) ; close ( element ) ; IPath movedFromPath = delta . getMovedFromPath ( ) ; IResource res = delta . getResource ( ) ; IResource movedFromRes ; if ( res instanceof IFile ) { movedFromRes = res . getWorkspace ( ) . getRoot ( ) . getFile ( movedFromPath ) ; } else { movedFromRes = res . getWorkspace ( ) . getRoot ( ) . getFolder ( movedFromPath ) ; } IPath rootPath = externalPath ( movedFromRes ) ; RootInfo movedFromInfo = enclosingRootInfo ( rootPath , IResourceDelta . REMOVED ) ; int movedFromType = elementType ( movedFromRes , IResourceDelta . REMOVED , element . getParent ( ) . getElementType ( ) , movedFromInfo ) ; this . currentElement = null ; Openable movedFromElement = elementType != IJavaElement . JAVA_PROJECT && movedFromType == IJavaElement . JAVA_PROJECT ? null : createElement ( movedFromRes , movedFromType , movedFromInfo ) ; if ( movedFromElement == null ) { currentDelta ( ) . added ( element ) ; } else { currentDelta ( ) . movedTo ( element , movedFromElement ) ; } } switch ( elementType ) { case IJavaElement . PACKAGE_FRAGMENT_ROOT : JavaProject project = ( JavaProject ) element . getJavaProject ( ) ; this . projectCachesToReset . add ( project ) ; break ; case IJavaElement . PACKAGE_FRAGMENT : project = ( JavaProject ) element . getJavaProject ( ) ; this . projectCachesToReset . add ( project ) ; break ; } } } private void elementRemoved ( Openable element , IResourceDelta delta , RootInfo rootInfo ) { int elementType = element . getElementType ( ) ; if ( delta == null || ( delta . getFlags ( ) & IResourceDelta . MOVED_TO ) == 0 ) { if ( isPrimaryWorkingCopy ( element , elementType ) ) { currentDelta ( ) . changed ( element , IJavaElementDelta . F_PRIMARY_RESOURCE ) ; } else { close ( element ) ; removeFromParentInfo ( element ) ; currentDelta ( ) . removed ( element ) ; } } else { close ( element ) ; removeFromParentInfo ( element ) ; IPath movedToPath = delta . getMovedToPath ( ) ; IResource res = delta . getResource ( ) ; IResource movedToRes ; switch ( res . getType ( ) ) { case IResource . PROJECT : movedToRes = res . getWorkspace ( ) . getRoot ( ) . getProject ( movedToPath . lastSegment ( ) ) ; break ; case IResource . FOLDER : movedToRes = res . getWorkspace ( ) . getRoot ( ) . getFolder ( movedToPath ) ; break ; case IResource . FILE : movedToRes = res . getWorkspace ( ) . getRoot ( ) . getFile ( movedToPath ) ; break ; default : return ; } IPath rootPath = externalPath ( movedToRes ) ; RootInfo movedToInfo = enclosingRootInfo ( rootPath , IResourceDelta . ADDED ) ; int movedToType = elementType ( movedToRes , IResourceDelta . ADDED , element . getParent ( ) . getElementType ( ) , movedToInfo ) ; this . currentElement = null ; Openable movedToElement = elementType != IJavaElement . JAVA_PROJECT && movedToType == IJavaElement . JAVA_PROJECT ? null : createElement ( movedToRes , movedToType , movedToInfo ) ; if ( movedToElement == null ) { currentDelta ( ) . removed ( element ) ; } else { currentDelta ( ) . movedFrom ( element , movedToElement ) ; } } switch ( elementType ) { case IJavaElement . JAVA_MODEL : this . manager . indexManager . reset ( ) ; break ; case IJavaElement . JAVA_PROJECT : this . state . updateRoots ( element . getPath ( ) , delta , this ) ; this . projectCachesToReset . add ( element ) ; break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : JavaProject project = ( JavaProject ) element . getJavaProject ( ) ; this . projectCachesToReset . add ( project ) ; break ; case IJavaElement . PACKAGE_FRAGMENT : project = ( JavaProject ) element . getJavaProject ( ) ; this . projectCachesToReset . add ( project ) ; break ; } } private int elementType ( IResource res , int kind , int parentType , RootInfo rootInfo ) { switch ( parentType ) { case IJavaElement . JAVA_MODEL : return IJavaElement . JAVA_PROJECT ; case NON_JAVA_RESOURCE : case IJavaElement . JAVA_PROJECT : if ( rootInfo == null ) { rootInfo = enclosingRootInfo ( res . getFullPath ( ) , kind ) ; } if ( rootInfo != null && rootInfo . isRootOfProject ( res . getFullPath ( ) ) ) { return IJavaElement . PACKAGE_FRAGMENT_ROOT ; } case IJavaElement . PACKAGE_FRAGMENT_ROOT : case IJavaElement . PACKAGE_FRAGMENT : if ( rootInfo == null ) { IPath rootPath = externalPath ( res ) ; rootInfo = enclosingRootInfo ( rootPath , kind ) ; } if ( rootInfo == null ) { return NON_JAVA_RESOURCE ; } if ( Util . isExcluded ( res , rootInfo . inclusionPatterns , rootInfo . exclusionPatterns ) ) { return NON_JAVA_RESOURCE ; } if ( res . getType ( ) == IResource . FOLDER ) { if ( parentType == NON_JAVA_RESOURCE && ! Util . isExcluded ( res . getParent ( ) , rootInfo . inclusionPatterns , rootInfo . exclusionPatterns ) ) { return NON_JAVA_RESOURCE ; } String sourceLevel = rootInfo . project == null ? null : rootInfo . project . getOption ( JavaCore . COMPILER_SOURCE , true ) ; String complianceLevel = rootInfo . project == null ? null : rootInfo . project . getOption ( JavaCore . COMPILER_COMPLIANCE , true ) ; if ( Util . isValidFolderNameForPackage ( res . getName ( ) , sourceLevel , complianceLevel ) ) { return IJavaElement . PACKAGE_FRAGMENT ; } return NON_JAVA_RESOURCE ; } String fileName = res . getName ( ) ; String sourceLevel = rootInfo . project == null ? null : rootInfo . project . getOption ( JavaCore . COMPILER_SOURCE , true ) ; String complianceLevel = rootInfo . project == null ? null : rootInfo . project . getOption ( JavaCore . COMPILER_COMPLIANCE , true ) ; if ( Util . isValidCompilationUnitName ( fileName , sourceLevel , complianceLevel ) ) { return IJavaElement . COMPILATION_UNIT ; } else if ( Util . isValidClassFileName ( fileName , sourceLevel , complianceLevel ) ) { return IJavaElement . CLASS_FILE ; } else { IPath rootPath = externalPath ( res ) ; if ( ( rootInfo = rootInfo ( rootPath , kind ) ) != null && rootInfo . project . getProject ( ) . getFullPath ( ) . isPrefixOf ( rootPath ) ) { return IJavaElement . PACKAGE_FRAGMENT_ROOT ; } else { return NON_JAVA_RESOURCE ; } } default : return NON_JAVA_RESOURCE ; } } public void flush ( ) { this . javaModelDeltas = new ArrayList ( ) ; } private SourceElementParser getSourceElementParser ( Openable element ) { if ( this . sourceElementParserCache == null ) this . sourceElementParserCache = this . manager . indexManager . getSourceElementParser ( element . getJavaProject ( ) , null ) ; return this . sourceElementParserCache ; } private RootInfo enclosingRootInfo ( IPath path , int kind ) { while ( path != null && path . segmentCount ( ) > 0 ) { RootInfo rootInfo = rootInfo ( path , kind ) ; if ( rootInfo != null ) return rootInfo ; path = path . removeLastSegments ( 1 ) ; } return null ; } private IPath externalPath ( IResource res ) { IPath resourcePath = res . getFullPath ( ) ; if ( ExternalFoldersManager . isInternalPathForExternalFolder ( resourcePath ) ) return res . getLocation ( ) ; return resourcePath ; } public void fire ( IJavaElementDelta customDelta , int eventType ) { if ( ! this . isFiring ) return ; if ( DEBUG ) { System . out . println ( "" ) ; } IJavaElementDelta deltaToNotify ; if ( customDelta == null ) { deltaToNotify = mergeDeltas ( this . javaModelDeltas ) ; } else { deltaToNotify = customDelta ; } if ( deltaToNotify != null ) { Iterator scopes = this . manager . searchScopes . keySet ( ) . iterator ( ) ; while ( scopes . hasNext ( ) ) { AbstractSearchScope scope = ( AbstractSearchScope ) scopes . next ( ) ; scope . processDelta ( deltaToNotify , eventType ) ; } JavaWorkspaceScope workspaceScope = this . manager . workspaceScope ; if ( workspaceScope != null ) workspaceScope . processDelta ( deltaToNotify , eventType ) ; } IElementChangedListener [ ] listeners ; int [ ] listenerMask ; int listenerCount ; synchronized ( this . state ) { listeners = this . state . elementChangedListeners ; listenerMask = this . state . elementChangedListenerMasks ; listenerCount = this . state . elementChangedListenerCount ; } switch ( eventType ) { case DEFAULT_CHANGE_EVENT : case ElementChangedEvent . POST_CHANGE : firePostChangeDelta ( deltaToNotify , listeners , listenerMask , listenerCount ) ; fireReconcileDelta ( listeners , listenerMask , listenerCount ) ; break ; } } private void firePostChangeDelta ( IJavaElementDelta deltaToNotify , IElementChangedListener [ ] listeners , int [ ] listenerMask , int listenerCount ) { if ( DEBUG ) { System . out . println ( "" + Thread . currentThread ( ) + "]:" ) ; System . out . println ( deltaToNotify == null ? "<NONE>" : deltaToNotify . toString ( ) ) ; } if ( deltaToNotify != null ) { flush ( ) ; JavaModelOperation . setAttribute ( JavaModelOperation . HAS_MODIFIED_RESOURCE_ATTR , null ) ; notifyListeners ( deltaToNotify , ElementChangedEvent . POST_CHANGE , listeners , listenerMask , listenerCount ) ; } } private void fireReconcileDelta ( IElementChangedListener [ ] listeners , int [ ] listenerMask , int listenerCount ) { IJavaElementDelta deltaToNotify = mergeDeltas ( this . reconcileDeltas . values ( ) ) ; if ( DEBUG ) { System . out . println ( "" + Thread . currentThread ( ) + "]:" ) ; System . out . println ( deltaToNotify == null ? "<NONE>" : deltaToNotify . toString ( ) ) ; } if ( deltaToNotify != null ) { this . reconcileDeltas = new HashMap ( ) ; notifyListeners ( deltaToNotify , ElementChangedEvent . POST_RECONCILE , listeners , listenerMask , listenerCount ) ; } } private boolean isAffectedBy ( IResourceDelta rootDelta ) { if ( rootDelta != null ) { class FoundRelevantDeltaException extends RuntimeException { private static final long serialVersionUID = 7137113252936111022L ; } try { rootDelta . accept ( new IResourceDeltaVisitor ( ) { public boolean visit ( IResourceDelta delta ) { switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : case IResourceDelta . REMOVED : throw new FoundRelevantDeltaException ( ) ; case IResourceDelta . CHANGED : if ( delta . getAffectedChildren ( ) . length == 0 && ( delta . getFlags ( ) & ~ ( IResourceDelta . SYNC | IResourceDelta . MARKERS ) ) != 0 ) { throw new FoundRelevantDeltaException ( ) ; } } return true ; } } , IContainer . INCLUDE_HIDDEN ) ; } catch ( FoundRelevantDeltaException e ) { return true ; } catch ( CoreException e ) { } } return false ; } private boolean isPrimaryWorkingCopy ( IJavaElement element , int elementType ) { if ( elementType == IJavaElement . COMPILATION_UNIT ) { CompilationUnit cu = ( CompilationUnit ) element ; return cu . isPrimary ( ) && cu . isWorkingCopy ( ) ; } return false ; } private boolean isResFilteredFromOutput ( RootInfo rootInfo , OutputsInfo info , IResource res , int elementType ) { if ( info != null ) { JavaProject javaProject = null ; String sourceLevel = null ; String complianceLevel = null ; IPath resPath = res . getFullPath ( ) ; for ( int i = 0 ; i < info . outputCount ; i ++ ) { if ( info . paths [ i ] . isPrefixOf ( resPath ) ) { if ( info . traverseModes [ i ] != IGNORE ) { if ( info . traverseModes [ i ] == SOURCE && elementType == IJavaElement . CLASS_FILE ) { return true ; } if ( elementType == IJavaElement . JAVA_PROJECT && res instanceof IFile ) { if ( sourceLevel == null ) { javaProject = rootInfo == null ? ( JavaProject ) createElement ( res . getProject ( ) , IJavaElement . JAVA_PROJECT , null ) : rootInfo . project ; if ( javaProject != null ) { sourceLevel = javaProject . getOption ( JavaCore . COMPILER_SOURCE , true ) ; complianceLevel = javaProject . getOption ( JavaCore . COMPILER_COMPLIANCE , true ) ; } } if ( Util . isValidClassFileName ( res . getName ( ) , sourceLevel , complianceLevel ) ) { return true ; } } } else { return true ; } } } } return false ; } private IJavaElementDelta mergeDeltas ( Collection deltas ) { if ( deltas . size ( ) == 0 ) return null ; if ( deltas . size ( ) == 1 ) return ( IJavaElementDelta ) deltas . iterator ( ) . next ( ) ; if ( VERBOSE ) { System . out . println ( "MERGING " + deltas . size ( ) + " DELTAS [" + Thread . currentThread ( ) + "]" ) ; } Iterator iterator = deltas . iterator ( ) ; JavaElementDelta rootDelta = new JavaElementDelta ( this . manager . javaModel ) ; boolean insertedTree = false ; while ( iterator . hasNext ( ) ) { JavaElementDelta delta = ( JavaElementDelta ) iterator . next ( ) ; if ( VERBOSE ) { System . out . println ( delta . toString ( ) ) ; } IJavaElement element = delta . getElement ( ) ; if ( this . manager . javaModel . equals ( element ) ) { IJavaElementDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int j = 0 ; j < children . length ; j ++ ) { JavaElementDelta projectDelta = ( JavaElementDelta ) children [ j ] ; rootDelta . insertDeltaTree ( projectDelta . getElement ( ) , projectDelta ) ; insertedTree = true ; } IResourceDelta [ ] resourceDeltas = delta . getResourceDeltas ( ) ; if ( resourceDeltas != null ) { for ( int i = 0 , length = resourceDeltas . length ; i < length ; i ++ ) { rootDelta . addResourceDelta ( resourceDeltas [ i ] ) ; insertedTree = true ; } } } else { rootDelta . insertDeltaTree ( element , delta ) ; insertedTree = true ; } } if ( insertedTree ) return rootDelta ; return null ; } private void notifyListeners ( IJavaElementDelta deltaToNotify , int eventType , IElementChangedListener [ ] listeners , int [ ] listenerMask , int listenerCount ) { final ElementChangedEvent extraEvent = new ElementChangedEvent ( deltaToNotify , eventType ) ; for ( int i = 0 ; i < listenerCount ; i ++ ) { if ( ( listenerMask [ i ] & eventType ) != 0 ) { final IElementChangedListener listener = listeners [ i ] ; long start = - 1 ; if ( VERBOSE ) { System . out . print ( "Listener #" + ( i + 1 ) + "=" + listener . toString ( ) ) ; start = System . currentTimeMillis ( ) ; } SafeRunner . run ( new ISafeRunnable ( ) { public void handleException ( Throwable exception ) { Util . log ( exception , "" ) ; } public void run ( ) throws Exception { PerformanceStats stats = null ; if ( PERF ) { stats = PerformanceStats . getStats ( JavaModelManager . DELTA_LISTENER_PERF , listener ) ; stats . startRun ( ) ; } listener . elementChanged ( extraEvent ) ; if ( PERF ) { stats . endRun ( ) ; } } } ) ; if ( VERBOSE ) { System . out . println ( " -> " + ( System . currentTimeMillis ( ) - start ) + "ms" ) ; } } } } private void notifyTypeHierarchies ( IElementChangedListener [ ] listeners , int listenerCount ) { for ( int i = 0 ; i < listenerCount ; i ++ ) { final IElementChangedListener listener = listeners [ i ] ; if ( ! ( listener instanceof TypeHierarchy ) ) continue ; SafeRunner . run ( new ISafeRunnable ( ) { public void handleException ( Throwable exception ) { Util . log ( exception , "" ) ; } public void run ( ) throws Exception { TypeHierarchy typeHierarchy = ( TypeHierarchy ) listener ; if ( typeHierarchy . hasFineGrainChanges ( ) ) { typeHierarchy . needsRefresh = true ; typeHierarchy . fireChange ( ) ; } } } ) ; } } private void nonJavaResourcesChanged ( Openable element , IResourceDelta delta ) throws JavaModelException { if ( element . isOpen ( ) ) { JavaElementInfo info = ( JavaElementInfo ) element . getElementInfo ( ) ; switch ( element . getElementType ( ) ) { case IJavaElement . JAVA_MODEL : ( ( JavaModelInfo ) info ) . nonJavaResources = null ; if ( ! ExternalFoldersManager . isInternalPathForExternalFolder ( delta . getFullPath ( ) ) ) currentDelta ( ) . addResourceDelta ( delta ) ; return ; case IJavaElement . JAVA_PROJECT : ( ( JavaProjectElementInfo ) info ) . setNonJavaResources ( null ) ; JavaProject project = ( JavaProject ) element ; PackageFragmentRoot projectRoot = ( PackageFragmentRoot ) project . getPackageFragmentRoot ( project . getProject ( ) ) ; if ( projectRoot . isOpen ( ) ) { ( ( PackageFragmentRootInfo ) projectRoot . getElementInfo ( ) ) . setNonJavaResources ( null ) ; } break ; case IJavaElement . PACKAGE_FRAGMENT : ( ( PackageFragmentInfo ) info ) . setNonJavaResources ( null ) ; break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : ( ( PackageFragmentRootInfo ) info ) . setNonJavaResources ( null ) ; } } JavaElementDelta current = currentDelta ( ) ; JavaElementDelta elementDelta = current . find ( element ) ; if ( elementDelta == null ) { elementDelta = current . changed ( element , IJavaElementDelta . F_CONTENT ) ; } if ( ! ExternalFoldersManager . isInternalPathForExternalFolder ( delta . getFullPath ( ) ) ) elementDelta . addResourceDelta ( delta ) ; } private RootInfo oldRootInfo ( IPath path , JavaProject project ) { RootInfo oldInfo = ( RootInfo ) this . state . oldRoots . get ( path ) ; if ( oldInfo == null ) return null ; if ( oldInfo . project . equals ( project ) ) return oldInfo ; ArrayList oldInfos = ( ArrayList ) this . state . oldOtherRoots . get ( path ) ; if ( oldInfos == null ) return null ; for ( int i = 0 , length = oldInfos . size ( ) ; i < length ; i ++ ) { oldInfo = ( RootInfo ) oldInfos . get ( i ) ; if ( oldInfo . project . equals ( project ) ) return oldInfo ; } return null ; } private ArrayList otherRootsInfo ( IPath path , int kind ) { if ( kind == IResourceDelta . REMOVED ) { return ( ArrayList ) this . state . oldOtherRoots . get ( path ) ; } return ( ArrayList ) this . state . otherRoots . get ( path ) ; } private OutputsInfo outputsInfo ( RootInfo rootInfo , IResource res ) { try { JavaProject proj = rootInfo == null ? ( JavaProject ) createElement ( res . getProject ( ) , IJavaElement . JAVA_PROJECT , null ) : rootInfo . project ; if ( proj != null ) { IPath projectOutput = proj . getOutputLocation ( ) ; int traverseMode = IGNORE ; if ( proj . getProject ( ) . getFullPath ( ) . equals ( projectOutput ) ) { return new OutputsInfo ( new IPath [ ] { projectOutput } , new int [ ] { SOURCE } , 1 ) ; } IClasspathEntry [ ] classpath = proj . getResolvedClasspath ( ) ; IPath [ ] outputs = new IPath [ classpath . length + 1 ] ; int [ ] traverseModes = new int [ classpath . length + 1 ] ; int outputCount = 1 ; outputs [ 0 ] = projectOutput ; traverseModes [ 0 ] = traverseMode ; for ( int i = 0 , length = classpath . length ; i < length ; i ++ ) { IClasspathEntry entry = classpath [ i ] ; IPath entryPath = entry . getPath ( ) ; IPath output = entry . getOutputLocation ( ) ; if ( output != null ) { outputs [ outputCount ] = output ; if ( entryPath . equals ( output ) ) { traverseModes [ outputCount ++ ] = ( entry . getEntryKind ( ) == IClasspathEntry . CPE_SOURCE ) ? SOURCE : BINARY ; } else { traverseModes [ outputCount ++ ] = IGNORE ; } } if ( entryPath . equals ( projectOutput ) ) { traverseModes [ 0 ] = ( entry . getEntryKind ( ) == IClasspathEntry . CPE_SOURCE ) ? SOURCE : BINARY ; } } return new OutputsInfo ( outputs , traverseModes , outputCount ) ; } } catch ( JavaModelException e ) { } return null ; } private void popUntilPrefixOf ( IPath path ) { while ( this . currentElement != null ) { IPath currentElementPath = null ; if ( this . currentElement instanceof IPackageFragmentRoot ) { currentElementPath = ( ( IPackageFragmentRoot ) this . currentElement ) . getPath ( ) ; } else { IResource currentElementResource = this . currentElement . resource ( ) ; if ( currentElementResource != null ) { currentElementPath = currentElementResource . getFullPath ( ) ; } } if ( currentElementPath != null ) { if ( this . currentElement instanceof IPackageFragment && ( ( IPackageFragment ) this . currentElement ) . isDefaultPackage ( ) && currentElementPath . segmentCount ( ) != path . segmentCount ( ) - 1 ) { this . currentElement = ( Openable ) this . currentElement . getParent ( ) ; } if ( currentElementPath . isPrefixOf ( path ) ) { return ; } } this . currentElement = ( Openable ) this . currentElement . getParent ( ) ; } } private IJavaElementDelta processResourceDelta ( IResourceDelta changes ) { try { IJavaModel model = this . manager . getJavaModel ( ) ; if ( ! model . isOpen ( ) ) { try { model . open ( null ) ; } catch ( JavaModelException e ) { if ( VERBOSE ) { e . printStackTrace ( ) ; } return null ; } } this . state . initializeRoots ( false ) ; this . currentElement = null ; IResourceDelta [ ] deltas = changes . getAffectedChildren ( IResourceDelta . ADDED | IResourceDelta . REMOVED | IResourceDelta . CHANGED , IContainer . INCLUDE_HIDDEN ) ; for ( int i = 0 ; i < deltas . length ; i ++ ) { IResourceDelta delta = deltas [ i ] ; IResource res = delta . getResource ( ) ; RootInfo rootInfo = null ; int elementType ; IProject proj = ( IProject ) res ; boolean wasJavaProject = this . state . findJavaProject ( proj . getName ( ) ) != null ; boolean isJavaProject = JavaProject . hasJavaNature ( proj ) ; if ( ! wasJavaProject && ! isJavaProject ) { elementType = NON_JAVA_RESOURCE ; } else { IPath rootPath = externalPath ( res ) ; rootInfo = enclosingRootInfo ( rootPath , delta . getKind ( ) ) ; if ( rootInfo != null && rootInfo . isRootOfProject ( rootPath ) ) { elementType = IJavaElement . PACKAGE_FRAGMENT_ROOT ; } else { elementType = IJavaElement . JAVA_PROJECT ; } } traverseDelta ( delta , elementType , rootInfo , null ) ; if ( elementType == NON_JAVA_RESOURCE || ( wasJavaProject != isJavaProject && ( delta . getKind ( ) ) == IResourceDelta . CHANGED ) ) { try { nonJavaResourcesChanged ( ( JavaModel ) model , delta ) ; } catch ( JavaModelException e ) { } } } resetProjectCaches ( ) ; return this . currentDelta ; } finally { this . currentDelta = null ; } } public void resetProjectCaches ( ) { if ( this . projectCachesToReset . size ( ) == 0 ) return ; JavaModelManager . getJavaModelManager ( ) . resetJarTypeCache ( ) ; Iterator iterator = this . projectCachesToReset . iterator ( ) ; HashMap projectDepencies = this . state . projectDependencies ; HashSet affectedDependents = new HashSet ( ) ; while ( iterator . hasNext ( ) ) { JavaProject project = ( JavaProject ) iterator . next ( ) ; project . resetCaches ( ) ; addDependentProjects ( project , projectDepencies , affectedDependents ) ; } iterator = affectedDependents . iterator ( ) ; while ( iterator . hasNext ( ) ) { JavaProject project = ( JavaProject ) iterator . next ( ) ; project . resetCaches ( ) ; } this . projectCachesToReset . clear ( ) ; } public void registerJavaModelDelta ( IJavaElementDelta delta ) { this . javaModelDeltas . add ( delta ) ; } private void removeFromParentInfo ( Openable child ) { Openable parent = ( Openable ) child . getParent ( ) ; if ( parent != null && parent . isOpen ( ) ) { try { OpenableElementInfo info = ( OpenableElementInfo ) parent . getElementInfo ( ) ; info . removeChild ( child ) ; } catch ( JavaModelException e ) { } } } public void resourceChanged ( IResourceChangeEvent event ) { int eventType = this . overridenEventType == - 1 ? event . getType ( ) : this . overridenEventType ; IResource resource = event . getResource ( ) ; IResourceDelta delta = event . getDelta ( ) ; switch ( eventType ) { case IResourceChangeEvent . PRE_DELETE : try { if ( resource . getType ( ) == IResource . PROJECT && ( ( IProject ) resource ) . hasNature ( JavaCore . NATURE_ID ) ) { deleting ( ( IProject ) resource ) ; } } catch ( CoreException e ) { } return ; case IResourceChangeEvent . PRE_REFRESH : IProject [ ] projects = null ; Object o = event . getSource ( ) ; if ( o instanceof IProject ) { projects = new IProject [ ] { ( IProject ) o } ; } else if ( o instanceof IWorkspace ) { projects = ( ( IWorkspace ) o ) . getRoot ( ) . getProjects ( IContainer . INCLUDE_HIDDEN ) ; } JavaModelManager . getExternalManager ( ) . refreshReferences ( projects , null ) ; IJavaProject [ ] javaElements = new IJavaProject [ projects . length ] ; for ( int index = 0 ; index < projects . length ; index ++ ) { javaElements [ index ] = JavaCore . create ( projects [ index ] ) ; } try { checkExternalArchiveChanges ( javaElements , true , null ) ; } catch ( JavaModelException e ) { if ( ! e . isDoesNotExist ( ) ) Util . log ( e , "" ) ; } return ; case IResourceChangeEvent . POST_CHANGE : HashSet elementsToRefresh = this . state . removeExternalElementsToRefresh ( ) ; if ( isAffectedBy ( delta ) || elementsToRefresh != null ) { try { try { stopDeltas ( ) ; checkProjectsAndClasspathChanges ( delta ) ; if ( elementsToRefresh != null ) { createExternalArchiveDelta ( elementsToRefresh , null ) ; } HashMap classpathChanges = this . state . removeAllClasspathChanges ( ) ; if ( classpathChanges . size ( ) > 0 ) { boolean hasDelta = this . currentDelta != null ; JavaElementDelta javaDelta = currentDelta ( ) ; Iterator changes = classpathChanges . values ( ) . iterator ( ) ; while ( changes . hasNext ( ) ) { ClasspathChange change = ( ClasspathChange ) changes . next ( ) ; int result = change . generateDelta ( javaDelta , false ) ; if ( ( result & ClasspathChange . HAS_DELTA ) != 0 ) { hasDelta = true ; this . state . rootsAreStale = true ; change . requestIndexing ( ) ; this . state . addClasspathValidation ( change . project ) ; } if ( ( result & ClasspathChange . HAS_PROJECT_CHANGE ) != 0 ) { this . state . addProjectReferenceChange ( change . project , change . oldResolvedClasspath ) ; } if ( ( result & ClasspathChange . HAS_LIBRARY_CHANGE ) != 0 ) { this . state . addExternalFolderChange ( change . project , change . oldResolvedClasspath ) ; } } elementsToRefresh = this . state . removeExternalElementsToRefresh ( ) ; if ( elementsToRefresh != null ) { hasDelta |= createExternalArchiveDelta ( elementsToRefresh , null ) ; } if ( ! hasDelta ) this . currentDelta = null ; } IJavaElementDelta translatedDelta = processResourceDelta ( delta ) ; if ( translatedDelta != null ) { registerJavaModelDelta ( translatedDelta ) ; } } finally { this . sourceElementParserCache = null ; startDeltas ( ) ; } IElementChangedListener [ ] listeners ; int listenerCount ; synchronized ( this . state ) { listeners = this . state . elementChangedListeners ; listenerCount = this . state . elementChangedListenerCount ; } notifyTypeHierarchies ( listeners , listenerCount ) ; fire ( null , ElementChangedEvent . POST_CHANGE ) ; } finally { this . state . resetOldJavaProjectNames ( ) ; this . oldRoots = null ; } } return ; case IResourceChangeEvent . PRE_BUILD : this . state . initializeRoots ( false ) ; boolean isAffected = isAffectedBy ( delta ) ; boolean needCycleValidation = isAffected && validateClasspaths ( delta ) ; ExternalFolderChange [ ] folderChanges = this . state . removeExternalFolderChanges ( ) ; if ( folderChanges != null ) { for ( int i = 0 , length = folderChanges . length ; i < length ; i ++ ) { try { folderChanges [ i ] . updateExternalFoldersIfNecessary ( false , null ) ; } catch ( JavaModelException e ) { if ( ! e . isDoesNotExist ( ) ) Util . log ( e , "" ) ; } } } ClasspathValidation [ ] validations = this . state . removeClasspathValidations ( ) ; if ( validations != null ) { for ( int i = 0 , length = validations . length ; i < length ; i ++ ) { ClasspathValidation validation = validations [ i ] ; validation . validate ( ) ; } } ProjectReferenceChange [ ] projectRefChanges = this . state . removeProjectReferenceChanges ( ) ; if ( projectRefChanges != null ) { for ( int i = 0 , length = projectRefChanges . length ; i < length ; i ++ ) { try { projectRefChanges [ i ] . updateProjectReferencesIfNecessary ( ) ; } catch ( JavaModelException e ) { if ( ! e . isDoesNotExist ( ) ) Util . log ( e , "" ) ; } } } if ( needCycleValidation || projectRefChanges != null ) { try { JavaProject . validateCycles ( null ) ; } catch ( JavaModelException e ) { } } if ( isAffected ) { JavaModel . flushExternalFileCache ( ) ; JavaBuilder . buildStarting ( ) ; } return ; case IResourceChangeEvent . POST_BUILD : JavaBuilder . buildFinished ( ) ; return ; } } private RootInfo rootInfo ( IPath path , int kind ) { if ( kind == IResourceDelta . REMOVED ) { return ( RootInfo ) this . state . oldRoots . get ( path ) ; } return ( RootInfo ) this . state . roots . get ( path ) ; } private void startDeltas ( ) { this . isFiring = true ; } private void stopDeltas ( ) { this . isFiring = false ; } private void traverseDelta ( IResourceDelta delta , int elementType , RootInfo rootInfo , OutputsInfo outputsInfo ) { IResource res = delta . getResource ( ) ; if ( this . currentElement == null && rootInfo != null ) { this . currentElement = rootInfo . project ; } boolean processChildren = true ; if ( res instanceof IProject ) { this . sourceElementParserCache = null ; processChildren = updateCurrentDeltaAndIndex ( delta , elementType == IJavaElement . PACKAGE_FRAGMENT_ROOT ? IJavaElement . JAVA_PROJECT : elementType , rootInfo ) ; } else if ( rootInfo != null ) { processChildren = updateCurrentDeltaAndIndex ( delta , elementType , rootInfo ) ; } else { processChildren = true ; } if ( outputsInfo == null ) outputsInfo = outputsInfo ( rootInfo , res ) ; if ( processChildren ) { IResourceDelta [ ] children = delta . getAffectedChildren ( ) ; boolean oneChildOnClasspath = false ; int length = children . length ; IResourceDelta [ ] orphanChildren = null ; Openable parent = null ; boolean isValidParent = true ; for ( int i = 0 ; i < length ; i ++ ) { IResourceDelta child = children [ i ] ; IResource childRes = child . getResource ( ) ; checkSourceAttachmentChange ( child , childRes ) ; IPath childPath = externalPath ( childRes ) ; int childKind = child . getKind ( ) ; RootInfo childRootInfo = rootInfo ( childPath , childKind ) ; RootInfo originalChildRootInfo = childRootInfo ; if ( childRootInfo != null && ! childRootInfo . isRootOfProject ( childPath ) ) { childRootInfo = null ; } int childType = elementType ( childRes , childKind , elementType , rootInfo == null ? childRootInfo : rootInfo ) ; boolean isResFilteredFromOutput = isResFilteredFromOutput ( rootInfo , outputsInfo , childRes , childType ) ; boolean isNestedRoot = rootInfo != null && childRootInfo != null ; if ( ! isResFilteredFromOutput && ! isNestedRoot ) { traverseDelta ( child , childType , rootInfo == null ? childRootInfo : rootInfo , outputsInfo ) ; if ( childType == NON_JAVA_RESOURCE ) { if ( rootInfo != null ) { if ( ! isValidParent ) continue ; if ( parent == null ) { if ( this . currentElement == null || ! rootInfo . project . equals ( this . currentElement . getJavaProject ( ) ) ) { this . currentElement = rootInfo . project ; } if ( elementType == IJavaElement . JAVA_PROJECT || ( elementType == IJavaElement . PACKAGE_FRAGMENT_ROOT && res instanceof IProject ) ) { parent = rootInfo . project ; } else { parent = createElement ( res , elementType , rootInfo ) ; } if ( parent == null ) { isValidParent = false ; continue ; } } try { nonJavaResourcesChanged ( parent , child ) ; } catch ( JavaModelException e ) { } } else { if ( orphanChildren == null ) orphanChildren = new IResourceDelta [ length ] ; orphanChildren [ i ] = child ; } } else { if ( rootInfo == null && childRootInfo == null ) { if ( orphanChildren == null ) orphanChildren = new IResourceDelta [ length ] ; orphanChildren [ i ] = child ; } } } else { oneChildOnClasspath = true ; } if ( isNestedRoot || ( childRootInfo == null && originalChildRootInfo != null ) ) { traverseDelta ( child , IJavaElement . PACKAGE_FRAGMENT_ROOT , originalChildRootInfo , null ) ; } ArrayList rootList ; if ( ( rootList = otherRootsInfo ( childPath , childKind ) ) != null ) { Iterator iterator = rootList . iterator ( ) ; while ( iterator . hasNext ( ) ) { originalChildRootInfo = ( RootInfo ) iterator . next ( ) ; this . currentElement = null ; traverseDelta ( child , IJavaElement . PACKAGE_FRAGMENT_ROOT , originalChildRootInfo , null ) ; } } } if ( orphanChildren != null && ( oneChildOnClasspath || res instanceof IProject ) ) { IProject rscProject = res . getProject ( ) ; JavaProject adoptiveProject = ( JavaProject ) JavaCore . create ( rscProject ) ; if ( adoptiveProject != null && JavaProject . hasJavaNature ( rscProject ) ) { for ( int i = 0 ; i < length ; i ++ ) { if ( orphanChildren [ i ] != null ) { try { nonJavaResourcesChanged ( adoptiveProject , orphanChildren [ i ] ) ; } catch ( JavaModelException e ) { } } } } } } } private void validateClasspaths ( IResourceDelta delta , HashSet affectedProjects ) { IResource resource = delta . getResource ( ) ; boolean processChildren = false ; switch ( resource . getType ( ) ) { case IResource . ROOT : if ( delta . getKind ( ) == IResourceDelta . CHANGED ) { processChildren = true ; } break ; case IResource . PROJECT : IProject project = ( IProject ) resource ; int kind = delta . getKind ( ) ; boolean isJavaProject = JavaProject . hasJavaNature ( project ) ; switch ( kind ) { case IResourceDelta . ADDED : processChildren = isJavaProject ; affectedProjects . add ( project . getFullPath ( ) ) ; break ; case IResourceDelta . CHANGED : processChildren = isJavaProject ; if ( ( delta . getFlags ( ) & IResourceDelta . OPEN ) != 0 ) { if ( isJavaProject ) { JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; this . state . addClasspathValidation ( javaProject ) ; } affectedProjects . add ( project . getFullPath ( ) ) ; } else if ( ( delta . getFlags ( ) & IResourceDelta . DESCRIPTION ) != 0 ) { boolean wasJavaProject = this . state . findJavaProject ( project . getName ( ) ) != null ; if ( wasJavaProject != isJavaProject ) { JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; this . state . addClasspathValidation ( javaProject ) ; affectedProjects . add ( project . getFullPath ( ) ) ; } } break ; case IResourceDelta . REMOVED : affectedProjects . add ( project . getFullPath ( ) ) ; break ; } break ; case IResource . FILE : IFile file = ( IFile ) resource ; String fileName = file . getName ( ) ; RootInfo rootInfo = null ; if ( fileName . equals ( JavaProject . CLASSPATH_FILENAME ) || ( ( rootInfo = rootInfo ( file . getFullPath ( ) , delta . getKind ( ) ) ) != null && rootInfo . entryKind == IClasspathEntry . CPE_LIBRARY ) ) { JavaProject javaProject = ( JavaProject ) JavaCore . create ( file . getProject ( ) ) ; this . state . addClasspathValidation ( javaProject ) ; affectedProjects . add ( file . getProject ( ) . getFullPath ( ) ) ; } break ; } if ( processChildren ) { IResourceDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int i = 0 ; i < children . length ; i ++ ) { validateClasspaths ( children [ i ] , affectedProjects ) ; } } } private boolean validateClasspaths ( IResourceDelta delta ) { HashSet affectedProjects = new HashSet ( 5 ) ; validateClasspaths ( delta , affectedProjects ) ; boolean needCycleValidation = false ; if ( ! affectedProjects . isEmpty ( ) ) { IWorkspaceRoot workspaceRoot = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; IProject [ ] projects = workspaceRoot . getProjects ( ) ; int length = projects . length ; for ( int i = 0 ; i < length ; i ++ ) { IProject project = projects [ i ] ; JavaProject javaProject = ( JavaProject ) JavaCore . create ( project ) ; try { IPath projectPath = project . getFullPath ( ) ; IClasspathEntry [ ] classpath = javaProject . getResolvedClasspath ( ) ; for ( int j = 0 , cpLength = classpath . length ; j < cpLength ; j ++ ) { IClasspathEntry entry = classpath [ j ] ; switch ( entry . getEntryKind ( ) ) { case IClasspathEntry . CPE_PROJECT : if ( affectedProjects . contains ( entry . getPath ( ) ) ) { this . state . addClasspathValidation ( javaProject ) ; needCycleValidation = true ; } break ; case IClasspathEntry . CPE_LIBRARY : IPath entryPath = entry . getPath ( ) ; IPath libProjectPath = entryPath . removeLastSegments ( entryPath . segmentCount ( ) - 1 ) ; if ( ! libProjectPath . equals ( projectPath ) && affectedProjects . contains ( libProjectPath ) ) { this . state . addClasspathValidation ( javaProject ) ; } break ; } } } catch ( JavaModelException e ) { } } } return needCycleValidation ; } public boolean updateCurrentDeltaAndIndex ( IResourceDelta delta , int elementType , RootInfo rootInfo ) { Openable element ; switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : IResource deltaRes = delta . getResource ( ) ; element = createElement ( deltaRes , elementType , rootInfo ) ; if ( element == null ) { this . state . updateRoots ( deltaRes . getFullPath ( ) , delta , this ) ; return rootInfo != null && rootInfo . inclusionPatterns != null ; } updateIndex ( element , delta ) ; elementAdded ( element , delta , rootInfo ) ; if ( elementType == IJavaElement . PACKAGE_FRAGMENT_ROOT ) this . state . addClasspathValidation ( rootInfo . project ) ; return elementType == IJavaElement . PACKAGE_FRAGMENT ; case IResourceDelta . REMOVED : deltaRes = delta . getResource ( ) ; element = createElement ( deltaRes , elementType , rootInfo ) ; if ( element == null ) { this . state . updateRoots ( deltaRes . getFullPath ( ) , delta , this ) ; return rootInfo != null && rootInfo . inclusionPatterns != null ; } updateIndex ( element , delta ) ; elementRemoved ( element , delta , rootInfo ) ; if ( elementType == IJavaElement . PACKAGE_FRAGMENT_ROOT ) this . state . addClasspathValidation ( rootInfo . project ) ; if ( deltaRes . getType ( ) == IResource . PROJECT ) { if ( JavaBuilder . DEBUG ) System . out . println ( "" + deltaRes ) ; this . manager . setLastBuiltState ( ( IProject ) deltaRes , null ) ; this . manager . previousSessionContainers . remove ( element ) ; } return elementType == IJavaElement . PACKAGE_FRAGMENT ; case IResourceDelta . CHANGED : int flags = delta . getFlags ( ) ; if ( elementType == IJavaElement . PACKAGE_FRAGMENT_ROOT && ( flags & IResourceDelta . LOCAL_CHANGED ) != 0 ) { if ( oldRootInfo ( rootInfo . rootPath , rootInfo . project ) == null ) { break ; } deltaRes = delta . getResource ( ) ; Object target = JavaModel . getExternalTarget ( deltaRes . getLocation ( ) , true ) ; element = createElement ( deltaRes , elementType , rootInfo ) ; updateIndex ( element , delta ) ; if ( target != null ) { elementAdded ( element , delta , rootInfo ) ; } else { elementRemoved ( element , delta , rootInfo ) ; } this . state . addClasspathValidation ( rootInfo . project ) ; } else if ( ( flags & IResourceDelta . CONTENT ) != 0 || ( flags & IResourceDelta . ENCODING ) != 0 ) { element = createElement ( delta . getResource ( ) , elementType , rootInfo ) ; if ( element == null ) return false ; updateIndex ( element , delta ) ; contentChanged ( element ) ; } else if ( elementType == IJavaElement . JAVA_PROJECT ) { if ( ( flags & IResourceDelta . OPEN ) != 0 ) { IProject res = ( IProject ) delta . getResource ( ) ; element = createElement ( res , elementType , rootInfo ) ; if ( element == null ) { this . state . updateRoots ( res . getFullPath ( ) , delta , this ) ; return false ; } if ( res . isOpen ( ) ) { if ( JavaProject . hasJavaNature ( res ) ) { addToParentInfo ( element ) ; currentDelta ( ) . opened ( element ) ; this . state . updateRoots ( element . getPath ( ) , delta , this ) ; this . projectCachesToReset . add ( element ) ; this . manager . indexManager . indexAll ( res ) ; } } else { boolean wasJavaProject = this . state . findJavaProject ( res . getName ( ) ) != null ; if ( wasJavaProject ) { close ( element ) ; removeFromParentInfo ( element ) ; currentDelta ( ) . closed ( element ) ; this . manager . indexManager . discardJobs ( element . getElementName ( ) ) ; this . manager . indexManager . removeIndexFamily ( res . getFullPath ( ) ) ; } } return false ; } if ( ( flags & IResourceDelta . DESCRIPTION ) != 0 ) { IProject res = ( IProject ) delta . getResource ( ) ; boolean wasJavaProject = this . state . findJavaProject ( res . getName ( ) ) != null ; boolean isJavaProject = JavaProject . hasJavaNature ( res ) ; if ( wasJavaProject != isJavaProject ) { element = createElement ( res , elementType , rootInfo ) ; if ( element == null ) return false ; if ( isJavaProject ) { elementAdded ( element , delta , rootInfo ) ; this . manager . indexManager . indexAll ( res ) ; } else { elementRemoved ( element , delta , rootInfo ) ; this . manager . indexManager . discardJobs ( element . getElementName ( ) ) ; this . manager . indexManager . removeIndexFamily ( res . getFullPath ( ) ) ; if ( JavaBuilder . DEBUG ) System . out . println ( "" + res ) ; this . manager . setLastBuiltState ( res , null ) ; } return false ; } } } return true ; } return true ; } private void updateIndex ( Openable element , IResourceDelta delta ) { IndexManager indexManager = this . manager . indexManager ; if ( indexManager == null ) return ; switch ( element . getElementType ( ) ) { case IJavaElement . JAVA_PROJECT : switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : indexManager . indexAll ( element . getJavaProject ( ) . getProject ( ) ) ; break ; case IResourceDelta . REMOVED : indexManager . removeIndexFamily ( element . getJavaProject ( ) . getProject ( ) . getFullPath ( ) ) ; break ; } break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : if ( element instanceof JarPackageFragmentRoot ) { JarPackageFragmentRoot root = ( JarPackageFragmentRoot ) element ; IPath jarPath = root . getPath ( ) ; switch ( delta . getKind ( ) ) { case IResourceDelta . ADDED : indexManager . indexLibrary ( jarPath , root . getJavaProject ( ) . getProject ( ) ) ; break ; case IResourceDelta . CHANGED : indexManager . removeIndex ( jarPath ) ; indexManager . indexLibrary ( jarPath , root . getJavaProject ( ) . getProject ( ) ) ; break ; case IResourceDelta . REMOVED : indexManager . discardJobs ( jarPath . toString ( ) ) ; indexManager . removeIndex ( jarPath ) ; break ; } break ; } int kind = delta . getKind ( ) ; if ( kind == IResourceDelta . ADDED || kind == IResourceDelta . REMOVED || ( kind == IResourceDelta . CHANGED && ( delta . getFlags ( ) & IResourceDelta . LOCAL_CHANGED ) != 0 ) ) { PackageFragmentRoot root = ( PackageFragmentRoot ) element ; updateRootIndex ( root , CharOperation . NO_STRINGS , delta ) ; break ; } case IJavaElement . PACKAGE_FRAGMENT : switch ( delta . getKind ( ) ) { case IResourceDelta . CHANGED : if ( ( delta . getFlags ( ) & IResourceDelta . LOCAL_CHANGED ) == 0 ) break ; case IResourceDelta . ADDED : case IResourceDelta . REMOVED : IPackageFragment pkg = null ; if ( element instanceof IPackageFragmentRoot ) { PackageFragmentRoot root = ( PackageFragmentRoot ) element ; pkg = root . getPackageFragment ( CharOperation . NO_STRINGS ) ; } else { pkg = ( IPackageFragment ) element ; } RootInfo rootInfo = rootInfo ( pkg . getParent ( ) . getPath ( ) , delta . getKind ( ) ) ; boolean isSource = rootInfo == null || rootInfo . entryKind == IClasspathEntry . CPE_SOURCE ; IResourceDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { IResourceDelta child = children [ i ] ; IResource resource = child . getResource ( ) ; if ( resource instanceof IFile ) { String name = resource . getName ( ) ; if ( isSource ) { if ( org . eclipse . jdt . internal . core . util . Util . isJavaLikeFileName ( name ) ) { Openable cu = ( Openable ) pkg . getCompilationUnit ( name ) ; updateIndex ( cu , child ) ; } } else if ( org . eclipse . jdt . internal . compiler . util . Util . isClassFileName ( name ) ) { Openable classFile = ( Openable ) pkg . getClassFile ( name ) ; updateIndex ( classFile , child ) ; } } } break ; } break ; case IJavaElement . CLASS_FILE : IFile file = ( IFile ) delta . getResource ( ) ; IJavaProject project = element . getJavaProject ( ) ; PackageFragmentRoot root = element . getPackageFragmentRoot ( ) ; IPath binaryFolderPath = root . isExternal ( ) && ! root . isArchive ( ) ? root . resource ( ) . getFullPath ( ) : root . getPath ( ) ; try { if ( binaryFolderPath . equals ( project . getOutputLocation ( ) ) ) { break ; } } catch ( JavaModelException e ) { } switch ( delta . getKind ( ) ) { case IResourceDelta . CHANGED : int flags = delta . getFlags ( ) ; if ( ( flags & IResourceDelta . CONTENT ) == 0 && ( flags & IResourceDelta . ENCODING ) == 0 ) break ; case IResourceDelta . ADDED : indexManager . addBinary ( file , binaryFolderPath ) ; break ; case IResourceDelta . REMOVED : String containerRelativePath = Util . relativePath ( file . getFullPath ( ) , binaryFolderPath . segmentCount ( ) ) ; indexManager . remove ( containerRelativePath , binaryFolderPath ) ; break ; } break ; case IJavaElement . COMPILATION_UNIT : file = ( IFile ) delta . getResource ( ) ; switch ( delta . getKind ( ) ) { case IResourceDelta . CHANGED : int flags = delta . getFlags ( ) ; if ( ( flags & IResourceDelta . CONTENT ) == 0 && ( flags & IResourceDelta . ENCODING ) == 0 ) break ; case IResourceDelta . ADDED : indexManager . addSource ( file , file . getProject ( ) . getFullPath ( ) , getSourceElementParser ( element ) ) ; this . manager . secondaryTypesRemoving ( file , false ) ; break ; case IResourceDelta . REMOVED : indexManager . remove ( Util . relativePath ( file . getFullPath ( ) , 1 ) , file . getProject ( ) . getFullPath ( ) ) ; this . manager . secondaryTypesRemoving ( file , true ) ; break ; } } } public void updateJavaModel ( IJavaElementDelta customDelta ) { if ( customDelta == null ) { for ( int i = 0 , length = this . javaModelDeltas . size ( ) ; i < length ; i ++ ) { IJavaElementDelta delta = ( IJavaElementDelta ) this . javaModelDeltas . get ( i ) ; this . modelUpdater . processJavaDelta ( delta ) ; } } else { this . modelUpdater . processJavaDelta ( customDelta ) ; } } private void updateRootIndex ( PackageFragmentRoot root , String [ ] pkgName , IResourceDelta delta ) { Openable pkg = root . getPackageFragment ( pkgName ) ; updateIndex ( pkg , delta ) ; IResourceDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { IResourceDelta child = children [ i ] ; IResource resource = child . getResource ( ) ; if ( resource instanceof IFolder ) { String [ ] subpkgName = Util . arrayConcat ( pkgName , resource . getName ( ) ) ; updateRootIndex ( root , subpkgName , child ) ; } } } } </s>