KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javadoc > search > SrcFinder


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

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 JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.logging.Level JavaDoc;
34 import java.util.logging.Logger JavaDoc;
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 /** This class finds the source to show it instead of documentation.
58  *
59  */

60 public final class SrcFinder extends Object JavaDoc {
61
62     /** SrcFinder is a singleton */
63     private SrcFinder() {
64     }
65
66     static Object JavaDoc[]/*FileObject, ElementHandle*/ findSource(String JavaDoc aPackage, URL JavaDoc url) {
67
68         aPackage = aPackage.replace( '.', '/' ); // NOI18N
69
String JavaDoc thePackage = null;
70         final String JavaDoc member = url.getRef();
71         String JavaDoc clazz = url.getFile();
72         String JavaDoc 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 // System.out.println("================================");
90
// System.out.println("URL :" + url );
91
// System.out.println("aPCKG :" + aPackage );
92
// System.out.println("--------------------------------");
93
// System.out.println("MEMBER :" + member ); // NOI18N
94
// System.out.println("CLASS :" + clazz ); // NOI18N
95
// System.out.println("PACKAGE :" + thePackage ); // NOI18N
96
// System.out.println("FILENAME:" + filename ); // NOI18N
97

98         String JavaDoc resourceName = thePackage + "/" + filename + ".java"; // NOI18N
99
FileObject fo = searchResource(url, resourceName);
100         
101         final ElementHandle[] handles = new ElementHandle[1];
102         
103         if ( fo != null ) {
104             final String JavaDoc 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 JavaDoc {
114                         ctrl.toPhase(Phase.ELEMENTS_RESOLVED);
115                         TypeElement classElm = findClass(ctrl, className);
116                         if (classElm == null) {
117                             // bad luck
118
} else if (member == null) {
119                             handles[0] = ElementHandle.create(classElm);
120                         } else {
121                             int pi = member.indexOf('(');
122                             if (pi == -1) {
123                                 // we are looking for fields
124
handles[0] = findField(classElm, member);
125                             } else {
126                                 // We are looking for method or constructor
127
handles[0] = findMethod(ctrl, classElm, member );
128                             }
129                         }
130                     }
131                 }, true);
132             } catch (IOException JavaDoc ex) {
133                 Logger.getLogger(SrcFinder.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
134             }
135             
136         }
137         return handles[0] != null? new Object JavaDoc[]{fo, handles[0]}: null;
138     }
139
140     /**
141      * searches the file corresponding to javadoc url on all source path.
142      * {@link GlobalPathRegistry#findResource}
143      * is insufficient due to returning just the first occurrence of the file. So having
144      * two platforms installed would bring troubles.
145      * @param url javadoc
146      * @param respath resource in form java/lang/Character.java
147      * @return the file
148      */

149     private static FileObject searchResource(URL JavaDoc url, String JavaDoc 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 JavaDoc classPathID, String JavaDoc respath, URL JavaDoc url) {
165         Set JavaDoc<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 JavaDoc respath, URL JavaDoc url) {
183         Set JavaDoc<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     /**
195      * checks if the javadoc url is assigned to a given classpath
196      * @param cpath classpath
197      * @param url javadoc
198      * @return is assigned?
199      */

200     private static boolean isJavadocAssigned(ClassPath cpath, URL JavaDoc url) {
201         FileObject[] cpRoots = cpath.getRoots();
202         String JavaDoc 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 JavaDoc[] jdRoots = result.getRoots();
206             for (int j = 0; j < jdRoots.length; j++) {
207                 String JavaDoc 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 JavaDoc 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 JavaDoc 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     /** Gets the method we are looking for
240      */

241     private static ElementHandle findMethod(CompilationController ctrl, TypeElement ce, String JavaDoc member) {
242         TreeUtilities utils = ctrl.getTreeUtilities();
243
244         int pi = member.indexOf( '(' );
245         String JavaDoc name = member.substring( 0, pi );
246
247         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc( member.substring( pi ), " ,()" ); // NOI18N
248
List JavaDoc<TypeMirror> paramList = new ArrayList JavaDoc<TypeMirror>();
249
250         while( tokenizer.hasMoreTokens() ) {
251             String JavaDoc token = tokenizer.nextToken();
252             if (token.endsWith("...")) { // NOI18N
253
// translate varargs to array
254
token = token.substring(0, token.length() - 3);
255                 token += "[]"; // NOI18N
256
}
257             TypeMirror type = utils.parseType(token, ce);
258             paramList.add(type);
259         }
260         
261         // search method or constructor
262
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 JavaDoc<TypeMirror> types, List JavaDoc<? extends VariableElement> params) {
278         if (types.size() != params.size()) {
279             return false;
280         }
281         
282         Iterator JavaDoc<? extends VariableElement> itParams = params.iterator();
283         Iterator JavaDoc<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             // check types are the same kind
290
if (type.getKind() != paramType.getKind()) {
291                 return false;
292             }
293             
294             // check elements since javadoc ignores generics
295
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)) { // arrays, primitives
302
return false;
303             }
304             
305         }
306         return true;
307     }
308
309 }
Popular Tags