This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 106505
Collapse All | Expand All

(-)editor/src/org/netbeans/modules/java/editor/imports/ComputeImports.java (-4 / +8 lines)
Lines 105-116 Link Here
105
                return new Pair(Collections.emptyMap(), Collections.emptyMap());
105
                return new Pair(Collections.emptyMap(), Collections.emptyMap());
106
            
106
            
107
            List<TypeElement> classes = new ArrayList<TypeElement>();
107
            List<TypeElement> classes = new ArrayList<TypeElement>();
108
            
108
            Set<ElementHandle<TypeElement>> typeNames = info.getJavaSource().getClasspathInfo().getClassIndex().getDeclaredTypes(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class));
109
            for (ElementHandle<TypeElement> typeNames : info.getJavaSource().getClasspathInfo().getClassIndex().getDeclaredTypes(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class))) {
109
            if (typeNames == null) {
110
                TypeElement te = info.getElements().getTypeElement(typeNames.getQualifiedName());
110
                //Canceled
111
                return new Pair(Collections.emptyMap(), Collections.emptyMap());
112
            }
113
            for (ElementHandle<TypeElement> typeName : typeNames) {
114
                TypeElement te = info.getElements().getTypeElement(typeName.getQualifiedName());
111
                
115
                
112
                if (te == null) {
116
                if (te == null) {
113
                    Logger.getLogger(ComputeImports.class.getName()).log(Level.INFO, "Cannot resolve type element \"" + typeNames + "\".");
117
                    Logger.getLogger(ComputeImports.class.getName()).log(Level.INFO, "Cannot resolve type element \"" + typeName + "\".");
114
                    continue;
118
                    continue;
115
                }
119
                }
116
                
120
                
(-)editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenAnnotationHandler.java (-2 / +5 lines)
Lines 440-447 Link Here
440
                ElementHandle<TypeElement> eh = l.remove(0);
440
                ElementHandle<TypeElement> eh = l.remove(0);
441
                
441
                
442
                result.add(eh);
442
                result.add(eh);
443
                
443
                Set<ElementHandle<TypeElement>> typeElements = cpinfo.getClassIndex().getElements(eh, Collections.singleton(SearchKind.IMPLEMENTORS), EnumSet.of(ClassIndex.SearchScope.SOURCE));
444
                l.addAll(cpinfo.getClassIndex().getElements(eh, Collections.singleton(SearchKind.IMPLEMENTORS), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
444
                //XXX: Canceling
445
                if (typeElements != null) {
446
                    l.addAll(typeElements);
447
                }
445
            }
448
            }
446
            return result;
449
            return result;
447
        } finally {
450
        } finally {
(-)editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenVisitor.java (-2 lines)
Lines 43-49 Link Here
43
class IsOverriddenVisitor extends CancellableTreePathScanner<Void, Tree> {
43
class IsOverriddenVisitor extends CancellableTreePathScanner<Void, Tree> {
44
    
44
    
45
    private CompilationInfo info;
45
    private CompilationInfo info;
46
    private ClassIndex uq;
47
    private Document doc;
46
    private Document doc;
48
    
47
    
49
    Map<ElementHandle<TypeElement>, List<ElementHandle<ExecutableElement>>> type2Declaration;
48
    Map<ElementHandle<TypeElement>, List<ElementHandle<ExecutableElement>>> type2Declaration;
Lines 55-61 Link Here
55
    IsOverriddenVisitor(Document doc, CompilationInfo info) {
54
    IsOverriddenVisitor(Document doc, CompilationInfo info) {
56
        this.doc = doc;
55
        this.doc = doc;
57
        this.info = info;
56
        this.info = info;
58
        this.uq = info.getJavaSource().getClasspathInfo().getClassIndex();
59
        
57
        
60
        type2Declaration = new HashMap<ElementHandle<TypeElement>, List<ElementHandle<ExecutableElement>>>();
58
        type2Declaration = new HashMap<ElementHandle<TypeElement>, List<ElementHandle<ExecutableElement>>>();
61
        declaration2Tree = new HashMap<ElementHandle<ExecutableElement>, MethodTree>();
59
        declaration2Tree = new HashMap<ElementHandle<ExecutableElement>, MethodTree>();
(-)source/apichanges.xml (+14 lines)
Lines 83-88 Link Here
83
83
84
    <changes>
84
    <changes>
85
        
85
        
86
        <change id="ClassIndex-interruption">
87
            <api name="general"/>
88
            <summary>ClassIndex methods are cancellable</summary>
89
            <version major="0" minor="15"/>
90
            <date day="13" month="6" year="2007"/>
91
            <author login="tzezula"/>
92
            <compatibility addition="no" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="incompatible" source="compatible"/>
93
            <description>
94
                The ClassIndex methods called from the CancellableTask are cancellable. In case when they are cancelled by the JavaSource infrastructure
95
                they return null instead of the Set to allow client to determine this state. The incompatible semantic change is that tasks registered by
96
                factories have to check if the value returned from class index is null.
97
            </description>
98
        </change>
99
        
86
        <change id="CompilationInfo-getTopLevelElements">
100
        <change id="CompilationInfo-getTopLevelElements">
87
            <api name="general"/>
101
            <api name="general"/>
88
            <summary>Added a method to obtain top level elements defined in the source/class file.</summary>
102
            <summary>Added a method to obtain top level elements defined in the source/class file.</summary>
(-)source/nbproject/project.properties (-1 / +1 lines)
Lines 21-25 Link Here
21
javadoc.title=Java Source
21
javadoc.title=Java Source
22
javadoc.arch=${basedir}/arch.xml
22
javadoc.arch=${basedir}/arch.xml
23
javadoc.apichanges=${basedir}/apichanges.xml
23
javadoc.apichanges=${basedir}/apichanges.xml
24
spec.version.base=0.14.0
24
spec.version.base=0.15.0
25
test.unit.run.cp.extra=${core.dir}/core/core.jar:${core.dir}/lib/boot.jar:../../junit/external/insanelib.jar
25
test.unit.run.cp.extra=${core.dir}/core/core.jar:${core.dir}/lib/boot.jar:../../junit/external/insanelib.jar
(-)source/src/org/netbeans/api/java/source/ClassIndex.java (-18 / +40 lines)
Lines 213-219 Link Here
213
     * @param searchKind type of reference, {@see SearchKind}
213
     * @param searchKind type of reference, {@see SearchKind}
214
     * @param scope to search in {@see SearchScope}
214
     * @param scope to search in {@see SearchScope}
215
     * @return set of {@link ElementHandle}s containing the reference(s)
215
     * @return set of {@link ElementHandle}s containing the reference(s)
216
     *
216
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
217
     * inside call of this method.
217
     */
218
     */
218
    public Set<ElementHandle<TypeElement>> getElements (final ElementHandle<TypeElement> element, final Set<SearchKind> searchKind, final Set<SearchScope> scope) {
219
    public Set<ElementHandle<TypeElement>> getElements (final ElementHandle<TypeElement> element, final Set<SearchKind> searchKind, final Set<SearchScope> scope) {
219
        assert element != null;
220
        assert element != null;
Lines 224-235 Link Here
224
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
225
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
225
        final String binaryName = element.getSignature()[0];
226
        final String binaryName = element.getSignature()[0];
226
        final ResultConvertor<ElementHandle<TypeElement>> thConvertor = ResultConvertor.elementHandleConvertor();
227
        final ResultConvertor<ElementHandle<TypeElement>> thConvertor = ResultConvertor.elementHandleConvertor();
227
        if (!ut.isEmpty()) {
228
        try {
228
            for (ClassIndexImpl query : queries) {
229
            if (!ut.isEmpty()) {
229
                query.search(binaryName, ut, thConvertor, result);
230
                for (ClassIndexImpl query : queries) {
231
                    query.search(binaryName, ut, thConvertor, result);
232
                }
230
            }
233
            }
234
            return Collections.unmodifiableSet(result);
235
        } catch (InterruptedException e) {
236
            return null;
231
        }
237
        }
232
        return Collections.unmodifiableSet(result);
233
    }
238
    }
234
    
239
    
235
    /**
240
    /**
Lines 238-244 Link Here
238
     * @param searchKind type of reference, {@see SearchKind}
243
     * @param searchKind type of reference, {@see SearchKind}
239
     * @param scope to search in {@see SearchScope}
244
     * @param scope to search in {@see SearchScope}
240
     * @return set of {@link FileObject}s containing the reference(s)
245
     * @return set of {@link FileObject}s containing the reference(s)
241
     *
246
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
247
     * inside call of this method.
242
     */
248
     */
243
    public Set<FileObject> getResources (final ElementHandle<TypeElement> element, final Set<SearchKind> searchKind, final Set<SearchScope> scope) {
249
    public Set<FileObject> getResources (final ElementHandle<TypeElement> element, final Set<SearchKind> searchKind, final Set<SearchScope> scope) {
244
        assert element != null;
250
        assert element != null;
Lines 248-260 Link Here
248
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
254
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
249
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
255
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
250
        final String binaryName = element.getSignature()[0];        
256
        final String binaryName = element.getSignature()[0];        
251
        if (!ut.isEmpty()) {
257
        try {
252
            for (ClassIndexImpl query : queries) {
258
            if (!ut.isEmpty()) {
253
                final ResultConvertor<FileObject> foConvertor = ResultConvertor.fileObjectConvertor (query.getSourceRoots());
259
                for (ClassIndexImpl query : queries) {
254
                query.search (binaryName, ut, foConvertor, result);
260
                    final ResultConvertor<FileObject> foConvertor = ResultConvertor.fileObjectConvertor (query.getSourceRoots());
261
                    query.search (binaryName, ut, foConvertor, result);
262
                }
255
            }
263
            }
264
            return Collections.unmodifiableSet(result);
265
        } catch (InterruptedException e) {
266
            return null;
256
        }
267
        }
257
        return Collections.unmodifiableSet(result);
258
    }        
268
    }        
259
    
269
    
260
    
270
    
Lines 265-270 Link Here
265
     * @param kind of the name {@see NameKind}
275
     * @param kind of the name {@see NameKind}
266
     * @param scope to search in {@see SearchScope}
276
     * @param scope to search in {@see SearchScope}
267
     * @return set of all matched declared types
277
     * @return set of all matched declared types
278
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
279
     * inside call of this method.
268
     */
280
     */
269
    public Set<ElementHandle<TypeElement>> getDeclaredTypes (final String name, final NameKind kind, final Set<SearchScope> scope) {
281
    public Set<ElementHandle<TypeElement>> getDeclaredTypes (final String name, final NameKind kind, final Set<SearchScope> scope) {
270
        assert name != null;
282
        assert name != null;
Lines 272-282 Link Here
272
        final Set<ElementHandle<TypeElement>> result = new HashSet<ElementHandle<TypeElement>>();        
284
        final Set<ElementHandle<TypeElement>> result = new HashSet<ElementHandle<TypeElement>>();        
273
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);        
285
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);        
274
        final ResultConvertor<ElementHandle<TypeElement>> thConvertor = ResultConvertor.elementHandleConvertor();
286
        final ResultConvertor<ElementHandle<TypeElement>> thConvertor = ResultConvertor.elementHandleConvertor();
275
        for (ClassIndexImpl query : queries) {
287
        try {
276
            query.getDeclaredTypes (name, kind, thConvertor, result);
288
            for (ClassIndexImpl query : queries) {
289
                query.getDeclaredTypes (name, kind, thConvertor, result);
290
            }
291
            LOGGER.fine(String.format("ClassIndex.getDeclaredTypes returned %d elements\n", result.size()));
292
            return Collections.unmodifiableSet(result);
293
        } catch (InterruptedException e) {
294
            return null;
277
        }
295
        }
278
        LOGGER.fine(String.format("ClassIndex.getDeclaredTypes returned %d elements\n", result.size()));
279
        return Collections.unmodifiableSet(result);
280
    }
296
    }
281
    
297
    
282
    /**
298
    /**
Lines 286-300 Link Here
286
     * the nearest component of the package.
302
     * the nearest component of the package.
287
     * @param scope to search in {@see SearchScope}
303
     * @param scope to search in {@see SearchScope}
288
     * @return set of all matched package names
304
     * @return set of all matched package names
305
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
306
     * inside call of this method.
289
     */
307
     */
290
    public Set<String> getPackageNames (final String prefix, boolean directOnly, final Set<SearchScope> scope) {
308
    public Set<String> getPackageNames (final String prefix, boolean directOnly, final Set<SearchScope> scope) {
291
        assert prefix != null;
309
        assert prefix != null;
292
        final Set<String> result = new HashSet<String> ();        
310
        final Set<String> result = new HashSet<String> ();        
293
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
311
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
294
        for (ClassIndexImpl query : queries) {
312
        try {
295
            query.getPackageNames (prefix, directOnly, result);
313
            for (ClassIndexImpl query : queries) {
314
                query.getPackageNames (prefix, directOnly, result);
315
            }
316
            return Collections.unmodifiableSet(result);
317
        } catch (InterruptedException e) {
318
            return null;
296
        }
319
        }
297
        return Collections.unmodifiableSet(result);
298
    }
320
    }
299
    
321
    
300
    // Private innerclasses ----------------------------------------------------
322
    // Private innerclasses ----------------------------------------------------
(-)source/src/org/netbeans/api/java/source/JavaSource.java (-10 / +21 lines)
Lines 111-116 Link Here
111
import org.netbeans.modules.java.source.tasklist.CompilerSettings;
111
import org.netbeans.modules.java.source.tasklist.CompilerSettings;
112
import org.netbeans.modules.java.source.usages.ClassIndexImpl;
112
import org.netbeans.modules.java.source.usages.ClassIndexImpl;
113
import org.netbeans.modules.java.source.usages.ClassIndexManager;
113
import org.netbeans.modules.java.source.usages.ClassIndexManager;
114
import org.netbeans.modules.java.source.usages.Index;
114
import org.netbeans.modules.java.source.usages.RepositoryUpdater;
115
import org.netbeans.modules.java.source.usages.RepositoryUpdater;
115
import org.netbeans.modules.java.source.util.LowMemoryEvent;
116
import org.netbeans.modules.java.source.util.LowMemoryEvent;
116
import org.netbeans.modules.java.source.util.LowMemoryListener;
117
import org.netbeans.modules.java.source.util.LowMemoryListener;
Lines 1436-1442 Link Here
1436
                                                    //The state (or greater) was reached and document was not modified during moveToPhase
1437
                                                    //The state (or greater) was reached and document was not modified during moveToPhase
1437
                                                    try {
1438
                                                    try {
1438
                                                        final long startTime = System.currentTimeMillis();
1439
                                                        final long startTime = System.currentTimeMillis();
1439
                                                        ((CancellableTask<CompilationInfo>)r.task).run (ci); //XXX: How to do it in save way?
1440
                                                        Index.cancel.set(currentRequest.getCanceledRef());
1441
                                                        try {
1442
                                                            ((CancellableTask<CompilationInfo>)r.task).run (ci); //XXX: How to do it in save way?
1443
                                                        } finally {
1444
                                                            Index.cancel.remove();
1445
                                                        }
1440
                                                        final long endTime = System.currentTimeMillis();
1446
                                                        final long endTime = System.currentTimeMillis();
1441
                                                        if (LOGGER.isLoggable(Level.FINEST)) {
1447
                                                        if (LOGGER.isLoggable(Level.FINEST)) {
1442
                                                            LOGGER.finest(String.format("executed task: %s in %d ms.",  //NOI18N
1448
                                                            LOGGER.finest(String.format("executed task: %s in %d ms.",  //NOI18N
Lines 1822-1831 Link Here
1822
        private JavaSource.Request reference;
1828
        private JavaSource.Request reference;
1823
        private JavaSource.Request canceledReference;
1829
        private JavaSource.Request canceledReference;
1824
        private long cancelTime;
1830
        private long cancelTime;
1825
        private boolean canceled;
1831
        private final AtomicBoolean canceled;
1826
        private boolean mayCancelJavac;
1832
        private boolean mayCancelJavac;
1827
        
1833
        
1828
        CurrentRequestReference () {
1834
        CurrentRequestReference () {
1835
            this.canceled = new AtomicBoolean();
1829
        }
1836
        }
1830
        
1837
        
1831
        boolean setCurrentTask (JavaSource.Request reference) throws InterruptedException {
1838
        boolean setCurrentTask (JavaSource.Request reference) throws InterruptedException {
Lines 1834-1841 Link Here
1834
                while (this.canceledReference!=null) {
1841
                while (this.canceledReference!=null) {
1835
                    INTERNAL_LOCK.wait();
1842
                    INTERNAL_LOCK.wait();
1836
                }
1843
                }
1837
                result = this.canceled;
1844
                result = this.canceled.getAndSet(false);
1838
                this.canceled = this.mayCancelJavac = false;
1845
                this.mayCancelJavac = false;
1839
                this.cancelTime = 0;
1846
                this.cancelTime = 0;
1840
                this.reference = reference;                
1847
                this.reference = reference;                
1841
            }
1848
            }
Lines 1851-1857 Link Here
1851
                        request = this.reference;
1858
                        request = this.reference;
1852
                        this.canceledReference = request;
1859
                        this.canceledReference = request;
1853
                        this.reference = null;
1860
                        this.reference = null;
1854
                        this.canceled = true;                    
1861
                        this.canceled.set(true);                    
1855
                        this.cancelTime = System.currentTimeMillis();
1862
                        this.cancelTime = System.currentTimeMillis();
1856
                    }
1863
                    }
1857
                }
1864
                }
Lines 1868-1874 Link Here
1868
                        request = this.reference;
1875
                        request = this.reference;
1869
                        this.canceledReference = request;
1876
                        this.canceledReference = request;
1870
                        this.reference = null;
1877
                        this.reference = null;
1871
                        this.canceled = true;
1878
                        this.canceled.set(true);
1872
                        this.mayCancelJavac = mayCancelJavac;
1879
                        this.mayCancelJavac = mayCancelJavac;
1873
                        this.cancelTime = System.currentTimeMillis();
1880
                        this.cancelTime = System.currentTimeMillis();
1874
                    }
1881
                    }
Lines 1892-1898 Link Here
1892
                        request = this.reference;
1899
                        request = this.reference;
1893
                        this.canceledReference = request;
1900
                        this.canceledReference = request;
1894
                        this.reference = null;
1901
                        this.reference = null;
1895
                        this.canceled = true;
1902
                        this.canceled.set(true);
1896
                    }
1903
                    }
1897
                }
1904
                }
1898
            }
1905
            }
