Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refine search code #8636

Merged
merged 6 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.jabref.gui.search.rules.describer;

import org.jabref.logic.search.SearchQuery;
import org.jabref.model.search.rules.ContainBasedSearchRule;
import org.jabref.model.search.rules.ContainsBasedSearchRule;
import org.jabref.model.search.rules.GrammarBasedSearchRule;
import org.jabref.model.search.rules.RegexBasedSearchRule;

Expand All @@ -19,7 +19,7 @@ private SearchDescribers() {
public static SearchDescriber getSearchDescriberFor(SearchQuery searchQuery) {
if (searchQuery.getRule() instanceof GrammarBasedSearchRule grammarBasedSearchRule) {
return new GrammarBasedSearchRuleDescriber(grammarBasedSearchRule.getSearchFlags(), grammarBasedSearchRule.getTree());
} else if (searchQuery.getRule() instanceof ContainBasedSearchRule containBasedSearchRule) {
} else if (searchQuery.getRule() instanceof ContainsBasedSearchRule containBasedSearchRule) {
return new ContainsAndRegexBasedSearchRuleDescriber(containBasedSearchRule.getSearchFlags(), searchQuery.getQuery());
} else if (searchQuery.getRule() instanceof RegexBasedSearchRule regexBasedSearchRule) {
return new ContainsAndRegexBasedSearchRuleDescriber(regexBasedSearchRule.getSearchFlags(), searchQuery.getQuery());
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/jabref/logic/search/SearchQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.search.SearchMatcher;
import org.jabref.model.search.rules.ContainBasedSearchRule;
import org.jabref.model.search.rules.ContainsBasedSearchRule;
import org.jabref.model.search.rules.GrammarBasedSearchRule;
import org.jabref.model.search.rules.SearchRule;
import org.jabref.model.search.rules.SearchRules;
Expand Down Expand Up @@ -82,7 +82,7 @@ public boolean isValid() {
}

public boolean isContainsBasedSearch() {
return rule instanceof ContainBasedSearchRule;
return rule instanceof ContainsBasedSearchRule;
}

private String getCaseSensitiveDescription() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.jabref.model.search.rules;

import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.jabref.architecture.AllowedToUseLogic;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.search.rules.SearchRules.SearchFlags;

/**
* Search rule for a search based on String.contains()
*/
@AllowedToUseLogic("Because access to the lucene index is needed")
public class ContainsBasedSearchRule extends FullTextSearchRule {

public ContainsBasedSearchRule(EnumSet<SearchFlags> searchFlags) {
super(searchFlags);
}

@Override
public boolean validateSearchStrings(String query) {
return true;
}

@Override
public boolean applyRule(String query, BibEntry bibEntry) {
String searchString = query;
if (!searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE)) {
searchString = searchString.toLowerCase(Locale.ROOT);
}

List<String> unmatchedWords = new SentenceAnalyzer(searchString).getWords();

for (Field fieldKey : bibEntry.getFields()) {
String formattedFieldContent = bibEntry.getLatexFreeField(fieldKey).get();
if (!searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE)) {
formattedFieldContent = formattedFieldContent.toLowerCase(Locale.ROOT);
}

Iterator<String> unmatchedWordsIterator = unmatchedWords.iterator();
while (unmatchedWordsIterator.hasNext()) {
String word = unmatchedWordsIterator.next();
if (formattedFieldContent.contains(word)) {
unmatchedWordsIterator.remove();
}
}

if (unmatchedWords.isEmpty()) {
return true;
}
}

return getFulltextResults(query, bibEntry).numSearchResults() > 0; // Didn't match all words.
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.jabref.model.search.rules;

import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Collectors;

import org.jabref.architecture.AllowedToUseLogic;
import org.jabref.gui.Globals;
import org.jabref.logic.pdf.search.retrieval.PdfSearcher;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.pdf.search.PdfSearchResults;
import org.jabref.model.pdf.search.SearchResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* All classes providing full text search results inherit from this class.
* <p>
* Some kind of caching of the full text search results is implemented.
*/
@AllowedToUseLogic("Because access to the lucene index is needed")
public abstract class FullTextSearchRule implements SearchRule {

private static final Logger LOGGER = LoggerFactory.getLogger(FullTextSearchRule.class);

protected final EnumSet<SearchRules.SearchFlags> searchFlags;

protected String lastQuery;
protected List<SearchResult> lastSearchResults;

private final BibDatabaseContext databaseContext;

public FullTextSearchRule(EnumSet<SearchRules.SearchFlags> searchFlags) {
this.searchFlags = searchFlags;
this.lastQuery = "";
lastSearchResults = Collections.emptyList();

databaseContext = Globals.stateManager.getActiveDatabase().orElse(null);
}

public EnumSet<SearchRules.SearchFlags> getSearchFlags() {
return searchFlags;
}

@Override
public PdfSearchResults getFulltextResults(String query, BibEntry bibEntry) {
if (!searchFlags.contains(SearchRules.SearchFlags.FULLTEXT) || databaseContext == null) {
return new PdfSearchResults();
}

if (!query.equals(this.lastQuery)) {
this.lastQuery = query;
lastSearchResults = Collections.emptyList();
try {
PdfSearcher searcher = PdfSearcher.of(databaseContext);
PdfSearchResults results = searcher.search(query, 5);
lastSearchResults = results.getSortedByScore();
} catch (IOException e) {
LOGGER.error("Could not retrieve search results!", e);
}
}

return new PdfSearchResults(lastSearchResults.stream()
.filter(searchResult -> searchResult.isResultFor(bibEntry))
.collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
package org.jabref.model.search.rules;

import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;

import org.jabref.architecture.AllowedToUseLogic;
import org.jabref.gui.Globals;
import org.jabref.logic.pdf.search.retrieval.PdfSearcher;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.pdf.search.PdfSearchResults;
import org.jabref.model.pdf.search.SearchResult;
import org.jabref.model.search.rules.SearchRules.SearchFlags;

import org.slf4j.Logger;
Expand All @@ -27,36 +18,18 @@
* Search rule for regex-based search.
*/
@AllowedToUseLogic("Because access to the lucene index is needed")
public class RegexBasedSearchRule implements SearchRule {
public class RegexBasedSearchRule extends FullTextSearchRule {

private static final Logger LOGGER = LoggerFactory.getLogger(GrammarBasedSearchRule.class);

private final EnumSet<SearchFlags> searchFlags;

private String lastQuery;
private List<SearchResult> lastSearchResults;

private final BibDatabaseContext databaseContext;
private static final Logger LOGGER = LoggerFactory.getLogger(RegexBasedSearchRule.class);

public RegexBasedSearchRule(EnumSet<SearchFlags> searchFlags) {
this.searchFlags = searchFlags;

databaseContext = Globals.stateManager.getActiveDatabase().orElse(null);
}

public EnumSet<SearchFlags> getSearchFlags() {
return searchFlags;
super(searchFlags);
}

@Override
public boolean validateSearchStrings(String query) {
String searchString = query;
if (!searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE)) {
searchString = searchString.toLowerCase(Locale.ROOT);
}

try {
Pattern.compile(searchString, searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? 0 : Pattern.CASE_INSENSITIVE);
Pattern.compile(query, searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? 0 : Pattern.CASE_INSENSITIVE);
} catch (PatternSyntaxException ex) {
return false;
}
Expand All @@ -66,10 +39,10 @@ public boolean validateSearchStrings(String query) {
@Override
public boolean applyRule(String query, BibEntry bibEntry) {
Pattern pattern;

try {
pattern = Pattern.compile(query, searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? 0 : Pattern.CASE_INSENSITIVE);
} catch (PatternSyntaxException ex) {
LOGGER.debug("Could not compile regex {}", query, ex);
return false;
}

Expand All @@ -86,24 +59,4 @@ public boolean applyRule(String query, BibEntry bibEntry) {
return getFulltextResults(query, bibEntry).numSearchResults() > 0;
}

@Override
public PdfSearchResults getFulltextResults(String query, BibEntry bibEntry) {

if (!searchFlags.contains(SearchRules.SearchFlags.FULLTEXT) || databaseContext == null) {
return new PdfSearchResults(List.of());
}

if (!query.equals(this.lastQuery)) {
this.lastQuery = query;
lastSearchResults = List.of();
try {
PdfSearcher searcher = PdfSearcher.of(databaseContext);
PdfSearchResults results = searcher.search(query, 5);
lastSearchResults = results.getSortedByScore();
} catch (IOException e) {
LOGGER.error("Could not retrieve search results!", e);
}
}
return new PdfSearchResults(lastSearchResults.stream().filter(searchResult -> searchResult.isResultFor(bibEntry)).collect(Collectors.toList()));
}
}
Loading