1 19 20 package org.netbeans.modules.java; 21 22 import java.util.*; 23 24 import org.openide.cookies.SourceCookie; 25 26 import org.openide.filesystems.FileObject; 27 import org.openide.filesystems.FileUtil; 28 29 import org.openide.loaders.DataObject; 30 import org.openide.loaders.DataObjectNotFoundException; 31 32 import org.openide.src.*; 33 import org.netbeans.api.java.classpath.ClassPath; 34 import org.netbeans.api.java.queries.SourceForBinaryQuery; 35 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 36 37 55 class ClassElementFinder implements ClassElement.Finder { 56 59 private static final boolean DEBUG = false; 60 61 private static ClassElementFinder finder; 62 63 66 private ClassElementFinder() { 67 } 68 69 73 public static ClassElementFinder getInstance() { 74 if (finder != null) 75 return finder; 76 synchronized (ClassElementFinder.class) { 77 if (finder == null) 78 finder = new ClassElementFinder(); 79 } 80 return finder; 81 } 82 83 91 private ClassElement findSpecifiedInner(FileObject projectArtefact, String fullName, int packageDelimiter, 92 int innerDelimiter) { 93 94 String packName = packageDelimiter >= 0 ? fullName.substring(0, packageDelimiter) : ""; 95 int classnameOffset = packageDelimiter + 1; 96 String topName = fullName.substring(classnameOffset, innerDelimiter); 97 FileObject fo = searchFile(projectArtefact, packName, topName); 98 if (fo == null) 99 return null; 100 101 StringTokenizer tt = new StringTokenizer(fullName.substring(classnameOffset), 102 "$"); return findClassInFile(fo, tt); 104 } 105 106 112 private ClassElement findInSource(SourceElement s, Enumeration names) { 113 Identifier classID; 114 ClassElement c; 115 116 classID = Identifier.create((String )names.nextElement()); 117 c = s.getClass(classID); 118 if (DEBUG) { 119 System.err.println("getClass(" + classID.getName() + ") = " + (c == null ? "nothing" : c.getName().getFullName())); } 122 if (!names.hasMoreElements() || c == null) 123 return c; 124 do { 125 classID = Identifier.create((String )names.nextElement()); 126 c = c.getClass(classID); 127 if (DEBUG) { 128 System.err.println("getClass(" + classID.getName() + ") = " + (c == null ? "nothing" : c.getName().getFullName())); } 131 } while (c != null && names.hasMoreElements()); 132 return c; 133 } 134 135 138 public ClassElement find(String className, FileObject projectArtefact) { 139 int lastDot = className.length() - 1; 140 int innerDelimiter = -1; 141 ClassElement result; 142 143 if (lastDot < 0) 144 return null; 145 146 while (lastDot > 0 && className.charAt(lastDot) != '.') { 147 if (className.charAt(lastDot) == '$') 148 innerDelimiter = lastDot; 149 lastDot--; 150 } 151 if (lastDot == 0) { 152 if (className.charAt(lastDot) == '.') { 153 return null; } 155 else { 156 lastDot-=1; 157 } 158 } 159 160 if (DEBUG) { 161 System.err.println("[ClassFinder] Searching for " + className + " lastDot = " + lastDot + " delimiter = " + innerDelimiter); } 164 165 if (innerDelimiter > 0) 169 return findSpecifiedInner(projectArtefact, className, lastDot, innerDelimiter); 170 171 int nameEnd = className.length(); 172 String baseName; 173 String packName; 174 FileObject f; 175 176 if (lastDot > 0) { 177 baseName = className.substring(lastDot + 1, nameEnd); 178 packName = className.substring(0, lastDot); 179 } else { 180 baseName = className; 181 packName = ""; } 183 184 while (true) { 185 FileObject fo = searchFile(projectArtefact, packName, baseName); 186 if (fo != null) { 187 if (DEBUG) { 188 System.err.println("Finally found file " + f); } 190 String partName = lastDot > 0? className.substring(lastDot + 1): className; 191 result = findClassInFile(fo,new StringTokenizer(partName, ".")); if (result != null) 193 return result; 194 } 195 if (lastDot <= 0) 197 break; 198 199 nameEnd = lastDot; 200 lastDot = className.lastIndexOf('.', lastDot - 1); 201 if (lastDot > 0) { 202 baseName = className.substring(lastDot + 1, nameEnd); 203 packName = className.substring(0, lastDot); 204 } else { 205 packName = ""; baseName = className.substring(0, nameEnd); 207 } 208 } 209 return null; 210 } 211 212 217 private ClassElement findClassInFile(FileObject f, Enumeration names) { 218 DataObject d; 219 SourceElement s; 220 try { 221 d = DataObject.find(f); 222 223 SourceCookie sc = (SourceCookie)d.getCookie(SourceCookie.class); 224 if (DEBUG) 225 System.err.println("SourceCookie = " + sc); if (sc == null) 227 return null; 228 s = sc.getSource(); 229 } catch (DataObjectNotFoundException ex) { 230 return null; 231 } 232 return findInSource(s, names); 233 } 234 235 242 private FileObject searchFile(FileObject projectArtefact, String packName, String baseName) { 243 StringBuffer sb = new StringBuffer (packName.replace('.', '/')); 244 if (packName.length() != 0) 245 sb.append('/'); 246 sb.append(baseName); 247 String resNameBase = sb.toString(); 248 FileObject result = null; 249 ClassPath classPath = ClassPath.getClassPath(projectArtefact,ClassPath.SOURCE); 250 if (classPath != null) { 251 result = classPath.findResource(resNameBase+".java"); if (result != null) { 253 return result; 254 } 255 } 256 classPath = ClassPath.getClassPath (projectArtefact,ClassPath.COMPILE); 257 if (classPath != null) { 258 result = classPath.findResource(resNameBase+".class"); if (result != null) { 260 ClassPath.Entry root = findRoot (classPath, result); 262 FileObject[] sources = findSourceFile (root, resNameBase); 263 if (sources.length == 1) { 264 return sources[0]; 266 } 267 return result; 268 } else { 269 Iterator it = classPath.entries().iterator(); 272 while (it.hasNext()) { 273 ClassPath.Entry entry = (ClassPath.Entry)it.next(); 274 FileObject[] sourceRoots = SourceForBinaryQuery.findSourceRoots(entry.getURL()).getRoots(); 275 if (sourceRoots.length > 0) { 276 ClassPath cp = ClassPathSupport.createClassPath(sourceRoots); 277 result = cp.findResource(resNameBase+".java"); if (result != null) { 279 return result; 280 } 281 } 282 } 283 } 284 } 285 classPath = ClassPath.getClassPath (projectArtefact,ClassPath.BOOT); 286 if (classPath != null) { 287 result = classPath.findResource(resNameBase+".class"); if (result != null) { 289 ClassPath.Entry root = findRoot (classPath, result); 291 FileObject[] sources = findSourceFile (root, resNameBase); 292 if (sources.length == 1) { 293 return sources[0]; 295 } 296 return result; 297 } 298 } 299 return null; 300 } 301 302 public ClassElement find(Class clazz, FileObject context) { 303 return null; 304 } 305 306 307 308 314 private static FileObject[] findSourceFile (ClassPath.Entry root, String resourceName) { 315 Set result = new HashSet (); 316 if (resourceName != null) { 317 resourceName+=".java"; FileObject[] sourceRoots = SourceForBinaryQuery.findSourceRoots (root.getURL()).getRoots(); 319 if (sourceRoots.length > 0) { 320 ClassPath cp = ClassPathSupport.createClassPath (sourceRoots); 321 result.addAll(cp.findAllResources (resourceName)); 322 } 323 } 324 return (FileObject[]) result.toArray (new FileObject [result.size()]); 325 } 326 327 private static ClassPath.Entry findRoot (ClassPath cp, FileObject file) { 328 FileObject owner = cp.findOwnerRoot (file); 329 for (Iterator it = cp.entries().iterator(); it.hasNext();) { 330 ClassPath.Entry entry = ((ClassPath.Entry)it.next()); 331 FileObject root = entry.getRoot(); 332 if (root != null && root.equals(owner)) 333 return entry; 334 } 335 return null; 336 } 337 } 338 | Popular Tags |