Lines 1908-1914 Link Here
1908
                        assert this.canceledReference == null;
1915
                        assert this.canceledReference == null;
1909
                        this.canceledReference = request;
1916
                        this.canceledReference = request;
1910
                        this.reference = null;
1917
                        this.reference = null;
1911
                        this.canceled = true;
1918
                        this.canceled.set(true);
1912
                        this.cancelTime = System.currentTimeMillis();
1919
                        this.cancelTime = System.currentTimeMillis();
1913
                    }
1920
                    }
1914
                }
1921
                }
Lines 1940-1946 Link Here
1940
                        if (!result) {
1947
                        if (!result) {
1941
                            this.reference = null;                        
1948
                            this.reference = null;                        
1942
                        }
1949
                        }
1943
                        this.canceled = result;
1950
                        this.canceled.set(result);
1944
                        this.cancelTime = System.currentTimeMillis();
1951
                        this.cancelTime = System.currentTimeMillis();
1945
                    }
1952
                    }
1946
                }
1953
                }
Lines 1950-1957 Link Here
1950
        
1957
        
1951
        boolean isCanceled () {
1958
        boolean isCanceled () {
1952
            synchronized (INTERNAL_LOCK) {
1959
            synchronized (INTERNAL_LOCK) {
1953
                return this.canceled;
1960
                return this.canceled.get();
1954
            }
1961
            }
1962
        }
1963
        
1964
        AtomicBoolean getCanceledRef () {
1965
            return this.canceled;
1955
        }
1966
        }
