KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > classpath > GlobalSourcePath


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.java.source.classpath;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.beans.PropertyChangeListener JavaDoc;
26 import java.lang.ref.WeakReference JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.HashSet JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.TooManyListenersException JavaDoc;
39 import java.util.concurrent.CopyOnWriteArrayList JavaDoc;
40 import javax.swing.event.ChangeEvent JavaDoc;
41 import javax.swing.event.ChangeListener JavaDoc;
42 import org.netbeans.api.java.classpath.ClassPath;
43 import org.netbeans.api.java.classpath.GlobalPathRegistry;
44 import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
45 import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
46 import org.netbeans.api.java.queries.SourceForBinaryQuery;
47 import org.netbeans.spi.java.classpath.ClassPathImplementation;
48 import org.netbeans.spi.java.classpath.PathResourceImplementation;
49 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
50 import org.openide.ErrorManager;
51 import org.openide.filesystems.FileObject;
52 import org.openide.filesystems.FileStateInvalidException;
53 import org.openide.util.Utilities;
54 import org.openide.util.WeakListeners;
55
56 /**
57  *
58  * @author Tomas Zezula
59  */

60 public class GlobalSourcePath {
61     
62     public static final String JavaDoc PROP_INCLUDES = ClassPath.PROP_INCLUDES;
63     
64     private static GlobalSourcePath instance;
65     
66     private final GlobalPathRegistry gpr;
67     private List JavaDoc<? extends PathResourceImplementation> resources;
68     private List JavaDoc<? extends PathResourceImplementation> unknownResources;
69     private List JavaDoc<? extends PathResourceImplementation> binaryResources;
70     private Set JavaDoc<ClassPath> activeCps;
71     private Map JavaDoc<URL JavaDoc, SourceForBinaryQuery.Result> sourceResults;
72     private Map JavaDoc<URL JavaDoc, URL JavaDoc[]> translatedRoots;
73     private Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots;
74     private long timeStamp; //Lamport event ordering
75
private Runnable JavaDoc debugCallBack;
76     
77     private final SourcePathImplementation sourcePath;
78     private final BinaryPathImplementation binaryPath;
79     private final UnknownSourcePathImplementation unknownSourcePath;
80     
81     private final Listener JavaDoc listener;
82     
83     private PropertyChangeListener JavaDoc excludesListener;
84
85     /** Creates a new instance of GlobalSourcePath */
86     private GlobalSourcePath() {
87         this.listener = new Listener JavaDoc ();
88         this.sourcePath = new SourcePathImplementation ();
89         this.binaryPath = new BinaryPathImplementation ();
90         this.unknownSourcePath = new UnknownSourcePathImplementation ();
91         this.timeStamp = -1;
92         this.gpr = GlobalPathRegistry.getDefault();
93         this.activeCps = Collections.emptySet();
94         this.sourceResults = Collections.emptyMap();
95         this.unknownRoots = new HashMap JavaDoc<URL JavaDoc, WeakValue>();
96         this.translatedRoots = new HashMap JavaDoc<URL JavaDoc, URL JavaDoc[]> ();
97         this.gpr.addGlobalPathRegistryListener ((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class,this.listener,this.gpr));
98     }
99     
100     
101     public void setExcludesListener (final PropertyChangeListener JavaDoc listener) throws TooManyListenersException JavaDoc {
102         if (this.excludesListener != null) {
103             throw new TooManyListenersException JavaDoc ();
104         }
105         this.excludesListener=listener;
106     }
107     
108     public URL JavaDoc[] getSourceRootForBinaryRoot (final URL JavaDoc binaryRoot, final ClassPath definingClassPath, final boolean fire) {
109         URL JavaDoc[] result = this.translatedRoots.get(binaryRoot);
110         if (result != null) {
111             if (result.length > 0) {
112                 return result;
113             }
114             else {
115                 return null;
116             }
117         }
118         else {
119             List JavaDoc<URL JavaDoc> cacheRoots = new ArrayList JavaDoc<URL JavaDoc> ();
120             Collection JavaDoc<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots(binaryRoot).getRoots(),cacheRoots,null);
121             if (unknownRes.isEmpty()) {
122                 return null;
123             }
124             else {
125                 result = new URL JavaDoc[cacheRoots.size()];
126                 synchronized (this) {
127                     Iterator JavaDoc<URL JavaDoc> it = cacheRoots.iterator();
128                     for (int i=0; it.hasNext(); i++) {
129                         result[i] = it.next ();
130                         unknownRoots.put(result[i],new WeakValue(definingClassPath,result[i]));
131                     }
132                 }
133                 if (fire) {
134                     this.resetCacheAndFire();
135                 }
136                 return result;
137             }
138         }
139     }
140     
141     public ClassPathImplementation getSourcePath () {
142         return this.sourcePath;
143     }
144     
145     public ClassPathImplementation getUnknownSourcePath () {
146         return this.unknownSourcePath;
147     }
148     
149     public ClassPathImplementation getBinaryPath () {
150         return this.binaryPath;
151     }
152     
153     private void resetCacheAndFire () {
154         synchronized (this) {
155             this.resources = null;
156             this.binaryResources = null;
157             this.unknownResources = null;
158             this.timeStamp++;
159         }
160         this.sourcePath.firePropertyChange ();
161         this.binaryPath.firePropertyChange ();
162         this.unknownSourcePath.firePropertyChange();
163     }
164     
165     private static Result createResources (final Request r) {
166         assert r != null;
167         Set JavaDoc<PathResourceImplementation> result = new HashSet JavaDoc<PathResourceImplementation> ();
168         Set JavaDoc<PathResourceImplementation> unknownResult = new HashSet JavaDoc<PathResourceImplementation> ();
169         Set JavaDoc<PathResourceImplementation> binaryResult = new HashSet JavaDoc<PathResourceImplementation> ();
170         final Map JavaDoc<URL JavaDoc,URL JavaDoc[]> translatedRoots = new HashMap JavaDoc<URL JavaDoc, URL JavaDoc[]>();
171         Set JavaDoc<ClassPath> newCps = new HashSet JavaDoc<ClassPath> ();
172         for (ClassPath cp : r.sourceCps) {
173             boolean isNew = !r.oldCps.remove(cp);
174             for (ClassPath.Entry entry : cp.entries()) {
175                 result.add(ClassPathSupport.createResource(entry.getURL()));
176             }
177             boolean notContained = newCps.add (cp);
178             if (isNew && notContained) {
179                cp.addPropertyChangeListener(r.propertyListener);
180             }
181         }
182         Map JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> newSR = new HashMap JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> ();
183         for (ClassPath cp : r.bootCps) {
184             boolean isNew = !r.oldCps.remove(cp);
185             for (ClassPath.Entry entry : cp.entries()) {
186                 URL JavaDoc url = entry.getURL();
187                 if (!translatedRoots.containsKey(url)) {
188                     SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
189                     boolean isNewSR;
190                     if (sr == null) {
191                         sr = SourceForBinaryQuery.findSourceRoots(url);
192                         isNewSR = true;
193                     }
194                     else {
195                         isNewSR = false;
196                     }
197                     assert !newSR.containsKey(url);
198                     newSR.put(url,sr);
199                     List JavaDoc<URL JavaDoc> cacheURLs = new ArrayList JavaDoc<URL JavaDoc> ();
200                     Collection JavaDoc<? extends PathResourceImplementation> srcRoots = getSources (sr.getRoots(), cacheURLs, r.unknownRoots);
201                     if (srcRoots.isEmpty()) {
202                         binaryResult.add (ClassPathSupport.createResource(url));
203                     }
204                     else {
205                         result.addAll(srcRoots);
206                     }
207                     translatedRoots.put(url, cacheURLs.toArray(new URL JavaDoc[cacheURLs.size()]));
208                     if (isNewSR) {
209                         sr.addChangeListener(r.changeListener);
210                     }
211                 }
212             }
213             boolean notContained = newCps.add (cp);
214             if (isNew && notContained) {
215                 cp.addPropertyChangeListener(r.propertyListener);
216             }
217         }
218         
219         for (ClassPath cp : r.compileCps) {
220             boolean isNew = !r.oldCps.remove(cp);
221             for (ClassPath.Entry entry : cp.entries()) {
222                 URL JavaDoc url = entry.getURL();
223                 if (!translatedRoots.containsKey(url)) {
224                     SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
225                     boolean isNewSR;
226                     if (sr == null) {
227                         sr = SourceForBinaryQuery.findSourceRoots(url);
228                         isNewSR = true;
229                     }
230                     else {
231                         isNewSR = false;
232                     }
233                     assert !newSR.containsKey(url);
234                     newSR.put(url,sr);
235                     List JavaDoc<URL JavaDoc> cacheURLs = new ArrayList JavaDoc<URL JavaDoc> ();
236                     Collection JavaDoc<? extends PathResourceImplementation> srcRoots = getSources(sr.getRoots(),cacheURLs, r.unknownRoots);
237                     if (srcRoots.isEmpty()) {
238                         binaryResult.add(ClassPathSupport.createResource(url));
239                     }
240                     else {
241                         result.addAll(srcRoots);
242                     }
243                     translatedRoots.put(url, cacheURLs.toArray(new URL JavaDoc[cacheURLs.size()]));
244                     if (isNewSR) {
245                         sr.addChangeListener(r.changeListener);
246                     }
247                 }
248             }
249             boolean notContained = newCps.add (cp);
250             if (isNew && notContained) {
251                 cp.addPropertyChangeListener(r.propertyListener);
252             }
253         }
254         
255         for (ClassPath cp : r.oldCps) {
256             cp.removePropertyChangeListener(r.propertyListener);
257         }
258         
259         for (Map.Entry JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> entry : r.oldSR.entrySet()) {
260             entry.getValue().removeChangeListener(r.changeListener);
261         }
262         for (URL JavaDoc unknownRoot : r.unknownRoots.keySet()) {
263             unknownResult.add (ClassPathSupport.createResource(unknownRoot));
264         }
265         return new Result (r.timeStamp, new ArrayList JavaDoc<PathResourceImplementation> (result), new ArrayList JavaDoc(binaryResult), new ArrayList JavaDoc<PathResourceImplementation>(unknownResult),
266                 newCps,newSR,translatedRoots, r.unknownRoots);
267     }
268     
269     /**
270      * Unit test method, used to set a callback which is called
271      * form getResources to emulate a race condition.
272      * The access to debugCallBack is not synchronized, it should be
273      * set before test and unset after test.
274      * @param callBack to be called
275      *
276      **/

