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 199432
Collapse All | Expand All

(-)a/java.source/apichanges.xml (+13 lines)
Lines 108-113 Link Here
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
109
109
110
    <changes>
110
    <changes>
111
        <change id="ClassIndex-package-scope">
112
             <api name="general"/>
113
             <summary>Added package search scope into <code>ClassIndex</code> to restrict search in given packages</summary>
114
             <version major="0" minor="82"/>
115
             <date day="17" month="6" year="2011"/>
116
             <author login="tzezula"/>
117
             <compatibility addition="yes"/>
118
             <description>
119
                 Added package search scope into <code>ClassIndex</code> to restrict search in given packages.
120
             </description>
121
             <class package="org.netbeans.api.java.source" name="ClassIndex"/>
122
             <issue number="197194"/>
123
        </change>
111
        <change id="TreeUtilities.findMethodParameterSpan">
124
        <change id="TreeUtilities.findMethodParameterSpan">
112
             <api name="general"/>
125
             <api name="general"/>
113
             <summary>Find span of the MethodTree#getParameters() parameter list in the source.</summary>
126
             <summary>Find span of the MethodTree#getParameters() parameter list in the source.</summary>
(-)a/java.source/nbproject/project.properties (-1 / +1 lines)
Lines 46-52 Link Here
46
javadoc.title=Java Source
46
javadoc.title=Java Source
47
javadoc.arch=${basedir}/arch.xml
47
javadoc.arch=${basedir}/arch.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
49
spec.version.base=0.81.0
49
spec.version.base=0.82.0
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
(-)a/java.source/src/org/netbeans/api/java/source/ClassIndex.java (-26 / +137 lines)
Lines 48-53 Link Here
48
import java.beans.PropertyChangeListener;
48
import java.beans.PropertyChangeListener;
49
import java.io.IOException;
49
import java.io.IOException;
50
import java.net.URL;
50
import java.net.URL;
51
import java.util.Arrays;
51
import java.util.Collection;
52
import java.util.Collection;
52
import java.util.Collections;
53
import java.util.Collections;
53
import java.util.EnumSet;
54
import java.util.EnumSet;
Lines 63-68 Link Here
63
import javax.lang.model.element.ElementKind;
64
import javax.lang.model.element.ElementKind;
64
import javax.lang.model.element.TypeElement;
65
import javax.lang.model.element.TypeElement;
65
import org.apache.lucene.document.Document;
66
import org.apache.lucene.document.Document;
67
import org.netbeans.api.annotations.common.CheckForNull;
66
import org.netbeans.api.annotations.common.NonNull;
68
import org.netbeans.api.annotations.common.NonNull;
67
import org.netbeans.api.annotations.common.NullUnknown;
69
import org.netbeans.api.annotations.common.NullUnknown;
68
import org.netbeans.api.java.classpath.ClassPath;
70
import org.netbeans.api.java.classpath.ClassPath;
Lines 87-92 Link Here
87
import org.openide.filesystems.FileObject;
89
import org.openide.filesystems.FileObject;
88
import org.openide.util.Exceptions;
90
import org.openide.util.Exceptions;
89
import org.openide.util.Mutex;
91
import org.openide.util.Mutex;
92
import org.openide.util.Parameters;
90
import org.openide.util.WeakListeners;
93
import org.openide.util.WeakListeners;
91
94
92
/**
95
/**
Lines 212-230 Link Here
212
    };
215
    };
213
    
216
    
214
    /**
217
    /**
215
     * Scope used by {@link ClassIndex} to search in
218
     * Default predefined {@link SearchScopeType}s
216
     */
219
     */
217
    public enum SearchScope {
220
    public enum SearchScope implements SearchScopeType {
218
        /**
221
        /**
219
         * Search is done in source path
222
         * Search is done in source path
220
         */
223
         */
221
        SOURCE,
224
        SOURCE {
225
            @Override
226
            public boolean isSources() {return true;}
227
            @Override
228
            public boolean isDependencies() {return false;}
229
        },
222
        /**
230
        /**
223
         * Search is done in compile and boot path
231
         * Search is done in compile and boot path
224
         */
232
         */
225
        DEPENDENCIES
233
        DEPENDENCIES {
234
            @Override
235
            public boolean isSources() {return false;}
236
            @Override
237
            public boolean isDependencies() {return true;}
238
        };
239
240
        @Override
241
        @CheckForNull
242
        public Set<? extends String> getPackages() {
243
            return null;
244
        }
226
    };
245
    };
227
    
246
247
    /**
248
     * Scope used by {@link ClassIndex} to search in
249
     * @since 0.82.0
250
     */
251
    public static interface SearchScopeType {
252
        /**
253
         * Limits search only into given packages.
254
         * @return set of packages to search in or null which
255
         * means all packages
256
         */
257
        @CheckForNull
258
        Set<? extends String> getPackages();
259
260
        /**
261
         * Search in source path.
262
         * @return if true search in done in sources
263
         */
264
        boolean isSources();
265
266
        /**
267
         * Search in dependent libraries bootpath,  compilepath.
268
         * @return if true search in done in dependent libraries
269
         */
270
        boolean isDependencies();
271
    }
272
228
    static {
273
    static {
229
	ClassIndexImpl.FACTORY = new ClassIndexFactoryImpl();
274
	ClassIndexImpl.FACTORY = new ClassIndexFactoryImpl();
230
    }
275
    }