1956
        
1967
        
1957
        boolean isInterruptJavac () {
1968
        boolean isInterruptJavac () {
(-)source/src/org/netbeans/modules/java/source/JBrowseModule.java (-1 / +4 lines)
Lines 79-85 Link Here
79
            });
79
            });
80
        } catch (IOException ex) {
80
        } catch (IOException ex) {
81
            Exceptions.printStackTrace(ex);
81
            Exceptions.printStackTrace(ex);
82
        };            
82
        }  
83
        catch (InterruptedException e) {
84
            Exceptions.printStackTrace(e);
85
        }
83
        if (ENABLE_MBEANS) {
86
        if (ENABLE_MBEANS) {
84
            unregisterMBeans();
87
            unregisterMBeans();
85
        }
88
        }
(-)source/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java (-5 / +3 lines)
Lines 27-35 Link Here
27
import java.util.List;
27
import java.util.List;
28
import java.util.Set;
28
import java.util.Set;
29
import org.netbeans.api.java.source.ClassIndex;
29
import org.netbeans.api.java.source.ClassIndex;
30
import org.netbeans.api.java.source.ClassIndexListener;
31
import org.netbeans.api.java.source.JavaSource;
30
import org.netbeans.api.java.source.JavaSource;
32
import org.netbeans.api.java.source.TypesEvent;
33
import org.openide.filesystems.FileObject;
31
import org.openide.filesystems.FileObject;
34
import org.openide.util.Utilities;
32
import org.openide.util.Utilities;
35
33
Lines 64-74 Link Here
64
    
62
    
65
    public static ClassIndexFactory FACTORY;    
63
    public static ClassIndexFactory FACTORY;    
66
    
64
    
67
    public abstract <T> void search (final String binaryName, final Set<UsageType> usageType, final ResultConvertor<T> convertor, final Set<? super T> result);
65
    public abstract <T> void search (final String binaryName, final Set<UsageType> usageType, final ResultConvertor<T> convertor, final Set<? super T> result) throws InterruptedException;
68
    
66
    
69
    public abstract <T> void getDeclaredTypes (String name, ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result);
67
    public abstract <T> void getDeclaredTypes (String name, ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result) throws InterruptedException;
70
    
68
    
71
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result);
69
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws InterruptedException;
72
    
70
    
73
    public abstract FileObject[] getSourceRoots ();
71
    public abstract FileObject[] getSourceRoots ();
74
   
72
   
(-)source/src/org/netbeans/modules/java/source/usages/ClassIndexManager.java (-3 / +3 lines)
Lines 65-71 Link Here
65
        this.listeners.remove(listener);
65
        this.listeners.remove(listener);
66
    }
66
    }
67
    
67
    
68
    public <T> T writeLock (final ExceptionAction<T> r) throws IOException {
68
    public <T> T writeLock (final ExceptionAction<T> r) throws IOException, InterruptedException {
69
        this.lock.writeLock().lock();
69
        this.lock.writeLock().lock();
70
        try {
70
        try {
71
            depth++;
71
            depth++;
Lines 94-100 Link Here
94
        }
94
        }
95
    }
95
    }
