diff --git a/api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java b/api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java --- a/api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java +++ b/api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java @@ -46,6 +46,9 @@ import java.net.URL; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.event.ChangeEvent; @@ -58,6 +61,8 @@ import org.openide.util.ChangeSupport; import org.openide.util.Lookup; import org.openide.util.Parameters; +import org.openide.util.RequestProcessor; +import org.openide.util.RequestProcessor.Task; import org.openide.util.WeakListeners; /** @@ -115,6 +120,22 @@ public static Result2 findSourceRoots2 (URL binaryRoot) { // XXX as above, consider deleting SimplePathResourceImplementation.verify(binaryRoot, null); + Result2 r = foo(binaryRoot); + + if (r != null) { + return r; + } + + EmptyResultImpl eri = new EmptyResultImpl(binaryRoot); + + emptyCache.put(binaryRoot, eri); + + W.schedule(1000); + + return new Result2(eri); + } + + private static Result2 foo(URL binaryRoot) { for (SourceForBinaryQueryImplementation impl : implementations.allInstances()) { Result2 result = null; if (impl instanceof SourceForBinaryQueryImplementation2) { @@ -137,10 +158,75 @@ } } LOG.log(Level.FINE, "findSourceRoots2({0}) -> nil", binaryRoot); - return EMPTY_RESULT2; + return null; } + private static final Map emptyCache = new HashMap(); + + private static final Task W = RequestProcessor.getDefault().create(new Runnable() { + + @Override + public void run() { + for (EmptyResultImpl r : emptyCache.values()) r.update(); + W.schedule(1000); + } + }); + + private static final class EmptyResultImpl implements SourceForBinaryQueryImplementation2.Result, ChangeListener { + + private final ChangeSupport cs = new ChangeSupport(this); + private final AtomicReference delegate = new AtomicReference(); + private final URL binaryRoot; + + public EmptyResultImpl(URL binaryRoot) { + this.binaryRoot = binaryRoot; + } + + @Override + public boolean preferSources() { + Result2 r = delegate.get(); + + if (r == null) return false; + return r.preferSources(); + } + + @Override + public FileObject[] getRoots() { + Result2 r = delegate.get(); + + if (r == null) return new FileObject[0]; + return r.getRoots(); + } + + @Override + public void addChangeListener(ChangeListener l) { + cs.addChangeListener(l); + } + + @Override + public void removeChangeListener(ChangeListener l) { + cs.removeChangeListener(l); + } + + private void update() { + if (delegate.get() == null) { + Result2 r = foo(binaryRoot); + + if (r != null) { + delegate.set(r); + r.addChangeListener(this); + cs.fireChange(); + } + } + } + + @Override + public void stateChanged(ChangeEvent e) { + cs.fireChange(); + } + + } /** * Result of finding sources, encapsulating the answer as well as the * ability to listen to it.