Lines 288-294 Link Here
288
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
333
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
289
     * inside call of this method.
334
     * inside call of this method.
290
     */
335
     */
291
    public @NullUnknown Set<ElementHandle<TypeElement>> getElements (final @NonNull ElementHandle<TypeElement> element, final @NonNull Set<SearchKind> searchKind, final @NonNull Set<SearchScope> scope) {
336
    public @NullUnknown Set<ElementHandle<TypeElement>> getElements (
337
            final @NonNull ElementHandle<TypeElement> element,
338
            final @NonNull Set<SearchKind> searchKind,
339
            final @NonNull Set<? extends SearchScopeType> scope) {
292
        assert element != null;
340
        assert element != null;
293
        assert element.getSignature()[0] != null;
341
        assert element.getSignature()[0] != null;
294
        assert searchKind != null;
342
        assert searchKind != null;
Lines 301-307 Link Here
301
            if (!ut.isEmpty()) {
349
            if (!ut.isEmpty()) {
302
                for (ClassIndexImpl query : queries) {
350
                for (ClassIndexImpl query : queries) {
303
                    try {
351
                    try {
304
                        query.search(binaryName, ut, thConvertor, result);
352
                        query.search(
353
                            binaryName,
354
                            ut,
355
                            scope,
356
                            thConvertor,
357
                            result);
305
                    } catch (Index.IndexClosedException e) {
358
                    } catch (Index.IndexClosedException e) {
306
                        logClosedIndex (query);
359
                        logClosedIndex (query);
307
                    } catch (IOException e) {
360
                    } catch (IOException e) {
Lines 324-343 Link Here
324
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
377
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
325
     * inside call of this method.
378
     * inside call of this method.
326
     */
379
     */
327
    public @NullUnknown Set<FileObject> getResources (final @NonNull ElementHandle<TypeElement> element, final @NonNull Set<SearchKind> searchKind, final @NonNull Set<SearchScope> scope) {
380
    public @NullUnknown Set<FileObject> getResources (
381
            final @NonNull ElementHandle<TypeElement> element,
382
            final @NonNull Set<SearchKind> searchKind,
383
            final @NonNull Set<? extends SearchScopeType> scope) {
328
        assert element != null;
384
        assert element != null;
329
        assert element.getSignature()[0] != null;
385
        assert element.getSignature()[0] != null;
330
        assert searchKind != null;
386
        assert searchKind != null;
331
        final Set<FileObject> result = new HashSet<FileObject> ();
387
        final Set<FileObject> result = new HashSet<FileObject> ();
332
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
388
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
333
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
389
        final Set<ClassIndexImpl.UsageType> ut =  encodeSearchKind(element.getKind(),searchKind);
334
        final String binaryName = element.getSignature()[0];        
390
        final String binaryName = element.getSignature()[0];
335
        try {
391
        try {
336
            if (!ut.isEmpty()) {
392
            if (!ut.isEmpty()) {
337
                for (ClassIndexImpl query : queries) {
393
                for (ClassIndexImpl query : queries) {
338
                    final Convertor<? super Document, FileObject> foConvertor = DocumentUtil.fileObjectConvertor (query.getSourceRoots());
394
                    final Convertor<? super Document, FileObject> foConvertor = DocumentUtil.fileObjectConvertor (query.getSourceRoots());
339
                    try {
395
                    try {
340
                        query.search (binaryName, ut, foConvertor, result);
396
                        query.search(
397
                            binaryName,
398
                            ut,
399
                            scope,
400
                            foConvertor,
401
                            result);
341
                    } catch (Index.IndexClosedException e) {
402
                    } catch (Index.IndexClosedException e) {
342
                        logClosedIndex (query);
403
                        logClosedIndex (query);
343
                    } catch (IOException e) {
404
                    } catch (IOException e) {
Lines 349-355 Link Here
349
        } catch (InterruptedException e) {
410
        } catch (InterruptedException e) {
350
            return null;
411
            return null;
351
        }
412
        }
352
    }        
413
    }
353
    
414
    
354
    
415
    
355
    /**
416
    /**
Lines 362-368 Link Here
362
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
423
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
363
     * inside call of this method.
424
     * inside call of this method.
364
     */
425
     */
365
    public @NullUnknown Set<ElementHandle<TypeElement>> getDeclaredTypes (final @NonNull String name, final @NonNull NameKind kind, final @NonNull Set<SearchScope> scope) {
426
    public @NullUnknown Set<ElementHandle<TypeElement>> getDeclaredTypes (
427
            final @NonNull String name,
428
            final @NonNull NameKind kind,
429
            final @NonNull Set<? extends SearchScopeType> scope) {
366
        assert name != null;
430
        assert name != null;
367
        assert kind != null;
431
        assert kind != null;
368
        final Set<ElementHandle<TypeElement>> result = new HashSet<ElementHandle<TypeElement>>();        
432
        final Set<ElementHandle<TypeElement>> result = new HashSet<ElementHandle<TypeElement>>();        
Lines 371-377 Link Here
371
        try {
435
        try {
372
            for (ClassIndexImpl query : queries) {
436
            for (ClassIndexImpl query : queries) {
373
                try {
437
                try {
374
                    query.getDeclaredTypes (name, kind, thConvertor, result);
438
                    query.getDeclaredTypes (
439
                        name,
440
                        kind,
441
                        scope,
442
                        thConvertor,
443
                        result);
375
                } catch (Index.IndexClosedException e) {
444
                } catch (Index.IndexClosedException e) {
376
                    logClosedIndex (query);
445
                    logClosedIndex (query);
377
                } catch (IOException e) {
446
                } catch (IOException e) {
Lines 400-406 Link Here
400
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
469
     * It may return null when the caller is a CancellableTask&lt;CompilationInfo&gt; and is cancelled
401
     * inside call of this method.
470
     * inside call of this method.
402
     */
471
     */
403
    public @NullUnknown Set<String> getPackageNames (final @NonNull String prefix, boolean directOnly, final @NonNull Set<SearchScope> scope) {
472
    public @NullUnknown Set<String> getPackageNames (
473
            final @NonNull String prefix,
474
            boolean directOnly,
475
            final @NonNull Set<? extends SearchScopeType> scope) {
404
        assert prefix != null;
476
        assert prefix != null;
405
        final Set<String> result = new HashSet<String> ();        
477
        final Set<String> result = new HashSet<String> ();        
406
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
478
        final Iterable<? extends ClassIndexImpl> queries = this.getQueries (scope);
Lines 419-427 Link Here
419
            return null;
491
            return null;
420
        }
492
        }
421
    }
493
    }
422
    
494
423
    // Private innerclasses ----------------------------------------------------
495
    /**
424
        
496
     * Creates a search scope limited to list of packages.
497
     * @param base the base search scope to restrict
498
     * @param pkgs a list of packages in which the search should be performed
499
     * @return a newly created search scope
500
     * @since 0.82.0
501
     */
502
    @NonNull
503
    public static SearchScopeType createPackageSearchScope(
504
            @NonNull final SearchScopeType base,
505
            @NonNull final String... pkgs) {
506
        Parameters.notNull("base", base);   //NOI18N
507
        Parameters.notNull("pkgs", pkgs);   //NOI18N
508
        final Set<String> pkgSet = new HashSet<String>(Arrays.asList(pkgs));
509
        final Set<? extends String> basePkgs = base.getPackages();
510
        if (basePkgs != null) {
511
            pkgSet.addAll(basePkgs);
512
        }
513
        final Set<String> newPkgs = Collections.unmodifiableSet(pkgSet);
514
        return new SearchScopeType() {
515
            @Override
516
            public Set<? extends String> getPackages() {
517
                return newPkgs;
518
            }
519
520
            @Override
521
            public boolean isSources() {
522
                return base.isSources();
523
            }
524
525
            @Override
526
            public boolean isDependencies() {
527
                return base.isDependencies();
528
            }
529
        };
530
    }
531
532
    // <editor-fold defaultstate="collapsed" desc="Private implementation">
425
    private static class ClassIndexFactoryImpl implements ClassIndexFactory {
533
    private static class ClassIndexFactoryImpl implements ClassIndexFactory {
426
        
534
        
427
	public ClassIndex create(final ClassPath bootPath, final ClassPath classPath, final ClassPath sourcePath) {            
535
	public ClassIndex create(final ClassPath bootPath, final ClassPath classPath, final ClassPath sourcePath) {            
Lines 465-479 Link Here
465
            }
573
            }
466
        });        
574
        });        
467
    }
575
    }
468
    
576
469
    private Iterable<? extends ClassIndexImpl> getQueries (final Set<SearchScope> scope) {
577
    private Iterable<? extends ClassIndexImpl> getQueries (final Set<? extends SearchScopeType> scope) {
470
        final Set<ClassIndexImpl> result = new HashSet<ClassIndexImpl> ();
578
        final Set<ClassIndexImpl> result = new HashSet<ClassIndexImpl> ();
471
        synchronized (this) {
579
        synchronized (this) {
472
            if (scope.contains(SearchScope.SOURCE)) {
580
            for (SearchScopeType s : scope) {
473
                result.addAll(this.sourceIndeces);
581
                if (s.isSources()) {
474
            }
582
                    result.addAll(this.sourceIndeces);
475
            if (scope.contains(SearchScope.DEPENDENCIES)) {
583
                }
476
                result.addAll(this.depsIndeces);
584
                if (s.isDependencies()) {
585
                    result.addAll(this.depsIndeces);
586
                }
477
            }
587
            }
478
        }
588
        }
479
        LOGGER.log(
589
        LOGGER.log(
Lines 487-494 Link Here
487
                    result
597
                    result
488
                });
598
                });
489
        return result;
599
        return result;
490
    }        
600
    }
491
    
601
492
    private void createQueriesForRoots (final ClassPath cp, final boolean sources, final Set<? super ClassIndexImpl> queries, final Set<? super URL> oldState) {
602
    private void createQueriesForRoots (final ClassPath cp, final boolean sources, final Set<? super ClassIndexImpl> queries, final Set<? super URL> oldState) {
493
        final PathRegistry preg = PathRegistry.getDefault();
603
        final PathRegistry preg = PathRegistry.getDefault();
494
        List<ClassPath.Entry> entries = cp.entries();
604
        List<ClassPath.Entry> entries = cp.entries();
Lines 820-823 Link Here
820
    private static void assertParserEventThread() {
930
    private static void assertParserEventThread() {
821
        assert Utilities.isTaskProcessorThread(Thread.currentThread());
931
        assert Utilities.isTaskProcessorThread(Thread.currentThread());
822
    }
932
    }
933
    //</editor-fold>
823
}
934
}
(-)a/java.source/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java (-5 / +16 lines)
Lines 59-64 Link Here
59
import java.util.logging.Logger;
59
import java.util.logging.Logger;
60
import javax.lang.model.element.TypeElement;
60
import javax.lang.model.element.TypeElement;
61
import org.apache.lucene.document.Document;
61
import org.apache.lucene.document.Document;
62
import org.netbeans.api.annotations.common.NonNull;
62
import org.netbeans.api.java.source.ClassIndex;
63
import org.netbeans.api.java.source.ClassIndex;
63
import org.netbeans.api.java.source.ElementHandle;
64
import org.netbeans.api.java.source.ElementHandle;
64
import org.netbeans.modules.parsing.lucene.support.Convertor;
65
import org.netbeans.modules.parsing.lucene.support.Convertor;
Lines 101-111 Link Here
101
    
102
    
102
    private State state = State.NEW;
103
    private State state = State.NEW;
103
    private final List<WeakReference<ClassIndexImplListener>> listeners = Collections.synchronizedList(new ArrayList<WeakReference<ClassIndexImplListener>> ());
104
    private final List<WeakReference<ClassIndexImplListener>> listeners = Collections.synchronizedList(new ArrayList<WeakReference<ClassIndexImplListener>> ());
104
    
105
105
    public abstract <T> void search (final String binaryName, final Set<UsageType> usageType, final Convertor<? super Document, T> convertor, final Set<? super T> result) throws IOException, InterruptedException;
106
    public abstract <T> void search (
106
    
107
            @NonNull String binaryName,
107
    public abstract <T> void getDeclaredTypes (String name, ClassIndex.NameKind kind, final Convertor<? super Document, T> convertor, final Set<? super T> result) throws IOException, InterruptedException;
108
            @NonNull Set<? extends UsageType> usageType,
108
    
109
            @NonNull Set<? extends ClassIndex.SearchScopeType> scope,
110
            @NonNull Convertor<? super Document, T> convertor,
111
            @NonNull Set<? super T> result) throws IOException, InterruptedException;
112
113
    public abstract <T> void getDeclaredTypes (
114
            @NonNull String name,
115
            @NonNull ClassIndex.NameKind kind,
116
            @NonNull Set<? extends ClassIndex.SearchScopeType> scope,
117
            @NonNull Convertor<? super Document, T> convertor,
118
            @NonNull Set<? super T> result) throws IOException, InterruptedException;
119
109
    public abstract <T> void getDeclaredElements (String ident, ClassIndex.NameKind kind, Convertor<? super Document, T> convertor, Map<T,Set<String>> result) throws IOException, InterruptedException;
120
    public abstract <T> void getDeclaredElements (String ident, ClassIndex.NameKind kind, Convertor<? super Document, T> convertor, Map<T,Set<String>> result) throws IOException, InterruptedException;
110
    
121
    
111
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException;
122
    public abstract void getPackageNames (String prefix, boolean directOnly, Set<String> result) throws IOException, InterruptedException;
(-)a/java.source/src/org/netbeans/modules/java/source/usages/DocumentUtil.java (-2 / +2 lines)
Lines 217-223 Link Here
217
        return query;
217
        return query;
218
    }
218
    }
219
                                    
219
                                    
220
    static Term referencesTerm (String resourceName, final Set<ClassIndexImpl.UsageType> usageType) {
220
    static Term referencesTerm (String resourceName, final Set<? extends ClassIndexImpl.UsageType> usageType) {
221
        assert resourceName  != null;
221
        assert resourceName  != null;
222
        if (usageType != null) {
222
        if (usageType != null) {
223
            resourceName = encodeUsage (resourceName, usageType, WILDCARD).toString();
223
            resourceName = encodeUsage (resourceName, usageType, WILDCARD).toString();
Lines 291-297 Link Here
291
        return encodeUsage (className, usageTypes, NO).toString();
291
        return encodeUsage (className, usageTypes, NO).toString();
292
    }
292
    }
293
    
293
    
294
    private static StringBuilder encodeUsage (final String className, final Set<ClassIndexImpl.UsageType> usageTypes, char fill) {
294
    private static StringBuilder encodeUsage (final String className, final Set<? extends ClassIndexImpl.UsageType> usageTypes, char fill) {
295
        assert className != null;
295
        assert className != null;
296
        assert usageTypes != null;
296
        assert usageTypes != null;
297
        StringBuilder builder = new StringBuilder ();
297
        StringBuilder builder = new StringBuilder ();
(-)a/java.source/src/org/netbeans/modules/java/source/usages/PersistentClassIndex.java (-21 / +39 lines)
Lines 183-203 Link Here
183
    
183
    
184
    // Implementation of UsagesQueryImpl ---------------------------------------    
184
    // Implementation of UsagesQueryImpl ---------------------------------------    
185
    @Override
185
    @Override
186
    public <T> void search (final String binaryName, final Set<UsageType> usageType, final Convertor<? super Document, T> convertor, final Set<? super T> result) throws InterruptedException, IOException {
186
    public <T> void search (
187
            @NonNull final String binaryName,
188
            @NonNull final Set<? extends UsageType> usageType,
189
            @NonNull final Set<? extends ClassIndex.SearchScopeType> scope,
190
            @NonNull final Convertor<? super Document, T> convertor,
191
            @NonNull final Set<? super T> result) throws InterruptedException, IOException {
187
        updateDirty();
192
        updateDirty();
188
        try {
193
        try {
189
            if (BinaryAnalyser.OBJECT.equals(binaryName)) {
194
            if (BinaryAnalyser.OBJECT.equals(binaryName)) {
190
                this.getDeclaredTypes("", ClassIndex.NameKind.PREFIX, convertor, result);
195
                this.getDeclaredTypes(
191
                return;
196
                    "", //NOI18N
197
                    ClassIndex.NameKind.PREFIX,
198
                    scope,
199
                    convertor,
200
                    result);
201
            } else {
202
                IndexManager.readAccess(new IndexManager.Action<Void> () {
203
                    @Override
204
                    public Void run () throws IOException, InterruptedException {
205
                        final Query usagesQuery = QueryUtil.scopeFilter(
206
                                QueryUtil.createUsagesQuery(binaryName, usageType, Occur.SHOULD),
207
                                scope);
208
                        if (usagesQuery != null) {
209
                            index.query(result, convertor, DocumentUtil.declaredTypesFieldSelector(), cancel.get(), usagesQuery);
210
                        }
211
                        return null;
212
                    }
213
                });
192
            }
214
            }
193
194
            IndexManager.readAccess(new IndexManager.Action<Void> () {
195
                @Override
196
                public Void run () throws IOException, InterruptedException {
197
                    usages(binaryName, usageType, convertor, result);
198
                    return null;
199
                }
200
            });
201
        } catch (IOException ioe) {
215
        } catch (IOException ioe) {
202
            this.<Void,IOException>handleException(null, ioe);
216
            this.<Void,IOException>handleException(null, ioe);
203
        }
217
        }
Lines 205-222 Link Here
205
    
219
    
206
                       
220
                       
207
    @Override
221
    @Override
208
    public <T> void getDeclaredTypes (final String simpleName, final ClassIndex.NameKind kind, final Convertor<? super Document, T> convertor, final Set<? super T> result) throws InterruptedException, IOException {
222
    public <T> void getDeclaredTypes (
223
            @NonNull final String simpleName,
224
            @NonNull final ClassIndex.NameKind kind,
225
            @NonNull final Set<? extends ClassIndex.SearchScopeType> scope,
226
            @NonNull final Convertor<? super Document, T> convertor,
227
            @NonNull final Set<? super T> result) throws InterruptedException, IOException {
209
        updateDirty();
228
        updateDirty();
210
        try {
229
        try {
211
            IndexManager.readAccess(new IndexManager.Action<Void> () {
230
            IndexManager.readAccess(new IndexManager.Action<Void> () {
212
                @Override
231
                @Override
213
                public Void run () throws IOException, InterruptedException {
232
                public Void run () throws IOException, InterruptedException {
214
                    final Query query =  Queries.createQuery(
233
                    final Query query =  QueryUtil.scopeFilter(
234
                        Queries.createQuery(
215
                            DocumentUtil.FIELD_SIMPLE_NAME,
235
                            DocumentUtil.FIELD_SIMPLE_NAME,
216
                            DocumentUtil.FIELD_CASE_INSENSITIVE_NAME,
236
                            DocumentUtil.FIELD_CASE_INSENSITIVE_NAME,
217
                            simpleName,
237
                            simpleName,
218
                            DocumentUtil.translateQueryKind(kind));
238
                            DocumentUtil.translateQueryKind(kind)),
219
                    index.query(result, convertor, DocumentUtil.declaredTypesFieldSelector(), cancel.get(), query);
239
                        scope);
240
                    if (query != null) {
241
                        index.query(result, convertor, DocumentUtil.declaredTypesFieldSelector(), cancel.get(), query);
242
                    }
220
                    return null;
243
                    return null;
221
                }
244
                }
222
            });
245
            });
Lines 393-404 Link Here
393
            }
416
            }
394
        }
417
        }
395
    }
418
    }
396
    
419
397
    private <T> void usages (final String binaryName, final Set<UsageType> usageType, Convertor<? super Document, T> convertor, Set<? super T> result) throws InterruptedException, IOException {
398
        final Query usagesQuery = QueryUtil.createUsagesQuery(binaryName, usageType, Occur.SHOULD);
399
        this.index.query(result, convertor, DocumentUtil.declaredTypesFieldSelector(), cancel.get(), usagesQuery);
400
    }
401
    
402
    private synchronized void resetPkgCache() {        
420
    private synchronized void resetPkgCache() {        
403
        rootPkgCache = null;
421
        rootPkgCache = null;
404
    }
422
    }
(-)a/java.source/src/org/netbeans/modules/java/source/usages/QueryUtil.java (-6 / +62 lines)
Lines 43-57 Link Here
43
package org.netbeans.modules.java.source.usages;
43
package org.netbeans.modules.java.source.usages;
44
44
45
import java.util.EnumSet;
45
import java.util.EnumSet;
46
import java.util.HashSet;
46
import java.util.Set;
47
import java.util.Set;
47
import org.apache.lucene.index.Term;
48
import org.apache.lucene.index.Term;
48
import org.apache.lucene.search.BooleanClause.Occur;
49
import org.apache.lucene.search.BooleanClause.Occur;
49
import org.apache.lucene.search.BooleanQuery;
50
import org.apache.lucene.search.BooleanQuery;
51
import org.apache.lucene.search.FilteredQuery;
52
import org.apache.lucene.search.PrefixFilter;
50
import org.apache.lucene.search.Query;
53
import org.apache.lucene.search.Query;
54
import org.apache.lucene.search.TermQuery;
51
import org.apache.lucene.search.WildcardQuery;
55
import org.apache.lucene.search.WildcardQuery;
56
import org.netbeans.api.annotations.common.CheckForNull;
52
import org.netbeans.api.annotations.common.NonNull;
57
import org.netbeans.api.annotations.common.NonNull;
53
import org.netbeans.api.annotations.common.NullAllowed;
58
import org.netbeans.api.annotations.common.NullAllowed;
54
import org.netbeans.modules.parsing.lucene.support.Convertor;
59
import org.netbeans.api.java.source.ClassIndex.SearchScopeType;
55
import org.netbeans.modules.parsing.lucene.support.StoppableConvertor;
60
import org.netbeans.modules.parsing.lucene.support.StoppableConvertor;
56
import org.openide.util.Parameters;
61
import org.openide.util.Parameters;
57
62
Lines 65-71 Link Here
65
    
70
    
66
    static Query createUsagesQuery(
71
    static Query createUsagesQuery(
67
            final @NonNull String resourceName,
72
            final @NonNull String resourceName,
68
            final @NonNull Set<ClassIndexImpl.UsageType> mask,
73
            final @NonNull Set<? extends ClassIndexImpl.UsageType> mask,
69
            final @NonNull Occur operator) {
74
            final @NonNull Occur operator) {
70
        Parameters.notNull("resourceName", resourceName);
75
        Parameters.notNull("resourceName", resourceName);
71
        Parameters.notNull("mask", mask);
76
        Parameters.notNull("mask", mask);
Lines 83-89 Link Here
83
            throw new IllegalArgumentException();
88
            throw new IllegalArgumentException();
84
        }
89
        }
85
    }
90
    }
86
        
91
92
    @CheckForNull
93
    static Query scopeFilter (
94
            @NonNull final Query q,
95
            @NonNull final Set<? extends SearchScopeType> scope) {
96
        assert q != null;
97
        assert scope != null;
98
        Set<String> pkgs = null;
99
        for (SearchScopeType s : scope) {
100
            Set<? extends String> sp = s.getPackages();
101
            if (sp != null) {
102
                if (pkgs == null) {
103
                    pkgs = new HashSet<String>();
104
                }
105
                pkgs.addAll(sp);
106
            }
107
        }
108
        if (pkgs == null) {
109
            return q;
110
        }
111
        switch (pkgs.size()) {
112
            case 0:
113
                return null;
114
            case 1:
115
            {
116
                //Todo perf: Use filter query
117
                final BooleanQuery qFiltered = new BooleanQuery();
118
                qFiltered.add(
119
                    new TermQuery(
120
                        new Term (
121
                            DocumentUtil.FIELD_PACKAGE_NAME,
122
                            pkgs.iterator().next())),
123
                    Occur.MUST);
124
                qFiltered.add(q, Occur.MUST);
125
                return qFiltered;
126
            }
127
            default:
128
            {
129
                final BooleanQuery qPkgs = new BooleanQuery();
130
                for (String pkg : pkgs) {
131
                    qPkgs.add(
132
                        new TermQuery(
133
                            new Term(
134
                                DocumentUtil.FIELD_PACKAGE_NAME,
135
                                pkg)),
136
                            Occur.SHOULD);
137
                }
138
                final BooleanQuery qFiltered = new BooleanQuery();
139
                qFiltered.add(q, Occur.MUST);
140
                qFiltered.add(qPkgs, Occur.MUST);
141
                return qFiltered;
142
            }
143
        }
144
    }
145
87
    static Pair<StoppableConvertor<Term,String>,Term> createPackageFilter(
146
    static Pair<StoppableConvertor<Term,String>,Term> createPackageFilter(
88
            final @NullAllowed String prefix,
147
            final @NullAllowed String prefix,
89
            final boolean directOnly) {
148
            final boolean directOnly) {
Lines 128-136 Link Here
128
            }
187
            }
129
            return null;
188
            return null;
130
        }
189
        }
131
        
132
    }
190
    }
133
    
134
    //</editor-fold>
191
    //</editor-fold>
135
            
136
}
192
}
(-)a/java.source/test/unit/src/org/netbeans/api/java/source/ClassIndexTest.java (-2 / +213 lines)
Lines 51-64 Link Here
51
import java.io.PrintWriter;
51
import java.io.PrintWriter;
52
import java.net.URL;
52
import java.net.URL;
53
import java.util.ArrayList;
53
import java.util.ArrayList;
54
import java.util.Arrays;
54
import java.util.Collections;
55
import java.util.Collections;
55
import java.util.EnumSet;
56
import java.util.EnumSet;
57
import java.util.HashSet;
56
import java.util.Iterator;
58
import java.util.Iterator;
57
import java.util.LinkedList;
59
import java.util.LinkedList;
58
import java.util.List;
60
import java.util.List;
59
import java.util.Set;
61
import java.util.Set;
60
import java.util.concurrent.CountDownLatch;
62
import java.util.concurrent.CountDownLatch;
61
import java.util.concurrent.TimeUnit;
63
import java.util.concurrent.TimeUnit;
64
import javax.lang.model.element.ElementKind;
65
import javax.lang.model.element.TypeElement;
62
import javax.swing.event.ChangeListener;
66
import javax.swing.event.ChangeListener;
63
import org.netbeans.api.java.classpath.ClassPath;
67
import org.netbeans.api.java.classpath.ClassPath;
64
import org.netbeans.api.java.classpath.GlobalPathRegistry;
68
import org.netbeans.api.java.classpath.GlobalPathRegistry;
Lines 66-71 Link Here
66
import org.netbeans.api.java.queries.SourceForBinaryQuery;
70
import org.netbeans.api.java.queries.SourceForBinaryQuery;
67
import org.netbeans.junit.MockServices;
71
import org.netbeans.junit.MockServices;
68
import org.netbeans.junit.NbTestCase;
72
import org.netbeans.junit.NbTestCase;
73
import org.netbeans.modules.java.source.ElementHandleAccessor;
74
import org.netbeans.modules.java.source.parsing.FileObjects;
69
import org.netbeans.modules.java.source.usages.ClassIndexManager;
75
import org.netbeans.modules.java.source.usages.ClassIndexManager;
70
import org.netbeans.modules.java.source.usages.IndexUtil;
76
import org.netbeans.modules.java.source.usages.IndexUtil;
71
import org.netbeans.modules.parsing.api.indexing.IndexingManager;
77
import org.netbeans.modules.parsing.api.indexing.IndexingManager;
Lines 294-301 Link Here
294
            }
300
            }
295
        });
301
        });
296
    }
302
    }
