KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > retouche > source > 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.retouche.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.concurrent.CopyOnWriteArrayList JavaDoc;
39 import javax.swing.event.ChangeEvent JavaDoc;
40 import javax.swing.event.ChangeListener JavaDoc;
41 import org.netbeans.api.java.classpath.ClassPath;
42 import org.netbeans.api.java.classpath.GlobalPathRegistry;
43 import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
44 import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
45 import org.netbeans.api.java.queries.SourceForBinaryQuery;
46 import org.netbeans.spi.java.classpath.ClassPathImplementation;
47 import org.netbeans.spi.java.classpath.PathResourceImplementation;
48 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
49 import org.openide.ErrorManager;
50 import org.openide.filesystems.FileObject;
51 import org.openide.filesystems.FileStateInvalidException;
52 import org.openide.util.Utilities;
53 import org.openide.util.WeakListeners;
54
55 /**
56  * This file is originally from Retouche, the Java Support
57  * infrastructure in NetBeans. I have modified the file as little
58  * as possible to make merging Retouche fixes back as simple as
59  * possible.
60  *
61  *
62  * @author Tomas Zezula
63  */

64 public class GlobalSourcePath {
65     
66     private static GlobalSourcePath instance;
67     
68     private final GlobalPathRegistry gpr;
69     private List JavaDoc<? extends PathResourceImplementation> resources;
70     private List JavaDoc<? extends PathResourceImplementation> unknownResources;
71     private List JavaDoc<? extends PathResourceImplementation> binaryResources;
72     private Set JavaDoc<ClassPath> activeCps;
73     private Map JavaDoc<URL JavaDoc, SourceForBinaryQuery.Result> sourceResults;
74     private Map JavaDoc<URL JavaDoc, URL JavaDoc[]> translatedRoots;
75     private Map JavaDoc<URL JavaDoc, WeakValue> unknownRoots;
76     private long timeStamp; //Lamport event ordering
77
private Runnable JavaDoc debugCallBack;
78     
79     private final SourcePathImplementation sourcePath;
80     private final BinaryPathImplementation binaryPath;
81     private final UnknownSourcePathImplementation unknownSourcePath;
82     
83     private final Listener JavaDoc listener;
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     public URL JavaDoc[] getSourceRootForBinaryRoot (final URL JavaDoc binaryRoot, final ClassPath definingClassPath, final boolean fire) {
101         URL JavaDoc[] result = this.translatedRoots.get(binaryRoot);
102         if (result != null) {
103             if (result.length > 0) {
104                 return result;
105             }
106             else {
107                 return null;
108             }
109         }
110         else {
111             List JavaDoc<URL JavaDoc> cacheRoots = new ArrayList JavaDoc<URL JavaDoc> ();
112             Collection JavaDoc<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots(binaryRoot).getRoots(),cacheRoots,null);
113             if (unknownRes.isEmpty()) {
114                 return null;
115             }
116             else {
117                 result = new URL JavaDoc[cacheRoots.size()];
118                 synchronized (this) {
119                     Iterator JavaDoc<URL JavaDoc> it = cacheRoots.iterator();
120                     for (int i=0; it.hasNext(); i++) {
121                         result[i] = it.next ();
122                         unknownRoots.put(result[i],new WeakValue(definingClassPath,result[i]));
123                     }
124                 }
125                 if (fire) {
126                     this.resetCacheAndFire();
127                 }
128                 return result;
129             }
130         }
131     }
132     
133     public ClassPathImplementation getSourcePath () {
134         return this.sourcePath;
135     }
136     
137     public ClassPathImplementation getUnknownSourcePath () {
138         return this.unknownSourcePath;
139     }
140     
141     public ClassPathImplementation getBinaryPath () {
142         return this.binaryPath;
143     }
144     
145     private void resetCacheAndFire () {
146         synchronized (this) {
147             this.resources = null;
148             this.binaryResources = null;
149             this.unknownResources = null;
150             this.timeStamp++;
151         }
152         this.sourcePath.firePropertyChange ();
153         this.binaryPath.firePropertyChange ();
154         this.unknownSourcePath.firePropertyChange();
155     }
156     
157     private static Result createResources (final Request r) {
158         assert r != null;
159         Set JavaDoc<PathResourceImplementation> result = new HashSet JavaDoc<PathResourceImplementation> ();
160         Set JavaDoc<PathResourceImplementation> unknownResult = new HashSet JavaDoc<PathResourceImplementation> ();
161         Set JavaDoc<PathResourceImplementation> binaryResult = new HashSet JavaDoc<PathResourceImplementation> ();
162         final Map JavaDoc<URL JavaDoc,URL JavaDoc[]> translatedRoots = new HashMap JavaDoc<URL JavaDoc, URL JavaDoc[]>();
163         Set JavaDoc<ClassPath> newCps = new HashSet JavaDoc<ClassPath> ();
164         for (ClassPath cp : r.sourceCps) {
165             boolean isNew = !r.oldCps.remove(cp);
166             for (ClassPath.Entry entry : cp.entries()) {
167                 result.add(ClassPathSupport.createResource(entry.getURL()));
168             }
169             boolean notContained = newCps.add (cp);
170             if (isNew && notContained) {
171                 cp.addPropertyChangeListener(r.propertyListener);
172             }
173         }
174         // BEGIN TOR MODIFICATIONS
175
// NEW: Treat bootCps as a source path, not a binary - I want to scan
176
// directories
177
for (ClassPath cp : r.bootCps) {
178             boolean isNew = !r.oldCps.remove(cp);
179             for (ClassPath.Entry entry : cp.entries()) {
180                 result.add(ClassPathSupport.createResource(entry.getURL()));
181             }
182             boolean notContained = newCps.add (cp);
183             if (isNew && notContained) {
184                 cp.addPropertyChangeListener(r.propertyListener);
185             }
186         }
187         // END TOR MODIFICATIONS
188
Map JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> newSR = new HashMap JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> ();
189         /*
190         for (ClassPath cp : r.bootCps) {
191             boolean isNew = !r.oldCps.remove(cp);
192             for (ClassPath.Entry entry : cp.entries()) {
193                 URL url = entry.getURL();
194                 if (!translatedRoots.containsKey(url)) {
195                     SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
196                     boolean isNewSR;
197                     if (sr == null) {
198                         sr = SourceForBinaryQuery.findSourceRoots(url);
199                         isNewSR = true;
200                     }
201                     else {
202                         isNewSR = false;
203                     }
204                     assert !newSR.containsKey(url);
205                     newSR.put(url,sr);
206                     List<URL> cacheURLs = new ArrayList<URL> ();
207                     Collection<? extends PathResourceImplementation> srcRoots = getSources (sr.getRoots(), cacheURLs, r.unknownRoots);
208                     if (srcRoots.isEmpty()) {
209                         binaryResult.add (ClassPathSupport.createResource(url));
210                     }
211                     else {
212                         result.addAll(srcRoots);
213                     }
214                     translatedRoots.put(url, cacheURLs.toArray(new URL[cacheURLs.size()]));
215                     if (isNewSR) {
216                         sr.addChangeListener(r.changeListener);
217                     }
218                 }
219             }
220             boolean notContained = newCps.add (cp);
221             if (isNew && notContained) {
222                 cp.addPropertyChangeListener(r.propertyListener);
223             }
224         }
225          */

226         
227         for (ClassPath cp : r.compileCps) {
228             boolean isNew = !r.oldCps.remove(cp);
229             for (ClassPath.Entry entry : cp.entries()) {
230                 URL JavaDoc url = entry.getURL();
231                 if (!translatedRoots.containsKey(url)) {
232                     SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
233                     boolean isNewSR;
234                     if (sr == null) {
235                         sr = SourceForBinaryQuery.findSourceRoots(url);
236                         isNewSR = true;
237                     }
238                     else {
239                         isNewSR = false;
240                     }
241                     assert !newSR.containsKey(url);
242                     newSR.put(url,sr);
243                     List JavaDoc<URL JavaDoc> cacheURLs = new ArrayList JavaDoc<URL JavaDoc> ();
244                     Collection JavaDoc<? extends PathResourceImplementation> srcRoots = getSources(sr.getRoots(),cacheURLs, r.unknownRoots);
245                     if (srcRoots.isEmpty()) {
246                         binaryResult.add(ClassPathSupport.createResource(url));
247                     }
248                     else {
249                         result.addAll(srcRoots);
250                     }
251                     translatedRoots.put(url, cacheURLs.toArray(new URL JavaDoc[cacheURLs.size()]));
252                     if (isNewSR) {
253                         sr.addChangeListener(r.changeListener);
254                     }
255                 }
256             }
257             boolean notContained = newCps.add (cp);
258             if (isNew && notContained) {
259                 cp.addPropertyChangeListener(r.propertyListener);
260             }
261         }
262         
263         for (ClassPath cp : r.oldCps) {
264             cp.removePropertyChangeListener(r.propertyListener);
265         }
266         
267         for (Map.Entry JavaDoc<URL JavaDoc,SourceForBinaryQuery.Result> entry : r.oldSR.entrySet()) {
268             entry.getValue().removeChangeListener(r.changeListener);
269         }
270         for (URL JavaDoc unknownRoot : r.unknownRoots.keySet()) {
271             unknownResult.add (ClassPathSupport.createResource(unknownRoot));
272         }
273         return new Result (r.timeStamp, new ArrayList JavaDoc<PathResourceImplementation> (result), new ArrayList JavaDoc(binaryResult), new ArrayList JavaDoc<PathResourceImplementation>(unknownResult),
274                 newCps,newSR,translatedRoots, r.unknownRoots);
275     }
276     
277     /**
278      * Unit test method, used to set a callback which is called
279      * form getResources to emulate a race condition.
280      * The access to debugCallBack is not synchronized, it should be
281      * set before test and unset after test.
282      * @param callBack to be called
283      *
284      **/

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