1 11 package org.eclipse.jdt.internal.core.util; 12 13 import java.util.HashMap ; 14 import java.util.HashSet ; 15 16 import org.eclipse.core.resources.IFile; 17 import org.eclipse.core.resources.IProject; 18 import org.eclipse.core.resources.ResourcesPlugin; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IPath; 21 import org.eclipse.core.runtime.Path; 22 import org.eclipse.jdt.core.IClassFile; 23 import org.eclipse.jdt.core.IClasspathEntry; 24 import org.eclipse.jdt.core.ICompilationUnit; 25 import org.eclipse.jdt.core.IJavaElement; 26 import org.eclipse.jdt.core.IJavaProject; 27 import org.eclipse.jdt.core.IMember; 28 import org.eclipse.jdt.core.IPackageFragment; 29 import org.eclipse.jdt.core.IPackageFragmentRoot; 30 import org.eclipse.jdt.core.IType; 31 import org.eclipse.jdt.core.JavaCore; 32 import org.eclipse.jdt.core.JavaModelException; 33 import org.eclipse.jdt.core.compiler.CharOperation; 34 import org.eclipse.jdt.core.search.IJavaSearchScope; 35 import org.eclipse.jdt.internal.compiler.ast.*; 36 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 37 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 38 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 39 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 40 import org.eclipse.jdt.internal.compiler.lookup.MethodScope; 41 import org.eclipse.jdt.internal.compiler.lookup.Scope; 42 import org.eclipse.jdt.internal.core.*; 43 import org.eclipse.jdt.internal.core.JavaModel; 44 import org.eclipse.jdt.internal.core.JavaModelManager; 45 import org.eclipse.jdt.internal.core.JavaProject; 46 import org.eclipse.jdt.internal.core.Openable; 47 import org.eclipse.jdt.internal.core.PackageFragmentRoot; 48 import org.eclipse.jdt.internal.core.util.Util; 49 50 53 public class HandleFactory { 54 55 58 private String lastPkgFragmentRootPath; 59 private IPackageFragmentRoot lastPkgFragmentRoot; 60 61 64 private HashtableOfArrayToObject packageHandles; 65 66 private JavaModel javaModel; 67 68 public HandleFactory() { 69 this.javaModel = JavaModelManager.getJavaModelManager().getJavaModel(); 70 } 71 72 73 83 public Openable createOpenable(String resourcePath, IJavaSearchScope scope) { 84 int separatorIndex; 85 if ((separatorIndex= resourcePath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR)) > -1) { 86 int rootPathLength; 89 if (this.lastPkgFragmentRootPath == null 90 || (rootPathLength = this.lastPkgFragmentRootPath.length()) != resourcePath.length() 91 || !resourcePath.regionMatches(0, this.lastPkgFragmentRootPath, 0, rootPathLength)) { 92 String jarPath= resourcePath.substring(0, separatorIndex); 93 IPackageFragmentRoot root= this.getJarPkgFragmentRoot(jarPath, scope); 94 if (root == null) 95 return null; this.lastPkgFragmentRootPath= jarPath; 97 this.lastPkgFragmentRoot= root; 98 this.packageHandles= new HashtableOfArrayToObject(5); 99 } 100 String classFilePath= resourcePath.substring(separatorIndex + 1); 102 String [] simpleNames = new Path(classFilePath).segments(); 103 String [] pkgName; 104 int length = simpleNames.length-1; 105 if (length > 0) { 106 pkgName = new String [length]; 107 System.arraycopy(simpleNames, 0, pkgName, 0, length); 108 } else { 109 pkgName = CharOperation.NO_STRINGS; 110 } 111 IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName); 112 if (pkgFragment == null) { 113 pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName); 114 this.packageHandles.put(pkgName, pkgFragment); 115 } 116 IClassFile classFile= pkgFragment.getClassFile(simpleNames[length]); 117 return (Openable) classFile; 118 } else { 119 int rootPathLength = -1; 122 if (this.lastPkgFragmentRootPath == null 123 || !(resourcePath.startsWith(this.lastPkgFragmentRootPath) 124 && (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0 125 && resourcePath.charAt(rootPathLength) == '/')) { 126 IPackageFragmentRoot root= this.getPkgFragmentRoot(resourcePath); 127 if (root == null) 128 return null; this.lastPkgFragmentRoot = root; 130 this.lastPkgFragmentRootPath = this.lastPkgFragmentRoot.getPath().toString(); 131 this.packageHandles = new HashtableOfArrayToObject(5); 132 } 133 resourcePath = resourcePath.substring(this.lastPkgFragmentRootPath.length() + 1); 135 String [] simpleNames = new Path(resourcePath).segments(); 136 String [] pkgName; 137 int length = simpleNames.length-1; 138 if (length > 0) { 139 pkgName = new String [length]; 140 System.arraycopy(simpleNames, 0, pkgName, 0, length); 141 } else { 142 pkgName = CharOperation.NO_STRINGS; 143 } 144 IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName); 145 if (pkgFragment == null) { 146 pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName); 147 this.packageHandles.put(pkgName, pkgFragment); 148 } 149 String simpleName= simpleNames[length]; 150 if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(simpleName)) { 151 ICompilationUnit unit= pkgFragment.getCompilationUnit(simpleName); 152 return (Openable) unit; 153 } else { 154 IClassFile classFile= pkgFragment.getClassFile(simpleName); 155 return (Openable) classFile; 156 } 157 } 158 } 159 160 163 public IJavaElement createElement(ClassScope scope, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) { 164 return createElement(scope, scope.referenceContext.sourceStart, unit, existingElements, knownScopes); 165 } 166 169 private IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) { 170 IJavaElement newElement = (IJavaElement)knownScopes.get(scope); 171 if (newElement != null) return newElement; 172 173 switch(scope.kind) { 174 case Scope.COMPILATION_UNIT_SCOPE : 175 newElement = unit; 176 break; 177 case Scope.CLASS_SCOPE : 178 IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); 179 switch (parentElement.getElementType()) { 180 case IJavaElement.COMPILATION_UNIT : 181 newElement = ((ICompilationUnit)parentElement).getType(new String (scope.enclosingSourceType().sourceName)); 182 break; 183 case IJavaElement.TYPE : 184 newElement = ((IType)parentElement).getType(new String (scope.enclosingSourceType().sourceName)); 185 break; 186 case IJavaElement.FIELD : 187 case IJavaElement.INITIALIZER : 188 case IJavaElement.METHOD : 189 IMember member = (IMember)parentElement; 190 if (member.isBinary()) { 191 return null; 192 } else { 193 newElement = member.getType(new String (scope.enclosingSourceType().sourceName), 1); 194 if (newElement != null) { 196 while (!existingElements.add(newElement)) ((SourceRefElement)newElement).occurrenceCount++; 197 } 198 } 199 break; 200 } 201 if (newElement != null) { 202 knownScopes.put(scope, newElement); 203 } 204 break; 205 case Scope.METHOD_SCOPE : 206 IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); 207 MethodScope methodScope = (MethodScope) scope; 208 if (methodScope.isInsideInitializer()) { 209 TypeDeclaration type = methodScope.referenceType(); 211 int occurenceCount = 1; 212 for (int i = 0, length = type.fields.length; i < length; i++) { 213 FieldDeclaration field = type.fields[i]; 214 if (field.declarationSourceStart < elementPosition && field.declarationSourceEnd > elementPosition) { 215 switch (field.getKind()) { 216 case AbstractVariableDeclaration.FIELD : 217 case AbstractVariableDeclaration.ENUM_CONSTANT : 218 newElement = parentType.getField(new String (field.name)); 219 break; 220 case AbstractVariableDeclaration.INITIALIZER : 221 newElement = parentType.getInitializer(occurenceCount); 222 break; 223 } 224 break; 225 } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) { 226 occurenceCount++; 227 } 228 } 229 } else { 230 AbstractMethodDeclaration method = methodScope.referenceMethod(); 232 newElement = parentType.getMethod(new String (method.selector), Util.typeParameterSignatures(method)); 233 if (newElement != null) { 234 knownScopes.put(scope, newElement); 235 } 236 } 237 break; 238 case Scope.BLOCK_SCOPE : 239 newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); 241 break; 242 } 243 return newElement; 244 } 245 250 private IPackageFragmentRoot getJarPkgFragmentRoot(String jarPathString, IJavaSearchScope scope) { 251 252 IPath jarPath= new Path(jarPathString); 253 254 Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), jarPath, false); 255 if (target instanceof IFile) { 256 IFile jarFile = (IFile)target; 260 JavaProject javaProject = (JavaProject) this.javaModel.getJavaProject(jarFile); 261 try { 262 IClasspathEntry entry = javaProject.getClasspathEntryFor(jarPath); 263 if (entry != null) { 264 return javaProject.getPackageFragmentRoot(jarFile); 265 } 266 } catch (JavaModelException e) { 267 } 269 } 270 271 IJavaProject[] projects; 273 if (scope != null) { 274 IPath[] enclosingProjectsAndJars = scope.enclosingProjectsAndJars(); 275 int length = enclosingProjectsAndJars.length; 276 projects = new IJavaProject[length]; 277 int index = 0; 278 for (int i = 0; i < length; i++) { 279 IPath path = enclosingProjectsAndJars[i]; 280 if (!org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment())) { 281 projects[index++] = this.javaModel.getJavaProject(path.segment(0)); 282 } 283 } 284 if (index < length) { 285 System.arraycopy(projects, 0, projects = new IJavaProject[index], 0, index); 286 } 287 IPackageFragmentRoot root = getJarPkgFragmentRoot(jarPath, target, projects); 288 if (root != null) { 289 return root; 290 } 291 } 292 293 try { 295 projects = this.javaModel.getJavaProjects(); 296 } catch (JavaModelException e) { 297 return null; 299 } 300 return getJarPkgFragmentRoot(jarPath, target, projects); 301 } 302 303 private IPackageFragmentRoot getJarPkgFragmentRoot( 304 IPath jarPath, 305 Object target, 306 IJavaProject[] projects) { 307 for (int i= 0, projectCount= projects.length; i < projectCount; i++) { 308 try { 309 JavaProject javaProject= (JavaProject)projects[i]; 310 IClasspathEntry classpathEnty = javaProject.getClasspathEntryFor(jarPath); 311 if (classpathEnty != null) { 312 if (target instanceof IFile) { 313 return javaProject.getPackageFragmentRoot((IFile)target); 315 } else { 316 return javaProject.getPackageFragmentRoot0(jarPath); 318 } 319 } 320 } catch (JavaModelException e) { 321 } 323 } 324 return null; 325 } 326 327 330 private IPackageFragmentRoot getPkgFragmentRoot(String pathString) { 331 332 IPath path= new Path(pathString); 333 IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects(); 334 for (int i= 0, max= projects.length; i < max; i++) { 335 try { 336 IProject project = projects[i]; 337 if (!project.isAccessible() 338 || !project.hasNature(JavaCore.NATURE_ID)) continue; 339 IJavaProject javaProject= this.javaModel.getJavaProject(project); 340 IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots(); 341 for (int j= 0, rootCount= roots.length; j < rootCount; j++) { 342 PackageFragmentRoot root= (PackageFragmentRoot)roots[j]; 343 if (root.getPath().isPrefixOf(path) && !Util.isExcluded(path, root.fullInclusionPatternChars(), root.fullExclusionPatternChars(), false)) { 344 return root; 345 } 346 } 347 } catch (CoreException e) { 348 } 351 } 352 return null; 353 } 354 355 } 356 | Popular Tags |