96
    
96
    
97
    public <T> T readLock (final ExceptionAction<T> r) throws IOException {
97
    public <T> T readLock (final ExceptionAction<T> r) throws IOException, InterruptedException {
98
        this.lock.readLock().lock();
98
        this.lock.readLock().lock();
99
        try {
99
        try {
100
            return r.run();
100
            return r.run();
Lines 149-155 Link Here
149
    }
149
    }
150
    
150
    
151
    public static interface ExceptionAction<T> {
151
    public static interface ExceptionAction<T> {
152
        public T run () throws IOException;
152
        public T run () throws IOException, InterruptedException;
153
    }
153
    }
154
    
154
    
155
    private void fire (final Set<? extends URL> roots, final byte op) {
155
    private void fire (final Set<? extends URL> roots, final byte op) {
(-)source/src/org/netbeans/modules/java/source/usages/Index.java (-6 / +11 lines)
Lines 31-36 Link Here
31
import java.util.Map;
31
import java.util.Map;
32
import java.util.Properties;
32
import java.util.Properties;
33
import java.util.Set;
33
import java.util.Set;
34
import java.util.concurrent.atomic.AtomicBoolean;
34
import org.netbeans.api.java.source.ClassIndex;
35
import org.netbeans.api.java.source.ClassIndex;
35
import org.openide.ErrorManager;
36
import org.openide.ErrorManager;
36
import org.openide.filesystems.FileUtil;
37
import org.openide.filesystems.FileUtil;
Lines 60-71 Link Here
60
    private static File segmentsFile;
61
    private static File segmentsFile;
61
    private static int index = 0;
62
    private static int index = 0;
62
    
63
    
63
    public abstract boolean isValid (boolean tryOpen) throws IOException;
64
    public static final ThreadLocal<AtomicBoolean> cancel = new ThreadLocal<AtomicBoolean> () {
64
    public abstract List<String> getUsagesData (String resourceName, Set<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException;
65
        protected synchronized AtomicBoolean initialValue() {
65
    public abstract List<String> getUsagesFQN (String resourceName, Set<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException;
66
             return new AtomicBoolean ();
66
    public abstract List<String> getReferencesData (String resourceName) throws IOException;
67
         }
67
    public abstract <T> void getDeclaredTypes (String simpleName, ClassIndex.NameKind kind, ResultConvertor<T> convertor, Set<? super T> result) throws IOException;
68
    };    
68
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException;
69
    
70
    public abstract boolean isValid (boolean tryOpen) throws IOException;   
71
    public abstract List<String> getUsagesFQN (String resourceName, Set<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException, InterruptedException;
72
    public abstract <T> void getDeclaredTypes (String simpleName, ClassIndex.NameKind kind, ResultConvertor<T> convertor, Set<? super T> result) throws IOException, InterruptedException;
73
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException;
69
    public abstract void store (Map<String,List<String>> refs, Set<String> toDelete) throws IOException;
74
    public abstract void store (Map<String,List<String>> refs, Set<String> toDelete) throws IOException;
70
    public abstract void store (Map<String,List<String>> refs, List<String> topLevels) throws IOException;
75
    public abstract void store (Map<String,List<String>> refs, List<String> topLevels) throws IOException;
71
    public abstract boolean isUpToDate (String resourceName, long timeStamp) throws IOException;
76
    public abstract boolean isUpToDate (String resourceName, long timeStamp) throws IOException;
(-)source/src/org/netbeans/modules/java/source/usages/LuceneIndex.java (-19 / +53 lines)
Lines 21-26 Link Here
21
21
22
import java.io.File;
22
import java.io.File;
23
import java.io.IOException;
23
import java.io.IOException;
24
import java.io.InterruptedIOException;
24
import java.text.ParseException;
25
import java.text.ParseException;
25
import java.util.Comparator;
26
import java.util.Comparator;
26
import java.util.EnumSet;
27
import java.util.EnumSet;
Lines 80-86 Link Here
80
    private IndexReader reader; //Cache, do not use this dirrectly, use getReader
81
    private IndexReader reader; //Cache, do not use this dirrectly, use getReader
81
    private Set<String> rootPkgCache;   //Cache, do not use this dirrectly
82
    private Set<String> rootPkgCache;   //Cache, do not use this dirrectly
82
    
83
    
83
    public static Index create (final File cacheRoot) throws IOException {        
84
    static Index create (final File cacheRoot) throws IOException {        
84
        assert cacheRoot != null && cacheRoot.exists() && cacheRoot.canRead() && cacheRoot.canWrite();
85
        assert cacheRoot != null && cacheRoot.exists() && cacheRoot.canRead() && cacheRoot.canWrite();
85
        return new LuceneIndex (getReferencesCacheFolder(cacheRoot));
86
        return new LuceneIndex (getReferencesCacheFolder(cacheRoot));
86
    }
87
    }
Lines 92-101 Link Here
92
    }
93
    }
93
94
94
    @SuppressWarnings("unchecked") // NOI18N, unchecked - lucene has source 1.4
95
    @SuppressWarnings("unchecked") // NOI18N, unchecked - lucene has source 1.4
95
    public List<String> getUsagesData(final String resourceName, Set<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException {        
96
    private List<String> getUsagesData(final String resourceName, Set<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException {                
96
        if (!isValid(false)) {
97
        if (!isValid(false)) {
97
            return null;
98
            return null;
98
        }
99
        }        
99
        final Searcher searcher = new IndexSearcher (this.getReader());
100
        final Searcher searcher = new IndexSearcher (this.getReader());
100
        try {
101
        try {
101
            final List<String> result = new LinkedList<String> ();
102
            final List<String> result = new LinkedList<String> ();
Lines 139-148 Link Here
139
    }
140
    }
140
141
141
    @SuppressWarnings ("unchecked")     // NOI18N, unchecked - lucene has source 1.4
142
    @SuppressWarnings ("unchecked")     // NOI18N, unchecked - lucene has source 1.4
142
    public List<String> getUsagesFQN(final String resourceName, final Set<ClassIndexImpl.UsageType>mask, final BooleanOperator operator) throws IOException {
143
    public List<String> getUsagesFQN(final String resourceName, final Set<ClassIndexImpl.UsageType>mask, final BooleanOperator operator) throws IOException, InterruptedException {
143
        if (!isValid(false)) {
144
        if (!isValid(false)) {
144
            return null;
145
            return null;
145
        }
146
        }
147
        final AtomicBoolean cancel = this.cancel.get();
148
        assert cancel != null;
146
        assert resourceName != null;
149
        assert resourceName != null;
147
        assert mask != null;
150
        assert mask != null;
148
        assert operator != null;
151
        assert operator != null;
Lines 164-172 Link Here
164
                    break;
167
                    break;
165
                default:
168
                default:
166
                    throw new IllegalArgumentException (operator.toString());
169
                    throw new IllegalArgumentException (operator.toString());
167
            }            
170
            }
171
            if (cancel.get()) {
172
                throw new InterruptedException ();
173
            }
168
            final Hits hits = searcher.search (query);
174
            final Hits hits = searcher.search (query);
169
            for (Iterator<Hit> it = (Iterator<Hit>) hits.iterator(); it.hasNext();) {
175
            for (Iterator<Hit> it = (Iterator<Hit>) hits.iterator(); it.hasNext();) {
176
                if (cancel.get()) {
177
                    throw new InterruptedIOException ();
178
                }
170
                final Hit hit = it.next ();
179
                final Hit hit = it.next ();
171
                final Document doc = hit.getDocument();
180
                final Document doc = hit.getDocument();
172
                final String user = DocumentUtil.getBinaryName(doc);
181
                final String user = DocumentUtil.getBinaryName(doc);
Lines 178-184 Link Here
178
        }
187
        }
179
    }
188
    }
180
189
181
    public List<String> getReferencesData(final String resourceName) throws IOException {
190
    private List<String> getReferencesData(final String resourceName) throws IOException {
182
        if (!isValid(false)) {
191
        if (!isValid(false)) {
183
            return null;
192
            return null;
184
        }    
193
        }    
Lines 200-210 Link Here
200
    }
209
    }
201
        
210
        
202
    @SuppressWarnings ("unchecked") // NOI18N, unchecked - lucene has source 1.4
211
    @SuppressWarnings ("unchecked") // NOI18N, unchecked - lucene has source 1.4
203
    public <T> void getDeclaredTypes (final String name, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result) throws IOException {
212
    public <T> void getDeclaredTypes (final String name, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result) throws IOException, InterruptedException {
204
        if (!isValid(false)) {
213
        if (!isValid(false)) {
205
            LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
214
            LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
206
            return;
215
            return;
207
        }
216
        }
217
        final AtomicBoolean cancel = this.cancel.get();
218
        assert cancel != null;
208
        assert name != null;                
219
        assert name != null;                
209
        final Set<Term> toSearch = new TreeSet<Term> (new Comparator<Term>(){
220
        final Set<Term> toSearch = new TreeSet<Term> (new Comparator<Term>(){
210
            public int compare (Term t1, Term t2) {
221
            public int compare (Term t1, Term t2) {
Lines 225-247 Link Here
225
            case PREFIX:
236
            case PREFIX:
226
                if (name.length() == 0) {
237
                if (name.length() == 0) {
227
                    //Special case (all) handle in different way
238
                    //Special case (all) handle in different way
228
                    emptyPrefixSearch(in, convertor, result);
239
                    emptyPrefixSearch(in, convertor, result, cancel);
229
                    return;
240
                    return;
230
                }
241
                }
231
                else {
242
                else {
232
                    final Term nameTerm = DocumentUtil.simpleNameTerm(name);
243
                    final Term nameTerm = DocumentUtil.simpleNameTerm(name);
233
                    prefixSearh(nameTerm, in, toSearch);
244
                    prefixSearh(nameTerm, in, toSearch, cancel);
234
                    break;
245
                    break;
235
                }
246
                }
236
            case CASE_INSENSITIVE_PREFIX:
247
            case CASE_INSENSITIVE_PREFIX:
237
                if (name.length() == 0) {
248
                if (name.length() == 0) {
238
                    //Special case (all) handle in different way
249
                    //Special case (all) handle in different way
239
                    emptyPrefixSearch(in, convertor, result);
250
                    emptyPrefixSearch(in, convertor, result, cancel);
240
                    return;
251
                    return;
241
                }
252
                }
242
                else {                    
253
                else {                    
243
                    final Term nameTerm = DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase());     //XXX: I18N, Locale
254
                    final Term nameTerm = DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase());     //XXX: I18N, Locale
244
                    prefixSearh(nameTerm, in, toSearch);
255
                    prefixSearh(nameTerm, in, toSearch, cancel);
245
                    break;
256
                    break;
246
                }
257
                }
247
            case CAMEL_CASE:
258
            case CAMEL_CASE:
Lines 266-272 Link Here
266
                    }
277
                    }
267
                }
278
                }
268
                final Pattern pattern = Pattern.compile(patternString.toString());
279
                final Pattern pattern = Pattern.compile(patternString.toString());
269
                regExpSearch(pattern,DocumentUtil.simpleNameTerm(Character.toString(startChar)),in,toSearch);
280
                regExpSearch(pattern,DocumentUtil.simpleNameTerm(Character.toString(startChar)),in,toSearch,cancel);
270
                break;
281
                break;
271
                }
282
                }
272
            case CASE_INSENSITIVE_REGEXP:
283
            case CASE_INSENSITIVE_REGEXP:
Lines 275-281 Link Here
275
                }
286
                }
276
                {   
287
                {   
277
                    final Pattern pattern = Pattern.compile(name,Pattern.CASE_INSENSITIVE);
288
                    final Pattern pattern = Pattern.compile(name,Pattern.CASE_INSENSITIVE);
278
                    regExpSearch(pattern, DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase()), in, toSearch);      //XXX: Locale
289
                    regExpSearch(pattern, DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase()), in, toSearch,cancel);      //XXX: Locale
279
                    break;
290
                    break;
280
                }
291
                }
281
            case REGEXP:
292
            case REGEXP:
Lines 284-290 Link Here
284
                }                
295
                }                
285
                {   
296
                {   
286
                    final Pattern pattern = Pattern.compile(name);                    
297
                    final Pattern pattern = Pattern.compile(name);                    
287
                    regExpSearch(pattern, DocumentUtil.simpleNameTerm(name), in, toSearch);
298
                    regExpSearch(pattern, DocumentUtil.simpleNameTerm(name), in, toSearch, cancel);
288
                    break;
299
                    break;
289
                }
300
                }
290
            default:
301
            default:
Lines 296-314 Link Here
296
        final ElementKind[] kindHolder = new ElementKind[1];
307
        final ElementKind[] kindHolder = new ElementKind[1];
297
        Set<Integer> docNums = new TreeSet<Integer>();
308
        Set<Integer> docNums = new TreeSet<Integer>();
298
        while (it.hasNext()) {
309
        while (it.hasNext()) {
310
            if (cancel.get()) {
311
                throw new InterruptedException ();
312
            }
299
            tds.seek(it.next());
313
            tds.seek(it.next());
300
            while (tds.next()) {
314
            while (tds.next()) {
301
                docNums.add (tds.doc());
315
                docNums.add (tds.doc());
302
            }
316
            }
303
        }
317
        }
304
        for (Integer docNum : docNums) {
318
        for (Integer docNum : docNums) {
319
            if (cancel.get()) {
320
                throw new InterruptedException ();
321
            }
305
            final Document doc = in.document(docNum);
322
            final Document doc = in.document(docNum);
306
            final String binaryName = DocumentUtil.getBinaryName(doc, kindHolder);
323
            final String binaryName = DocumentUtil.getBinaryName(doc, kindHolder);
307
            result.add (convertor.convert(kindHolder[0],binaryName));
324
            result.add (convertor.convert(kindHolder[0],binaryName));
308
        }        
325
        }        
309
    }