297
    
303
298
    
304
    public void testGetElementsScopes() throws Exception {
305
        createJavaFile (srcRoot,"org.me.base","Base", "package org.me.base;\npublic class Base {}\n");
306
        createJavaFile (srcRoot,"org.me.pkg1","Class1", "package org.me.pkg1;\npublic class Class1 extends org.me.base.Base {}\n");
307
        createJavaFile (srcRoot,"org.me.pkg2","Class2", "package org.me.pkg2;\npublic class Class2 extends org.me.base.Base {}\n");
308
        IndexingManager.getDefault().refreshIndexAndWait(srcRoot.getURL(), null, true);
309
        final ClassPath scp = ClassPathSupport.createClassPath(srcRoot);
310
        final ClasspathInfo cpInfo = ClasspathInfo.create(
311
            ClassPathSupport.createClassPath(new URL[0]),
312
            ClassPathSupport.createClassPath(new URL[0]),
313
            scp);
314
        final ClassIndex ci = cpInfo.getClassIndex();
315
        Set<ElementHandle<TypeElement>> r = ci.getElements(
316
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
317
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
318
            EnumSet.of(ClassIndex.SearchScope.SOURCE));
319
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
320
321
        r = ci.getElements(
322
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
323
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
324
            Collections.singleton(
325
                ClassIndex.createPackageSearchScope(
326
                    ClassIndex.SearchScope.SOURCE,
327
                    "org.me.pkg1",
328
                    "org.me.pkg2")));
329
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
330
331
        Set<ClassIndex.SearchScopeType> scopes = new HashSet<ClassIndex.SearchScopeType>();
332
        scopes.add(ClassIndex.createPackageSearchScope(
333
            ClassIndex.SearchScope.SOURCE,
334
            "org.me.pkg1"));
335
        scopes.add(ClassIndex.createPackageSearchScope(
336
            ClassIndex.SearchScope.SOURCE,
337
            "org.me.pkg2"));
338
        r = ci.getElements(
339
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
340
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
341
            scopes);
342
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
343
344
        r = ci.getElements(
345
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
346
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
347
            Collections.singleton(
348
                new ClassIndex.SearchScopeType() {
349
                    @Override
350
                    public Set<? extends String> getPackages() {
351
                        return null;
352
                    }
353
354
                    @Override
355
                    public boolean isSources() {
356
                        return true;
357
                    }
358
359
                    @Override
360
                    public boolean isDependencies() {
361
                        return false;
362
                    }
363
                }));
364
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
365
366
        r = ci.getElements(
367
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
368
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
369
            Collections.singleton(
370
                ClassIndex.createPackageSearchScope(
371
                    ClassIndex.SearchScope.SOURCE,
372
                    "org.me.pkg1")));
373
        assertElementHandles(new String[]{"org.me.pkg1.Class1"}, r);
374
375
        r = ci.getElements(
376
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "org.me.base.Base"),
377
            EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
378
            Collections.singleton(
379
                ClassIndex.createPackageSearchScope(
380
                    ClassIndex.SearchScope.SOURCE)));
