Lines 44-53
Link Here
|
44 |
import java.beans.PropertyChangeEvent; |
44 |
import java.beans.PropertyChangeEvent; |
45 |
import java.beans.PropertyChangeListener; |
45 |
import java.beans.PropertyChangeListener; |
46 |
import java.lang.ref.WeakReference; |
46 |
import java.lang.ref.WeakReference; |
47 |
import java.net.URISyntaxException; |
|
|
48 |
import java.net.URL; |
47 |
import java.net.URL; |
49 |
import java.util.ArrayList; |
48 |
import java.util.ArrayList; |
50 |
import java.util.Arrays; |
|
|
51 |
import java.util.Collection; |
49 |
import java.util.Collection; |
52 |
import java.util.Collections; |
50 |
import java.util.Collections; |
53 |
import java.util.HashMap; |
51 |
import java.util.HashMap; |
Lines 58-89
Link Here
|
58 |
import java.util.Set; |
56 |
import java.util.Set; |
59 |
import java.util.TooManyListenersException; |
57 |
import java.util.TooManyListenersException; |
60 |
import java.util.concurrent.CopyOnWriteArrayList; |
58 |
import java.util.concurrent.CopyOnWriteArrayList; |
61 |
import java.util.logging.Logger; |
|
|
62 |
import javax.swing.event.ChangeEvent; |
59 |
import javax.swing.event.ChangeEvent; |
63 |
import javax.swing.event.ChangeListener; |
60 |
import javax.swing.event.ChangeListener; |
64 |
import org.netbeans.api.java.classpath.ClassPath; |
61 |
import org.netbeans.api.java.classpath.ClassPath; |
65 |
import org.netbeans.api.java.classpath.GlobalPathRegistry; |
62 |
import org.netbeans.api.java.classpath.GlobalPathRegistry; |
66 |
import org.netbeans.api.java.classpath.GlobalPathRegistryEvent; |
63 |
import org.netbeans.api.java.classpath.GlobalPathRegistryEvent; |
67 |
import org.netbeans.api.java.classpath.GlobalPathRegistryListener; |
64 |
import org.netbeans.api.java.classpath.GlobalPathRegistryListener; |
68 |
import org.netbeans.api.java.platform.JavaPlatform; |
|
|
69 |
import org.netbeans.api.java.platform.JavaPlatformManager; |
70 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
65 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
71 |
import org.netbeans.api.project.FileOwnerQuery; |
66 |
import org.netbeans.modules.java.source.usages.ClassIndexManager; |
72 |
import org.netbeans.api.project.Project; |
|
|
73 |
import org.netbeans.api.project.ProjectManager; |
74 |
import org.netbeans.api.project.SourceGroup; |
75 |
import org.netbeans.api.project.Sources; |
76 |
import org.netbeans.api.project.libraries.Library; |
77 |
import org.netbeans.api.project.libraries.LibraryManager; |
78 |
import org.netbeans.spi.java.classpath.ClassPathImplementation; |
67 |
import org.netbeans.spi.java.classpath.ClassPathImplementation; |
79 |
import org.netbeans.spi.java.classpath.PathResourceImplementation; |
68 |
import org.netbeans.spi.java.classpath.PathResourceImplementation; |
80 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
69 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
81 |
import org.netbeans.spi.project.libraries.support.LibrariesSupport; |
|
|
82 |
import org.openide.ErrorManager; |
83 |
import org.openide.filesystems.FileObject; |
70 |
import org.openide.filesystems.FileObject; |
84 |
import org.openide.filesystems.FileStateInvalidException; |
71 |
import org.openide.filesystems.FileStateInvalidException; |
85 |
import org.openide.util.Exceptions; |
72 |
import org.openide.util.Exceptions; |
86 |
import org.openide.util.Mutex; |
|
|
87 |
import org.openide.util.RequestProcessor; |
73 |
import org.openide.util.RequestProcessor; |
88 |
import org.openide.util.Utilities; |
74 |
import org.openide.util.Utilities; |
89 |
import org.openide.util.WeakListeners; |
75 |
import org.openide.util.WeakListeners; |
Lines 116-130
Link Here
|
116 |
private final BinaryPathImplementation binaryPath; |
102 |
private final BinaryPathImplementation binaryPath; |
117 |
private final UnknownSourcePathImplementation unknownSourcePath; |
103 |
private final UnknownSourcePathImplementation unknownSourcePath; |
118 |
|
104 |
|
119 |
private final JavaPlatformManager pm; |
|
|
120 |
private Set<JavaPlatform> seenPlatforms; |
121 |
private Set<Library> seenLibs; |
122 |
private Collection<LibraryManager> seenLibManagers; |
123 |
|
124 |
private Set<URL> libsSrcs; |
125 |
|
126 |
private final Listener listener; |
105 |
private final Listener listener; |
127 |
private final LibsListener libsListener; |
|
|
128 |
|
106 |
|
129 |
private volatile PropertyChangeListener excludesListener; |
107 |
private volatile PropertyChangeListener excludesListener; |
130 |
|
108 |
|
Lines 140-153
Link Here
|
140 |
this.sourceResults = Collections.emptyMap(); |
118 |
this.sourceResults = Collections.emptyMap(); |
141 |
this.unknownRoots = new HashMap<URL, WeakValue>(); |
119 |
this.unknownRoots = new HashMap<URL, WeakValue>(); |
142 |
this.translatedRoots = new HashMap<URL, URL[]> (); |
120 |
this.translatedRoots = new HashMap<URL, URL[]> (); |
143 |
this.gpr.addGlobalPathRegistryListener ((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class,this.listener,this.gpr)); |
121 |
this.gpr.addGlobalPathRegistryListener ((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class,this.listener,this.gpr)); |
144 |
this.seenPlatforms = new HashSet<JavaPlatform>(); |
|
|
145 |
this.seenLibs = new HashSet<Library> (); |
146 |
this.seenLibManagers = new HashSet<LibraryManager>(); |
147 |
this.libsListener = new LibsListener (); |
148 |
LibraryManager.addOpenManagersPropertyChangeListener(WeakListeners.propertyChange(libsListener, null)); |
149 |
this.pm = JavaPlatformManager.getDefault(); |
150 |
this.pm.addPropertyChangeListener(WeakListeners.propertyChange(libsListener, this.pm)); |
151 |
} |
122 |
} |
152 |
|
123 |
|
153 |
|
124 |
|
Lines 170-176
Link Here
|
170 |
} |
141 |
} |
171 |
else { |
142 |
else { |
172 |
List<URL> cacheRoots = new ArrayList<URL> (); |
143 |
List<URL> cacheRoots = new ArrayList<URL> (); |
173 |
Collection<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots(binaryRoot).getRoots(),cacheRoots,null); |
144 |
Collection<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots2(binaryRoot),cacheRoots,null); |
174 |
if (unknownRes.isEmpty()) { |
145 |
if (unknownRes.isEmpty()) { |
175 |
return null; |
146 |
return null; |
176 |
} |
147 |
} |
Lines 193-211
Link Here
|
193 |
|
164 |
|
194 |
public boolean isLibrary (final ClassPath cp) { |
165 |
public boolean isLibrary (final ClassPath cp) { |
195 |
assert cp != null; |
166 |
assert cp != null; |
196 |
Set<URL> libs = getLibsSources(); |
167 |
final ClassIndexManager mgr = ClassIndexManager.getDefault(); |
197 |
for (ClassPath.Entry entry : cp.entries()) { |
168 |
for (FileObject fo : cp.getRoots()) { |
198 |
if (libs.contains(entry.getURL())) { |
169 |
if (isLibrary (fo)) { |
199 |
return true; |
170 |
return true; |
200 |
} |
171 |
} |
201 |
} |
172 |
} |
202 |
return false; |
173 |
return false; |
203 |
} |
174 |
} |
204 |
|
175 |
|
205 |
public boolean isLibrary (final URL root) { |
176 |
public boolean isLibrary (final FileObject root) { |
206 |
assert root != null; |
177 |
assert root != null; |
207 |
Set<URL> libs = getLibsSources(); |
178 |
try { |
208 |
return libs.contains(root); |
179 |
return ClassIndexManager.getDefault().getUsagesQuery(root.getURL()) == null; |
|
|
180 |
} catch (FileStateInvalidException e) { |
181 |
Exceptions.printStackTrace(e); |
182 |
return true; //Safer |
183 |
} |
209 |
} |
184 |
} |
210 |
|
185 |
|
211 |
public ClassPathImplementation getSourcePath () { |
186 |
public ClassPathImplementation getSourcePath () { |
Lines 260-269
Link Here
|
260 |
for (ClassPath.Entry entry : cp.entries()) { |
235 |
for (ClassPath.Entry entry : cp.entries()) { |
261 |
URL url = entry.getURL(); |
236 |
URL url = entry.getURL(); |
262 |
if (!translatedRoots.containsKey(url)) { |
237 |
if (!translatedRoots.containsKey(url)) { |
263 |
SourceForBinaryQuery.Result sr = r.oldSR.remove (url); |
238 |
SourceForBinaryQuery.Result2 sr = r.oldSR.remove (url); |
264 |
boolean isNewSR; |
239 |
boolean isNewSR; |
265 |
if (sr == null) { |
240 |
if (sr == null) { |
266 |
sr = SourceForBinaryQuery.findSourceRoots(url); |
241 |
sr = SourceForBinaryQuery.findSourceRoots2(url); |
267 |
isNewSR = true; |
242 |
isNewSR = true; |
268 |
} |
243 |
} |
269 |
else { |
244 |
else { |
Lines 272-278
Link Here
|
272 |
assert !newSR.containsKey(url); |
247 |
assert !newSR.containsKey(url); |
273 |
newSR.put(url,sr); |
248 |
newSR.put(url,sr); |
274 |
List<URL> cacheURLs = new ArrayList<URL> (); |
249 |
List<URL> cacheURLs = new ArrayList<URL> (); |
275 |
Collection<? extends PathResourceImplementation> srcRoots = getSources (sr.getRoots(), cacheURLs, r.unknownRoots); |
250 |
Collection<? extends PathResourceImplementation> srcRoots = getSources (sr, cacheURLs, r.unknownRoots); |
276 |
if (srcRoots.isEmpty()) { |
251 |
if (srcRoots.isEmpty()) { |
277 |
binaryResult.add (ClassPathSupport.createResource(url)); |
252 |
binaryResult.add (ClassPathSupport.createResource(url)); |
278 |
} |
253 |
} |
Lines 296-305
Link Here
|
296 |
for (ClassPath.Entry entry : cp.entries()) { |
271 |
for (ClassPath.Entry entry : cp.entries()) { |
297 |
URL url = entry.getURL(); |
272 |
URL url = entry.getURL(); |
298 |
if (!translatedRoots.containsKey(url)) { |
273 |
if (!translatedRoots.containsKey(url)) { |
299 |
SourceForBinaryQuery.Result sr = r.oldSR.remove (url); |
274 |
SourceForBinaryQuery.Result2 sr = r.oldSR.remove (url); |
300 |
boolean isNewSR; |
275 |
boolean isNewSR; |
301 |
if (sr == null) { |
276 |
if (sr == null) { |
302 |
sr = SourceForBinaryQuery.findSourceRoots(url); |
277 |
sr = SourceForBinaryQuery.findSourceRoots2(url); |
303 |
isNewSR = true; |
278 |
isNewSR = true; |
304 |
} |
279 |
} |
305 |
else { |
280 |
else { |
Lines 308-314
Link Here
|
308 |
assert !newSR.containsKey(url); |
283 |
assert !newSR.containsKey(url); |
309 |
newSR.put(url,sr); |
284 |
newSR.put(url,sr); |
310 |
List<URL> cacheURLs = new ArrayList<URL> (); |
285 |
List<URL> cacheURLs = new ArrayList<URL> (); |
311 |
Collection<? extends PathResourceImplementation> srcRoots = getSources(sr.getRoots(),cacheURLs, r.unknownRoots); |
286 |
Collection<? extends PathResourceImplementation> srcRoots = getSources(sr,cacheURLs, r.unknownRoots); |
312 |
if (srcRoots.isEmpty()) { |
287 |
if (srcRoots.isEmpty()) { |
313 |
binaryResult.add(ClassPathSupport.createResource(url)); |
288 |
binaryResult.add(ClassPathSupport.createResource(url)); |
314 |
} |
289 |
} |
Lines 331-337
Link Here
|
331 |
cp.removePropertyChangeListener(r.propertyListener); |
306 |
cp.removePropertyChangeListener(r.propertyListener); |
332 |
} |
307 |
} |
333 |
|
308 |
|
334 |
for (Map.Entry<URL,SourceForBinaryQuery.Result> entry : r.oldSR.entrySet()) { |
309 |
for (Map.Entry<URL,SourceForBinaryQuery.Result2> entry : r.oldSR.entrySet()) { |
335 |
entry.getValue().removeChangeListener(r.changeListener); |
310 |
entry.getValue().removeChangeListener(r.changeListener); |
336 |
} |
311 |
} |
337 |
for (URL unknownRoot : r.unknownRoots.keySet()) { |
312 |
for (URL unknownRoot : r.unknownRoots.keySet()) { |
Lines 377-521
Link Here
|
377 |
} |
352 |
} |
378 |
} |
353 |
} |
379 |
|
354 |
|
380 |
private Collection <? extends PathResourceImplementation> getSources (final FileObject[] roots, final List<URL> cacheDirs, final Map<URL, WeakValue> unknownRoots) { |
355 |
private Collection <? extends PathResourceImplementation> getSources (final SourceForBinaryQuery.Result2 sr, final List<URL> cacheDirs, final Map<URL, WeakValue> unknownRoots) { |
381 |
assert roots != null; |
356 |
assert sr != null; |
382 |
URL[] urls = new URL[roots.length]; |
357 |
if (sr.preferSources()) { |
383 |
boolean add = true; |
358 |
final FileObject[] roots = sr.getRoots(); |
384 |
Set<URL> libs = getLibsSources(); |
359 |
assert roots != null; |
385 |
for (int i=0; i<roots.length; i++) { |
|
|
386 |
try { |
387 |
URL url = roots[i].getURL(); |
388 |
if (!"file".equals(url.getProtocol())) { //NOI18N |
389 |
add = false; |
390 |
break; |
391 |
} |
392 |
if (libs.contains (url)) { |
393 |
add = false; |
394 |
break; |
395 |
} |
396 |
urls[i] = url; |
397 |
} catch (FileStateInvalidException e) { |
398 |
ErrorManager.getDefault().notify(e); |
399 |
} |
400 |
} |
401 |
if (add) { |
402 |
List<PathResourceImplementation> result = new ArrayList<PathResourceImplementation> (roots.length); |
360 |
List<PathResourceImplementation> result = new ArrayList<PathResourceImplementation> (roots.length); |
403 |
for (int i=0; i<urls.length; i++) { |
361 |
for (int i=0; i<roots.length; i++) { |
|
|
362 |
try { |
363 |
final URL url = roots[i].getURL(); |
404 |
if (cacheDirs != null) { |
364 |
if (cacheDirs != null) { |
405 |
cacheDirs.add (urls[i]); |
365 |
cacheDirs.add (url); |
406 |
} |
366 |
} |
407 |
if (unknownRoots != null) { |
367 |
if (unknownRoots != null) { |
408 |
unknownRoots.remove (urls[i]); |
368 |
unknownRoots.remove (url); |
409 |
} |
369 |
} |
410 |
result.add(ClassPathSupport.createResource(urls[i])); |
370 |
result.add(ClassPathSupport.createResource(url)); |
|
|
371 |
} catch (FileStateInvalidException e) { |
372 |
Exceptions.printStackTrace(e); |
373 |
} |
411 |
} |
374 |
} |
412 |
return result; |
375 |
return result; |
413 |
} |
376 |
} |
414 |
return Collections.<PathResourceImplementation>emptySet(); |
377 |
else { |
415 |
} |
378 |
return Collections.<PathResourceImplementation>emptySet(); |
416 |
|
|
|
417 |
private Set<URL> getLibsSources () { |
418 |
if (!useLibraries) { |
419 |
//Running in the test where libraries modules SPI is not initialized |
420 |
return Collections.<URL>emptySet(); |
421 |
} |
379 |
} |
422 |
// retrieve list outside of java mutex: |
|
|
423 |
final Collection<LibraryManager> libraryManagers = LibraryManager.getOpenManagers(); |
424 |
final Mutex.Action<Set<URL>> libsTask = new Mutex.Action<Set<URL>> () { |
425 |
public Set<URL> run () { |
426 |
synchronized (GlobalSourcePath.this) { |
427 |
if (GlobalSourcePath.this.libsSrcs == null) { |
428 |
final Set<URL> _libSrcs = new HashSet<URL>(); |
429 |
Set<JavaPlatform> platforms = new HashSet<JavaPlatform> (Arrays.asList(pm.getInstalledPlatforms())); |
430 |
Set<JavaPlatform> oldPlatforms = new HashSet<JavaPlatform> (GlobalSourcePath.this.seenPlatforms); |
431 |
OUTER: for (JavaPlatform platform : platforms) { |
432 |
if (!oldPlatforms.remove(platform)) { |
433 |
platform.addPropertyChangeListener(GlobalSourcePath.this.libsListener); |
434 |
} |
435 |
ClassPath cp = platform.getSourceFolders(); |
436 |
assert cp != null : platform.getClass(); |
437 |
for (ClassPath.Entry e : cp.entries()) { |
438 |
URL url = e.getURL(); |
439 |
try { |
440 |
Project p = FileOwnerQuery.getOwner(url.toURI()); |
441 |
if (p != null) { |
442 |
Sources src = p.getLookup().lookup(Sources.class); |
443 |
if (src != null) { |
444 |
for (SourceGroup group : src.getSourceGroups("java")) { //NOI18N |
445 |
if (url.equals(group.getRootFolder().getURL())) { |
446 |
continue OUTER; |
447 |
} |
448 |
} |
449 |
} |
450 |
} |
451 |
} catch (URISyntaxException ex) { |
452 |
Exceptions.printStackTrace(ex); |
453 |
} |
454 |
catch (FileStateInvalidException ex) { |
455 |
Exceptions.printStackTrace(ex); |
456 |
} |
457 |
_libSrcs.add(url); |
458 |
} |
459 |
} |
460 |
for (JavaPlatform platform : oldPlatforms) { |
461 |
platform.removePropertyChangeListener(GlobalSourcePath.this.libsListener); |
462 |
} |
463 |
GlobalSourcePath.this.seenPlatforms = platforms; |
464 |
|
465 |
for (LibraryManager lm : GlobalSourcePath.this.seenLibManagers) { |
466 |
lm.removePropertyChangeListener(libsListener); |
467 |
} |
468 |
Set<Library> oldLibs = new HashSet<Library>(GlobalSourcePath.this.seenLibs); |
469 |
Set<Library> newLibs = new HashSet<Library>(); |
470 |
for (LibraryManager lm : libraryManagers) { |
471 |
lm.addPropertyChangeListener(libsListener); |
472 |
|
473 |
Set<Library> libs = new HashSet<Library> (Arrays.asList(lm.getLibraries())); |
474 |
OUTER: for (Library lib :libs) { |
475 |
newLibs.add(lib); |
476 |
if (!oldLibs.remove(lib)) { |
477 |
lib.addPropertyChangeListener(GlobalSourcePath.this.libsListener); |
478 |
} |
479 |
if (lib.getContent("classpath") != null) { //NOI18N |
480 |
List<URL> libSrc = lib.getContent("src"); //NOI18N |
481 |
for (URL url : libSrc) { |
482 |
try { |
483 |
url = LibrariesSupport.resolveLibraryEntryURL(lm.getLocation(), url); |
484 |
Project p = FileOwnerQuery.getOwner(url.toURI()); |
485 |
if (p != null) { |
486 |
Sources src = p.getLookup().lookup(Sources.class); |
487 |
if (src != null) { |
488 |
for (SourceGroup group : src.getSourceGroups("java")) { //NOI18N |
489 |
if (url.equals(group.getRootFolder().getURL())) { |
490 |
continue OUTER; |
491 |
} |
492 |
} |
493 |
} |
494 |
} |
495 |
} catch (URISyntaxException ex) { |
496 |
Exceptions.printStackTrace(ex); |
497 |
} |
498 |
catch (FileStateInvalidException ex) { |
499 |
Exceptions.printStackTrace(ex); |
500 |
} |
501 |
_libSrcs.add(url); |
502 |
} |
503 |
|
504 |
} |
505 |
} |
506 |
} |
507 |
for (Library lib : oldLibs) { |
508 |
lib.removePropertyChangeListener(GlobalSourcePath.this.libsListener); |
509 |
} |
510 |
GlobalSourcePath.this.seenLibManagers = libraryManagers; |
511 |
GlobalSourcePath.this.seenLibs = newLibs; |
512 |
GlobalSourcePath.this.libsSrcs = _libSrcs; |
513 |
} |
514 |
return GlobalSourcePath.this.libsSrcs; |
515 |
} |
516 |
} |
517 |
}; |
518 |
return ProjectManager.mutex().readAccess(libsTask); |
519 |
} |
380 |
} |
520 |
|
381 |
|
521 |
private class WeakValue extends WeakReference<ClassPath> implements Runnable { |
382 |
private class WeakValue extends WeakReference<ClassPath> implements Runnable { |
Lines 550-562
Link Here
|
550 |
final Set<ClassPath> bootCps; |
411 |
final Set<ClassPath> bootCps; |
551 |
final Set<ClassPath> compileCps; |
412 |
final Set<ClassPath> compileCps; |
552 |
final Set<ClassPath> oldCps; |
413 |
final Set<ClassPath> oldCps; |
553 |
final Map <URL, SourceForBinaryQuery.Result> oldSR; |
414 |
final Map <URL, SourceForBinaryQuery.Result2> oldSR; |
554 |
final Map<URL, WeakValue> unknownRoots; |
415 |
final Map<URL, WeakValue> unknownRoots; |
555 |
final PropertyChangeListener propertyListener; |
416 |
final PropertyChangeListener propertyListener; |
556 |
final ChangeListener changeListener; |
417 |
final ChangeListener changeListener; |
557 |
|
418 |
|
558 |
public Request (final long timeStamp, final Set<ClassPath> sourceCps, final Set<ClassPath> bootCps, final Set<ClassPath> compileCps, |
419 |
public Request (final long timeStamp, final Set<ClassPath> sourceCps, final Set<ClassPath> bootCps, final Set<ClassPath> compileCps, |
559 |
final Set<ClassPath> oldCps, final Map <URL, SourceForBinaryQuery.Result> oldSR, final Map<URL, WeakValue> unknownRoots, |
420 |
final Set<ClassPath> oldCps, final Map <URL, SourceForBinaryQuery.Result2> oldSR, final Map<URL, WeakValue> unknownRoots, |
560 |
final PropertyChangeListener propertyListener, final ChangeListener changeListener) { |
421 |
final PropertyChangeListener propertyListener, final ChangeListener changeListener) { |
561 |
assert sourceCps != null; |
422 |
assert sourceCps != null; |
562 |
assert bootCps != null; |
423 |
assert bootCps != null; |
Lines 867-882
Link Here
|
867 |
} |
728 |
} |
868 |
} |
729 |
} |
869 |
|
730 |
|
870 |
private class LibsListener implements PropertyChangeListener { |
|
|
871 |
|
872 |
public void propertyChange(PropertyChangeEvent evt) { |
873 |
synchronized (GlobalSourcePath.this) { |
874 |
GlobalSourcePath.this.libsSrcs = null; |
875 |
} |
876 |
} |
877 |
|
878 |
} |
879 |
|
880 |
public static synchronized GlobalSourcePath getDefault () { |
731 |
public static synchronized GlobalSourcePath getDefault () { |
881 |
if (instance == null) { |
732 |
if (instance == null) { |
882 |
instance = new GlobalSourcePath (); |
733 |
instance = new GlobalSourcePath (); |