326
    }
310
    
327
    
311
    private void regExpSearch (final Pattern pattern, final Term startTerm, final IndexReader in, final Set<Term> toSearch) throws IOException {        
328
    private void regExpSearch (final Pattern pattern, final Term startTerm, final IndexReader in, final Set<Term> toSearch, final AtomicBoolean cancel) throws IOException, InterruptedException {        
312
        final String startText = startTerm.text();
329
        final String startText = startTerm.text();
313
        final StringBuilder startBuilder = new StringBuilder ();
330
        final StringBuilder startBuilder = new StringBuilder ();
314
        startBuilder.append(startText.charAt(0));
331
        startBuilder.append(startText.charAt(0));
Lines 324-329 Link Here
324
        final TermEnum en = in.terms(startTerm);
341
        final TermEnum en = in.terms(startTerm);
325
        try {
342
        try {
326
            do {
343
            do {
344
                if (cancel.get()) {
345
                    throw new InterruptedException ();
346
                }
327
                Term term = en.term();                
347
                Term term = en.term();                
328
                if (term != null && camelField == term.field() && term.text().startsWith(startPrefix)) {
348
                if (term != null && camelField == term.field() && term.text().startsWith(startPrefix)) {
329
                    final Matcher m = pattern.matcher(term.text());
349
                    final Matcher m = pattern.matcher(term.text());
Lines 340-349 Link Here
340
        }
360
        }
341
    }
361
    }
342
    
362
    
343
    private <T> void emptyPrefixSearch (final IndexReader in, final ResultConvertor<T> convertor, final Set<? super T> result) throws IOException {        
363
    private <T> void emptyPrefixSearch (final IndexReader in, final ResultConvertor<T> convertor, final Set<? super T> result, final AtomicBoolean cancel) throws IOException, InterruptedException {        
344
        final int bound = in.maxDoc();        
364
        final int bound = in.maxDoc();        
345
        final ElementKind[] kindHolder = new ElementKind[1];
365
        final ElementKind[] kindHolder = new ElementKind[1];
346
        for (int i=0; i<bound; i++) {
366
        for (int i=0; i<bound; i++) {
367
            if (cancel.get()) {
368
                throw new InterruptedException ();
369
            }
347
            if (!in.isDeleted(i)) {
370
            if (!in.isDeleted(i)) {
348
                final Document doc = in.document(i);
371
                final Document doc = in.document(i);
349
                if (doc != null) {
372
                if (doc != null) {
Lines 360-371 Link Here
360
        }
383
        }
361
    }
384
    }
362
    
385
    
363
    private void prefixSearh (Term nameTerm, final IndexReader in, final Set<Term> toSearch) throws IOException {
386
    private void prefixSearh (Term nameTerm, final IndexReader in, final Set<Term> toSearch, final AtomicBoolean cancel) throws IOException, InterruptedException {
364
        final String prefixField = nameTerm.field();
387
        final String prefixField = nameTerm.field();
365
        final String name = nameTerm.text();
388
        final String name = nameTerm.text();
366
        final TermEnum en = in.terms(nameTerm);
389
        final TermEnum en = in.terms(nameTerm);
367
        try {
390
        try {
368
            do {
391
            do {
392
                if (cancel.get()) {
393
                    throw new InterruptedException ();
394
                }
369
                Term term = en.term();                
395
                Term term = en.term();                
370
                if (term != null && prefixField == term.field() && term.text().startsWith(name)) {
396
                if (term != null && prefixField == term.field() && term.text().startsWith(name)) {
371
                    toSearch.add (term);
397
                    toSearch.add (term);
Lines 380-389 Link Here
380
    }
406
    }
381
    
407
    
382
    
408
    
383
    public void getPackageNames (final String prefix, final boolean directOnly, final Set<String> result) throws IOException {
409
    public void getPackageNames (final String prefix, final boolean directOnly, final Set<String> result) throws IOException, InterruptedException {        
384
        if (!isValid(false)) {
410
        if (!isValid(false)) {
385
            return;
411
            return;
386
        }        
412
        }
413
        final AtomicBoolean cancel = this.cancel.get();
414
        assert cancel != null;
387
        final IndexReader in = getReader();
415
        final IndexReader in = getReader();
388
        final Term pkgTerm = DocumentUtil.packageNameTerm (prefix);
416
        final Term pkgTerm = DocumentUtil.packageNameTerm (prefix);
389
        final String prefixField = pkgTerm.field();
417
        final String prefixField = pkgTerm.field();
Lines 398-403 Link Here
398
                final TermEnum terms = in.terms ();
426
                final TermEnum terms = in.terms ();
399
                try {
427
                try {
400
                    do {
428
                    do {
429
                        if (cancel.get()) {
430
                            throw new InterruptedIOException ();
431
                        }
401
                        final Term currentTerm = terms.term();
432
                        final Term currentTerm = terms.term();
402
                        if (currentTerm != null && prefixField == currentTerm.field()) {
433
                        if (currentTerm != null && prefixField == currentTerm.field()) {
403
                            String pkgName = currentTerm.text();
434
                            String pkgName = currentTerm.text();
Lines 420-425 Link Here
420
            final TermEnum terms = in.terms (pkgTerm);
451
            final TermEnum terms = in.terms (pkgTerm);
421
            try {
452
            try {
422
                do {
453
                do {
454
                    if (cancel.get()) {
455
                        throw new InterruptedException ();
456
                    }
423
                    final Term currentTerm = terms.term();
457
                    final Term currentTerm = terms.term();
424
                    if (currentTerm != null && prefixField == currentTerm.field() && currentTerm.text().startsWith(prefix)) {
458
                    if (currentTerm != null && prefixField == currentTerm.field() && currentTerm.text().startsWith(prefix)) {
425
                        String pkgName = currentTerm.text();
459
                        String pkgName = currentTerm.text();
(-)source/src/org/netbeans/modules/java/source/usages/PersistentClassIndex.java (-9 / +23 lines)
Lines 53-65 Link Here
53
    private final boolean isSource;
53
    private final boolean isSource;
54
    private WeakReference<JavaSource> dirty;
54
    private WeakReference<JavaSource> dirty;
55
    private static final Logger LOGGER = Logger.getLogger(PersistentClassIndex.class.getName());
55
    private static final Logger LOGGER = Logger.getLogger(PersistentClassIndex.class.getName());
56
    private static IndexFactory indexFactory;
56
    
57
    
57
    /** Creates a new instance of ClassesAndMembersUQ */
58
    /** Creates a new instance of ClassesAndMembersUQ */
58
    private PersistentClassIndex(final URL root, final File cacheRoot, final boolean source) 
59
    private PersistentClassIndex(final URL root, final File cacheRoot, final boolean source) 
59
	    throws IOException, IllegalArgumentException {
60
	    throws IOException, IllegalArgumentException {
60
        assert root != null;
61
        assert root != null;
61
        this.root = root;
62
        this.root = root;
62
        this.index = LuceneIndex.create (cacheRoot);
63
        this.index = (indexFactory == null ? LuceneIndex.create (cacheRoot) : indexFactory.create(cacheRoot));
63
        this.isSource = source;
64
        this.isSource = source;
64
    }
65
    }
65
    
66
    
Lines 92-98 Link Here
92
    }
93
    }
93
    
94
    
94
    // Implementation of UsagesQueryImpl ---------------------------------------    
95
    // Implementation of UsagesQueryImpl ---------------------------------------    
95
    public <T> void search (final String binaryName, final Set<UsageType> usageType, final ResultConvertor<T> convertor, final Set<? super T> result) {
96
    public <T> void search (final String binaryName, final Set<UsageType> usageType, final ResultConvertor<T> convertor, final Set<? super T> result) throws InterruptedException {
96
        updateDirty();
97
        updateDirty();
97
        if (BinaryAnalyser.OBJECT.equals(binaryName)) {
98
        if (BinaryAnalyser.OBJECT.equals(binaryName)) {
98
            this.getDeclaredTypes("", ClassIndex.NameKind.PREFIX, convertor, result);
99
            this.getDeclaredTypes("", ClassIndex.NameKind.PREFIX, convertor, result);
Lines 100-106 Link Here
100
        }
101
        }
101
        try {
102
        try {
102
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void> () {
103
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void> () {
103
                public Void run () throws IOException {
104
                public Void run () throws IOException, InterruptedException {
104
                    usages(binaryName, usageType, convertor, result);
105
                    usages(binaryName, usageType, convertor, result);
105
                    return null;
106
                    return null;
106
                }
107
                }
Lines 113-123 Link Here
113
    
114
    
114
               
115
               
115
    
116
    
116
    public <T> void getDeclaredTypes (final String simpleName, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result) {
117
    public <T> void getDeclaredTypes (final String simpleName, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set<? super T> result) throws InterruptedException {
117
        updateDirty();
118
        updateDirty();
118
        try {
119
        try {
119
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void> () {
120
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void> () {
120
                public Void run () throws IOException {
121
                public Void run () throws IOException, InterruptedException {
121
                    index.getDeclaredTypes (simpleName,kind, convertor, result);
122
                    index.getDeclaredTypes (simpleName,kind, convertor, result);
122
                    return null;
123
                    return null;
123
                }                    
124
                }                    
Lines 128-137 Link Here
128
    }
129
    }
129
    
130
    
130
    
131
    
131
    public void getPackageNames (final String prefix, final boolean directOnly, final Set<String> result) {
132
    public void getPackageNames (final String prefix, final boolean directOnly, final Set<String> result) throws InterruptedException {
132
        try {
133
        try {
133
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void>() {
134
            ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void>() {
134
                public Void run () throws IOException {
135
                public Void run () throws IOException, InterruptedException {
135
                    index.getPackageNames(prefix, directOnly, result);
136
                    index.getPackageNames(prefix, directOnly, result);
136
                    return null;
137
                    return null;
137
                }
138
                }
Lines 154-159 Link Here
154
        return "CompromiseUQ["+this.root.toExternalForm()+"]";     // NOI18N
155
        return "CompromiseUQ["+this.root.toExternalForm()+"]";     // NOI18N
155
    }
156
    }
156
    
157
    
158
    //Unit test methods
159
    public static void setIndexFactory (final IndexFactory factory) {
160
        indexFactory = factory;
161
    }
162
    
157
    //Protected methods --------------------------------------------------------
163
    //Protected methods --------------------------------------------------------
158
    protected final void close () throws IOException {
164
    protected final void close () throws IOException {
159
        this.index.close();
165
        this.index.close();
Lines 191-196 Link Here
191
                    } catch (IOException ioe) {
197
                    } catch (IOException ioe) {
192
                        Exceptions.printStackTrace(ioe);
198
                        Exceptions.printStackTrace(ioe);
193
                    }
199
                    }
200
                    catch (InterruptedException e) {
201
                        //Should never happen
202
                        Exceptions.printStackTrace(e);
203
                    }
194
                }
204
                }
195
                else {
205
                else {
196
                    try {
206
                    try {
Lines 211-216 Link Here
211
                                } catch (IOException ioe) {
221
                                } catch (IOException ioe) {
212
                                    Exceptions.printStackTrace(ioe);
222
                                    Exceptions.printStackTrace(ioe);
213
                                }
223
                                }
224
                                catch (InterruptedException e) {
225
                                    //Should never happen
226
                                    Exceptions.printStackTrace(e);
227
                                }
214
                            }
228
                            }
215
229
216
                            public void cancel () {}
230
                            public void cancel () {}
Lines 228-234 Link Here
228
        }
242
        }
229
    }
243
    }
230
    
244
    
231
    private <T> void usages (final String binaryName, final Set<UsageType> usageType, ResultConvertor<T> convertor, Set<? super T> result) {               
245
    private <T> void usages (final String binaryName, final Set<UsageType> usageType, ResultConvertor<T> convertor, Set<? super T> result) throws InterruptedException {               
232
        final List<String> classInternalNames = this.getUsagesFQN(binaryName,usageType, Index.BooleanOperator.OR);
246
        final List<String> classInternalNames = this.getUsagesFQN(binaryName,usageType, Index.BooleanOperator.OR);
233
        for (String classInternalName : classInternalNames) {
247
        for (String classInternalName : classInternalNames) {
234
            T value = convertor.convert(ElementKind.OTHER, classInternalName);
248
            T value = convertor.convert(ElementKind.OTHER, classInternalName);
Lines 238-244 Link Here
238
        }
252
        }
239
    }    
253
    }    
240
    
254
    
241
    private List<String> getUsagesFQN (final String binaryName, final Set<UsageType> mask, final Index.BooleanOperator operator) {
255
    private List<String> getUsagesFQN (final String binaryName, final Set<UsageType> mask, final Index.BooleanOperator operator) throws InterruptedException {
242
        List<String> result = null;
256
        List<String> result = null;
243
        try {
257
        try {
244
            result = this.index.getUsagesFQN(binaryName, mask, operator);          
258
            result = this.index.getUsagesFQN(binaryName, mask, operator);          
(-)source/src/org/netbeans/modules/java/source/usages/RepositoryUpdater.java (+5 lines)
Lines 889-894 Link Here
889
        }
889
        }
890
        
890
        
891
        public void run (final CompilationInfo nullInfo) throws IOException {
891
        public void run (final CompilationInfo nullInfo) throws IOException {
892
            try {
892
            ClassIndexManager.getDefault().writeLock (new ClassIndexManager.ExceptionAction<Void> () {
893
            ClassIndexManager.getDefault().writeLock (new ClassIndexManager.ExceptionAction<Void> () {
893
                
894
                
894
                @SuppressWarnings("fallthrough")
895
                @SuppressWarnings("fallthrough")
Lines 1129-1134 Link Here
1129
                    }
1130
                    }
1130
                }
1131
                }
1131
            }});
1132
            }});
1133
            } catch (InterruptedException e) {
1134
                //Never thrown
1135
                Exceptions.printStackTrace(e);
1136
            }
1132
        }
1137
        }
1133
        
1138
        
1134
        private void findDependencies (final URL rootURL, final Stack<URL> cycleDetector, final Map<URL,List<URL>> depGraph,
1139
        private void findDependencies (final URL rootURL, final Stack<URL> cycleDetector, final Map<URL,List<URL>> depGraph,
(-)source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java (+158 lines)
Lines 36-41 Link Here
36
import java.net.URI;
36
import java.net.URI;
37
import java.net.URL;
37
import java.net.URL;
38
import java.text.MessageFormat;
38
import java.text.MessageFormat;
39
import java.util.Map;
39
import java.util.concurrent.CountDownLatch;
40
import java.util.concurrent.CountDownLatch;
40
import java.util.concurrent.Future;
41
import java.util.concurrent.Future;
41
import java.util.concurrent.atomic.AtomicBoolean;
42
import java.util.concurrent.atomic.AtomicBoolean;
Lines 53-64 Link Here
53
import java.util.EnumSet;
54
import java.util.EnumSet;
54
import java.util.LinkedList;
55
import java.util.LinkedList;
55
import java.util.List;
56
import java.util.List;
57
import java.util.Set;
56
import java.util.concurrent.TimeUnit;
58
import java.util.concurrent.TimeUnit;
57
import javax.swing.text.BadLocationException;
59
import javax.swing.text.BadLocationException;
58
import org.netbeans.api.java.classpath.ClassPath;
60
import org.netbeans.api.java.classpath.ClassPath;
61
import org.netbeans.api.java.source.ClassIndex;
62
import org.netbeans.api.java.source.ClassIndex.NameKind;
59
import org.netbeans.junit.NbTestCase;
63
import org.netbeans.junit.NbTestCase;
60
import org.netbeans.junit.NbTestSuite;
64
import org.netbeans.junit.NbTestSuite;
61
import org.netbeans.modules.java.source.parsing.SourceFileObject;
65
import org.netbeans.modules.java.source.parsing.SourceFileObject;
66
import org.netbeans.modules.java.source.usages.ClassIndexImpl.UsageType;
67
import org.netbeans.modules.java.source.usages.Index;
68
import org.netbeans.modules.java.source.usages.Index;
69
import org.netbeans.modules.java.source.usages.ResultConvertor;
62
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
70
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
63
import org.openide.cookies.EditorCookie;
71
import org.openide.cookies.EditorCookie;
64
import org.openide.cookies.SaveCookie;
72
import org.openide.cookies.SaveCookie;
Lines 74-80 Link Here
74
import org.netbeans.modules.java.preprocessorbridge.spi.JavaFileFilterImplementation;
82
import org.netbeans.modules.java.preprocessorbridge.spi.JavaFileFilterImplementation;
75
import org.netbeans.modules.java.source.JavaSourceAccessor;
83
import org.netbeans.modules.java.source.JavaSourceAccessor;
76
import org.netbeans.modules.java.source.classpath.CacheClassPath;
84
import org.netbeans.modules.java.source.classpath.CacheClassPath;
85
import org.netbeans.modules.java.source.usages.IndexFactory;
77
import org.netbeans.modules.java.source.usages.IndexUtil;
86
import org.netbeans.modules.java.source.usages.IndexUtil;
87
import org.netbeans.modules.java.source.usages.PersistentClassIndex;
78
import org.netbeans.modules.java.source.usages.RepositoryUpdater;
88
import org.netbeans.modules.java.source.usages.RepositoryUpdater;
79
import org.netbeans.spi.java.classpath.ClassPathProvider;
89
import org.netbeans.spi.java.classpath.ClassPathProvider;
80
/**
90
/**
Lines 1280-1285 Link Here
1280
        }, true);
1290
        }, true);
1281
    }
1291
    }
1282
    
1292
    
1293
    
1294
    public void testIndexCancel() throws Exception {
1295
        PersistentClassIndex.setIndexFactory(new TestIndexFactory());
1296
        try {
1297
            FileObject test = createTestFile ("Test1");
1298
            final ClassPath bootPath = createBootPath ();
1299
            final ClassPath compilePath = createCompilePath ();        
1300
            final ClassPath sourcePath = createSourcePath ();
1301
            
1302
            
1303
            ClassLoader l = JavaSourceTest.class.getClassLoader();
1304
            Lkp.DEFAULT.setLookupsWrapper(
1305
                Lookups.metaInfServices(l),
1306
                Lookups.singleton(l),
1307
                Lookups.singleton(new ClassPathProvider() {
1308
                public ClassPath findClassPath(FileObject file, String type) {
1309
                    if (ClassPath.BOOT == type) {
1310
                        return bootPath;
1311
                    }
1312
1313
                    if (ClassPath.SOURCE == type) {
1314
                        return sourcePath;
1315
                    }
1316
1317
                    if (ClassPath.COMPILE == type) {
1318
                        return compilePath;
1319
                    }                    
1320
                    return null;
1321
                }            
1322
            }));
1323
            
1324
            
1325
            JavaSource js = JavaSource.create(ClasspathInfo.create(bootPath, compilePath, sourcePath), test);
1326
            CountDownLatch rl = RepositoryUpdater.getDefault().scheduleCompilationAndWait(sourcePath.getRoots()[0], sourcePath.getRoots()[0]);
1327
            rl.await();
1328
            DataObject dobj = DataObject.find(test);
1329
            EditorCookie ec = (EditorCookie) dobj.getCookie(EditorCookie.class);                        
1330
            final StyledDocument doc = ec.openDocument();
1331
            Thread.sleep(500);  //It may happen that the js is invalidated before the dispatch of task is done and the test of timers may fail        
1332
1333
            final CountDownLatch[] end = new CountDownLatch[]{new CountDownLatch (1)};
1334
            final Object[] result = new Object[1];
1335
            
1336
            CancellableTask<CompilationInfo> task = new CancellableTask<CompilationInfo>() {
1337
1338
                public void cancel() {                
1339
                }
1340
1341
                public void run(CompilationInfo p) throws Exception {
1342
                    ClassIndex index = p.getClasspathInfo().getClassIndex();
1343
                    result[0] = index.getPackageNames("javax", true, EnumSet.allOf(ClassIndex.SearchScope.class));                    
1344
                    end[0].countDown();
1345
                }
1346
1347
            };
1348
            js.addPhaseCompletionTask (task,Phase.PARSED, Priority.HIGH);
1349
            Thread.sleep(500);  //Making test a more deterministic, when the task is cancelled by DocListener, it's hard for test to recover from it
1350
            NbDocument.runAtomic (doc,
1351
                new Runnable () {
1352
                    public void run () {                        
1353
                        try {
1354
                            String text = doc.getText(0,doc.getLength());
1355
                            int index = text.indexOf(REPLACE_PATTERN);
1356
                            assertTrue (index != -1);
1357
                            doc.remove(index,REPLACE_PATTERN.length());
1358
                            doc.insertString(index,"System.out.println();",null);
1359
                        } catch (BadLocationException ble) {
1360
                            ble.printStackTrace(System.out);
1361
                        }                 
1362
                    }
1363
            });               
1364
            end[0].await();
1365
            assertNull(result[0]);
1366
            js.removePhaseCompletionTask (task);
1367
        } finally {
1368
            PersistentClassIndex.setIndexFactory(null);
1369
        }
1370
    }
1371
    
1372
    
1283
    private static class TestProvider implements JavaSource.JavaFileObjectProvider {
1373
    private static class TestProvider implements JavaSource.JavaFileObjectProvider {
1284
        
1374
        
1285
        private Object lock;
1375
        private Object lock;
Lines 1597-1602 Link Here
1597
        
1687
        
1598
    }
1688
    }
1599
    
1689
    
1690
    private static class TestIndexFactory implements IndexFactory {        
1691
        
1692
        public Index create(File cacheRoot) throws IOException {
1693
            return new TestIndex ();
1694
        }
1695
        
1696
    }
1697
    
1698
    private static class TestIndex extends Index {
1699
        
1700
        
1701
        public TestIndex () {
1702
        }
1703
1704
        public boolean isValid(boolean tryOpen) throws IOException {
1705
            return true;
1706
        }
1707
1708
        public List<String> getUsagesFQN(String resourceName, Set<UsageType> mask, BooleanOperator operator) throws IOException, InterruptedException {
1709
            await ();
1710
            return Collections.<String>emptyList();
1711
        }
1712
1713
        public <T> void getDeclaredTypes(String simpleName, NameKind kind, ResultConvertor<T> convertor, Set<? super T> result) throws IOException, InterruptedException {
1714
            await ();
1715
        }
1716
1717
        public void getPackageNames(String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException {
1718
            await ();
1719
        }
1720
1721
        public void store(Map<String, List<String>> refs, Set<String> toDelete) throws IOException {            
1722
        }
1723
1724
        public void store(Map<String, List<String>> refs, List<String> topLevels) throws IOException {            
1725
        }
1726
1727
        public boolean isUpToDate(String resourceName, long timeStamp) throws IOException {
1728
            return true;
1729
        }
1730
1731
        public void clear() throws IOException {            
1732
        }
1733
1734
        public void close() throws IOException {            
1735
        }
1736
        
1737
        private void await () throws InterruptedException {
1738
            AtomicBoolean cancel = this.cancel.get();
1739
            while (true) {
1740
                if (cancel.get()) {
1741
                    throw new InterruptedException ();
1742
                }
1743
                Thread.sleep(100);
1744
            }
1745
        }
1746
        
1747
    }
1748
    
1600
    private FileObject createTestFile (String className) {
1749
    private FileObject createTestFile (String className) {
1601
        try {
1750
        try {
1602
            File workdir = this.getWorkDir();
1751
            File workdir = this.getWorkDir();
Lines 1636-1641 Link Here
1636
    
1785
    
1637
    private ClassPath createCompilePath () {
1786
    private ClassPath createCompilePath () {
1638
        return ClassPathSupport.createClassPath(Collections.EMPTY_LIST);
1787
        return ClassPathSupport.createClassPath(Collections.EMPTY_LIST);
1788
    }
1789
    
1790
    private ClassPath createSourcePath () throws IOException {
1791
        File workdir = this.getWorkDir();
1792
        File root = new File (workdir, "src");
1793
        if (!root.exists()) {
1794
            root.mkdirs();
1795
        }
1796
        return ClassPathSupport.createClassPath(new URL[] {root.toURI().toURL()});
1639
    }
1797
    }
1640
    
1798
    
1641
    private FileObject createTestFile (FileObject srcRoot, String relativeName, String content) throws IOException {
1799
    private FileObject createTestFile (FileObject srcRoot, String relativeName, String content) throws IOException {

Return to bug 106505