Lines 47-52
Link Here
|
47 |
import java.lang.ref.SoftReference; |
47 |
import java.lang.ref.SoftReference; |
48 |
import java.net.MalformedURLException; |
48 |
import java.net.MalformedURLException; |
49 |
import java.net.URL; |
49 |
import java.net.URL; |
|
|
50 |
import java.util.ArrayDeque; |
50 |
import java.util.ArrayList; |
51 |
import java.util.ArrayList; |
51 |
import java.util.Arrays; |
52 |
import java.util.Arrays; |
52 |
import java.util.Collection; |
53 |
import java.util.Collection; |
Lines 56-67
Link Here
|
56 |
import java.util.LinkedList; |
57 |
import java.util.LinkedList; |
57 |
import java.util.List; |
58 |
import java.util.List; |
58 |
import java.util.Map; |
59 |
import java.util.Map; |
|
|
60 |
import java.util.Queue; |
59 |
import java.util.Set; |
61 |
import java.util.Set; |
60 |
import java.util.concurrent.Callable; |
62 |
import java.util.concurrent.Callable; |
61 |
import java.util.logging.Level; |
63 |
import java.util.logging.Level; |
62 |
import java.util.logging.Logger; |
64 |
import java.util.logging.Logger; |
|
|
65 |
import org.apache.lucene.search.BooleanClause; |
63 |
import org.netbeans.api.annotations.common.CheckForNull; |
66 |
import org.netbeans.api.annotations.common.CheckForNull; |
64 |
import org.netbeans.api.annotations.common.NonNull; |
67 |
import org.netbeans.api.annotations.common.NonNull; |
|
|
68 |
import org.netbeans.api.annotations.common.NullAllowed; |
65 |
import org.netbeans.api.java.classpath.ClassPath; |
69 |
import org.netbeans.api.java.classpath.ClassPath; |
66 |
import org.netbeans.api.java.classpath.GlobalPathRegistry; |
70 |
import org.netbeans.api.java.classpath.GlobalPathRegistry; |
67 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
71 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
Lines 83-90
Link Here
|
83 |
import org.netbeans.modules.parsing.impl.indexing.friendapi.IndexingController; |
87 |
import org.netbeans.modules.parsing.impl.indexing.friendapi.IndexingController; |
84 |
import org.netbeans.modules.parsing.impl.indexing.lucene.LayeredDocumentIndex; |
88 |
import org.netbeans.modules.parsing.impl.indexing.lucene.LayeredDocumentIndex; |
85 |
import org.netbeans.modules.parsing.impl.indexing.lucene.LuceneIndexFactory; |
89 |
import org.netbeans.modules.parsing.impl.indexing.lucene.LuceneIndexFactory; |
86 |
import org.netbeans.modules.parsing.lucene.support.DocumentIndex; |
90 |
import org.netbeans.modules.parsing.lucene.support.Convertor; |
|
|
91 |
import org.netbeans.modules.parsing.lucene.support.DocumentIndex2; |
87 |
import org.netbeans.modules.parsing.lucene.support.Index; |
92 |
import org.netbeans.modules.parsing.lucene.support.Index; |
|
|
93 |
import org.netbeans.modules.parsing.lucene.support.IndexDocument; |
88 |
import org.netbeans.modules.parsing.lucene.support.Queries; |
94 |
import org.netbeans.modules.parsing.lucene.support.Queries; |
89 |
import org.openide.filesystems.FileObject; |
95 |
import org.openide.filesystems.FileObject; |
90 |
import org.openide.filesystems.FileStateInvalidException; |
96 |
import org.openide.filesystems.FileStateInvalidException; |
Lines 319-397
Link Here
|
319 |
Parameters.notNull("fieldName", fieldName); //NOI18N |
325 |
Parameters.notNull("fieldName", fieldName); //NOI18N |
320 |
Parameters.notNull("fieldValue", fieldValue); //NOI18N |
326 |
Parameters.notNull("fieldValue", fieldValue); //NOI18N |
321 |
Parameters.notNull("kind", kind); //NOI18N |
327 |
Parameters.notNull("kind", kind); //NOI18N |
322 |
try { |
328 |
return getQueryFactory().field(fieldName, fieldValue, kind).execute(fieldsToLoad); |
323 |
return Utilities.runPriorityIO(new Callable<Collection<? extends IndexResult>>() { |
329 |
} |
324 |
|
330 |
|
325 |
@Override |
331 |
|
326 |
public Collection<? extends IndexResult> call() throws Exception { |
332 |
/** |
327 |
Iterable<? extends Pair<URL, LayeredDocumentIndex>> indices = indexerQuery.getIndices(roots); |
333 |
* Returns the factory for creating composite queries. |
328 |
// check if there are stale indices |
334 |
* @return the {@link QuerySupport.Query.Factory} |
329 |
for (Pair<URL, LayeredDocumentIndex> pair : indices) { |
335 |
* @since 1.66 |
330 |
final LayeredDocumentIndex index = pair.second; |
336 |
*/ |
331 |
final Collection<? extends String> staleFiles = index.getDirtyKeys(); |
337 |
@NonNull |
332 |
final boolean scanningThread = RunWhenScanFinishedSupport.isScanningThread(); |
338 |
public Query.Factory getQueryFactory() { |
333 |
LOG.log( |
339 |
return new Query.Factory(this); |
334 |
Level.FINE, |
|
|
335 |
"Index: {0}, staleFiles: {1}, scanning thread: {2}", //NOI18N |
336 |
new Object[]{ |
337 |
index, |
338 |
staleFiles, |
339 |
scanningThread |
340 |
}); |
341 |
if (!staleFiles.isEmpty() && !scanningThread) { |
342 |
final URL root = pair.first; |
343 |
LinkedList<URL> list = new LinkedList<URL>(); |
344 |
for (String staleFile : staleFiles) { |
345 |
try { |
346 |
list.add(Util.resolveUrl(root, staleFile, false)); |
347 |
} catch (MalformedURLException ex) { |
348 |
LOG.log(Level.WARNING, null, ex); |
349 |
} |
350 |
} |
351 |
TransientUpdateSupport.setTransientUpdate(true); |
352 |
try { |
353 |
RepositoryUpdater.getDefault().enforcedFileListUpdate(root,list); |
354 |
} finally { |
355 |
TransientUpdateSupport.setTransientUpdate(false); |
356 |
} |
357 |
} |
358 |
} |
359 |
final List<IndexResult> result = new LinkedList<IndexResult>(); |
360 |
for (Pair<URL, LayeredDocumentIndex> pair : indices) { |
361 |
final DocumentIndex index = pair.second; |
362 |
final URL root = pair.first; |
363 |
final Collection<? extends org.netbeans.modules.parsing.lucene.support.IndexDocument> pr = index.query( |
364 |
fieldName, |
365 |
fieldValue, |
366 |
translateQueryKind(kind), |
367 |
fieldsToLoad); |
368 |
if (LOG.isLoggable(Level.FINE)) { |
369 |
LOG.fine("query(\"" + fieldName + "\", \"" + fieldValue + "\", " + kind + ", " + printFiledToLoad(fieldsToLoad) + ") invoked at " + getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "[indexer=" + indexerQuery.getIndexerId() + "]:"); //NOI18N |
370 |
for (org.netbeans.modules.parsing.lucene.support.IndexDocument idi : pr) { |
371 |
LOG.fine(" " + idi); //NOI18N |
372 |
} |
373 |
LOG.fine("----"); //NOI18N |
374 |
} |
375 |
for (org.netbeans.modules.parsing.lucene.support.IndexDocument di : pr) { |
376 |
result.add(new IndexResult(di, root)); |
377 |
} |
378 |
} |
379 |
return result; |
380 |
} |
381 |
}); |
382 |
} catch (Index.IndexClosedException ice) { |
383 |
if (Installer.isClosed()) { |
384 |
return Collections.<IndexResult>emptySet(); |
385 |
} else { |
386 |
throw ice; |
387 |
} |
388 |
} catch (IOException ioe) { |
389 |
throw ioe; |
390 |
} catch (RuntimeException re) { |
391 |
throw re; |
392 |
} catch (Exception ex) { |
393 |
throw new IOException(ex); |
394 |
} |
395 |
} |
340 |
} |
396 |
|
341 |
|
397 |
/** |
342 |
/** |
Lines 433-438
Link Here
|
433 |
CASE_INSENSITIVE_CAMEL_CASE; |
378 |
CASE_INSENSITIVE_CAMEL_CASE; |
434 |
} |
379 |
} |
435 |
|
380 |
|
|
|
381 |
/** |
382 |
* An index query. |
383 |
* @since 1.66 |
384 |
*/ |
385 |
public static final class Query { |
386 |
|
387 |
private final QuerySupport qs; |
388 |
private final org.apache.lucene.search.Query queryImpl; |
389 |
|
390 |
private Query( |
391 |
@NonNull final QuerySupport qs, |
392 |
@NonNull final org.apache.lucene.search.Query queryImpl) { |
393 |
assert qs != null; |
394 |
assert queryImpl != null; |
395 |
this.qs = qs; |
396 |
this.queryImpl = queryImpl; |
397 |
} |
398 |
|
399 |
/** |
400 |
* Factory for an index queries. |
401 |
*/ |
402 |
public static final class Factory { |
403 |
|
404 |
private final QuerySupport qs; |
405 |
|
406 |
private Factory(@NonNull final QuerySupport qs) { |
407 |
assert qs != null; |
408 |
this.qs = qs; |
409 |
} |
410 |
|
411 |
/** |
412 |
* Creates a query for required field value. |
413 |
* @param fieldName the name of the tested field |
414 |
* @param fieldValue the required value of the tested field |
415 |
* @param kind the kind of the query |
416 |
* @return the newly created query |
417 |
*/ |
418 |
@NonNull |
419 |
public Query field( |
420 |
@NonNull final String fieldName, |
421 |
@NonNull final String fieldValue, |
422 |
@NonNull final Kind kind) { |
423 |
Parameters.notNull("fieldName", fieldName); //NOI18N |
424 |
Parameters.notNull("fieldValue", fieldValue); //NOI18N |
425 |
Parameters.notNull("kind", kind); //NOI18N |
426 |
return new Query( |
427 |
qs, |
428 |
Queries.createQuery( |
429 |
fieldName, |
430 |
fieldName, |
431 |
fieldValue, |
432 |
translateQueryKind(kind))); |
433 |
} |
434 |
|
435 |
/** |
436 |
* Creates a boolean AND query. |
437 |
* @param queries the queries to compose into the AND query |
438 |
* @return the newly created AND query |
439 |
*/ |
440 |
@NonNull |
441 |
public Query and(@NonNull final Query...queries) { |
442 |
Parameters.notNull("queries", queries); //NOI18N |
443 |
final org.apache.lucene.search.BooleanQuery bq = new org.apache.lucene.search.BooleanQuery(); |
444 |
for (Query q : queries) { |
445 |
bq.add(new BooleanClause(q.queryImpl, org.apache.lucene.search.BooleanClause.Occur.MUST)); |
446 |
} |
447 |
return new Query( |
448 |
qs, |
449 |
bq); |
450 |
} |
451 |
|
452 |
/** |
453 |
* Creates a boolean OR query. |
454 |
* @param queries the queries to compose into the OR query |
455 |
* @return the newly created OR query |
456 |
*/ |
457 |
@NonNull |
458 |
public Query or(@NonNull final Query...queries) { |
459 |
Parameters.notNull("queries", queries); //NOI18N |
460 |
final org.apache.lucene.search.BooleanQuery bq = new org.apache.lucene.search.BooleanQuery(); |
461 |
for (Query q : queries) { |
462 |
bq.add(new BooleanClause(q.queryImpl, org.apache.lucene.search.BooleanClause.Occur.SHOULD)); |
463 |
} |
464 |
return new Query( |
465 |
qs, |
466 |
bq); |
467 |
} |
468 |
} |
469 |
|
470 |
/** |
471 |
* Executes the query. |
472 |
* @param fieldsToLoad the filter for fields to be loaded into the {@link IndexResult}s |
473 |
* @return the {@link Collection} of {@link IndexResult} matching the {@link QuerySupport.Query} |
474 |
* @throws IOException in case of IO error. |
475 |
*/ |
476 |
@NonNull |
477 |
public Collection<? extends IndexResult> execute(@NullAllowed final String... fieldsToLoad) throws IOException { |
478 |
try { |
479 |
return Utilities.runPriorityIO(new Callable<Collection<? extends IndexResult>>() { |
480 |
@Override |
481 |
public Collection<? extends IndexResult> call() throws Exception { |
482 |
Iterable<? extends Pair<URL, LayeredDocumentIndex>> indices = qs.indexerQuery.getIndices(qs.roots); |
483 |
// check if there are stale indices |
484 |
for (Pair<URL, LayeredDocumentIndex> pair : indices) { |
485 |
final LayeredDocumentIndex index = pair.second; |
486 |
final Collection<? extends String> staleFiles = index.getDirtyKeys(); |
487 |
final boolean scanningThread = RunWhenScanFinishedSupport.isScanningThread(); |
488 |
LOG.log( |
489 |
Level.FINE, |
490 |
"Index: {0}, staleFiles: {1}, scanning thread: {2}", //NOI18N |
491 |
new Object[]{ |
492 |
index, |
493 |
staleFiles, |
494 |
scanningThread |
495 |
}); |
496 |
if (!staleFiles.isEmpty() && !scanningThread) { |
497 |
final URL root = pair.first; |
498 |
LinkedList<URL> list = new LinkedList<URL>(); |
499 |
for (String staleFile : staleFiles) { |
500 |
try { |
501 |
list.add(Util.resolveUrl(root, staleFile, false)); |
502 |
} catch (MalformedURLException ex) { |
503 |
LOG.log(Level.WARNING, null, ex); |
504 |
} |
505 |
} |
506 |
TransientUpdateSupport.setTransientUpdate(true); |
507 |
try { |
508 |
RepositoryUpdater.getDefault().enforcedFileListUpdate(root,list); |
509 |
} finally { |
510 |
TransientUpdateSupport.setTransientUpdate(false); |
511 |
} |
512 |
} |
513 |
} |
514 |
final Queue<IndexResult> result = new ArrayDeque<IndexResult>(); |
515 |
for (Pair<URL, LayeredDocumentIndex> pair : indices) { |
516 |
final DocumentIndex2 index = pair.second; |
517 |
final URL root = pair.first; |
518 |
final Collection<? extends IndexResult> pr = |
519 |
index.query( |
520 |
queryImpl, |
521 |
new DocumentToResultConvertor(root), |
522 |
fieldsToLoad); |
523 |
result.addAll(pr); //TODO: Perf: Replace by ProxyCollection |
524 |
if (LOG.isLoggable(Level.FINE)) { |
525 |
LOG.log( |
526 |
Level.FINE, "{0} (loading fields {1}) invoked at {2}@{3}[indexer={4}]:", //NOI18N |
527 |
new Object[]{ |
528 |
this, |
529 |
printFiledToLoad(fieldsToLoad), |
530 |
qs.getClass().getSimpleName(), |
531 |
Integer.toHexString(System.identityHashCode(qs)), |
532 |
qs.indexerQuery.getIndexerId()}); |
533 |
for (IndexResult idi : pr) { |
534 |
LOG.log(Level.FINE, " {0}", idi); //NOI18N |
535 |
} |
536 |
LOG.fine("----"); //NOI18N |
537 |
} |
538 |
} |
539 |
return result; |
540 |
} |
541 |
}); |
542 |
} catch (Index.IndexClosedException ice) { |
543 |
if (Installer.isClosed()) { |
544 |
return Collections.<IndexResult>emptySet(); |
545 |
} else { |
546 |
throw ice; |
547 |
} |
548 |
} catch (IOException ioe) { |
549 |
throw ioe; |
550 |
} catch (RuntimeException re) { |
551 |
throw re; |
552 |
} catch (Exception ex) { |
553 |
throw new IOException(ex); |
554 |
} |
555 |
|
556 |
} |
557 |
|
558 |
@NonNull |
559 |
@Override |
560 |
public String toString() { |
561 |
return String.format( |
562 |
"QuerySupport.Query[%s]", //NOI18N |
563 |
queryImpl); |
564 |
} |
565 |
} |
566 |
|
436 |
// ------------------------------------------------------------------------ |
567 |
// ------------------------------------------------------------------------ |
437 |
// Private implementation |
568 |
// Private implementation |
438 |
// ------------------------------------------------------------------------ |
569 |
// ------------------------------------------------------------------------ |
Lines 720-723
Link Here
|
720 |
return null; |
851 |
return null; |
721 |
} |
852 |
} |
722 |
} // End of IndexerQuery class |
853 |
} // End of IndexerQuery class |
|
|
854 |
|
855 |
private static final class DocumentToResultConvertor implements Convertor<IndexDocument, IndexResult> { |
856 |
|
857 |
private final URL root; |
858 |
|
859 |
DocumentToResultConvertor(@NonNull final URL root) { |
860 |
this.root = root; |
861 |
} |
862 |
|
863 |
@Override |
864 |
@CheckForNull |
865 |
public IndexResult convert(@NullAllowed final IndexDocument p) { |
866 |
return p == null ? |
867 |
null : |
868 |
new IndexResult(p, root); |
869 |
} |
870 |
|
871 |
} |
723 |
} |
872 |
} |