1 19 20 package org.netbeans.modules.javadoc.search; 21 22 import com.sun.source.tree.ClassTree; 23 import com.sun.source.tree.CompilationUnitTree; 24 import com.sun.source.tree.Tree; 25 import com.sun.source.util.Trees; 26 import java.io.IOException ; 27 import java.net.URL ; 28 import java.util.StringTokenizer ; 29 import java.util.ArrayList ; 30 import java.util.Set ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 import javax.lang.model.element.Element; 36 import javax.lang.model.element.ElementKind; 37 import javax.lang.model.element.ExecutableElement; 38 import javax.lang.model.element.TypeElement; 39 import javax.lang.model.element.VariableElement; 40 import javax.lang.model.type.DeclaredType; 41 import javax.lang.model.type.TypeKind; 42 import javax.lang.model.type.TypeMirror; 43 import org.netbeans.api.java.classpath.GlobalPathRegistry; 44 import org.netbeans.api.java.classpath.ClassPath; 45 import org.netbeans.api.java.queries.JavadocForBinaryQuery; 46 import org.netbeans.api.java.queries.SourceForBinaryQuery; 47 import org.netbeans.api.java.source.CancellableTask; 48 import org.netbeans.api.java.source.CompilationController; 49 import org.netbeans.api.java.source.ElementHandle; 50 import org.netbeans.api.java.source.JavaSource; 51 import org.netbeans.api.java.source.JavaSource.Phase; 52 import org.netbeans.api.java.source.TreeUtilities; 53 import org.openide.filesystems.FileObject; 54 import org.openide.filesystems.URLMapper; 55 56 57 60 public final class SrcFinder extends Object { 61 62 63 private SrcFinder() { 64 } 65 66 static Object [] findSource(String aPackage, URL url) { 67 68 aPackage = aPackage.replace( '.', '/' ); String thePackage = null; 70 final String member = url.getRef(); 71 String clazz = url.getFile(); 72 String filename = null; 73 74 int pIndex; 75 76 if ((pIndex = clazz.toLowerCase().lastIndexOf(aPackage.trim().toLowerCase())) != -1) { 77 thePackage = clazz.substring(pIndex, pIndex + aPackage.trim().length() - 1 ); 78 clazz = clazz.substring( pIndex + aPackage.trim().length(), clazz.length() - 5 ); 79 80 int ei; 81 if ( ( ei = clazz.indexOf('.')) != -1 ) { 82 filename = clazz.substring(0, ei ); 83 } 84 else 85 filename = clazz; 86 87 } 88 89 98 String resourceName = thePackage + "/" + filename + ".java"; FileObject fo = searchResource(url, resourceName); 100 101 final ElementHandle[] handles = new ElementHandle[1]; 102 103 if ( fo != null ) { 104 final String className = clazz; 105 JavaSource js = JavaSource.forFileObject(fo); 106 107 try { 108 js.runUserActionTask(new CancellableTask<CompilationController>() { 109 110 public void cancel() { 111 } 112 113 public void run(CompilationController ctrl) throws Exception { 114 ctrl.toPhase(Phase.ELEMENTS_RESOLVED); 115 TypeElement classElm = findClass(ctrl, className); 116 if (classElm == null) { 117 } else if (member == null) { 119 handles[0] = ElementHandle.create(classElm); 120 } else { 121 int pi = member.indexOf('('); 122 if (pi == -1) { 123 handles[0] = findField(classElm, member); 125 } else { 126 handles[0] = findMethod(ctrl, classElm, member ); 128 } 129 } 130 } 131 }, true); 132 } catch (IOException ex) { 133 Logger.getLogger(SrcFinder.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex); 134 } 135 136 } 137 return handles[0] != null? new Object []{fo, handles[0]}: null; 138 } 139 140 149 private static FileObject searchResource(URL url, String respath) { 150 FileObject res = searchBinaryPath(ClassPath.BOOT, respath, url); 151 152 if (res == null) { 153 res = searchBinaryPath(ClassPath.COMPILE, respath, url); 154 } 155 156 if (res == null) { 157 res = searchSourcePath(respath, url); 158 } 159 160 return res; 161 162 } 163 164 private static FileObject searchBinaryPath(String classPathID, String respath, URL url) { 165 Set <ClassPath> cpaths = GlobalPathRegistry.getDefault().getPaths(classPathID); 166 for (ClassPath cpath: cpaths) { 167 FileObject[] cpRoots = cpath.getRoots(); 168 for (int i = 0; i < cpRoots.length; i++) { 169 SourceForBinaryQuery.Result result = SourceForBinaryQuery.findSourceRoots(URLMapper.findURL(cpRoots[i], URLMapper.EXTERNAL)); 170 FileObject[] srcRoots = result.getRoots(); 171 for (int j = 0; j < srcRoots.length; j++) { 172 FileObject fo = srcRoots[j].getFileObject(respath); 173 if (fo != null && isJavadocAssigned(cpath, url)) { 174 return fo; 175 } 176 } 177 } 178 } 179 return null; 180 } 181 182 private static FileObject searchSourcePath(String respath, URL url) { 183 Set <ClassPath> cpaths = GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE); 184 for (ClassPath cpath: cpaths) { 185 FileObject fo = cpath.findResource(respath); 186 if (fo != null && isJavadocAssigned(cpath, url)) { 187 return fo; 188 } 189 } 190 191 return null; 192 } 193 194 200 private static boolean isJavadocAssigned(ClassPath cpath, URL url) { 201 FileObject[] cpRoots = cpath.getRoots(); 202 String urlPath = url.toExternalForm(); 203 for (int i = 0; i < cpRoots.length; i++) { 204 JavadocForBinaryQuery.Result result = JavadocForBinaryQuery.findJavadoc(URLMapper.findURL(cpRoots[i], URLMapper.EXTERNAL)); 205 URL [] jdRoots = result.getRoots(); 206 for (int j = 0; j < jdRoots.length; j++) { 207 String jdRootPath = jdRoots[j].toExternalForm(); 208 if (urlPath.indexOf(jdRootPath) >= 0) { 209 return true; 210 } 211 } 212 } 213 return false; 214 } 215 216 private static TypeElement findClass(CompilationController ctrl, String className) { 217 CompilationUnitTree cunit = ctrl.getCompilationUnit(); 218 for (Tree declTree : cunit.getTypeDecls()) { 219 ClassTree classTree = (ClassTree) declTree; 220 if (className.equals(classTree.getSimpleName().toString())) { 221 Trees trees = ctrl.getTrees(); 222 TypeElement classElm = (TypeElement) trees.getElement(trees.getPath(cunit, classTree)); 223 return classElm; 224 } 225 } 226 return null; 227 } 228 229 private static ElementHandle findField(TypeElement classElm, String name) { 230 for (Element elm: classElm.getEnclosedElements()) { 231 if (elm.getKind() == ElementKind.FIELD && 232 name.equals(elm.getSimpleName().toString())) { 233 return ElementHandle.create(elm); 234 } 235 } 236 return null; 237 } 238 239 241 private static ElementHandle findMethod(CompilationController ctrl, TypeElement ce, String member) { 242 TreeUtilities utils = ctrl.getTreeUtilities(); 243 244 int pi = member.indexOf( '(' ); 245 String name = member.substring( 0, pi ); 246 247 StringTokenizer tokenizer = new StringTokenizer ( member.substring( pi ), " ,()" ); List <TypeMirror> paramList = new ArrayList <TypeMirror>(); 249 250 while( tokenizer.hasMoreTokens() ) { 251 String token = tokenizer.nextToken(); 252 if (token.endsWith("...")) { token = token.substring(0, token.length() - 3); 255 token += "[]"; } 257 TypeMirror type = utils.parseType(token, ce); 258 paramList.add(type); 259 } 260 261 for (Element e: ce.getEnclosedElements()) { 263 if (e.getKind() == ElementKind.METHOD 264 && name.equals(e.getSimpleName().toString()) 265 && compareTypes(ctrl, paramList, ((ExecutableElement) e).getParameters())) { 266 return ElementHandle.create(e); 267 } else if (e.getKind() == ElementKind.CONSTRUCTOR 268 && name.equals(ce.getSimpleName().toString()) 269 && compareTypes(ctrl, paramList, ((ExecutableElement) e).getParameters())) { 270 return ElementHandle.create(e); 271 } 272 } 273 274 return null; 275 } 276 277 private static boolean compareTypes(CompilationController ctrl, List <TypeMirror> types, List <? extends VariableElement> params) { 278 if (types.size() != params.size()) { 279 return false; 280 } 281 282 Iterator <? extends VariableElement> itParams = params.iterator(); 283 Iterator <TypeMirror> itTypes = types.iterator(); 284 while (itParams.hasNext()) { 285 VariableElement varEl = itParams.next(); 286 TypeMirror paramType = varEl.asType(); 287 TypeMirror type = itTypes.next(); 288 289 if (type.getKind() != paramType.getKind()) { 291 return false; 292 } 293 294 if (type.getKind() == TypeKind.DECLARED) { 296 Element paramElm = ((DeclaredType) paramType).asElement(); 297 Element typeElm = ((DeclaredType) type).asElement(); 298 if (paramElm != typeElm) { 299 return false; 300 } 301 } else if (!ctrl.getTypes().isSameType(type, paramType)) { return false; 303 } 304 305 } 306 return true; 307 } 308 309 } | Popular Tags |