Lines 61-66
Link Here
|
61 |
import java.util.Set; |
61 |
import java.util.Set; |
62 |
import java.util.StringTokenizer; |
62 |
import java.util.StringTokenizer; |
63 |
import java.util.WeakHashMap; |
63 |
import java.util.WeakHashMap; |
|
|
64 |
import java.util.concurrent.Callable; |
65 |
import java.util.concurrent.Future; |
66 |
import java.util.concurrent.TimeUnit; |
67 |
import java.util.concurrent.TimeoutException; |
64 |
import java.util.logging.Level; |
68 |
import java.util.logging.Level; |
65 |
import java.util.logging.Logger; |
69 |
import java.util.logging.Logger; |
66 |
import javax.lang.model.element.Element; |
70 |
import javax.lang.model.element.Element; |
Lines 81-86
Link Here
|
81 |
import org.openide.filesystems.FileStateInvalidException; |
85 |
import org.openide.filesystems.FileStateInvalidException; |
82 |
import org.openide.filesystems.FileUtil; |
86 |
import org.openide.filesystems.FileUtil; |
83 |
import org.openide.filesystems.URLMapper; |
87 |
import org.openide.filesystems.URLMapper; |
|
|
88 |
import org.openide.util.RequestProcessor; |
84 |
|
89 |
|
85 |
/** |
90 |
/** |
86 |
* Utilities to assist with retrieval of Javadoc text. |
91 |
* Utilities to assist with retrieval of Javadoc text. |
Lines 88-93
Link Here
|
88 |
public class JavadocHelper { |
93 |
public class JavadocHelper { |
89 |
|
94 |
|
90 |
private static final Logger LOG = Logger.getLogger(JavadocHelper.class.getName()); |
95 |
private static final Logger LOG = Logger.getLogger(JavadocHelper.class.getName()); |
|
|
96 |
private static final RequestProcessor RP = new RequestProcessor(JavadocHelper.class.getName(),1); |
91 |
|
97 |
|
92 |
private JavadocHelper() {} |
98 |
private JavadocHelper() {} |
93 |
|
99 |
|
Lines 185-200
Link Here
|
185 |
} |
191 |
} |
186 |
|
192 |
|
187 |
private static final Map<Element,TextStream> cachedJavadoc = new WeakHashMap<Element,TextStream>(); |
193 |
private static final Map<Element,TextStream> cachedJavadoc = new WeakHashMap<Element,TextStream>(); |
188 |
|
194 |
|
189 |
/** |
195 |
/** |
190 |
* Richer version of {@link SourceUtils#getJavadoc}. |
196 |
* Richer version of {@link SourceUtils#getJavadoc}. |
191 |
* Finds {@link URL} of a javadoc page for given element when available. This method |
197 |
* Finds {@link URL} of a javadoc page for given element when available. This method |
192 |
* uses {@link JavadocForBinaryQuery} to find the javadoc page for the give element. |
198 |
* uses {@link JavadocForBinaryQuery} to find the javadoc page for the give element. |
193 |
* For {@link PackageElement} it returns the package-summary.html for given package. |
199 |
* For {@link PackageElement} it returns the package-summary.html for given package. |
194 |
* @param element to find the Javadoc for |
200 |
* @param element to find the Javadoc for |
|
|
201 |
* @param cancel a Callable to signal cancel request |
195 |
* @return the javadoc page or null when the javadoc is not available. |
202 |
* @return the javadoc page or null when the javadoc is not available. |
196 |
*/ |
203 |
*/ |
197 |
public static TextStream getJavadoc(Element element) { |
204 |
public static TextStream getJavadoc(Element element, final Callable<Boolean> cancel) { |
198 |
synchronized (cachedJavadoc) { |
205 |
synchronized (cachedJavadoc) { |
199 |
TextStream result = cachedJavadoc.get(element); |
206 |
TextStream result = cachedJavadoc.get(element); |
200 |
if (result != null) { |
207 |
if (result != null) { |
Lines 202-220
Link Here
|
202 |
return result; |
209 |
return result; |
203 |
} |
210 |
} |
204 |
} |
211 |
} |
205 |
TextStream result = doGetJavadoc(element); |
212 |
TextStream result = doGetJavadoc(element, cancel); |
206 |
synchronized (cachedJavadoc) { |
213 |
synchronized (cachedJavadoc) { |
207 |
cachedJavadoc.put(element, result); |
214 |
cachedJavadoc.put(element, result); |
208 |
} |
215 |
} |
209 |
return result; |
216 |
return result; |
210 |
} |
217 |
} |
211 |
|
218 |
|
|
|
219 |
public static TextStream getJavadoc(Element element) { |
220 |
return getJavadoc(element, null); |
221 |
} |
222 |
|
212 |
@org.netbeans.api.annotations.common.SuppressWarnings(value="DMI_COLLECTION_OF_URLS"/*,justification="URLs have never host part"*/) |
223 |
@org.netbeans.api.annotations.common.SuppressWarnings(value="DMI_COLLECTION_OF_URLS"/*,justification="URLs have never host part"*/) |
213 |
private static TextStream doGetJavadoc(final Element element) { |
224 |
private static TextStream doGetJavadoc(final Element element, final Callable<Boolean> cancel) { |
214 |
if (element == null) { |
225 |
if (element == null) { |
215 |
throw new IllegalArgumentException("Cannot pass null as an argument of the SourceUtils.getJavadoc"); // NOI18N |
226 |
throw new IllegalArgumentException("Cannot pass null as an argument of the SourceUtils.getJavadoc"); // NOI18N |
216 |
} |
227 |
} |
217 |
|
|
|
218 |
ClassSymbol clsSym = null; |
228 |
ClassSymbol clsSym = null; |
219 |
String pkgName; |
229 |
String pkgName; |
220 |
String pageName; |
230 |
String pageName; |
Lines 258-282
Link Here
|
258 |
if (clsSym.completer != null) { |
268 |
if (clsSym.completer != null) { |
259 |
clsSym.complete(); |
269 |
clsSym.complete(); |
260 |
} |
270 |
} |
|
|
271 |
if (clsSym.classfile != null) { |
272 |
try { |
273 |
final URL classFile = clsSym.classfile.toUri().toURL(); |
274 |
final String pkgNameF = pkgName; |
275 |
final String pageNameF = pageName; |
276 |
final CharSequence fragment = buildFragment ? getFragment(element) : null; |
277 |
final Future<TextStream> future = RP.submit(new Callable<TextStream>() { |
278 |
@Override |
279 |
public TextStream call() throws Exception { |
280 |
return findJavadoc(classFile, pkgNameF, pageNameF, fragment); |
281 |
} |
282 |
}); |
283 |
do { |
284 |
if (cancel != null && cancel.call()) { |
285 |
break; |
286 |
} |
287 |
try { |
288 |
return future.get(100, TimeUnit.MILLISECONDS); |
289 |
} catch (TimeoutException timeOut) { |
290 |
//Retry |
291 |
} |
292 |
} while (true); |
293 |
} catch (Exception e) { |
294 |
LOG.log(Level.INFO, null, e); |
295 |
} |
296 |
} |
297 |
return null; |
298 |
} |
299 |
|
300 |
private static final String PACKAGE_SUMMARY = "package-summary"; // NOI18N |
301 |
|
302 |
private static TextStream findJavadoc( |
303 |
final URL classFile, |
304 |
final String pkgName, |
305 |
final String pageName, |
306 |
final CharSequence fragment) { |
261 |
|
307 |
|
262 |
URL sourceRoot = null; |
308 |
URL sourceRoot = null; |
263 |
Set<URL> binaries = new HashSet<URL>(); |
309 |
Set<URL> binaries = new HashSet<URL>(); |
264 |
try { |
310 |
try { |
265 |
if (clsSym.classfile != null) { |
311 |
FileObject fo = URLMapper.findFileObject(classFile); |
266 |
FileObject fo = URLMapper.findFileObject(clsSym.classfile.toUri().toURL()); |
312 |
StringTokenizer tk = new StringTokenizer(pkgName, "/"); // NOI18N |
267 |
StringTokenizer tk = new StringTokenizer(pkgName, "/"); // NOI18N |
313 |
for (int i = 0; fo != null && i <= tk.countTokens(); i++) { |
268 |
for (int i = 0; fo != null && i <= tk.countTokens(); i++) { |
314 |
fo = fo.getParent(); |
269 |
fo = fo.getParent(); |
315 |
} |
270 |
} |
316 |
if (fo != null) { |
271 |
if (fo != null) { |
317 |
URL url = fo.getURL(); |
272 |
URL url = fo.getURL(); |
318 |
sourceRoot = JavaIndex.getSourceRootForClassFolder(url); |
273 |
sourceRoot = JavaIndex.getSourceRootForClassFolder(url); |
319 |
if (sourceRoot == null) { |
274 |
if (sourceRoot == null) { |
320 |
binaries.add(url); |
275 |
binaries.add(url); |
321 |
} else { |
276 |
} else { |
322 |
// sourceRoot may be a class root in reality |
277 |
// sourceRoot may be a class root in reality |
323 |
binaries.add(sourceRoot); |
278 |
binaries.add(sourceRoot); |
|
|
279 |
} |
280 |
} |
324 |
} |
281 |
} |
325 |
} |
282 |
if (sourceRoot != null) { |
326 |
if (sourceRoot != null) { |
Lines 303-310
Link Here
|
303 |
out: |
347 |
out: |
304 |
for (URL e : roots) { |
348 |
for (URL e : roots) { |
305 |
FileObject[] res = SourceForBinaryQuery.findSourceRoots(e).getRoots(); |
349 |
FileObject[] res = SourceForBinaryQuery.findSourceRoots(e).getRoots(); |
306 |
for (FileObject fo : res) { |
350 |
for (FileObject r : res) { |
307 |
if (sourceRoots.contains(fo)) { |
351 |
if (sourceRoots.contains(r)) { |
308 |
binaries.add(e); |
352 |
binaries.add(e); |
309 |
continue out; |
353 |
continue out; |
310 |
} |
354 |
} |
Lines 313-319
Link Here
|
313 |
} |
357 |
} |
314 |
} |
358 |
} |
315 |
} |
359 |
} |
316 |
CharSequence fragment = buildFragment ? getFragment(element) : null; |
360 |
|
317 |
for (URL binary : binaries) { |
361 |
for (URL binary : binaries) { |
318 |
JavadocForBinaryQuery.Result javadocResult = JavadocForBinaryQuery.findJavadoc(binary); |
362 |
JavadocForBinaryQuery.Result javadocResult = JavadocForBinaryQuery.findJavadoc(binary); |
319 |
URL[] result = javadocResult.getRoots(); |
363 |
URL[] result = javadocResult.getRoots(); |
Lines 366-373
Link Here
|
366 |
} |
410 |
} |
367 |
return null; |
411 |
return null; |
368 |
} |
412 |
} |
369 |
|
|
|
370 |
private static final String PACKAGE_SUMMARY = "package-summary"; // NOI18N |
371 |
|
413 |
|
372 |
/** |
414 |
/** |
373 |
* {@code ElementJavadoc} currently will check every class in an API set if you keep on using code completion. |
415 |
* {@code ElementJavadoc} currently will check every class in an API set if you keep on using code completion. |