<s> package org . eclipse . jdt . internal . core ; import java . util . ArrayList ; import java . util . HashMap ; import java . util . HashSet ; import java . util . Iterator ; import java . util . Map ; import org . eclipse . core . resources . IFolder ; import org . eclipse . core . resources . IResource ; import org . eclipse . core . resources . IWorkspace ; import org . eclipse . core . resources . ResourcesPlugin ; import org . eclipse . core . runtime . CoreException ; import org . eclipse . core . runtime . IPath ; import org . eclipse . jdt . core . IClasspathEntry ; import org . eclipse . jdt . core . IJavaElementDelta ; import org . eclipse . jdt . core . IPackageFragment ; import org . eclipse . jdt . core . IPackageFragmentRoot ; import org . eclipse . jdt . core . JavaModelException ; import org . eclipse . jdt . internal . compiler . util . ObjectVector ; import org . eclipse . jdt . internal . core . DeltaProcessor . RootInfo ; import org . eclipse . jdt . internal . core . JavaModelManager . PerProjectInfo ; import org . eclipse . jdt . internal . core . search . indexing . IndexManager ; import org . eclipse . jdt . internal . core . util . Util ; public class ClasspathChange { public static final int NO_DELTA = 0x00 ; public static final int HAS_DELTA = 0x01 ; public static final int HAS_PROJECT_CHANGE = 0x02 ; public static final int HAS_LIBRARY_CHANGE = 0x04 ; JavaProject project ; IClasspathEntry [ ] oldRawClasspath ; IPath oldOutputLocation ; IClasspathEntry [ ] oldResolvedClasspath ; public ClasspathChange ( JavaProject project , IClasspathEntry [ ] oldRawClasspath , IPath oldOutputLocation , IClasspathEntry [ ] oldResolvedClasspath ) { this . project = project ; this . oldRawClasspath = oldRawClasspath ; this . oldOutputLocation = oldOutputLocation ; this . oldResolvedClasspath = oldResolvedClasspath ; } private void addClasspathDeltas ( JavaElementDelta delta , IPackageFragmentRoot [ ] roots , int flag ) { for ( int i = 0 ; i < roots . length ; i ++ ) { IPackageFragmentRoot root = roots [ i ] ; delta . changed ( root , flag ) ; if ( ( flag & IJavaElementDelta . F_REMOVED_FROM_CLASSPATH ) != 0 || ( flag & IJavaElementDelta . F_SOURCEATTACHED ) != 0 || ( flag & IJavaElementDelta . F_SOURCEDETACHED ) != 0 ) { try { root . close ( ) ; } catch ( JavaModelException e ) { } } } } private int classpathContains ( IClasspathEntry [ ] list , IClasspathEntry entry ) { IPath [ ] exclusionPatterns = entry . getExclusionPatterns ( ) ; IPath [ ] inclusionPatterns = entry . getInclusionPatterns ( ) ; int listLen = list == null ? 0 : list . length ; nextEntry : for ( int i = 0 ; i < listLen ; i ++ ) { IClasspathEntry other = list [ i ] ; if ( other . getContentKind ( ) == entry . getContentKind ( ) && other . getEntryKind ( ) == entry . getEntryKind ( ) && other . isExported ( ) == entry . isExported ( ) && other . getPath ( ) . equals ( entry . getPath ( ) ) ) { IPath entryOutput = entry . getOutputLocation ( ) ; IPath otherOutput = other . getOutputLocation ( ) ; if ( entryOutput == null ) { if ( otherOutput != null ) continue ; } else { if ( ! entryOutput . equals ( otherOutput ) ) continue ; } IPath [ ] otherIncludes = other . getInclusionPatterns ( ) ; if ( inclusionPatterns != otherIncludes ) { if ( inclusionPatterns == null ) continue ; int includeLength = inclusionPatterns . length ; if ( otherIncludes == null || otherIncludes . length != includeLength ) continue ; for ( int j = 0 ; j < includeLength ; j ++ ) { if ( ! inclusionPatterns [ j ] . toString ( ) . equals ( otherIncludes [ j ] . toString ( ) ) ) continue nextEntry ; } } IPath [ ] otherExcludes = other . getExclusionPatterns ( ) ; if ( exclusionPatterns != otherExcludes ) { if ( exclusionPatterns == null ) continue ; int excludeLength = exclusionPatterns . length ; if ( otherExcludes == null || otherExcludes . length != excludeLength ) continue ; for ( int j = 0 ; j < excludeLength ; j ++ ) { if ( ! exclusionPatterns [ j ] . toString ( ) . equals ( otherExcludes [ j ] . toString ( ) ) ) continue nextEntry ; } } return i ; } } return - 1 ; } private void collectAllSubfolders ( IFolder folder , ArrayList collection ) throws JavaModelException { try { IResource [ ] members = folder . members ( ) ; for ( int i = 0 , max = members . length ; i < max ; i ++ ) { IResource r = members [ i ] ; if ( r . getType ( ) == IResource . FOLDER ) { collection . add ( r ) ; collectAllSubfolders ( ( IFolder ) r , collection ) ; } } } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } private ArrayList determineAffectedPackageFragments ( IPath location ) throws JavaModelException { ArrayList fragments = new ArrayList ( ) ; IWorkspace workspace = ResourcesPlugin . getWorkspace ( ) ; IResource resource = null ; if ( location != null ) { resource = workspace . getRoot ( ) . findMember ( location ) ; } if ( resource != null && resource . getType ( ) == IResource . FOLDER ) { IFolder folder = ( IFolder ) resource ; IClasspathEntry [ ] classpath = this . project . getExpandedClasspath ( ) ; for ( int i = 0 ; i < classpath . length ; i ++ ) { IClasspathEntry entry = classpath [ i ] ; IPath path = classpath [ i ] . getPath ( ) ; if ( entry . getEntryKind ( ) != IClasspathEntry . CPE_PROJECT && path . isPrefixOf ( location ) && ! path . equals ( location ) ) { IPackageFragmentRoot [ ] roots = this . project . computePackageFragmentRoots ( classpath [ i ] ) ; PackageFragmentRoot root = ( PackageFragmentRoot ) roots [ 0 ] ; ArrayList folders = new ArrayList ( ) ; folders . add ( folder ) ; collectAllSubfolders ( folder , folders ) ; Iterator elements = folders . iterator ( ) ; int segments = path . segmentCount ( ) ; while ( elements . hasNext ( ) ) { IFolder f = ( IFolder ) elements . next ( ) ; IPath relativePath = f . getFullPath ( ) . removeFirstSegments ( segments ) ; String [ ] pkgName = relativePath . segments ( ) ; IPackageFragment pkg = root . getPackageFragment ( pkgName ) ; if ( ! Util . isExcluded ( pkg ) ) fragments . add ( pkg ) ; } } } } return fragments ; } public boolean equals ( Object obj ) { if ( ! ( obj instanceof ClasspathChange ) ) return false ; return this . project . equals ( ( ( ClasspathChange ) obj ) . project ) ; } public int generateDelta ( JavaElementDelta delta , boolean addClasspathChange ) { JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; DeltaProcessingState state = manager . deltaState ; if ( state . findJavaProject ( this . project . getElementName ( ) ) == null ) return NO_DELTA ; DeltaProcessor deltaProcessor = state . getDeltaProcessor ( ) ; IClasspathEntry [ ] newResolvedClasspath = null ; IPath newOutputLocation = null ; int result = NO_DELTA ; try { PerProjectInfo perProjectInfo = this . project . getPerProjectInfo ( ) ; this . project . resolveClasspath ( perProjectInfo , false , addClasspathChange ) ; IClasspathEntry [ ] newRawClasspath ; synchronized ( perProjectInfo ) { newRawClasspath = perProjectInfo . rawClasspath ; newResolvedClasspath = perProjectInfo . getResolvedClasspath ( ) ; newOutputLocation = perProjectInfo . outputLocation ; } if ( newResolvedClasspath == null ) { PerProjectInfo temporaryInfo = this . project . newTemporaryInfo ( ) ; this . project . resolveClasspath ( temporaryInfo , false , addClasspathChange ) ; newRawClasspath = temporaryInfo . rawClasspath ; newResolvedClasspath = temporaryInfo . getResolvedClasspath ( ) ; newOutputLocation = temporaryInfo . outputLocation ; } if ( this . oldRawClasspath != null && ! JavaProject . areClasspathsEqual ( this . oldRawClasspath , newRawClasspath , this . oldOutputLocation , newOutputLocation ) ) { delta . changed ( this . project , IJavaElementDelta . F_CLASSPATH_CHANGED ) ; result |= HAS_DELTA ; for ( int i = 0 , length = this . oldRawClasspath . length ; i < length ; i ++ ) { IClasspathEntry entry = this . oldRawClasspath [ i ] ; if ( entry . getEntryKind ( ) == IClasspathEntry . CPE_CONTAINER ) { if ( classpathContains ( newRawClasspath , entry ) == - 1 ) manager . containerPut ( this . project , entry . getPath ( ) , null ) ; } } } if ( this . oldResolvedClasspath != null && JavaProject . areClasspathsEqual ( this . oldResolvedClasspath , newResolvedClasspath , this . oldOutputLocation , newOutputLocation ) ) return result ; this . project . close ( ) ; deltaProcessor . projectCachesToReset . add ( this . project ) ; } catch ( JavaModelException e ) { if ( DeltaProcessor . VERBOSE ) { e . printStackTrace ( ) ; } return result ; } if ( this . oldResolvedClasspath == null ) return result ; delta . changed ( this . project , IJavaElementDelta . F_RESOLVED_CLASSPATH_CHANGED ) ; result |= HAS_DELTA ; state . addForRefresh ( this . project ) ; Map removedRoots = null ; IPackageFragmentRoot [ ] roots = null ; Map allOldRoots ; if ( ( allOldRoots = deltaProcessor . oldRoots ) != null ) { roots = ( IPackageFragmentRoot [ ] ) allOldRoots . get ( this . project ) ; } if ( roots != null ) { removedRoots = new HashMap ( ) ; for ( int i = 0 ; i < roots . length ; i ++ ) { IPackageFragmentRoot root = roots [ i ] ; removedRoots . put ( root . getPath ( ) , root ) ; } } int newLength = newResolvedClasspath . length ; int oldLength = this . oldResolvedClasspath . length ; for ( int i = 0 ; i < oldLength ; i ++ ) { int index = classpathContains ( newResolvedClasspath , this . oldResolvedClasspath [ i ] ) ; if ( index == - 1 ) { int entryKind = this . oldResolvedClasspath [ i ] . getEntryKind ( ) ; if ( entryKind == IClasspathEntry . CPE_PROJECT ) { result |= HAS_PROJECT_CHANGE ; continue ; } if ( entryKind == IClasspathEntry . CPE_LIBRARY ) { result |= HAS_LIBRARY_CHANGE ; } IPackageFragmentRoot [ ] pkgFragmentRoots = null ; if ( removedRoots != null ) { PackageFragmentRoot oldRoot = ( PackageFragmentRoot ) removedRoots . get ( this . oldResolvedClasspath [ i ] . getPath ( ) ) ; if ( oldRoot != null ) { pkgFragmentRoots = new PackageFragmentRoot [ ] { oldRoot } ; } } if ( pkgFragmentRoots == null ) { try { ObjectVector accumulatedRoots = new ObjectVector ( ) ; HashSet rootIDs = new HashSet ( 5 ) ; rootIDs . add ( this . project . rootID ( ) ) ; this . project . computePackageFragmentRoots ( this . oldResolvedClasspath [ i ] , accumulatedRoots , rootIDs , null , false , null ) ; RootInfo rootInfo = ( RootInfo ) state . oldRoots . get ( this . oldResolvedClasspath [ i ] . getPath ( ) ) ; if ( rootInfo != null && rootInfo . cache != null ) { IPackageFragmentRoot oldRoot = rootInfo . cache ; boolean found = false ; for ( int j = 0 ; j < accumulatedRoots . size ( ) ; j ++ ) { IPackageFragmentRoot root = ( IPackageFragmentRoot ) accumulatedRoots . elementAt ( j ) ; if ( ! root . getPath ( ) . equals ( oldRoot . getPath ( ) ) ) { found = true ; break ; } } if ( ! found ) accumulatedRoots . add ( oldRoot ) ; } pkgFragmentRoots = new PackageFragmentRoot [ accumulatedRoots . size ( ) ] ; accumulatedRoots . copyInto ( pkgFragmentRoots ) ; } catch ( JavaModelException e ) { pkgFragmentRoots = new PackageFragmentRoot [ ] { } ; } } addClasspathDeltas ( delta , pkgFragmentRoots , IJavaElementDelta . F_REMOVED_FROM_CLASSPATH ) ; } else { if ( this . oldResolvedClasspath [ i ] . getEntryKind ( ) == IClasspathEntry . CPE_PROJECT ) { result |= HAS_PROJECT_CHANGE ; continue ; } if ( index != i ) { addClasspathDeltas ( delta , this . project . computePackageFragmentRoots ( this . oldResolvedClasspath [ i ] ) , IJavaElementDelta . F_REORDER ) ; } IPath newSourcePath = newResolvedClasspath [ index ] . getSourceAttachmentPath ( ) ; int sourceAttachmentFlags = getSourceAttachmentDeltaFlag ( this . oldResolvedClasspath [ i ] . getSourceAttachmentPath ( ) , newSourcePath ) ; IPath oldRootPath = this . oldResolvedClasspath [ i ] . getSourceAttachmentRootPath ( ) ; IPath newRootPath = newResolvedClasspath [ index ] . getSourceAttachmentRootPath ( ) ; int sourceAttachmentRootFlags = getSourceAttachmentDeltaFlag ( oldRootPath , newRootPath ) ; int flags = sourceAttachmentFlags | sourceAttachmentRootFlags ; if ( flags != 0 ) { addClasspathDeltas ( delta , this . project . computePackageFragmentRoots ( this . oldResolvedClasspath [ i ] ) , flags ) ; } else { if ( oldRootPath == null && newRootPath == null ) { IPackageFragmentRoot [ ] computedRoots = this . project . computePackageFragmentRoots ( this . oldResolvedClasspath [ i ] ) ; for ( int j = 0 ; j < computedRoots . length ; j ++ ) { IPackageFragmentRoot root = computedRoots [ j ] ; try { root . close ( ) ; } catch ( JavaModelException e ) { } } } } } } for ( int i = 0 ; i < newLength ; i ++ ) { int index = classpathContains ( this . oldResolvedClasspath , newResolvedClasspath [ i ] ) ; if ( index == - 1 ) { int entryKind = newResolvedClasspath [ i ] . getEntryKind ( ) ; if ( entryKind == IClasspathEntry . CPE_PROJECT ) { result |= HAS_PROJECT_CHANGE ; continue ; } if ( entryKind == IClasspathEntry . CPE_LIBRARY ) { result |= HAS_LIBRARY_CHANGE ; } addClasspathDeltas ( delta , this . project . computePackageFragmentRoots ( newResolvedClasspath [ i ] ) , IJavaElementDelta . F_ADDED_TO_CLASSPATH ) ; } } if ( ( newOutputLocation == null && this . oldOutputLocation != null ) || ( newOutputLocation != null && ! newOutputLocation . equals ( this . oldOutputLocation ) ) ) { try { ArrayList added = determineAffectedPackageFragments ( this . oldOutputLocation ) ; Iterator iter = added . iterator ( ) ; while ( iter . hasNext ( ) ) { IPackageFragment frag = ( IPackageFragment ) iter . next ( ) ; ( ( IPackageFragmentRoot ) frag . getParent ( ) ) . close ( ) ; delta . added ( frag ) ; } ArrayList removed = determineAffectedPackageFragments ( newOutputLocation ) ; iter = removed . iterator ( ) ; while ( iter . hasNext ( ) ) { IPackageFragment frag = ( IPackageFragment ) iter . next ( ) ; ( ( IPackageFragmentRoot ) frag . getParent ( ) ) . close ( ) ; delta . removed ( frag ) ; } } catch ( JavaModelException e ) { if ( DeltaProcessor . VERBOSE ) e . printStackTrace ( ) ; } } return result ; } private int getSourceAttachmentDeltaFlag ( IPath oldPath , IPath newPath ) { if ( oldPath == null ) { if ( newPath != null ) { return IJavaElementDelta . F_SOURCEATTACHED ; } else { return 0 ; } } else if ( newPath == null ) { return IJavaElementDelta . F_SOURCEDETACHED ; } else if ( ! oldPath . equals ( newPath ) ) { return IJavaElementDelta . F_SOURCEATTACHED | IJavaElementDelta . F_SOURCEDETACHED ; } else { return 0 ; } } public int hashCode ( ) { return this . project . hashCode ( ) ; } public void requestIndexing ( ) { IClasspathEntry [ ] newResolvedClasspath = null ; try { newResolvedClasspath = this . project . getResolvedClasspath ( ) ; } catch ( JavaModelException e ) { return ; } JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; IndexManager indexManager = manager . indexManager ; if ( indexManager == null ) return ; DeltaProcessingState state = manager . deltaState ; int newLength = newResolvedClasspath . length ; int oldLength = this . oldResolvedClasspath == null ? 0 : this . oldResolvedClasspath . length ; for ( int i = 0 ; i < oldLength ; i ++ ) { int index = classpathContains ( newResolvedClasspath , this . oldResolvedClasspath [ i ] ) ; if ( index == - 1 ) { if ( this . oldResolvedClasspath [ i ] . getEntryKind ( ) == IClasspathEntry . CPE_PROJECT ) { continue ; } IClasspathEntry oldEntry = this . oldResolvedClasspath [ i ] ; final IPath path = oldEntry . getPath ( ) ; int changeKind = this . oldResolvedClasspath [ i ] . getEntryKind ( ) ; switch ( changeKind ) { case IClasspathEntry . CPE_SOURCE : char [ ] [ ] inclusionPatterns = ( ( ClasspathEntry ) oldEntry ) . fullInclusionPatternChars ( ) ; char [ ] [ ] exclusionPatterns = ( ( ClasspathEntry ) oldEntry ) . fullExclusionPatternChars ( ) ; indexManager . removeSourceFolderFromIndex ( this . project , path , inclusionPatterns , exclusionPatterns ) ; break ; case IClasspathEntry . CPE_LIBRARY : if ( state . otherRoots . get ( path ) == null ) { indexManager . discardJobs ( path . toString ( ) ) ; indexManager . removeIndex ( path ) ; } break ; } } } for ( int i = 0 ; i < newLength ; i ++ ) { int index = classpathContains ( this . oldResolvedClasspath , newResolvedClasspath [ i ] ) ; if ( index == - 1 ) { if ( newResolvedClasspath [ i ] . getEntryKind ( ) == IClasspathEntry . CPE_PROJECT ) { continue ; } int entryKind = newResolvedClasspath [ i ] . getEntryKind ( ) ; switch ( entryKind ) { case IClasspathEntry . CPE_LIBRARY : boolean pathHasChanged = true ; IPath newPath = newResolvedClasspath [ i ] . getPath ( ) ; for ( int j = 0 ; j < oldLength ; j ++ ) { IClasspathEntry oldEntry = this . oldResolvedClasspath [ j ] ; if ( oldEntry . getPath ( ) . equals ( newPath ) ) { pathHasChanged = false ; break ; } } if ( pathHasChanged ) { indexManager . indexLibrary ( newPath , this . project . getProject ( ) ) ; } break ; case IClasspathEntry . CPE_SOURCE : IClasspathEntry entry = newResolvedClasspath [ i ] ; IPath path = entry . getPath ( ) ; char [ ] [ ] inclusionPatterns = ( ( ClasspathEntry ) entry ) . fullInclusionPatternChars ( ) ; char [ ] [ ] exclusionPatterns = ( ( ClasspathEntry ) entry ) . fullExclusionPatternChars ( ) ; indexManager . indexSourceFolder ( this . project , path , inclusionPatterns , exclusionPatterns ) ; break ; } } } } public String toString ( ) { return "" + this . project . getElementName ( ) ; } } </s>