277     void setDebugCallBack (final Runnable JavaDoc callBack) {
278         this.debugCallBack = callBack;
279     }
280     
281     private static Collection JavaDoc <? extends PathResourceImplementation> getSources (final FileObject[] roots, final List JavaDoc<URL JavaDoc> cacheDirs, final Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots) {
282         assert roots != null;
283         URL JavaDoc[] urls = new URL JavaDoc[roots.length];
284         boolean add = true;
285         for (int i=0; i<roots.length; i++) {
286             try {
287                 URL JavaDoc url = roots[i].getURL();
288                 if (!"file".equals(url.getProtocol())) { //NOI18N
289
add = false;
290                     break;
291                 }
292                 urls[i] = url;
293             } catch (FileStateInvalidException e) {
294                 ErrorManager.getDefault().notify(e);
295             }
296         }
297         if (add) {
298             List JavaDoc<PathResourceImplementation> result = new ArrayList JavaDoc<PathResourceImplementation> (roots.length);
299             for (int i=0; i<urls.length; i++) {
300                 if (cacheDirs != null) {
301                     cacheDirs.add (urls[i]);
302                 }
303                 if (unknownRoots != null) {
304                     unknownRoots.remove (urls[i]);
305                 }
306                 result.add(ClassPathSupport.createResource(urls[i]));
307             }
308             return result;
309         }
310         return Collections.<PathResourceImplementation>emptySet();
311     }
312        
313     private class WeakValue extends WeakReference JavaDoc<ClassPath> implements Runnable JavaDoc {
314         
315         private URL JavaDoc key;
316         
317         public WeakValue (ClassPath ref, URL JavaDoc key) {
318             super (ref, Utilities.activeReferenceQueue());
319             assert key != null;
320             this.key = key;
321         }
322         
323         public void run () {
324             boolean fire = false;
325             synchronized (GlobalSourcePath.this) {
326                 fire = (GlobalSourcePath.this.unknownRoots.remove (key) != null);
327             }
328             if (fire) {
329                 GlobalSourcePath.this.resetCacheAndFire();
330             }
331         }
332     }
333     
334     private long getTimeStamp () {
335         return this.timeStamp;
336     }
337     
338     private static class Request {
339         
340         final long timeStamp;
341         final Set JavaDoc<ClassPath> sourceCps;
342         final Set JavaDoc<ClassPath> bootCps;
343         final Set JavaDoc<ClassPath> compileCps;
344         final Set JavaDoc<ClassPath> oldCps;
345         final Map JavaDoc <URL JavaDoc, SourceForBinaryQuery.Result> oldSR;
346         final Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots;
347         final PropertyChangeListener JavaDoc propertyListener;
348         final ChangeListener JavaDoc changeListener;
349         
350         public Request (final long timeStamp, final Set JavaDoc<ClassPath> sourceCps, final Set JavaDoc<ClassPath> bootCps, final Set JavaDoc<ClassPath> compileCps,
351             final Set JavaDoc<ClassPath> oldCps, final Map JavaDoc <URL JavaDoc, SourceForBinaryQuery.Result> oldSR, final Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots,
352             final PropertyChangeListener JavaDoc propertyListener, final ChangeListener JavaDoc changeListener) {
353             assert sourceCps != null;
354             assert bootCps != null;
355             assert compileCps != null;
356             assert oldCps != null;
357             assert oldSR != null;
358             assert unknownRoots != null;
359             assert propertyListener != null;
360             assert changeListener != null;
361             
362             this.timeStamp = timeStamp;
363             this.sourceCps = sourceCps;
364             this.bootCps = bootCps;
365             this.compileCps = compileCps;
366             this.oldCps = oldCps;
367             this.oldSR = oldSR;
368             this.unknownRoots = unknownRoots;
369             this.propertyListener = propertyListener;
370             this.changeListener = changeListener;
371         }
372     }
373     
374     private static class Result {
375      
376         final long timeStamp;
377         final List JavaDoc<? extends PathResourceImplementation> resources;
378         final List JavaDoc<? extends PathResourceImplementation> binaryResources;
379         final List JavaDoc<? extends PathResourceImplementation> unknownResources;
380         final Set JavaDoc<ClassPath> newCps;
381         final Map JavaDoc<URL JavaDoc, SourceForBinaryQuery.Result> newSR;
382         final Map JavaDoc<URL JavaDoc, URL JavaDoc[]> translatedRoots;
383         final Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots;
384         
385         public Result (final long timeStamp, final List JavaDoc<? extends PathResourceImplementation> resources,
386             final List JavaDoc<? extends PathResourceImplementation> binaryResources,
387             final List JavaDoc<? extends PathResourceImplementation> unknownResources,
388             final Set JavaDoc<ClassPath> newCps,
389             final Map JavaDoc<URL JavaDoc, SourceForBinaryQuery.Result> newSR, final Map JavaDoc<URL JavaDoc, URL JavaDoc[]> translatedRoots,
390             final Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots) {
391             assert resources != null;
392             assert binaryResources != null;
393             assert unknownResources != null;
394             assert newCps != null;
395             assert newSR != null;
396             assert translatedRoots != null;
397             this.timeStamp = timeStamp;
398             this.resources = resources;
399             this.binaryResources = binaryResources;
400             this.unknownResources = unknownResources;
401             this.newCps = newCps;
402             this.newSR = newSR;
403             this.translatedRoots = translatedRoots;
404             this.unknownRoots = unknownRoots;
405         }
406     }
407     
408     private class SourcePathImplementation implements ClassPathImplementation {
409         
410         private List JavaDoc<PropertyChangeListener JavaDoc> listeners = new ArrayList JavaDoc<PropertyChangeListener JavaDoc>();
411         
412     
413         public List JavaDoc<? extends PathResourceImplementation> getResources() {
414             Request request;
415             synchronized (GlobalSourcePath.this) {
416                 if (GlobalSourcePath.this.resources != null) {
417                     return GlobalSourcePath.this.resources;
418                 }
419                 request = new Request (
420                     GlobalSourcePath.this.getTimeStamp(),
421                     GlobalSourcePath.this.gpr.getPaths(ClassPath.SOURCE),
422                     GlobalSourcePath.this.gpr.getPaths(ClassPath.BOOT),
423                     GlobalSourcePath.this.gpr.getPaths(ClassPath.COMPILE),
424                     new HashSet JavaDoc (GlobalSourcePath.this.activeCps),
425                     new HashMap JavaDoc (GlobalSourcePath.this.sourceResults),
426                     new HashMap JavaDoc<URL JavaDoc,WeakValue> (GlobalSourcePath.this.unknownRoots),
427                     GlobalSourcePath.this.listener,
428                     GlobalSourcePath.this.listener);
429             }
430             Result res = createResources (request);
431             if (GlobalSourcePath.this.debugCallBack != null) {
432                 GlobalSourcePath.this.debugCallBack.run();
433             }
434             synchronized (this) {
435                 if (GlobalSourcePath.this.getTimeStamp() == res.timeStamp) {
436                     if (GlobalSourcePath.this.resources == null) {
437                         GlobalSourcePath.this.resources = res.resources;
438                         GlobalSourcePath.this.binaryResources = res.binaryResources;
439                         GlobalSourcePath.this.unknownResources = res.unknownResources;
440                         GlobalSourcePath.this.activeCps = res.newCps;
441                         GlobalSourcePath.this.sourceResults = res.newSR;
442                         GlobalSourcePath.this.translatedRoots = res.translatedRoots;
443                         GlobalSourcePath.this.unknownRoots = res.unknownRoots;
444                     }
445                     return GlobalSourcePath.this.resources;
446                 }
447                 else {
448                     return res.resources;
449                 }
450             }
451         }
452     
453         public synchronized void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
454             assert listener != null;
455             if (this.listeners == null) {
456                 this.listeners = new ArrayList JavaDoc<PropertyChangeListener JavaDoc> ();
457             }
458             this.listeners.add (listener);
459         }
460
461         public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
462             assert listener != null;
463             if (this.listeners == null) {
464                 return;
465             }
466             this.listeners.remove(listener);
467         }
468         
469         void firePropertyChange () {
470             PropertyChangeListener JavaDoc[] _listeners;
471             synchronized (this) {
472                 if (this.listeners == null) {
473                     return;
474                 }
475                 _listeners = this.listeners.toArray(new PropertyChangeListener JavaDoc[this.listeners.size()]);
476             }
477             PropertyChangeEvent JavaDoc event = new PropertyChangeEvent JavaDoc (this,PROP_RESOURCES,null,null);
478             for (PropertyChangeListener JavaDoc l : _listeners) {
479                 l.propertyChange (event);
480             }
481         }
482     }
483     
484     private class UnknownSourcePathImplementation implements ClassPathImplementation {
485         
486         private List JavaDoc<PropertyChangeListener JavaDoc> listeners = new CopyOnWriteArrayList JavaDoc<PropertyChangeListener JavaDoc> ();
487     
488         public List JavaDoc<? extends PathResourceImplementation> getResources() {
489             Request request;
490             synchronized (GlobalSourcePath.this) {
491                 if (GlobalSourcePath.this.unknownResources != null) {
492                     return GlobalSourcePath.this.unknownResources;
493                 }
494                 request = new Request (
495                     GlobalSourcePath.this.getTimeStamp(),
496                     GlobalSourcePath.this.gpr.getPaths(ClassPath.SOURCE),
497                     GlobalSourcePath.this.gpr.getPaths(ClassPath.BOOT),
498                     GlobalSourcePath.this.gpr.getPaths(ClassPath.COMPILE),
499                     new HashSet JavaDoc (GlobalSourcePath.this.activeCps),
500                     new HashMap JavaDoc (GlobalSourcePath.this.sourceResults),
501                     new HashMap JavaDoc<URL JavaDoc, WeakValue> (GlobalSourcePath.this.unknownRoots),
502                     GlobalSourcePath.this.listener,
503                     GlobalSourcePath.this.listener);
504             }
505             Result res = createResources (request);
506             if (GlobalSourcePath.this.debugCallBack != null) {
507                 GlobalSourcePath.this.debugCallBack.run();
508             }
509             synchronized (this) {
510                 if (GlobalSourcePath.this.getTimeStamp() == res.timeStamp) {
511                     if (GlobalSourcePath.this.binaryResources == null) {
512                         GlobalSourcePath.this.resources = res.resources;
513                         GlobalSourcePath.this.binaryResources = res.binaryResources;
514                         GlobalSourcePath.this.unknownResources = res.unknownResources;
515                         GlobalSourcePath.this.activeCps = res.newCps;
516                         GlobalSourcePath.this.sourceResults = res.newSR;
517                         GlobalSourcePath.this.translatedRoots = res.translatedRoots;
518                         GlobalSourcePath.this.unknownRoots = res.unknownRoots;
519                     }
520                     return GlobalSourcePath.this.unknownResources;
521                 }
522                 else {
523                     return res.unknownResources;
524                 }
525             }
526         }
527
528         public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
529             assert listener != null;
530             this.listeners.add (listener);
531         }
532
533         public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
534             assert listener != null;
535             this.listeners.remove (listener);
536         }
537         
538         
539         void firePropertyChange () {
540             PropertyChangeEvent JavaDoc event = new PropertyChangeEvent JavaDoc (this,PROP_RESOURCES,null,null);
541             for (PropertyChangeListener JavaDoc l : this.listeners) {
542                 l.propertyChange (event);
543             }
544         }
545 }
546     
547     private class BinaryPathImplementation implements ClassPathImplementation {
548         private List JavaDoc<PropertyChangeListener JavaDoc> listeners = new ArrayList JavaDoc<PropertyChangeListener JavaDoc>();
549     
550         public List JavaDoc<? extends PathResourceImplementation> getResources() {
551             Request request;
552             synchronized (GlobalSourcePath.this) {
553                 if (GlobalSourcePath.this.binaryResources != null) {
554                     return GlobalSourcePath.this.binaryResources;
555                 }
556                 request = new Request (
557                     GlobalSourcePath.this.getTimeStamp(),
558                     GlobalSourcePath.this.gpr.getPaths(ClassPath.SOURCE),
559                     GlobalSourcePath.this.gpr.getPaths(ClassPath.BOOT),
560                     GlobalSourcePath.this.gpr.getPaths(ClassPath.COMPILE),
561                     new HashSet JavaDoc(GlobalSourcePath.this.activeCps),
562                     new HashMap JavaDoc(GlobalSourcePath.this.sourceResults),
563                     new HashMap JavaDoc<URL JavaDoc, WeakValue> (GlobalSourcePath.this.unknownRoots),
564                     GlobalSourcePath.this.listener,
565                     GlobalSourcePath.this.listener);
566             }
567             Result res = createResources (request);
568             if (GlobalSourcePath.this.debugCallBack != null) {
569                 GlobalSourcePath.this.debugCallBack.run();
570             }
571             synchronized (this) {
572                 if (GlobalSourcePath.this.getTimeStamp() == res.timeStamp) {
573                     if (GlobalSourcePath.this.binaryResources == null) {
574                         GlobalSourcePath.this.resources = res.resources;
575                         GlobalSourcePath.this.binaryResources = res.binaryResources;
576                         GlobalSourcePath.this.unknownResources = res.unknownResources;
577                         GlobalSourcePath.this.activeCps = res.newCps;
578                         GlobalSourcePath.this.sourceResults = res.newSR;
579                         GlobalSourcePath.this.translatedRoots = res.translatedRoots;
580                         GlobalSourcePath.this.unknownRoots = res.unknownRoots;
581                     }
582                     return GlobalSourcePath.this.binaryResources;
583                 }
584                 else {
585                     return res.binaryResources;
586                 }
587             }
588         }
589         
590         public synchronized void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
591             assert listener != null;
592             if (this.listeners == null) {
593                 this.listeners = new ArrayList JavaDoc<PropertyChangeListener JavaDoc> ();
594             }
595             this.listeners.add (listener);
596         }
597
598         public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
599             assert listener != null;
600             if (this.listeners == null) {
601                 return;
602             }
603             this.listeners.remove(listener);
604         }
605         
606         void firePropertyChange () {
607             PropertyChangeListener JavaDoc[] _listeners;
608             synchronized (this) {
609                 if (this.listeners == null) {
610                     return;
611                 }
612                 _listeners = this.listeners.toArray(new PropertyChangeListener JavaDoc[this.listeners.size()]);
613             }
614             PropertyChangeEvent JavaDoc event = new PropertyChangeEvent JavaDoc (this,PROP_RESOURCES,null,null);
615             for (PropertyChangeListener JavaDoc l : _listeners) {
616                 l.propertyChange (event);
617             }
618         }
619     }
620     
621     
622     private class Listener implements GlobalPathRegistryListener, PropertyChangeListener JavaDoc, ChangeListener JavaDoc {
623         
624             public void pathsAdded(GlobalPathRegistryEvent event) {
625                 resetCacheAndFire ();
626             }
627
628             public void pathsRemoved(GlobalPathRegistryEvent event) {
629                 resetCacheAndFire ();
630             }
631
632             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
633                 String JavaDoc propName = evt.getPropertyName();
634                 if (ClassPath.PROP_ENTRIES.equals(propName)) {
635                     resetCacheAndFire ();
636                 }
637                 else if (ClassPath.PROP_INCLUDES.equals(propName)) {
638                     if (excludesListener != null) {
639                         PropertyChangeEvent JavaDoc event = new PropertyChangeEvent JavaDoc (this,PROP_INCLUDES,evt.getSource(),evt.getSource());
640                         excludesListener.propertyChange(event);
641                     }
642                 }
643             }
644     
645             public void stateChanged (ChangeEvent JavaDoc event) {
646                 resetCacheAndFire();
647             }
648     }
649     
650     public static synchronized GlobalSourcePath getDefault () {
651         if (instance == null) {
652             instance = new GlobalSourcePath ();
653         }
654         return instance;
655     }
656     
657 }
658
Popular Tags