diff -r e9ab20458c3f java.sourceui/src/org/netbeans/modules/java/source/ui/JavaTypeProvider.java --- a/java.sourceui/src/org/netbeans/modules/java/source/ui/JavaTypeProvider.java Tue Dec 08 17:02:56 2009 +0100 +++ b/java.sourceui/src/org/netbeans/modules/java/source/ui/JavaTypeProvider.java Wed Dec 09 13:53:35 2009 +0100 @@ -347,13 +347,8 @@ } if (types.isEmpty() && scanInProgress) { - try { - synchronized (JavaTypeProvider.this) { - this.wait(2000); - } - } catch (InterruptedException ex) { - Exceptions.printStackTrace(ex); - } + res.pendingResult(); + return; } if ( isCanceled ) { diff -r e9ab20458c3f jumpto/apichanges.xml --- a/jumpto/apichanges.xml Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/apichanges.xml Wed Dec 09 13:53:35 2009 +0100 @@ -121,6 +121,22 @@ + + + Added method (Type|Symbol)Provider.Result.pendingResult() + + + + + + Added method TypeProvider.Result.pendingResult() and + SymbolProvider.Result.pendingResult() to notify + provider's caller that the provider should be called again. + + + + + diff -r e9ab20458c3f jumpto/manifest.mf --- a/jumpto/manifest.mf Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/manifest.mf Wed Dec 09 13:53:35 2009 +0100 @@ -2,5 +2,5 @@ OpenIDE-Module: org.netbeans.modules.jumpto/1 OpenIDE-Module-Layer: org/netbeans/modules/jumpto/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jumpto/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.13 +OpenIDE-Module-Specification-Version: 1.14 AutoUpdate-Show-In-Client: false diff -r e9ab20458c3f jumpto/src/org/netbeans/modules/jumpto/symbol/SymbolProviderAccessor.java --- a/jumpto/src/org/netbeans/modules/jumpto/symbol/SymbolProviderAccessor.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/src/org/netbeans/modules/jumpto/symbol/SymbolProviderAccessor.java Wed Dec 09 13:53:35 2009 +0100 @@ -45,6 +45,7 @@ import org.netbeans.spi.jumpto.symbol.SymbolProvider; import org.netbeans.spi.jumpto.type.SearchType; import org.openide.util.Exceptions; +import static org.netbeans.spi.jumpto.symbol.SymbolProvider.*; /** * @@ -65,4 +66,6 @@ public abstract SymbolProvider.Context createContext(Project p, String text, SearchType t); public abstract SymbolProvider.Result createResult(List result, String[] message); + + public abstract int getRetry(Result result); } diff -r e9ab20458c3f jumpto/src/org/netbeans/modules/jumpto/type/GoToTypeAction.java --- a/jumpto/src/org/netbeans/modules/jumpto/type/GoToTypeAction.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/src/org/netbeans/modules/jumpto/type/GoToTypeAction.java Wed Dec 09 13:53:35 2009 +0100 @@ -397,45 +397,59 @@ } public void run() { - Profile profile = initializeProfiling(); - try { - LOGGER.fine( "Worker for " + text + " - started " + ( System.currentTimeMillis() - createTime ) + " ms." ); + for (;;) { + final int[] retry = new int[1]; - final List types = getTypeNames( text ); - if ( isCanceled ) { - LOGGER.fine( "Worker for " + text + " exited after cancel " + ( System.currentTimeMillis() - createTime ) + " ms." ); + Profile profile = initializeProfiling(); + try { + LOGGER.fine( "Worker for " + text + " - started " + ( System.currentTimeMillis() - createTime ) + " ms." ); + + final List types = getTypeNames(text, retry); + if ( isCanceled ) { + LOGGER.fine( "Worker for " + text + " exited after cancel " + ( System.currentTimeMillis() - createTime ) + " ms." ); + return; + } + ListModel model = Models.fromList(types); + if (typeFilter != null) { + model = LazyListModel.create(model, GoToTypeAction.this, 0.1, "Not computed yet"); + } + final ListModel fmodel = model; + if ( isCanceled ) { + LOGGER.fine( "Worker for " + text + " exited after cancel " + ( System.currentTimeMillis() - createTime ) + " ms." ); + return; + } + + if ( !isCanceled && fmodel != null ) { + LOGGER.fine( "Worker for text " + text + " finished after " + ( System.currentTimeMillis() - createTime ) + " ms." ); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + panel.setModel(fmodel); + if (okButton != null && !types.isEmpty()) { + okButton.setEnabled (true); + } + } + }); + } + } finally { + if (profile != null) { + try { + profile.stop(); + } catch (Exception ex) { + LOGGER.log(Level.INFO, "Cannot stop profiling", ex); + } + } + } + + if (retry[0] > 0) { + try { + Thread.sleep(retry[0]); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } + } else { return; } - ListModel model = Models.fromList(types); - if (typeFilter != null) { - model = LazyListModel.create(model, GoToTypeAction.this, 0.1, "Not computed yet"); - } - final ListModel fmodel = model; - if ( isCanceled ) { - LOGGER.fine( "Worker for " + text + " exited after cancel " + ( System.currentTimeMillis() - createTime ) + " ms." ); - return; - } - - if ( !isCanceled && fmodel != null ) { - LOGGER.fine( "Worker for text " + text + " finished after " + ( System.currentTimeMillis() - createTime ) + " ms." ); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel.setModel(fmodel); - if (okButton != null && !types.isEmpty()) { - okButton.setEnabled (true); - } - } - }); - } - } finally { - if (profile != null) { - try { - profile.stop(); - } catch (Exception ex) { - LOGGER.log(Level.INFO, "Cannot stop profiling", ex); - } - } - } + } // for } public void cancel() { @@ -453,7 +467,7 @@ } @SuppressWarnings("unchecked") - private List getTypeNames(String text) { + private List getTypeNames(String text, int[] retry) { // TODO: Search twice, first for current project, then for all projects List items; // Multiple providers: merge results @@ -478,8 +492,8 @@ } long delta = System.currentTimeMillis() - start; LOGGER.fine("Provider '" + provider.getDisplayName() + "' took " + delta + " ms."); - } + retry[0] = TypeProviderAccessor.DEFAULT.getRetry(result); if ( !isCanceled ) { //time = System.currentTimeMillis(); Collections.sort(items, new TypeComparator()); @@ -526,7 +540,7 @@ final void waitSearchFinished() { task.waitFinished(); } - + private static class Renderer extends DefaultListCellRenderer implements ChangeListener { private MyPanel rendererComponent; diff -r e9ab20458c3f jumpto/src/org/netbeans/modules/jumpto/type/TypeProviderAccessor.java --- a/jumpto/src/org/netbeans/modules/jumpto/type/TypeProviderAccessor.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/src/org/netbeans/modules/jumpto/type/TypeProviderAccessor.java Wed Dec 09 13:53:35 2009 +0100 @@ -64,4 +64,6 @@ public abstract Context createContext(Project p, String text, SearchType t); public abstract Result createResult(List result, String[] message); + + public abstract int getRetry(Result result); } diff -r e9ab20458c3f jumpto/src/org/netbeans/spi/jumpto/symbol/SymbolProvider.java --- a/jumpto/src/org/netbeans/spi/jumpto/symbol/SymbolProvider.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/src/org/netbeans/spi/jumpto/symbol/SymbolProvider.java Wed Dec 09 13:53:35 2009 +0100 @@ -135,7 +135,14 @@ @Override public Result createResult(List result, String[] message) { return new Result(result, message); - } + } + + @Override + public int getRetry(Result result) { + return result.retry; + } + + }; } @@ -179,6 +186,7 @@ private List result; private String[] message; + private int retry; Result(List result, String[] message) { this.result = result; @@ -213,6 +221,19 @@ public void addResult(List symbolDescriptor) { ((List)result).addAll(symbolDescriptor); //workaround javac issue http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6507334 } + + /** + * Notify caller that a provider should be called again because + * of incomplete or inaccurate results. + * + * Method can be used when long running task blocks the provider + * to complete the data. + * + * @since 1.14 + */ + public void pendingResult() { + retry = 2000; + } } } diff -r e9ab20458c3f jumpto/src/org/netbeans/spi/jumpto/type/TypeProvider.java --- a/jumpto/src/org/netbeans/spi/jumpto/type/TypeProvider.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/src/org/netbeans/spi/jumpto/type/TypeProvider.java Wed Dec 09 13:53:35 2009 +0100 @@ -138,6 +138,11 @@ public Result createResult(List result, String[] message) { return new Result(result, message); } + + @Override + public int getRetry(Result result) { + return result.retry; + } }; } @@ -182,6 +187,7 @@ private List result; private String[] message; + private int retry; Result(List result, String[] message) { this.result = result; @@ -216,6 +222,19 @@ public void addResult(List typeDescriptor) { ((List)result).addAll(typeDescriptor); //workaround javac issue http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6507334 } + + /** + * Notify caller that a provider should be called again because + * of incomplete or inaccurate results. + * + * Method can be used when long running task blocks the provider + * to complete the data. + * + * @since 1.14 + */ + public void pendingResult() { + retry = 2000; + } } } diff -r e9ab20458c3f jumpto/test/unit/src/org/netbeans/modules/jumpto/type/GoToTypeActionTest.java --- a/jumpto/test/unit/src/org/netbeans/modules/jumpto/type/GoToTypeActionTest.java Tue Dec 08 17:02:56 2009 +0100 +++ b/jumpto/test/unit/src/org/netbeans/modules/jumpto/type/GoToTypeActionTest.java Wed Dec 09 13:53:35 2009 +0100 @@ -69,6 +69,16 @@ action.waitSearchFinished(); assertEquals("Provider queried once", 1, TestTypeProvider.count); } + + public void testPendingResults() throws IOException { + TestTypeProvider.count = 10; + GoToTypeAction action = new GoToTypeAction(); + TypeDescriptor desc = action.getSelectedType(false); + panel = action.panel; + panel.nameField.setText("Pepik"); + action.waitSearchFinished(); + assertEquals("Provider queried once", 12, TestTypeProvider.count); + } @Override protected void tearDown() throws Exception { @@ -90,7 +100,7 @@ final String text = panel.messageLabel.getText(); assertTrue(text, text.startsWith("Searching")); count++; -//SPI if (count == 1) result.pendingResult(); + if (count == 10) result.pendingResult(); } public void cancel() {