381
        assertElementHandles(new String[]{}, r);
382
383
        r = ci.getElements(
384
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "java.lang.Object"),
385
            EnumSet.allOf(ClassIndex.SearchKind.class),
386
            EnumSet.of(ClassIndex.SearchScope.SOURCE));
387
        assertElementHandles(new String[]{"org.me.base.Base", "org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
388
389
        r = ci.getElements(
390
            ElementHandleAccessor.INSTANCE.create(ElementKind.CLASS, "java.lang.Object"),
391
            EnumSet.allOf(ClassIndex.SearchKind.class),
392
            Collections.singleton(ClassIndex.createPackageSearchScope(ClassIndex.SearchScope.SOURCE, "org.me.pkg1")));
393
        assertElementHandles(new String[]{"org.me.pkg1.Class1"}, r);
394
    }
395
396
    public void testGetDeclaredTypesScopes() throws Exception {
397
        createJavaFile (srcRoot,"org.me.pkg1","Class1", "package org.me.pkg1;\npublic class Class1 {}\n");
398
        createJavaFile (srcRoot,"org.me.pkg2","Class2", "package org.me.pkg2;\npublic class Class2 {}\n");
399
        IndexingManager.getDefault().refreshIndexAndWait(srcRoot.getURL(), null, true);
400
        final ClassPath scp = ClassPathSupport.createClassPath(srcRoot);
401
        final ClasspathInfo cpInfo = ClasspathInfo.create(
402
            ClassPathSupport.createClassPath(new URL[0]),
403
            ClassPathSupport.createClassPath(new URL[0]),
404
            scp);
405
        final ClassIndex ci = cpInfo.getClassIndex();
406
        Set<ElementHandle<TypeElement>> r = ci.getDeclaredTypes(
407
            "",
408
            ClassIndex.NameKind.PREFIX,
409
            EnumSet.of(ClassIndex.SearchScope.SOURCE));
410
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
411
412
        r = ci.getDeclaredTypes(
413
            "",
414
            ClassIndex.NameKind.PREFIX,
415
            Collections.singleton(
416
                ClassIndex.createPackageSearchScope(
417
                    ClassIndex.SearchScope.SOURCE,
418
                    "org.me.pkg1",
419
                    "org.me.pkg2")));
420
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
421
422
        Set<ClassIndex.SearchScopeType> scopes = new HashSet<ClassIndex.SearchScopeType>();
423
        scopes.add(ClassIndex.createPackageSearchScope(
424
            ClassIndex.SearchScope.SOURCE,
425
            "org.me.pkg1"));
426
        scopes.add(ClassIndex.createPackageSearchScope(
427
            ClassIndex.SearchScope.SOURCE,
428
            "org.me.pkg2"));
429
        r = ci.getDeclaredTypes(
430
            "",
431
            ClassIndex.NameKind.PREFIX,
432
            scopes);
433
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
434
        r = ci.getDeclaredTypes(
435
            "",
436
            ClassIndex.NameKind.PREFIX,
437
            Collections.singleton(
438
                new ClassIndex.SearchScopeType() {
439
                    @Override
440
                    public Set<? extends String> getPackages() {
441
                        return null;
442
                    }
443
444
                    @Override
445
                    public boolean isSources() {
446
                        return true;
447
                    }
448
449
                    @Override
450
                    public boolean isDependencies() {
451
                        return false;
452
                    }
453
                }));
454
        assertElementHandles(new String[]{"org.me.pkg1.Class1","org.me.pkg2.Class2"}, r);
455
456
        r = ci.getDeclaredTypes(
457
            "",
458
            ClassIndex.NameKind.PREFIX,
459
            Collections.singleton(
460
                ClassIndex.createPackageSearchScope(
461
                    ClassIndex.SearchScope.SOURCE,
462
                    "org.me.pkg1")));
463
        assertElementHandles(new String[]{"org.me.pkg1.Class1"}, r);
464
465
        r = ci.getDeclaredTypes(
466
            "",
467
            ClassIndex.NameKind.PREFIX,
468
            Collections.singleton(
469
                ClassIndex.createPackageSearchScope(
470
                    ClassIndex.SearchScope.SOURCE)));
471
        assertElementHandles(new String[]{}, r);
472
    }
473
474
    private FileObject createJavaFile (
475
            final FileObject root,
476
            final String pkg,
477
            final String name,
478
            final String content) throws IOException {
479
            final FileObject file = FileUtil.createData(
480
                root,
481
                String.format("%s/%s.java",
482
                    FileObjects.convertPackage2Folder(pkg),
483
                    name));
484
            final FileLock lck = file.lock();
485
            try {
486
                final PrintWriter out = new PrintWriter (new OutputStreamWriter(file.getOutputStream(lck)));
487
                try {
488
                    out.print(content);
489
                } finally {
490
                    out.close();
491
                }
492
            } finally {
493
                lck.releaseLock();
494
            }
495
            return file;
496
    }
497
498
    private void assertElementHandles(final String[] expected, final Set<ElementHandle<TypeElement>> result) {
499
        final Set<String> expSet = new HashSet(Arrays.asList(expected));
500
        for (ElementHandle<TypeElement> handle : result) {
501
            if (!expSet.remove(handle.getQualifiedName())) {
502
                throw new AssertionError("Expected: " + Arrays.toString(expected) +" Result: " + result);
503
            }
504
        }
505
        if (!expSet.isEmpty()) {
506
            throw new AssertionError("Expected: " + Arrays.toString(expected) +" Result: " + result);
507
        }
508
    }
509
299
    private static void assertExpectedEvents (final Set<EventType> et, final List<? extends EventRecord> eventLog) {
510
    private static void assertExpectedEvents (final Set<EventType> et, final List<? extends EventRecord> eventLog) {
300
        assert et != null;
511
        assert et != null;
301
        assert eventLog != null;
512
        assert eventLog != null;

Return to bug 199432