<s> package org . eclipse . jdt . internal . core . search ; import java . util . ArrayList ; import java . util . HashSet ; import java . util . Map ; import org . eclipse . core . resources . IFolder ; import org . eclipse . core . resources . IProject ; import org . eclipse . core . resources . IResource ; import org . eclipse . core . resources . ResourcesPlugin ; import org . eclipse . core . runtime . IPath ; import org . eclipse . core . runtime . Path ; import org . eclipse . jdt . core . IClasspathContainer ; import org . eclipse . jdt . core . IClasspathEntry ; import org . eclipse . jdt . core . IJavaElement ; import org . eclipse . jdt . core . IJavaElementDelta ; import org . eclipse . jdt . core . IJavaModel ; import org . eclipse . jdt . core . IJavaProject ; import org . eclipse . jdt . core . IMember ; import org . eclipse . jdt . core . IPackageFragmentRoot ; import org . eclipse . jdt . core . JavaCore ; import org . eclipse . jdt . core . JavaModelException ; import org . eclipse . jdt . internal . compiler . env . AccessRuleSet ; import org . eclipse . jdt . internal . core . ClasspathEntry ; import org . eclipse . jdt . internal . core . ExternalFoldersManager ; import org . eclipse . jdt . internal . core . JavaElement ; import org . eclipse . jdt . internal . core . JavaModel ; import org . eclipse . jdt . internal . core . JavaModelManager ; import org . eclipse . jdt . internal . core . JavaProject ; import org . eclipse . jdt . internal . core . PackageFragment ; import org . eclipse . jdt . internal . core . PackageFragmentRoot ; import org . eclipse . jdt . internal . core . util . Util ; public class JavaSearchScope extends AbstractJavaSearchScope { private ArrayList elements ; private ArrayList projectPaths = new ArrayList ( ) ; private int [ ] projectIndexes ; private String [ ] containerPaths ; private String [ ] relativePaths ; private boolean [ ] isPkgPath ; protected AccessRuleSet [ ] pathRestrictions ; private int pathsCount ; private int threshold ; private IPath [ ] enclosingProjectsAndJars ; public final static AccessRuleSet NOT_ENCLOSED = new AccessRuleSet ( null , ( byte ) 0 , null ) ; public JavaSearchScope ( ) { this ( 5 ) ; } private JavaSearchScope ( int size ) { initialize ( size ) ; } private void addEnclosingProjectOrJar ( IPath path ) { int length = this . enclosingProjectsAndJars . length ; for ( int i = 0 ; i < length ; i ++ ) { if ( this . enclosingProjectsAndJars [ i ] . equals ( path ) ) return ; } System . arraycopy ( this . enclosingProjectsAndJars , 0 , this . enclosingProjectsAndJars = new IPath [ length + 1 ] , 0 , length ) ; this . enclosingProjectsAndJars [ length ] = path ; } public void add ( JavaProject project , int includeMask , HashSet projectsToBeAdded ) throws JavaModelException { add ( project , null , includeMask , projectsToBeAdded , new HashSet ( 2 ) , null ) ; } void add ( JavaProject javaProject , IPath pathToAdd , int includeMask , HashSet projectsToBeAdded , HashSet visitedProjects , IClasspathEntry referringEntry ) throws JavaModelException { IProject project = javaProject . getProject ( ) ; if ( ! project . isAccessible ( ) || ! visitedProjects . add ( project ) ) return ; IPath projectPath = project . getFullPath ( ) ; String projectPathString = projectPath . toString ( ) ; addEnclosingProjectOrJar ( projectPath ) ; IClasspathEntry [ ] entries = javaProject . getResolvedClasspath ( ) ; IJavaModel model = javaProject . getJavaModel ( ) ; JavaModelManager . PerProjectInfo perProjectInfo = javaProject . getPerProjectInfo ( ) ; for ( int i = 0 , length = entries . length ; i < length ; i ++ ) { IClasspathEntry entry = entries [ i ] ; AccessRuleSet access = null ; ClasspathEntry cpEntry = ( ClasspathEntry ) entry ; if ( referringEntry != null ) { if ( ! entry . isExported ( ) && entry . getEntryKind ( ) != IClasspathEntry . CPE_SOURCE ) { continue ; } cpEntry = cpEntry . combineWith ( ( ClasspathEntry ) referringEntry ) ; } access = cpEntry . getAccessRuleSet ( ) ; switch ( entry . getEntryKind ( ) ) { case IClasspathEntry . CPE_LIBRARY : IClasspathEntry rawEntry = null ; Map rootPathToRawEntries = perProjectInfo . rootPathToRawEntries ; if ( rootPathToRawEntries != null ) { rawEntry = ( IClasspathEntry ) rootPathToRawEntries . get ( entry . getPath ( ) ) ; } if ( rawEntry == null ) break ; rawKind : switch ( rawEntry . getEntryKind ( ) ) { case IClasspathEntry . CPE_LIBRARY : case IClasspathEntry . CPE_VARIABLE : if ( ( includeMask & APPLICATION_LIBRARIES ) != 0 ) { IPath path = entry . getPath ( ) ; if ( pathToAdd == null || pathToAdd . equals ( path ) ) { Object target = JavaModel . getTarget ( path , false ) ; if ( target instanceof IFolder ) path = ( ( IFolder ) target ) . getFullPath ( ) ; String pathToString = path . getDevice ( ) == null ? path . toString ( ) : path . toOSString ( ) ; add ( projectPath . toString ( ) , "" , pathToString , false , access ) ; addEnclosingProjectOrJar ( entry . getPath ( ) ) ; } } break ; case IClasspathEntry . CPE_CONTAINER : IClasspathContainer container = JavaCore . getClasspathContainer ( rawEntry . getPath ( ) , javaProject ) ; if ( container == null ) break ; switch ( container . getKind ( ) ) { case IClasspathContainer . K_APPLICATION : if ( ( includeMask & APPLICATION_LIBRARIES ) == 0 ) break rawKind ; break ; case IClasspathContainer . K_SYSTEM : case IClasspathContainer . K_DEFAULT_SYSTEM : if ( ( includeMask & SYSTEM_LIBRARIES ) == 0 ) break rawKind ; break ; default : break rawKind ; } IPath path = entry . getPath ( ) ; if ( pathToAdd == null || pathToAdd . equals ( path ) ) { Object target = JavaModel . getTarget ( path , false ) ; if ( target instanceof IFolder ) path = ( ( IFolder ) target ) . getFullPath ( ) ; String pathToString = path . getDevice ( ) == null ? path . toString ( ) : path . toOSString ( ) ; add ( projectPath . toString ( ) , "" , pathToString , false , access ) ; addEnclosingProjectOrJar ( entry . getPath ( ) ) ; } break ; } break ; case IClasspathEntry . CPE_PROJECT : if ( ( includeMask & REFERENCED_PROJECTS ) != 0 ) { IPath path = entry . getPath ( ) ; if ( pathToAdd == null || pathToAdd . equals ( path ) ) { JavaProject referencedProject = ( JavaProject ) model . getJavaProject ( path . lastSegment ( ) ) ; if ( ! projectsToBeAdded . contains ( referencedProject ) ) { add ( referencedProject , null , includeMask , projectsToBeAdded , visitedProjects , cpEntry ) ; } } } break ; case IClasspathEntry . CPE_SOURCE : if ( ( includeMask & SOURCES ) != 0 ) { IPath path = entry . getPath ( ) ; if ( pathToAdd == null || pathToAdd . equals ( path ) ) { add ( projectPath . toString ( ) , Util . relativePath ( path , 1 ) , projectPathString , false , access ) ; } } break ; } } } public void add ( IJavaElement element ) throws JavaModelException { IPath containerPath = null ; String containerPathToString = null ; PackageFragmentRoot root = null ; int includeMask = SOURCES | APPLICATION_LIBRARIES | SYSTEM_LIBRARIES ; switch ( element . getElementType ( ) ) { case IJavaElement . JAVA_MODEL : break ; case IJavaElement . JAVA_PROJECT : add ( ( JavaProject ) element , null , includeMask , new HashSet ( 2 ) , new HashSet ( 2 ) , null ) ; break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : root = ( PackageFragmentRoot ) element ; IPath rootPath = root . internalPath ( ) ; containerPath = root . getKind ( ) == IPackageFragmentRoot . K_SOURCE ? root . getParent ( ) . getPath ( ) : rootPath ; containerPathToString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; IResource rootResource = root . resource ( ) ; String projectPath = root . getJavaProject ( ) . getPath ( ) . toString ( ) ; if ( rootResource != null && rootResource . isAccessible ( ) ) { String relativePath = Util . relativePath ( rootResource . getFullPath ( ) , containerPath . segmentCount ( ) ) ; add ( projectPath , relativePath , containerPathToString , false , null ) ; } else { add ( projectPath , "" , containerPathToString , false , null ) ; } break ; case IJavaElement . PACKAGE_FRAGMENT : root = ( PackageFragmentRoot ) element . getParent ( ) ; projectPath = root . getJavaProject ( ) . getPath ( ) . toString ( ) ; if ( root . isArchive ( ) ) { String relativePath = Util . concatWith ( ( ( PackageFragment ) element ) . names , '/' ) ; containerPath = root . getPath ( ) ; containerPathToString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; add ( projectPath , relativePath , containerPathToString , true , null ) ; } else { IResource resource = ( ( JavaElement ) element ) . resource ( ) ; if ( resource != null ) { if ( resource . isAccessible ( ) ) { containerPath = root . getKind ( ) == IPackageFragmentRoot . K_SOURCE ? root . getParent ( ) . getPath ( ) : root . internalPath ( ) ; } else { containerPath = resource . getParent ( ) . getFullPath ( ) ; } containerPathToString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; String relativePath = Util . relativePath ( resource . getFullPath ( ) , containerPath . segmentCount ( ) ) ; add ( projectPath , relativePath , containerPathToString , true , null ) ; } } break ; default : if ( element instanceof IMember ) { if ( this . elements == null ) { this . elements = new ArrayList ( ) ; } this . elements . add ( element ) ; } root = ( PackageFragmentRoot ) element . getAncestor ( IJavaElement . PACKAGE_FRAGMENT_ROOT ) ; projectPath = root . getJavaProject ( ) . getPath ( ) . toString ( ) ; String relativePath ; if ( root . getKind ( ) == IPackageFragmentRoot . K_SOURCE ) { containerPath = root . getParent ( ) . getPath ( ) ; relativePath = Util . relativePath ( getPath ( element , false ) , 1 ) ; } else { containerPath = root . internalPath ( ) ; relativePath = getPath ( element , true ) . toString ( ) ; } containerPathToString = containerPath . getDevice ( ) == null ? containerPath . toString ( ) : containerPath . toOSString ( ) ; add ( projectPath , relativePath , containerPathToString , false , null ) ; } if ( root != null ) addEnclosingProjectOrJar ( root . getKind ( ) == IPackageFragmentRoot . K_SOURCE ? root . getParent ( ) . getPath ( ) : root . getPath ( ) ) ; } private void add ( String projectPath , String relativePath , String containerPath , boolean isPackage , AccessRuleSet access ) { containerPath = normalize ( containerPath ) ; relativePath = normalize ( relativePath ) ; int length = this . containerPaths . length , index = ( containerPath . hashCode ( ) & 0x7FFFFFFF ) % length ; String currentRelativePath , currentContainerPath ; while ( ( currentRelativePath = this . relativePaths [ index ] ) != null && ( currentContainerPath = this . containerPaths [ index ] ) != null ) { if ( currentRelativePath . equals ( relativePath ) && currentContainerPath . equals ( containerPath ) ) return ; if ( ++ index == length ) { index = 0 ; } } int idx = this . projectPaths . indexOf ( projectPath ) ; if ( idx == - 1 ) { this . projectPaths . add ( projectPath ) ; idx = this . projectPaths . indexOf ( projectPath ) ; } this . projectIndexes [ index ] = idx ; this . relativePaths [ index ] = relativePath ; this . containerPaths [ index ] = containerPath ; this . isPkgPath [ index ] = isPackage ; if ( this . pathRestrictions != null ) this . pathRestrictions [ index ] = access ; else if ( access != null ) { this . pathRestrictions = new AccessRuleSet [ this . relativePaths . length ] ; this . pathRestrictions [ index ] = access ; } if ( ++ this . pathsCount > this . threshold ) rehash ( ) ; } public boolean encloses ( String resourcePathString ) { int separatorIndex = resourcePathString . indexOf ( JAR_FILE_ENTRY_SEPARATOR ) ; if ( separatorIndex != - 1 ) { String jarPath = resourcePathString . substring ( 0 , separatorIndex ) ; String relativePath = resourcePathString . substring ( separatorIndex + 1 ) ; return indexOf ( jarPath , relativePath ) >= 0 ; } return indexOf ( resourcePathString ) >= 0 ; } private int indexOf ( String fullPath ) { for ( int i = 0 , length = this . relativePaths . length ; i < length ; i ++ ) { String currentRelativePath = this . relativePaths [ i ] ; if ( currentRelativePath == null ) continue ; String currentContainerPath = this . containerPaths [ i ] ; String currentFullPath = currentRelativePath . length ( ) == 0 ? currentContainerPath : ( currentContainerPath + '/' + currentRelativePath ) ; if ( encloses ( currentFullPath , fullPath , i ) ) return i ; } return - 1 ; } private int indexOf ( String containerPath , String relativePath ) { int length = this . containerPaths . length , index = ( containerPath . hashCode ( ) & 0x7FFFFFFF ) % length ; String currentContainerPath ; while ( ( currentContainerPath = this . containerPaths [ index ] ) != null ) { if ( currentContainerPath . equals ( containerPath ) ) { String currentRelativePath = this . relativePaths [ index ] ; if ( encloses ( currentRelativePath , relativePath , index ) ) return index ; } if ( ++ index == length ) { index = 0 ; } } return - 1 ; } private boolean encloses ( String enclosingPath , String path , int index ) { path = normalize ( path ) ; int pathLength = path . length ( ) ; int enclosingLength = enclosingPath . length ( ) ; if ( pathLength < enclosingLength ) { return false ; } if ( enclosingLength == 0 ) { return true ; } if ( pathLength == enclosingLength ) { return path . equals ( enclosingPath ) ; } if ( ! this . isPkgPath [ index ] ) { return path . startsWith ( enclosingPath ) && path . charAt ( enclosingLength ) == '/' ; } else { if ( path . startsWith ( enclosingPath ) && ( ( enclosingPath . length ( ) == path . lastIndexOf ( '/' ) ) || ( enclosingPath . length ( ) == path . length ( ) ) ) ) { return true ; } } return false ; } public boolean encloses ( IJavaElement element ) { if ( this . elements != null ) { for ( int i = 0 , length = this . elements . size ( ) ; i < length ; i ++ ) { IJavaElement scopeElement = ( IJavaElement ) this . elements . get ( i ) ; IJavaElement searchedElement = element ; while ( searchedElement != null ) { if ( searchedElement . equals ( scopeElement ) ) return true ; searchedElement = searchedElement . getParent ( ) ; } } return false ; } IPackageFragmentRoot root = ( IPackageFragmentRoot ) element . getAncestor ( IJavaElement . PACKAGE_FRAGMENT_ROOT ) ; if ( root != null && root . isArchive ( ) ) { IPath rootPath = root . getPath ( ) ; String rootPathToString = rootPath . getDevice ( ) == null ? rootPath . toString ( ) : rootPath . toOSString ( ) ; IPath relativePath = getPath ( element , true ) ; return indexOf ( rootPathToString , relativePath . toString ( ) ) >= 0 ; } String fullResourcePathString = getPath ( element , false ) . toString ( ) ; return indexOf ( fullResourcePathString ) >= 0 ; } public IPath [ ] enclosingProjectsAndJars ( ) { return this . enclosingProjectsAndJars ; } private IPath getPath ( IJavaElement element , boolean relativeToRoot ) { switch ( element . getElementType ( ) ) { case IJavaElement . JAVA_MODEL : return Path . EMPTY ; case IJavaElement . JAVA_PROJECT : return element . getPath ( ) ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : if ( relativeToRoot ) return Path . EMPTY ; return element . getPath ( ) ; case IJavaElement . PACKAGE_FRAGMENT : String relativePath = Util . concatWith ( ( ( PackageFragment ) element ) . names , '/' ) ; return getPath ( element . getParent ( ) , relativeToRoot ) . append ( new Path ( relativePath ) ) ; case IJavaElement . COMPILATION_UNIT : case IJavaElement . CLASS_FILE : return getPath ( element . getParent ( ) , relativeToRoot ) . append ( new Path ( element . getElementName ( ) ) ) ; default : return getPath ( element . getParent ( ) , relativeToRoot ) ; } } public AccessRuleSet getAccessRuleSet ( String relativePath , String containerPath ) { int index = indexOf ( containerPath , relativePath ) ; if ( index == - 1 ) { return NOT_ENCLOSED ; } if ( this . pathRestrictions == null ) return null ; return this . pathRestrictions [ index ] ; } protected void initialize ( int size ) { this . pathsCount = 0 ; this . threshold = size ; int extraRoom = ( int ) ( size * 1.75f ) ; if ( this . threshold == extraRoom ) extraRoom ++ ; this . relativePaths = new String [ extraRoom ] ; this . containerPaths = new String [ extraRoom ] ; this . projectPaths = new ArrayList ( ) ; this . projectIndexes = new int [ extraRoom ] ; this . isPkgPath = new boolean [ extraRoom ] ; this . pathRestrictions = null ; this . enclosingProjectsAndJars = new IPath [ 0 ] ; } private String normalize ( String path ) { int pathLength = path . length ( ) ; int index = pathLength - 1 ; while ( index >= 0 && path . charAt ( index ) == '/' ) index -- ; if ( index != pathLength - 1 ) return path . substring ( 0 , index + 1 ) ; return path ; } public void processDelta ( IJavaElementDelta delta , int eventType ) { switch ( delta . getKind ( ) ) { case IJavaElementDelta . CHANGED : IJavaElementDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { IJavaElementDelta child = children [ i ] ; processDelta ( child , eventType ) ; } break ; case IJavaElementDelta . REMOVED : IJavaElement element = delta . getElement ( ) ; if ( this . encloses ( element ) ) { if ( this . elements != null ) { this . elements . remove ( element ) ; } String path = null ; switch ( element . getElementType ( ) ) { case IJavaElement . JAVA_PROJECT : path = ( ( IJavaProject ) element ) . getProject ( ) . getFullPath ( ) . toString ( ) ; break ; case IJavaElement . PACKAGE_FRAGMENT_ROOT : path = ( ( IPackageFragmentRoot ) element ) . getPath ( ) . toString ( ) ; break ; default : return ; } for ( int i = 0 ; i < this . pathsCount ; i ++ ) { if ( this . relativePaths [ i ] . equals ( path ) ) { this . relativePaths [ i ] = null ; rehash ( ) ; break ; } } } break ; } } public IPackageFragmentRoot packageFragmentRoot ( String resourcePathString , int jarSeparatorIndex , String jarPath ) { int index = - 1 ; boolean isJarFile = jarSeparatorIndex != - 1 ; if ( isJarFile ) { String relativePath = resourcePathString . substring ( jarSeparatorIndex + 1 ) ; index = indexOf ( jarPath , relativePath ) ; } else { index = indexOf ( resourcePathString ) ; } if ( index >= 0 ) { int idx = this . projectIndexes [ index ] ; String projectPath = idx == - 1 ? null : ( String ) this . projectPaths . get ( idx ) ; if ( projectPath != null ) { IJavaProject project = JavaCore . create ( ResourcesPlugin . getWorkspace ( ) . getRoot ( ) . getProject ( projectPath ) ) ; if ( isJarFile ) { IResource resource = JavaModel . getWorkspaceTarget ( new Path ( jarPath ) ) ; if ( resource != null ) return project . getPackageFragmentRoot ( resource ) ; return project . getPackageFragmentRoot ( jarPath ) ; } Object target = JavaModel . getWorkspaceTarget ( new Path ( this . containerPaths [ index ] + '/' + this . relativePaths [ index ] ) ) ; if ( target != null ) { if ( target instanceof IProject ) { return project . getPackageFragmentRoot ( ( IProject ) target ) ; } IJavaElement element = JavaModelManager . create ( ( IResource ) target , project ) ; return ( IPackageFragmentRoot ) element . getAncestor ( IJavaElement . PACKAGE_FRAGMENT_ROOT ) ; } } } return null ; } private void rehash ( ) { JavaSearchScope newScope = new JavaSearchScope ( this . pathsCount * 2 ) ; newScope . projectPaths . ensureCapacity ( this . projectPaths . size ( ) ) ; String currentPath ; for ( int i = 0 , length = this . relativePaths . length ; i < length ; i ++ ) if ( ( currentPath = this . relativePaths [ i ] ) != null ) { int idx = this . projectIndexes [ i ] ; String projectPath = idx == - 1 ? null : ( String ) this . projectPaths . get ( idx ) ; newScope . add ( projectPath , currentPath , this . containerPaths [ i ] , this . isPkgPath [ i ] , this . pathRestrictions == null ? null : this . pathRestrictions [ i ] ) ; } this . relativePaths = newScope . relativePaths ; this . containerPaths = newScope . containerPaths ; this . projectPaths = newScope . projectPaths ; this . projectIndexes = newScope . projectIndexes ; this . isPkgPath = newScope . isPkgPath ; this . pathRestrictions = newScope . pathRestrictions ; this . threshold = newScope . threshold ; } public String toString ( ) { StringBuffer result = new StringBuffer ( "" ) ; if ( this . elements != null ) { result . append ( "[" ) ; for ( int i = 0 , length = this . elements . size ( ) ; i < length ; i ++ ) { JavaElement element = ( JavaElement ) this . elements . get ( i ) ; result . append ( "nt" ) ; result . append ( element . toStringWithAncestors ( ) ) ; } result . append ( "n]" ) ; } else { if ( this . pathsCount == 0 ) { result . append ( "" ) ; } else { result . append ( "[" ) ; String [ ] paths = new String [ this . relativePaths . length ] ; int index = 0 ; for ( int i = 0 ; i < this . relativePaths . length ; i ++ ) { String path = this . relativePaths [ i ] ; if ( path == null ) continue ; String containerPath ; if ( ExternalFoldersManager . isInternalPathForExternalFolder ( new Path ( this . containerPaths [ i ] ) ) ) { Object target = JavaModel . getWorkspaceTarget ( new Path ( this . containerPaths [ i ] ) ) ; containerPath = ( ( IFolder ) target ) . getLocation ( ) . toOSString ( ) ; } else { containerPath = this . containerPaths [ i ] ; } if ( path . length ( ) > 0 ) { paths [ index ++ ] = containerPath + '/' + path ; } else { paths [ index ++ ] = containerPath ; } } System . arraycopy ( paths , 0 , paths = new String [ index ] , 0 , index ) ; Util . sort ( paths ) ; for ( int i = 0 ; i < index ; i ++ ) { result . append ( "nt" ) ; result . append ( paths [ i ] ) ; } result . append ( "n]" ) ; } } return result . toString ( ) ; } } </s>