From 2df81db45c4982390255642a89a99e778936b701 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 2 Nov 2021 01:25:23 +0100 Subject: [PATCH 01/10] Add support for Lucene-based search --- CHANGELOG.md | 1 + .../jabref/gui/search/GlobalSearchBar.java | 2 +- .../LuceneBasedSearchRuleDescriber.java | 24 +++ .../rules/describer/SearchDescribers.java | 7 +- .../AbstractQueryTransformer.java | 2 +- .../model/search/rules/BibQueryVisitor.java | 151 ++++++++++++++++++ .../search/rules/LuceneBasedSearchRule.java | 77 +++++++++ .../model/search/rules/SearchRules.java | 10 +- src/main/resources/l10n/JabRef_en.properties | 2 +- .../jabref/logic/l10n/LocalizationTest.java | 2 +- .../rules/LuceneBasedSearchRuleTest.java | 102 ++++++++++++ .../model/search/rules/SearchRulesTest.java | 29 ++++ 12 files changed, 402 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java create mode 100644 src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java create mode 100644 src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java create mode 100644 src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java create mode 100644 src/test/java/org/jabref/model/search/rules/SearchRulesTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 26e4a24f8f6..878e3e1227e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added confirmation dialog when user wants to close a library where any empty entires are detected. [#8096](https://github.com/JabRef/jabref/issues/8096) - We added import support for CFF files. [#7945](https://github.com/JabRef/jabref/issues/7945) +- We added support to use Lucence search syntax also for the searchin the library or in dynamic groups. - We added the option to copy the DOI of an entry directly from the context menu copy submenu. [#7826](https://github.com/JabRef/jabref/issues/7826) - We added a fulltext search feature. [#2838](https://github.com/JabRef/jabref/pull/2838) - We improved the deduction of bib-entries from imported fulltext pdfs. [#7947](https://github.com/JabRef/jabref/pull/7947) diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index da016e1f219..30ef144e6a8 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -361,7 +361,7 @@ private void updateResults(int matched, TextFlow description, boolean grammarBas private void setSearchFieldHintTooltip(TextFlow description) { if (preferencesService.getGeneralPreferences().shouldShowAdvancedHints()) { - String genericDescription = Localization.lang("Hint:\n\nTo search all fields for Smith, enter:\nsmith\n\nTo search the field author for Smith and the field title for electrical, enter:\nauthor=Smith and title=electrical"); + String genericDescription = Localization.lang("Hint:\n\nTo search all fields for Smith, enter:\nsmith\n\nTo search the field author for Smith and the field title for electrical, enter:\nauthor:Smith and title:electrical"); List genericDescriptionTexts = TooltipTextUtil.createTextsFromHtml(genericDescription); if (description == null) { diff --git a/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java b/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java new file mode 100644 index 00000000000..ecd132e9bac --- /dev/null +++ b/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java @@ -0,0 +1,24 @@ +package org.jabref.gui.search.rules.describer; + +import java.util.EnumSet; + +import javafx.scene.text.TextFlow; + +import org.jabref.model.search.rules.SearchRules.SearchFlags; + +public class LuceneBasedSearchRuleDescriber implements SearchDescriber { + + private final EnumSet searchFlags; + private final String query; + + public LuceneBasedSearchRuleDescriber(EnumSet searchFlags, String query) { + this.searchFlags = searchFlags; + this.query = query; + } + + @Override + public TextFlow getDescription() { + TextFlow searchDescription = new TextFlow(); + return searchDescription; + } +} diff --git a/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java b/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java index de696f03632..06155b580fa 100644 --- a/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java +++ b/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java @@ -3,6 +3,7 @@ import org.jabref.logic.search.SearchQuery; import org.jabref.model.search.rules.ContainsBasedSearchRule; import org.jabref.model.search.rules.GrammarBasedSearchRule; +import org.jabref.model.search.rules.LuceneBasedSearchRule; import org.jabref.model.search.rules.RegexBasedSearchRule; public class SearchDescribers { @@ -17,12 +18,14 @@ private SearchDescribers() { * @return the search describer to turn the search into something human understandable */ public static SearchDescriber getSearchDescriberFor(SearchQuery searchQuery) { - if (searchQuery.getRule() instanceof GrammarBasedSearchRule grammarBasedSearchRule) { - return new GrammarBasedSearchRuleDescriber(grammarBasedSearchRule.getSearchFlags(), grammarBasedSearchRule.getTree()); + if (searchQuery.getRule() instanceof LuceneBasedSearchRule lucenceBasedSearchRule) { + return new LuceneBasedSearchRuleDescriber(lucenceBasedSearchRule.getSearchFlags(), searchQuery.getQuery()); } 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()); + } else if (searchQuery.getRule() instanceof GrammarBasedSearchRule grammarBasedSearchRule) { + return new GrammarBasedSearchRuleDescriber(grammarBasedSearchRule.getSearchFlags(), grammarBasedSearchRule.getTree()); } else { throw new IllegalStateException("Cannot find a describer for searchRule " + searchQuery.getRule() + " and query " + searchQuery.getQuery()); } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/transformers/AbstractQueryTransformer.java b/src/main/java/org/jabref/logic/importer/fetcher/transformers/AbstractQueryTransformer.java index 21d45a13952..563bbd8fc10 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/transformers/AbstractQueryTransformer.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/transformers/AbstractQueryTransformer.java @@ -23,7 +23,7 @@ public abstract class AbstractQueryTransformer { public static final String NO_EXPLICIT_FIELD = "default"; private static final Logger LOGGER = LoggerFactory.getLogger(AbstractQueryTransformer.class); - // These can be used for filtering in post processing + // These can be used for filtering in post-processing protected int startYear = Integer.MAX_VALUE; protected int endYear = Integer.MIN_VALUE; diff --git a/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java b/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java new file mode 100644 index 00000000000..af8a30548ae --- /dev/null +++ b/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java @@ -0,0 +1,151 @@ +package org.jabref.model.search.rules; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.Field; +import org.jabref.model.entry.field.FieldFactory; + +import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; +import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BibQueryVisitor { + public static final String NO_EXPLICIT_FIELD = "default"; + private static final Logger LOGGER = LoggerFactory.getLogger(BibQueryVisitor.class); + + private final BibEntry bibEntry; + private EnumSet searchFlags; + + public BibQueryVisitor(BibEntry bibEntry, EnumSet searchFlags) { + this.bibEntry = bibEntry; + this.searchFlags = searchFlags; + } + + public boolean matchFound(QueryNode query) { + if (query instanceof FieldQueryNode) { + return matchFound((FieldQueryNode) query); + } else if (query instanceof BooleanQueryNode) { + return matchFound((BooleanQueryNode) query); + } else if (query instanceof ModifierQueryNode) { + return matchFound((ModifierQueryNode) query); + } else if (query instanceof RegexpQueryNode) { + return matchFound((RegexpQueryNode) query); + } else { + LOGGER.error("Unsupported case when transforming the query:\n {}", query); + return false; + } + } + + private boolean matchFound(String searchField, String searchString, boolean regExMode) { + Pattern pattern = null; + if (regExMode) { + try { + pattern = Pattern.compile(searchString, searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? 0 : Pattern.CASE_INSENSITIVE); + } catch (PatternSyntaxException ex) { + LOGGER.error("Could not compile regex {}", searchString, ex); + return false; + } + } else { + if (!searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE)) { + searchString = searchString.toLowerCase(Locale.ROOT); + } + } + String finalSearchString = searchString; + + Pattern finalPattern = pattern; + + if (searchField.isEmpty()) { + return bibEntry.getFields().stream() + .map(field -> bibEntry.getLatexFreeField(field)) + .filter(content -> matchFound(finalSearchString, finalPattern, content)) + .findAny() + .isPresent(); + } else { + Field field = FieldFactory.parseField(searchField); + return matchFound(finalSearchString, finalPattern, bibEntry.getLatexFreeField(field)); + } + } + + private boolean matchFound(FieldQueryNode query) { + if (searchFlags.contains(SearchRules.SearchFlags.REGULAR_EXPRESSION)) { + LOGGER.info("RegEx search is not supported in lucene search"); + } + return matchFound(query.getFieldAsString(), query.getTextAsString(), false); + } + + private boolean matchFound(RegexpQueryNode query) { + return matchFound(query.getFieldAsString(), query.getText().toString(), true); + } + + /** + * @param finalPattern if not null, the RegEx pattern to match for. If null, a "normal" search is executed + */ + private boolean matchFound(String finalSearchString, Pattern finalPattern, Optional content) { + return content.map(value -> searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? value : value.toLowerCase(Locale.ROOT)) + .filter(value -> { + if (finalPattern != null) { + return finalPattern.matcher(value).find(); + } else { + List unmatchedWords = new SentenceAnalyzer(finalSearchString).getWords(); + Iterator unmatchedWordsIterator = unmatchedWords.iterator(); + while (unmatchedWordsIterator.hasNext()) { + String word = unmatchedWordsIterator.next(); + if (value.contains(word)) { + unmatchedWordsIterator.remove(); + } + } + return unmatchedWords.isEmpty(); + } + }) + .isPresent(); + } + + private boolean matchFound(BooleanQueryNode query) { + if (query instanceof OrQueryNode) { + return matchFound((OrQueryNode) query); + } else { + // AND is the default + return matchFoundForAnd(query); + } + } + + private boolean matchFoundForAnd(BooleanQueryNode query) { + for (QueryNode child : query.getChildren()) { + if (!matchFound(child)) { + return false; + } + } + return true; + } + + private boolean matchFound(OrQueryNode query) { + for (QueryNode child : query.getChildren()) { + if (matchFound(child)) { + return true; + } + } + return false; + } + + private boolean matchFound(ModifierQueryNode query) { + ModifierQueryNode.Modifier modifier = query.getModifier(); + if (modifier == ModifierQueryNode.Modifier.MOD_NOT) { + return !matchFound(query.getChild()); + } else { + // optional not yet supported + return matchFound(query.getChild()); + } + } +} diff --git a/src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java b/src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java new file mode 100644 index 00000000000..90f838c2214 --- /dev/null +++ b/src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java @@ -0,0 +1,77 @@ +package org.jabref.model.search.rules; + +import java.util.EnumSet; +import java.util.Locale; +import java.util.concurrent.ExecutionException; + +import org.jabref.architecture.AllowedToUseLogic; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.search.rules.SearchRules.SearchFlags; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import org.apache.lucene.queryparser.flexible.core.QueryNodeException; +import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; +import org.apache.lucene.queryparser.flexible.core.parser.SyntaxParser; +import org.apache.lucene.queryparser.flexible.standard.parser.StandardSyntaxParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Search rule for a search based on String.contains() + */ +@AllowedToUseLogic("Because access to the lucene index is needed") +public class LuceneBasedSearchRule extends FullTextSearchRule { + + private static final Logger LOGGER = LoggerFactory.getLogger(LuceneBasedSearchRule.class); + + // We use SyntaxParser to be consistent with org.jabref.logic.importer + // We do not use "PrecedenceQueryParser", because this parser keeps the term "AND" + private SyntaxParser parser = new StandardSyntaxParser(); + private LoadingCache cache = CacheBuilder.newBuilder() + .maximumSize(100) + .build( + new CacheLoader<>() { + @Override + public QueryNode load(String query) throws Exception { + return parser.parse(query, ""); + } + } + ); + + public LuceneBasedSearchRule(EnumSet searchFlags) { + super(searchFlags); + } + + @Override + public boolean validateSearchStrings(String query) { + // Using the Lucene parser and checking for an exception is the only way to check whether the query is valid + try { + parser.parse(query, ""); + } catch (QueryNodeException e) { + return false; + } + return true; + } + + @Override + public boolean applyRule(String queryString, BibEntry bibEntry) { + String searchString = queryString; + QueryNode query; + try { + query = cache.get(searchString); + } catch (ExecutionException e) { + LOGGER.error("Could not parse query {}", queryString, e); + return false; + } + + BibQueryVisitor bibQueryVisitor = new BibQueryVisitor(bibEntry, searchFlags); + if (bibQueryVisitor.matchFound(query)) { + return true; + } + + return getFulltextResults(queryString, bibEntry).numSearchResults() > 0; // Didn't match all words. + } + +} diff --git a/src/main/java/org/jabref/model/search/rules/SearchRules.java b/src/main/java/org/jabref/model/search/rules/SearchRules.java index 71c35a7e33e..c949f4af1ee 100644 --- a/src/main/java/org/jabref/model/search/rules/SearchRules.java +++ b/src/main/java/org/jabref/model/search/rules/SearchRules.java @@ -8,7 +8,11 @@ */ public class SearchRules { - private static final Pattern SIMPLE_EXPRESSION = Pattern.compile("[^\\p{Punct}]*"); + // In case Lucene keywords are contained, it is not a simple expression any more + private static final Pattern SIMPLE_EXPRESSION = Pattern.compile("^((?! AND | OR )[^\\p{Punct}])*$"); + + // used for checking the syntax of the query + private static LuceneBasedSearchRule luceneBasedSearchRule = new LuceneBasedSearchRule(EnumSet.noneOf(SearchFlags.class)); private SearchRules() { } @@ -21,6 +25,10 @@ public static SearchRule getSearchRuleByQuery(String query, EnumSet return new ContainsBasedSearchRule(searchFlags); } + if (luceneBasedSearchRule.validateSearchStrings(query)) { + return new LuceneBasedSearchRule(searchFlags); + } + // this searches specified fields if specified, // and all fields otherwise SearchRule searchExpression = new GrammarBasedSearchRule(searchFlags); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 0fefcd90936..47c2c6f8050 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2092,7 +2092,7 @@ Keyword\ delimiter=Keyword delimiter Hierarchical\ keyword\ delimiter=Hierarchical keyword delimiter Escape\ ampersands=Escape ampersands -Hint\:\n\nTo\ search\ all\ fields\ for\ Smith,\ enter\:\nsmith\n\nTo\ search\ the\ field\ author\ for\ Smith\ and\ the\ field\ title\ for\ electrical,\ enter\:\nauthor\=Smith\ and\ title\=electrical=Hint:\n\nTo search all fields for Smith, enter:\nsmith\n\nTo search the field author for Smith and the field title for electrical, enter:\nauthor=Smith and title=electrical +Hint\:\n\nTo\ search\ all\ fields\ for\ Smith,\ enter\:\nsmith\n\nTo\ search\ the\ field\ author\ for\ Smith\ and\ the\ field\ title\ for\ electrical,\ enter\:\nauthor\:Smith\ and\ title\:electrical=Hint:\n\nTo search all fields for Smith, enter:\nsmith\n\nTo search the field author for Smith and the field title for electrical, enter:\nauthor:Smith and title:electrical Copied\ '%0'\ to\ clipboard.=Copied '%0' to clipboard. This\ operation\ requires\ an\ open\ library.=This operation requires an open library. diff --git a/src/test/java/org/jabref/logic/l10n/LocalizationTest.java b/src/test/java/org/jabref/logic/l10n/LocalizationTest.java index 596139f8b5d..69d7dd00f4a 100644 --- a/src/test/java/org/jabref/logic/l10n/LocalizationTest.java +++ b/src/test/java/org/jabref/logic/l10n/LocalizationTest.java @@ -51,7 +51,7 @@ void testKnownGermanTranslation() { @Test void newLineIsAvailableAndKeptUnescaped() { Localization.setLanguage(Language.ENGLISH); - assertEquals("Hint: To search specific fields only, enter for example:\nauthor=smith and title=electrical", Localization.lang("Hint: To search specific fields only, enter for example:\nauthor=smith and title=electrical")); + assertEquals("Hint: To search specific fields only, enter for example:\nauthor:smith and title:electrical", Localization.lang("Hint: To search specific fields only, enter for example:\nauthor:ssmith and title:electrical")); } @Test diff --git a/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java b/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java new file mode 100644 index 00000000000..0caf0424aca --- /dev/null +++ b/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java @@ -0,0 +1,102 @@ +package org.jabref.model.search.rules; + +import java.util.EnumSet; + +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.types.StandardEntryType; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class LuceneBasedSearchRuleTest { + + private final BibEntry bibEntry = new BibEntry(StandardEntryType.InCollection) + .withCitationKey("shields01") + .withField(StandardField.TITLE, "Marine finfish larviculture in Europe") + .withField(StandardField.YEAR, "2001") + .withField(StandardField.AUTHOR, "Kevin Shields"); + + private final LuceneBasedSearchRule luceneBasedSearchRuleCaseSensitive = new LuceneBasedSearchRule(EnumSet.of(SearchRules.SearchFlags.CASE_SENSITIVE)); + private final LuceneBasedSearchRule luceneBasedSearchRuleCaseInsensitive = new LuceneBasedSearchRule(EnumSet.noneOf(SearchRules.SearchFlags.class)); + + @ParameterizedTest + @ValueSource(strings = { + "year:2001", + "year=2001", + + // Current JabRef special feature: sub strings are also matched + "title:Marine", + "title=Marine", + + // TODO glob patterns: "title:Marine*" + + "year:2001 title:Marine", + "year=2001 title=Marine", + "year=2001 title:Marine", + + "year:2001 AND title:Marine", + + "year:2001 OR title:Marine", + + "Marine", + + // RegEx syntax of Lucene + "/M[a-z]+e/" + }) + public void findsCaseSensitive(String query) { + assertTrue(luceneBasedSearchRuleCaseSensitive.validateSearchStrings(query)); + assertTrue(luceneBasedSearchRuleCaseSensitive.applyRule(query, bibEntry)); + } + + @ParameterizedTest + @ValueSource(strings = { + "year:2002", + "year=2002", + + // Current JabRef special feature: sub strings are also matched + "title:Marie", + "title=Marie", + + // TODO glob patterns: "title:Marine*" + + "year:2002 title:Marine", + "year=2002 title=Marine", + "year=2002 title:Marine", + + "year:2002 AND title:Marine", + + "year:2002 OR title:Marie", + + "Marie", + + "/M[0-9]+e/" + }) + public void nofindsCaseSensitive(String query) { + assertTrue(luceneBasedSearchRuleCaseSensitive.validateSearchStrings(query)); + assertFalse(luceneBasedSearchRuleCaseSensitive.applyRule(query, bibEntry)); + } + + @ParameterizedTest + @ValueSource(strings = { + "year:2001", + + "title:Marine", + + "year:2001 title:Marine", + + "year:2001 AND title:Marine", + + "year:2001 OR title:Marine", + + "Marine" + }) + public void findsCaseInSensitive(String query) { + assertTrue(luceneBasedSearchRuleCaseInsensitive.validateSearchStrings(query)); + assertTrue(luceneBasedSearchRuleCaseInsensitive.applyRule(query, bibEntry)); + } + +} diff --git a/src/test/java/org/jabref/model/search/rules/SearchRulesTest.java b/src/test/java/org/jabref/model/search/rules/SearchRulesTest.java new file mode 100644 index 00000000000..5558794adc1 --- /dev/null +++ b/src/test/java/org/jabref/model/search/rules/SearchRulesTest.java @@ -0,0 +1,29 @@ +package org.jabref.model.search.rules; + +import java.util.EnumSet; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +class SearchRulesTest { + + @Test + void simpleLuceneQueryReturnsContainsBasedSearchRule() { + SearchRule searchRule = SearchRules.getSearchRuleByQuery("test", EnumSet.noneOf(SearchRules.SearchFlags.class)); + assertInstanceOf(ContainsBasedSearchRule.class, searchRule); + } + + @Test + void andLuceneQueryReturnsLuceneBasedSearchRule() { + SearchRule searchRule = SearchRules.getSearchRuleByQuery("test AND lucene", EnumSet.noneOf(SearchRules.SearchFlags.class)); + assertInstanceOf(LuceneBasedSearchRule.class, searchRule); + } + + @Test + void simpleFieldedLuceneQueryReturnsLuceneBasedSearchRule() { + SearchRule searchRule = SearchRules.getSearchRuleByQuery("title:test", EnumSet.noneOf(SearchRules.SearchFlags.class)); + assertInstanceOf(LuceneBasedSearchRule.class, searchRule); + } + +} From b9b3a8f21c6a28f6a46653ee7d565f89d144c213 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Wed, 3 Nov 2021 06:17:36 +0100 Subject: [PATCH 02/10] Add support for grouping --- .../jabref/model/search/rules/BibQueryVisitor.java | 5 ++++- .../search/rules/LuceneBasedSearchRuleTest.java | 13 ++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java b/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java index af8a30548ae..d213920a7e0 100644 --- a/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java +++ b/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java @@ -14,6 +14,7 @@ import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; @@ -42,8 +43,10 @@ public boolean matchFound(QueryNode query) { return matchFound((ModifierQueryNode) query); } else if (query instanceof RegexpQueryNode) { return matchFound((RegexpQueryNode) query); + } else if (query instanceof GroupQueryNode) { + return matchFound(((GroupQueryNode) query).getChild()); } else { - LOGGER.error("Unsupported case when transforming the query:\n {}", query); + LOGGER.error("Unsupported case when evaluating the query:\n {}", query); return false; } } diff --git a/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java b/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java index 0caf0424aca..a4b804c3e4f 100644 --- a/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java @@ -18,7 +18,8 @@ class LuceneBasedSearchRuleTest { .withCitationKey("shields01") .withField(StandardField.TITLE, "Marine finfish larviculture in Europe") .withField(StandardField.YEAR, "2001") - .withField(StandardField.AUTHOR, "Kevin Shields"); + .withField(StandardField.AUTHOR, "Kevin Shields") + .withField(StandardField.GROUPS, "included"); private final LuceneBasedSearchRule luceneBasedSearchRuleCaseSensitive = new LuceneBasedSearchRule(EnumSet.of(SearchRules.SearchFlags.CASE_SENSITIVE)); private final LuceneBasedSearchRule luceneBasedSearchRuleCaseInsensitive = new LuceneBasedSearchRule(EnumSet.noneOf(SearchRules.SearchFlags.class)); @@ -73,9 +74,15 @@ public void findsCaseSensitive(String query) { "Marie", - "/M[0-9]+e/" + "/M[0-9]+e/", + + // this tests for grouping (indicated the brackets) + "(groups=excluded)", + + // this tests for the NOT operator, grouping and Boolean AND + "NOT(groups=excluded) AND NOT(groups=included)" }) - public void nofindsCaseSensitive(String query) { + public void notFindsCaseSensitive(String query) { assertTrue(luceneBasedSearchRuleCaseSensitive.validateSearchStrings(query)); assertFalse(luceneBasedSearchRuleCaseSensitive.applyRule(query, bibEntry)); } From d118d5958643fac333aa2ca235811d21dd22a8d1 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sun, 14 Nov 2021 15:54:23 +0100 Subject: [PATCH 03/10] Refine CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 878e3e1227e..68315727192 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,7 +93,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added confirmation dialog when user wants to close a library where any empty entires are detected. [#8096](https://github.com/JabRef/jabref/issues/8096) - We added import support for CFF files. [#7945](https://github.com/JabRef/jabref/issues/7945) -- We added support to use Lucence search syntax also for the searchin the library or in dynamic groups. +- We added support to use [Apache Lucence search syntax](https://lucene.apache.org/core/8_10_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description) also for the search in the library or in dynamic groups. For end users, there should be no significant difference. - We added the option to copy the DOI of an entry directly from the context menu copy submenu. [#7826](https://github.com/JabRef/jabref/issues/7826) - We added a fulltext search feature. [#2838](https://github.com/JabRef/jabref/pull/2838) - We improved the deduction of bib-entries from imported fulltext pdfs. [#7947](https://github.com/JabRef/jabref/pull/7947) From de493cd1789b00498360fac2853cadbfe7496eca Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sun, 14 Nov 2021 15:57:48 +0100 Subject: [PATCH 04/10] Move search from model to logic --- src/jmh/java/org/jabref/benchmarks/Benchmarks.java | 2 +- .../fileannotationtab/FulltextSearchResultsTab.java | 2 +- .../java/org/jabref/gui/groups/GroupDialogView.java | 4 ++-- .../org/jabref/gui/groups/GroupDialogViewModel.java | 4 ++-- .../org/jabref/gui/maintable/MainTableDataModel.java | 4 ++-- .../java/org/jabref/gui/search/GlobalSearchBar.java | 2 +- .../ContainsAndRegexBasedSearchRuleDescriber.java | 6 +++--- .../describer/GrammarBasedSearchRuleDescriber.java | 6 +++--- .../describer/LuceneBasedSearchRuleDescriber.java | 2 +- .../gui/search/rules/describer/SearchDescribers.java | 8 ++++---- .../org/jabref/logic/exporter/GroupSerializer.java | 2 +- .../org/jabref/logic/importer/util/GroupsParser.java | 4 ++-- .../{model => logic}/search/GroupSearchQuery.java | 8 ++++---- .../jabref/{model => logic}/search/SearchMatcher.java | 2 +- .../java/org/jabref/logic/search/SearchQuery.java | 11 +++++------ .../{model => logic}/search/matchers/AndMatcher.java | 2 +- .../{model => logic}/search/matchers/MatcherSet.java | 4 ++-- .../{model => logic}/search/matchers/MatcherSets.java | 2 +- .../{model => logic}/search/matchers/NotMatcher.java | 4 ++-- .../{model => logic}/search/matchers/OrMatcher.java | 2 +- .../search/rules/BibQueryVisitor.java | 2 +- .../search/rules/ContainsBasedSearchRule.java | 6 ++---- .../search/rules/FullTextSearchRule.java | 2 +- .../search/rules/GrammarBasedSearchRule.java | 6 ++---- .../search/rules/LuceneBasedSearchRule.java | 7 ++----- .../search/rules/RegexBasedSearchRule.java | 6 ++---- .../{model => logic}/search/rules/SearchRule.java | 2 +- .../{model => logic}/search/rules/SearchRules.java | 2 +- .../search/rules/SentenceAnalyzer.java | 2 +- .../java/org/jabref/model/groups/AbstractGroup.java | 2 +- .../java/org/jabref/model/groups/GroupTreeNode.java | 6 +++--- .../java/org/jabref/model/groups/SearchGroup.java | 4 ++-- .../org/jabref/preferences/JabRefPreferences.java | 2 +- .../org/jabref/preferences/SearchPreferences.java | 2 +- .../jabref/architecture/MainArchitectureTests.java | 6 +++--- .../ContainsAndRegexBasedSearchRuleDescriberTest.java | 4 ++-- .../search/GrammarBasedSearchRuleDescriberTest.java | 6 +++--- .../jabref/logic/exporter/GroupSerializerTest.java | 2 +- .../jabref/logic/importer/util/GroupsParserTest.java | 2 +- .../org/jabref/logic/search/DatabaseSearcherTest.java | 2 +- .../java/org/jabref/logic/search/SearchQueryTest.java | 4 ++-- .../search/matchers/MatcherSetsTest.java | 4 ++-- .../search/rules/ContainsBasedSearchRuleTest.java | 2 +- .../search/rules/GrammarBasedSearchRuleTest.java | 2 +- .../search/rules/LuceneBasedSearchRuleTest.java | 2 +- .../search/rules/MockSearchMatcher.java | 4 ++-- .../search/rules/SearchRulesTest.java | 2 +- .../search/rules/SentenceAnalyzerTest.java | 2 +- .../org/jabref/model/groups/GroupTreeNodeTest.java | 8 ++++---- .../java/org/jabref/model/groups/SearchGroupTest.java | 2 +- 50 files changed, 88 insertions(+), 98 deletions(-) rename src/main/java/org/jabref/{model => logic}/search/GroupSearchQuery.java (89%) rename src/main/java/org/jabref/{model => logic}/search/SearchMatcher.java (80%) rename src/main/java/org/jabref/{model => logic}/search/matchers/AndMatcher.java (88%) rename src/main/java/org/jabref/{model => logic}/search/matchers/MatcherSet.java (91%) rename src/main/java/org/jabref/{model => logic}/search/matchers/MatcherSets.java (87%) rename src/main/java/org/jabref/{model => logic}/search/matchers/NotMatcher.java (84%) rename src/main/java/org/jabref/{model => logic}/search/matchers/OrMatcher.java (89%) rename src/main/java/org/jabref/{model => logic}/search/rules/BibQueryVisitor.java (99%) rename src/main/java/org/jabref/{model => logic}/search/rules/ContainsBasedSearchRule.java (88%) rename src/main/java/org/jabref/{model => logic}/search/rules/FullTextSearchRule.java (98%) rename src/main/java/org/jabref/{model => logic}/search/rules/GrammarBasedSearchRule.java (98%) rename src/main/java/org/jabref/{model => logic}/search/rules/LuceneBasedSearchRule.java (92%) rename src/main/java/org/jabref/{model => logic}/search/rules/RegexBasedSearchRule.java (89%) rename src/main/java/org/jabref/{model => logic}/search/rules/SearchRule.java (88%) rename src/main/java/org/jabref/{model => logic}/search/rules/SearchRules.java (98%) rename src/main/java/org/jabref/{model => logic}/search/rules/SentenceAnalyzer.java (97%) rename src/test/java/org/jabref/{model => logic}/search/matchers/MatcherSetsTest.java (93%) rename src/test/java/org/jabref/{model => logic}/search/rules/ContainsBasedSearchRuleTest.java (98%) rename src/test/java/org/jabref/{model => logic}/search/rules/GrammarBasedSearchRuleTest.java (99%) rename src/test/java/org/jabref/{model => logic}/search/rules/LuceneBasedSearchRuleTest.java (98%) rename src/test/java/org/jabref/{model => logic}/search/rules/MockSearchMatcher.java (82%) rename src/test/java/org/jabref/{model => logic}/search/rules/SearchRulesTest.java (96%) rename src/test/java/org/jabref/{model => logic}/search/rules/SentenceAnalyzerTest.java (96%) diff --git a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java index b0073114ac5..3bcaa3d54bd 100644 --- a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java +++ b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java @@ -31,7 +31,7 @@ import org.jabref.model.groups.KeywordGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.preferences.GeneralPreferences; import org.jabref.preferences.JabRefPreferences; diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java index 8fe5c146b5b..c4923e7f78e 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java @@ -30,7 +30,7 @@ import org.jabref.model.entry.LinkedFile; import org.jabref.model.pdf.search.PdfSearchResults; import org.jabref.model.pdf.search.SearchResult; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.preferences.PreferencesService; import org.slf4j.Logger; diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogView.java b/src/main/java/org/jabref/gui/groups/GroupDialogView.java index 32047ec21a4..2d729734534 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogView.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogView.java @@ -36,8 +36,8 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.groups.AbstractGroup; import org.jabref.model.groups.GroupHierarchyType; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java index 522d129bb08..3a8a1749748 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java @@ -49,8 +49,8 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.strings.StringUtil; import org.jabref.preferences.PreferencesService; diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 5210613e4de..0382d8ed0b4 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -20,8 +20,8 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.GroupTreeNode; -import org.jabref.model.search.matchers.MatcherSet; -import org.jabref.model.search.matchers.MatcherSets; +import org.jabref.logic.search.matchers.MatcherSet; +import org.jabref.logic.search.matchers.MatcherSets; import org.jabref.preferences.PreferencesService; import com.tobiasdiez.easybind.EasyBind; diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 30ef144e6a8..7354c5f5a6f 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -60,7 +60,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.logic.search.SearchQuery; import org.jabref.model.entry.Author; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.preferences.PreferencesService; import org.jabref.preferences.SearchPreferences; diff --git a/src/main/java/org/jabref/gui/search/rules/describer/ContainsAndRegexBasedSearchRuleDescriber.java b/src/main/java/org/jabref/gui/search/rules/describer/ContainsAndRegexBasedSearchRuleDescriber.java index d411c263c7c..6ed27aa2744 100644 --- a/src/main/java/org/jabref/gui/search/rules/describer/ContainsAndRegexBasedSearchRuleDescriber.java +++ b/src/main/java/org/jabref/gui/search/rules/describer/ContainsAndRegexBasedSearchRuleDescriber.java @@ -8,9 +8,9 @@ import org.jabref.gui.util.TooltipTextUtil; import org.jabref.logic.l10n.Localization; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; -import org.jabref.model.search.rules.SentenceAnalyzer; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SentenceAnalyzer; public class ContainsAndRegexBasedSearchRuleDescriber implements SearchDescriber { diff --git a/src/main/java/org/jabref/gui/search/rules/describer/GrammarBasedSearchRuleDescriber.java b/src/main/java/org/jabref/gui/search/rules/describer/GrammarBasedSearchRuleDescriber.java index 416aa8dd618..0036fd50f1c 100644 --- a/src/main/java/org/jabref/gui/search/rules/describer/GrammarBasedSearchRuleDescriber.java +++ b/src/main/java/org/jabref/gui/search/rules/describer/GrammarBasedSearchRuleDescriber.java @@ -12,9 +12,9 @@ import org.jabref.gui.util.TooltipTextUtil; import org.jabref.logic.l10n.Localization; -import org.jabref.model.search.rules.GrammarBasedSearchRule; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.GrammarBasedSearchRule; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.strings.StringUtil; import org.jabref.search.SearchBaseVisitor; import org.jabref.search.SearchParser; diff --git a/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java b/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java index ecd132e9bac..8bea86402e0 100644 --- a/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java +++ b/src/main/java/org/jabref/gui/search/rules/describer/LuceneBasedSearchRuleDescriber.java @@ -4,7 +4,7 @@ import javafx.scene.text.TextFlow; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; public class LuceneBasedSearchRuleDescriber implements SearchDescriber { diff --git a/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java b/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java index 06155b580fa..707a398c26f 100644 --- a/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java +++ b/src/main/java/org/jabref/gui/search/rules/describer/SearchDescribers.java @@ -1,10 +1,10 @@ package org.jabref.gui.search.rules.describer; import org.jabref.logic.search.SearchQuery; -import org.jabref.model.search.rules.ContainsBasedSearchRule; -import org.jabref.model.search.rules.GrammarBasedSearchRule; -import org.jabref.model.search.rules.LuceneBasedSearchRule; -import org.jabref.model.search.rules.RegexBasedSearchRule; +import org.jabref.logic.search.rules.ContainsBasedSearchRule; +import org.jabref.logic.search.rules.GrammarBasedSearchRule; +import org.jabref.logic.search.rules.LuceneBasedSearchRule; +import org.jabref.logic.search.rules.RegexBasedSearchRule; public class SearchDescribers { diff --git a/src/main/java/org/jabref/logic/exporter/GroupSerializer.java b/src/main/java/org/jabref/logic/exporter/GroupSerializer.java index 4e9c9997dd8..ce9006759b5 100644 --- a/src/main/java/org/jabref/logic/exporter/GroupSerializer.java +++ b/src/main/java/org/jabref/logic/exporter/GroupSerializer.java @@ -18,7 +18,7 @@ import org.jabref.model.groups.RegexKeywordGroup; import org.jabref.model.groups.SearchGroup; import org.jabref.model.groups.TexGroup; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.strings.StringUtil; public class GroupSerializer { diff --git a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java index da08aae3abc..16df5b701aa 100644 --- a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java +++ b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java @@ -27,8 +27,8 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.strings.StringUtil; import org.jabref.model.util.FileUpdateMonitor; diff --git a/src/main/java/org/jabref/model/search/GroupSearchQuery.java b/src/main/java/org/jabref/logic/search/GroupSearchQuery.java similarity index 89% rename from src/main/java/org/jabref/model/search/GroupSearchQuery.java rename to src/main/java/org/jabref/logic/search/GroupSearchQuery.java index 90056d9b0f7..520084120ec 100644 --- a/src/main/java/org/jabref/model/search/GroupSearchQuery.java +++ b/src/main/java/org/jabref/logic/search/GroupSearchQuery.java @@ -1,12 +1,12 @@ -package org.jabref.model.search; +package org.jabref.logic.search; import java.util.EnumSet; import java.util.Objects; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.rules.SearchRule; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRule; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; public class GroupSearchQuery implements SearchMatcher { diff --git a/src/main/java/org/jabref/model/search/SearchMatcher.java b/src/main/java/org/jabref/logic/search/SearchMatcher.java similarity index 80% rename from src/main/java/org/jabref/model/search/SearchMatcher.java rename to src/main/java/org/jabref/logic/search/SearchMatcher.java index f40dde892d8..03322593944 100644 --- a/src/main/java/org/jabref/model/search/SearchMatcher.java +++ b/src/main/java/org/jabref/logic/search/SearchMatcher.java @@ -1,4 +1,4 @@ -package org.jabref.model.search; +package org.jabref.logic.search; import org.jabref.model.entry.BibEntry; diff --git a/src/main/java/org/jabref/logic/search/SearchQuery.java b/src/main/java/org/jabref/logic/search/SearchQuery.java index 4dc9fd40a58..1871da18501 100644 --- a/src/main/java/org/jabref/logic/search/SearchQuery.java +++ b/src/main/java/org/jabref/logic/search/SearchQuery.java @@ -11,12 +11,11 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.SearchMatcher; -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; -import org.jabref.model.search.rules.SentenceAnalyzer; +import org.jabref.logic.search.rules.ContainsBasedSearchRule; +import org.jabref.logic.search.rules.GrammarBasedSearchRule; +import org.jabref.logic.search.rules.SearchRule; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SentenceAnalyzer; public class SearchQuery implements SearchMatcher { diff --git a/src/main/java/org/jabref/model/search/matchers/AndMatcher.java b/src/main/java/org/jabref/logic/search/matchers/AndMatcher.java similarity index 88% rename from src/main/java/org/jabref/model/search/matchers/AndMatcher.java rename to src/main/java/org/jabref/logic/search/matchers/AndMatcher.java index 81839607ad0..c0e4116cd1c 100644 --- a/src/main/java/org/jabref/model/search/matchers/AndMatcher.java +++ b/src/main/java/org/jabref/logic/search/matchers/AndMatcher.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; import org.jabref.model.entry.BibEntry; diff --git a/src/main/java/org/jabref/model/search/matchers/MatcherSet.java b/src/main/java/org/jabref/logic/search/matchers/MatcherSet.java similarity index 91% rename from src/main/java/org/jabref/model/search/matchers/MatcherSet.java rename to src/main/java/org/jabref/logic/search/matchers/MatcherSet.java index 46043c86551..044c0626fae 100644 --- a/src/main/java/org/jabref/model/search/matchers/MatcherSet.java +++ b/src/main/java/org/jabref/logic/search/matchers/MatcherSet.java @@ -1,10 +1,10 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import org.jabref.model.search.SearchMatcher; +import org.jabref.logic.search.SearchMatcher; public abstract class MatcherSet implements SearchMatcher { diff --git a/src/main/java/org/jabref/model/search/matchers/MatcherSets.java b/src/main/java/org/jabref/logic/search/matchers/MatcherSets.java similarity index 87% rename from src/main/java/org/jabref/model/search/matchers/MatcherSets.java rename to src/main/java/org/jabref/logic/search/matchers/MatcherSets.java index 369db6f9faf..6327255a7bb 100644 --- a/src/main/java/org/jabref/model/search/matchers/MatcherSets.java +++ b/src/main/java/org/jabref/logic/search/matchers/MatcherSets.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; public class MatcherSets { diff --git a/src/main/java/org/jabref/model/search/matchers/NotMatcher.java b/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java similarity index 84% rename from src/main/java/org/jabref/model/search/matchers/NotMatcher.java rename to src/main/java/org/jabref/logic/search/matchers/NotMatcher.java index 09be8c7f86e..58a1d727301 100644 --- a/src/main/java/org/jabref/model/search/matchers/NotMatcher.java +++ b/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java @@ -1,9 +1,9 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; import java.util.Objects; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.SearchMatcher; +import org.jabref.logic.search.SearchMatcher; /** * Inverts the search result. diff --git a/src/main/java/org/jabref/model/search/matchers/OrMatcher.java b/src/main/java/org/jabref/logic/search/matchers/OrMatcher.java similarity index 89% rename from src/main/java/org/jabref/model/search/matchers/OrMatcher.java rename to src/main/java/org/jabref/logic/search/matchers/OrMatcher.java index 578b2b97c00..0801569981d 100644 --- a/src/main/java/org/jabref/model/search/matchers/OrMatcher.java +++ b/src/main/java/org/jabref/logic/search/matchers/OrMatcher.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; import org.jabref.model.entry.BibEntry; import org.jabref.model.util.ListUtil; diff --git a/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java similarity index 99% rename from src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java rename to src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java index d213920a7e0..a279e7b93c8 100644 --- a/src/main/java/org/jabref/model/search/rules/BibQueryVisitor.java +++ b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; import java.util.Iterator; diff --git a/src/main/java/org/jabref/model/search/rules/ContainsBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java similarity index 88% rename from src/main/java/org/jabref/model/search/rules/ContainsBasedSearchRule.java rename to src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java index 989a4f34e0c..e11b18e981d 100644 --- a/src/main/java/org/jabref/model/search/rules/ContainsBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java @@ -1,19 +1,17 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.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; +import org.jabref.logic.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) { diff --git a/src/main/java/org/jabref/model/search/rules/FullTextSearchRule.java b/src/main/java/org/jabref/logic/search/rules/FullTextSearchRule.java similarity index 98% rename from src/main/java/org/jabref/model/search/rules/FullTextSearchRule.java rename to src/main/java/org/jabref/logic/search/rules/FullTextSearchRule.java index 27cfbf65b8b..99326ca0a6a 100644 --- a/src/main/java/org/jabref/model/search/rules/FullTextSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/FullTextSearchRule.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.io.IOException; import java.util.Collections; diff --git a/src/main/java/org/jabref/model/search/rules/GrammarBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/GrammarBasedSearchRule.java similarity index 98% rename from src/main/java/org/jabref/model/search/rules/GrammarBasedSearchRule.java rename to src/main/java/org/jabref/logic/search/rules/GrammarBasedSearchRule.java index 777cbb6ebf8..c396c422453 100644 --- a/src/main/java/org/jabref/model/search/rules/GrammarBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/GrammarBasedSearchRule.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.io.IOException; import java.util.ArrayList; @@ -12,9 +12,9 @@ import java.util.regex.Pattern; 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.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.Keyword; @@ -22,7 +22,6 @@ import org.jabref.model.entry.field.InternalField; import org.jabref.model.pdf.search.PdfSearchResults; import org.jabref.model.pdf.search.SearchResult; -import org.jabref.model.search.rules.SearchRules.SearchFlags; import org.jabref.search.SearchBaseVisitor; import org.jabref.search.SearchLexer; import org.jabref.search.SearchParser; @@ -43,7 +42,6 @@ *

* This class implements the "Advanced Search Mode" described in the help */ -@AllowedToUseLogic("Because access to the lucene index is needed") public class GrammarBasedSearchRule implements SearchRule { private static final Logger LOGGER = LoggerFactory.getLogger(GrammarBasedSearchRule.class); diff --git a/src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java similarity index 92% rename from src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java rename to src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java index 90f838c2214..8658af21808 100644 --- a/src/main/java/org/jabref/model/search/rules/LuceneBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java @@ -1,12 +1,10 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; -import java.util.Locale; import java.util.concurrent.ExecutionException; -import org.jabref.architecture.AllowedToUseLogic; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -21,7 +19,6 @@ /** * Search rule for a search based on String.contains() */ -@AllowedToUseLogic("Because access to the lucene index is needed") public class LuceneBasedSearchRule extends FullTextSearchRule { private static final Logger LOGGER = LoggerFactory.getLogger(LuceneBasedSearchRule.class); diff --git a/src/main/java/org/jabref/model/search/rules/RegexBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/RegexBasedSearchRule.java similarity index 89% rename from src/main/java/org/jabref/model/search/rules/RegexBasedSearchRule.java rename to src/main/java/org/jabref/logic/search/rules/RegexBasedSearchRule.java index 456cded97be..135eaf92b31 100644 --- a/src/main/java/org/jabref/model/search/rules/RegexBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/RegexBasedSearchRule.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; import java.util.Optional; @@ -6,10 +6,9 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.jabref.architecture.AllowedToUseLogic; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; -import org.jabref.model.search.rules.SearchRules.SearchFlags; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +16,6 @@ /** * Search rule for regex-based search. */ -@AllowedToUseLogic("Because access to the lucene index is needed") public class RegexBasedSearchRule extends FullTextSearchRule { private static final Logger LOGGER = LoggerFactory.getLogger(RegexBasedSearchRule.class); diff --git a/src/main/java/org/jabref/model/search/rules/SearchRule.java b/src/main/java/org/jabref/logic/search/rules/SearchRule.java similarity index 88% rename from src/main/java/org/jabref/model/search/rules/SearchRule.java rename to src/main/java/org/jabref/logic/search/rules/SearchRule.java index 1be2b05b342..c56f0a73e80 100644 --- a/src/main/java/org/jabref/model/search/rules/SearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/SearchRule.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import org.jabref.model.entry.BibEntry; import org.jabref.model.pdf.search.PdfSearchResults; diff --git a/src/main/java/org/jabref/model/search/rules/SearchRules.java b/src/main/java/org/jabref/logic/search/rules/SearchRules.java similarity index 98% rename from src/main/java/org/jabref/model/search/rules/SearchRules.java rename to src/main/java/org/jabref/logic/search/rules/SearchRules.java index c949f4af1ee..27d58b6b76a 100644 --- a/src/main/java/org/jabref/model/search/rules/SearchRules.java +++ b/src/main/java/org/jabref/logic/search/rules/SearchRules.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; import java.util.regex.Pattern; diff --git a/src/main/java/org/jabref/model/search/rules/SentenceAnalyzer.java b/src/main/java/org/jabref/logic/search/rules/SentenceAnalyzer.java similarity index 97% rename from src/main/java/org/jabref/model/search/rules/SentenceAnalyzer.java rename to src/main/java/org/jabref/logic/search/rules/SentenceAnalyzer.java index 89987d9d5ac..f18c934346d 100644 --- a/src/main/java/org/jabref/model/search/rules/SentenceAnalyzer.java +++ b/src/main/java/org/jabref/logic/search/rules/SentenceAnalyzer.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/jabref/model/groups/AbstractGroup.java b/src/main/java/org/jabref/model/groups/AbstractGroup.java index e61d3b30e52..84b88dfde66 100644 --- a/src/main/java/org/jabref/model/groups/AbstractGroup.java +++ b/src/main/java/org/jabref/model/groups/AbstractGroup.java @@ -9,7 +9,7 @@ import javafx.scene.paint.Color; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.SearchMatcher; +import org.jabref.logic.search.SearchMatcher; import org.jabref.model.strings.StringUtil; /** diff --git a/src/main/java/org/jabref/model/groups/GroupTreeNode.java b/src/main/java/org/jabref/model/groups/GroupTreeNode.java index 6cb8b15d722..30724119f1c 100644 --- a/src/main/java/org/jabref/model/groups/GroupTreeNode.java +++ b/src/main/java/org/jabref/model/groups/GroupTreeNode.java @@ -12,9 +12,9 @@ import org.jabref.model.TreeNode; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.SearchMatcher; -import org.jabref.model.search.matchers.MatcherSet; -import org.jabref.model.search.matchers.MatcherSets; +import org.jabref.logic.search.SearchMatcher; +import org.jabref.logic.search.matchers.MatcherSet; +import org.jabref.logic.search.matchers.MatcherSets; /** * A node in the groups tree that holds exactly one AbstractGroup. diff --git a/src/main/java/org/jabref/model/groups/SearchGroup.java b/src/main/java/org/jabref/model/groups/SearchGroup.java index c1df365bef2..655d0de758c 100644 --- a/src/main/java/org/jabref/model/groups/SearchGroup.java +++ b/src/main/java/org/jabref/model/groups/SearchGroup.java @@ -4,8 +4,8 @@ import java.util.Objects; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.GroupSearchQuery; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.GroupSearchQuery; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 52c9746abba..1e40d1970f4 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -111,7 +111,7 @@ import org.jabref.model.metadata.SaveOrderConfig; import org.jabref.model.pdf.search.SearchFieldConstants; import org.jabref.model.push.PushToApplicationConstants; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.strings.StringUtil; import com.tobiasdiez.easybind.EasyBind; diff --git a/src/main/java/org/jabref/preferences/SearchPreferences.java b/src/main/java/org/jabref/preferences/SearchPreferences.java index 10273c0a892..3dadcb59f09 100644 --- a/src/main/java/org/jabref/preferences/SearchPreferences.java +++ b/src/main/java/org/jabref/preferences/SearchPreferences.java @@ -10,7 +10,7 @@ import javafx.collections.ObservableSet; import org.jabref.gui.search.SearchDisplayMode; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; public class SearchPreferences { diff --git a/src/test/java/org/jabref/architecture/MainArchitectureTests.java b/src/test/java/org/jabref/architecture/MainArchitectureTests.java index 40e3d945f2b..6806b6ee62c 100644 --- a/src/test/java/org/jabref/architecture/MainArchitectureTests.java +++ b/src/test/java/org/jabref/architecture/MainArchitectureTests.java @@ -119,9 +119,9 @@ public static void doNotUseLogicInModel(JavaClasses classes) { public static void restrictUsagesInModel(JavaClasses classes) { // Until we switch to Lucene, we need to access Globals.stateManager().getActiveDatabase() from the search classes, // because the PDFSearch needs to access the index of the corresponding database - noClasses().that().areNotAssignableFrom("org.jabref.model.search.rules.ContainBasedSearchRule") - .and().areNotAssignableFrom("org.jabref.model.search.rules.RegexBasedSearchRule") - .and().areNotAssignableFrom("org.jabref.model.search.rules.GrammarBasedSearchRule") + noClasses().that().areNotAssignableFrom("org.jabref.logic.search.rules.ContainBasedSearchRule") + .and().areNotAssignableFrom("org.jabref.logic.search.rules.RegexBasedSearchRule") + .and().areNotAssignableFrom("org.jabref.logic.search.rules.GrammarBasedSearchRule") .and().resideInAPackage(PACKAGE_ORG_JABREF_MODEL) .should().dependOnClassesThat().resideInAPackage(PACKAGE_JAVAX_SWING) .orShould().dependOnClassesThat().haveFullyQualifiedName(CLASS_ORG_JABREF_GLOBALS) diff --git a/src/test/java/org/jabref/gui/search/ContainsAndRegexBasedSearchRuleDescriberTest.java b/src/test/java/org/jabref/gui/search/ContainsAndRegexBasedSearchRuleDescriberTest.java index bc3406ec43c..c97daaab630 100644 --- a/src/test/java/org/jabref/gui/search/ContainsAndRegexBasedSearchRuleDescriberTest.java +++ b/src/test/java/org/jabref/gui/search/ContainsAndRegexBasedSearchRuleDescriberTest.java @@ -9,8 +9,8 @@ import org.jabref.gui.search.rules.describer.ContainsAndRegexBasedSearchRuleDescriber; import org.jabref.gui.util.TooltipTextUtil; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.testutils.category.GUITest; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java b/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java index cad5aa79e89..4e6af906ca2 100644 --- a/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java +++ b/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java @@ -10,9 +10,9 @@ import org.jabref.gui.search.rules.describer.GrammarBasedSearchRuleDescriber; import org.jabref.gui.util.TooltipTextUtil; -import org.jabref.model.search.rules.GrammarBasedSearchRule; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.GrammarBasedSearchRule; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.testutils.category.GUITest; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java b/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java index 1753495506a..092730d8a77 100644 --- a/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java +++ b/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java @@ -25,7 +25,7 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.util.DummyFileUpdateMonitor; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java b/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java index 29580b7be2a..a311e541a1e 100644 --- a/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java +++ b/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java @@ -21,7 +21,7 @@ import org.jabref.model.groups.SearchGroup; import org.jabref.model.groups.TexGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.model.util.FileUpdateMonitor; diff --git a/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java b/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java index f276f9ddfaf..c861a8bee7c 100644 --- a/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java +++ b/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java @@ -8,7 +8,7 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.StandardEntryType; -import org.jabref.model.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/logic/search/SearchQueryTest.java b/src/test/java/org/jabref/logic/search/SearchQueryTest.java index 4bf01fadb73..66138f65aab 100644 --- a/src/test/java/org/jabref/logic/search/SearchQueryTest.java +++ b/src/test/java/org/jabref/logic/search/SearchQueryTest.java @@ -7,8 +7,8 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.StandardEntryType; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/model/search/matchers/MatcherSetsTest.java b/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java similarity index 93% rename from src/test/java/org/jabref/model/search/matchers/MatcherSetsTest.java rename to src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java index be77c6773e3..a5af05dc00c 100644 --- a/src/test/java/org/jabref/model/search/matchers/MatcherSetsTest.java +++ b/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java @@ -1,7 +1,7 @@ -package org.jabref.model.search.matchers; +package org.jabref.logic.search.matchers; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.rules.MockSearchMatcher; +import org.jabref.logic.search.rules.MockSearchMatcher; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/model/search/rules/ContainsBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/ContainsBasedSearchRuleTest.java similarity index 98% rename from src/test/java/org/jabref/model/search/rules/ContainsBasedSearchRuleTest.java rename to src/test/java/org/jabref/logic/search/rules/ContainsBasedSearchRuleTest.java index ed77afd40be..846df2b0560 100644 --- a/src/test/java/org/jabref/model/search/rules/ContainsBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/ContainsBasedSearchRuleTest.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; diff --git a/src/test/java/org/jabref/model/search/rules/GrammarBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java similarity index 99% rename from src/test/java/org/jabref/model/search/rules/GrammarBasedSearchRuleTest.java rename to src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java index 6b410b5a088..ed8dd8bda38 100644 --- a/src/test/java/org/jabref/model/search/rules/GrammarBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; diff --git a/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java similarity index 98% rename from src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java rename to src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java index a4b804c3e4f..02479edef3c 100644 --- a/src/test/java/org/jabref/model/search/rules/LuceneBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; diff --git a/src/test/java/org/jabref/model/search/rules/MockSearchMatcher.java b/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java similarity index 82% rename from src/test/java/org/jabref/model/search/rules/MockSearchMatcher.java rename to src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java index d6174ad00d6..45888fce895 100644 --- a/src/test/java/org/jabref/model/search/rules/MockSearchMatcher.java +++ b/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java @@ -1,7 +1,7 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import org.jabref.model.entry.BibEntry; -import org.jabref.model.search.SearchMatcher; +import org.jabref.logic.search.SearchMatcher; /** * Mock search rule that returns the values passed. Useful for testing. diff --git a/src/test/java/org/jabref/model/search/rules/SearchRulesTest.java b/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java similarity index 96% rename from src/test/java/org/jabref/model/search/rules/SearchRulesTest.java rename to src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java index 5558794adc1..1ab8115da3e 100644 --- a/src/test/java/org/jabref/model/search/rules/SearchRulesTest.java +++ b/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.EnumSet; diff --git a/src/test/java/org/jabref/model/search/rules/SentenceAnalyzerTest.java b/src/test/java/org/jabref/logic/search/rules/SentenceAnalyzerTest.java similarity index 96% rename from src/test/java/org/jabref/model/search/rules/SentenceAnalyzerTest.java rename to src/test/java/org/jabref/logic/search/rules/SentenceAnalyzerTest.java index 61e05e3def4..337052f0a70 100644 --- a/src/test/java/org/jabref/model/search/rules/SentenceAnalyzerTest.java +++ b/src/test/java/org/jabref/logic/search/rules/SentenceAnalyzerTest.java @@ -1,4 +1,4 @@ -package org.jabref.model.search.rules; +package org.jabref.logic.search.rules; import java.util.List; import java.util.stream.Stream; diff --git a/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java b/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java index 8878219ecda..75961b9dde9 100644 --- a/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java +++ b/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java @@ -10,10 +10,10 @@ import org.jabref.model.FieldChange; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; -import org.jabref.model.search.matchers.AndMatcher; -import org.jabref.model.search.matchers.OrMatcher; -import org.jabref.model.search.rules.SearchRules; -import org.jabref.model.search.rules.SearchRules.SearchFlags; +import org.jabref.logic.search.matchers.AndMatcher; +import org.jabref.logic.search.matchers.OrMatcher; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/model/groups/SearchGroupTest.java b/src/test/java/org/jabref/model/groups/SearchGroupTest.java index 5bdec41d87e..1a6cdada876 100644 --- a/src/test/java/org/jabref/model/groups/SearchGroupTest.java +++ b/src/test/java/org/jabref/model/groups/SearchGroupTest.java @@ -2,9 +2,9 @@ import java.util.EnumSet; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; -import org.jabref.model.search.rules.SearchRules; import org.junit.jupiter.api.Test; From 8d685dc909bcaefc222e52b689d8a5ec36b333db Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sun, 14 Nov 2021 20:20:18 +0100 Subject: [PATCH 05/10] Add support for "anyfield", "anykeyword" --- .../logic/search/rules/BibQueryVisitor.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java index a279e7b93c8..326deb0a944 100644 --- a/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java +++ b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java @@ -11,6 +11,7 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.FieldFactory; +import org.jabref.model.entry.field.StandardField; import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; @@ -69,15 +70,23 @@ private boolean matchFound(String searchField, String searchString, boolean regE Pattern finalPattern = pattern; - if (searchField.isEmpty()) { + if (searchField.isEmpty() || searchField.equalsIgnoreCase("anyfield")) { return bibEntry.getFields().stream() .map(field -> bibEntry.getLatexFreeField(field)) - .filter(content -> matchFound(finalSearchString, finalPattern, content)) + .filter(content -> matchFound(finalSearchString, finalPattern, content, false)) .findAny() .isPresent(); } else { - Field field = FieldFactory.parseField(searchField); - return matchFound(finalSearchString, finalPattern, bibEntry.getLatexFreeField(field)); + boolean exactWordMatch; + Field field; + if (searchField.equals("anykeyword")) { + field = StandardField.KEYWORDS; + exactWordMatch = true; + } else { + field = FieldFactory.parseField(searchField); + exactWordMatch = false; + } + return matchFound(finalSearchString, finalPattern, bibEntry.getLatexFreeField(field), exactWordMatch); } } @@ -93,9 +102,10 @@ private boolean matchFound(RegexpQueryNode query) { } /** - * @param finalPattern if not null, the RegEx pattern to match for. If null, a "normal" search is executed + * @param finalPattern if not null, the RegEx pattern to match for. If null, a "normal" search is executed + * @param exactWordMatch */ - private boolean matchFound(String finalSearchString, Pattern finalPattern, Optional content) { + private boolean matchFound(String finalSearchString, Pattern finalPattern, Optional content, boolean exactWordMatch) { return content.map(value -> searchFlags.contains(SearchRules.SearchFlags.CASE_SENSITIVE) ? value : value.toLowerCase(Locale.ROOT)) .filter(value -> { if (finalPattern != null) { @@ -105,7 +115,8 @@ private boolean matchFound(String finalSearchString, Pattern finalPattern, Optio Iterator unmatchedWordsIterator = unmatchedWords.iterator(); while (unmatchedWordsIterator.hasNext()) { String word = unmatchedWordsIterator.next(); - if (value.contains(word)) { + if ((exactWordMatch && value.equals(word)) || + (!exactWordMatch && value.contains(word))) { unmatchedWordsIterator.remove(); } } From 3202fd0fe5ed12b0ee231657fd9fa72ae276d96e Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sun, 14 Nov 2021 21:10:10 +0100 Subject: [PATCH 06/10] Add test case mirroring our documentation --- .../jabref/logic/search/rules/GrammarBasedSearchRuleTest.java | 2 ++ .../jabref/logic/search/rules/LuceneBasedSearchRuleTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java index ed8dd8bda38..65013f7a3b8 100644 --- a/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/GrammarBasedSearchRuleTest.java @@ -37,6 +37,8 @@ void applyRuleDoesNotMatchSingleTermWithRegex() { @Test void searchRuleOfDocumentationMatches() { + // FIXME: Even though we do not provide a regex, the following instantiation does not match anything: + // GrammarBasedSearchRule searchRule = new GrammarBasedSearchRule(EnumSet.noneOf(SearchRules.SearchFlags.class)); GrammarBasedSearchRule searchRule = new GrammarBasedSearchRule(EnumSet.of(SearchRules.SearchFlags.REGULAR_EXPRESSION)); String query = "(author = miller or title|keywords = \"image processing\") and not author = brown"; diff --git a/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java index 02479edef3c..3c682bc1b09 100644 --- a/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java @@ -45,6 +45,8 @@ class LuceneBasedSearchRuleTest { "Marine", + "(author = miller or title|keywords = \"finfish\") and not author = brown", + // RegEx syntax of Lucene "/M[a-z]+e/" }) From 6a165b093bbe6410d2592127a21e2b79c6301ca8 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 23 Nov 2021 20:17:13 +0100 Subject: [PATCH 07/10] Fix checkstyle --- src/jmh/java/org/jabref/benchmarks/Benchmarks.java | 2 +- .../fileannotationtab/FulltextSearchResultsTab.java | 2 +- src/main/java/org/jabref/gui/groups/GroupDialogView.java | 4 ++-- .../java/org/jabref/gui/groups/GroupDialogViewModel.java | 4 ++-- .../java/org/jabref/gui/maintable/MainTableDataModel.java | 4 ++-- src/main/java/org/jabref/gui/search/GlobalSearchBar.java | 2 +- .../java/org/jabref/logic/exporter/GroupSerializer.java | 2 +- .../logic/importer/fileformat/EndnoteXmlImporter.java | 2 -- .../java/org/jabref/logic/importer/util/GroupsParser.java | 4 ++-- src/main/java/org/jabref/logic/search/GroupSearchQuery.java | 2 +- src/main/java/org/jabref/logic/search/SearchQuery.java | 2 +- .../java/org/jabref/logic/search/matchers/NotMatcher.java | 2 +- .../jabref/logic/search/rules/ContainsBasedSearchRule.java | 2 +- .../jabref/logic/search/rules/LuceneBasedSearchRule.java | 2 +- src/main/java/org/jabref/model/groups/AbstractGroup.java | 2 +- src/main/java/org/jabref/model/groups/GroupTreeNode.java | 6 +++--- src/main/java/org/jabref/model/groups/SearchGroup.java | 2 +- src/main/java/org/jabref/preferences/JabRefPreferences.java | 2 +- .../java/org/jabref/logic/exporter/GroupSerializerTest.java | 2 +- .../org/jabref/logic/importer/util/GroupsParserTest.java | 2 +- .../java/org/jabref/logic/search/DatabaseSearcherTest.java | 2 +- src/test/java/org/jabref/logic/search/SearchQueryTest.java | 4 ++-- .../org/jabref/logic/search/matchers/MatcherSetsTest.java | 2 +- .../org/jabref/logic/search/rules/MockSearchMatcher.java | 2 +- .../java/org/jabref/model/groups/GroupTreeNodeTest.java | 6 +++--- 25 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java index 3bcaa3d54bd..06bc095559c 100644 --- a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java +++ b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java @@ -18,6 +18,7 @@ import org.jabref.logic.layout.format.HTMLChars; import org.jabref.logic.layout.format.LatexToUnicodeFormatter; import org.jabref.logic.search.SearchQuery; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.logic.util.OS; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; @@ -31,7 +32,6 @@ import org.jabref.model.groups.KeywordGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.preferences.GeneralPreferences; import org.jabref.preferences.JabRefPreferences; diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java index c4923e7f78e..6d4bffb87ae 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java @@ -26,11 +26,11 @@ import org.jabref.gui.maintable.OpenFolderAction; import org.jabref.gui.util.TooltipTextUtil; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; import org.jabref.model.pdf.search.PdfSearchResults; import org.jabref.model.pdf.search.SearchResult; -import org.jabref.logic.search.rules.SearchRules; import org.jabref.preferences.PreferencesService; import org.slf4j.Logger; diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogView.java b/src/main/java/org/jabref/gui/groups/GroupDialogView.java index 2d729734534..695052f9c1f 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogView.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogView.java @@ -33,11 +33,11 @@ import org.jabref.gui.util.IconValidationDecorator; import org.jabref.gui.util.ViewModelListCellFactory; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.groups.AbstractGroup; import org.jabref.model.groups.GroupHierarchyType; -import org.jabref.logic.search.rules.SearchRules; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java index 3a8a1749748..4b213a397ee 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java @@ -31,6 +31,8 @@ import org.jabref.logic.auxparser.DefaultAuxParser; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.logic.util.StandardFileType; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabase; @@ -49,8 +51,6 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.logic.search.rules.SearchRules; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.strings.StringUtil; import org.jabref.preferences.PreferencesService; diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 0382d8ed0b4..698f852ae72 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -17,11 +17,11 @@ import org.jabref.gui.groups.GroupsPreferences; import org.jabref.gui.util.BindingsHelper; import org.jabref.logic.search.SearchQuery; +import org.jabref.logic.search.matchers.MatcherSet; +import org.jabref.logic.search.matchers.MatcherSets; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.GroupTreeNode; -import org.jabref.logic.search.matchers.MatcherSet; -import org.jabref.logic.search.matchers.MatcherSets; import org.jabref.preferences.PreferencesService; import com.tobiasdiez.easybind.EasyBind; diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 7354c5f5a6f..82f4e9af710 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -59,8 +59,8 @@ import org.jabref.gui.util.TooltipTextUtil; import org.jabref.logic.l10n.Localization; import org.jabref.logic.search.SearchQuery; -import org.jabref.model.entry.Author; import org.jabref.logic.search.rules.SearchRules; +import org.jabref.model.entry.Author; import org.jabref.preferences.PreferencesService; import org.jabref.preferences.SearchPreferences; diff --git a/src/main/java/org/jabref/logic/exporter/GroupSerializer.java b/src/main/java/org/jabref/logic/exporter/GroupSerializer.java index ce9006759b5..390055fd19f 100644 --- a/src/main/java/org/jabref/logic/exporter/GroupSerializer.java +++ b/src/main/java/org/jabref/logic/exporter/GroupSerializer.java @@ -5,6 +5,7 @@ import javafx.scene.paint.Color; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.logic.util.MetadataSerializationConfiguration; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.groups.AbstractGroup; @@ -18,7 +19,6 @@ import org.jabref.model.groups.RegexKeywordGroup; import org.jabref.model.groups.SearchGroup; import org.jabref.model.groups.TexGroup; -import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.strings.StringUtil; public class GroupSerializer { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java index 168fc291bbc..1a9f4668b70 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java @@ -31,11 +31,9 @@ import org.jabref.logic.importer.fileformat.endnote.Keywords; import org.jabref.logic.importer.fileformat.endnote.Label; import org.jabref.logic.importer.fileformat.endnote.Notes; -import org.jabref.logic.importer.fileformat.endnote.Number; import org.jabref.logic.importer.fileformat.endnote.Pages; import org.jabref.logic.importer.fileformat.endnote.PdfUrls; import org.jabref.logic.importer.fileformat.endnote.Publisher; -import org.jabref.logic.importer.fileformat.endnote.Record; import org.jabref.logic.importer.fileformat.endnote.RefType; import org.jabref.logic.importer.fileformat.endnote.RelatedUrls; import org.jabref.logic.importer.fileformat.endnote.SecondaryTitle; diff --git a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java index 16df5b701aa..0bcc96ac4a5 100644 --- a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java +++ b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java @@ -10,6 +10,8 @@ import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.logic.importer.ParseException; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.logic.util.MetadataSerializationConfiguration; import org.jabref.logic.util.strings.QuotedStringTokenizer; import org.jabref.model.database.BibDatabase; @@ -27,8 +29,6 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.logic.search.rules.SearchRules; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.strings.StringUtil; import org.jabref.model.util.FileUpdateMonitor; diff --git a/src/main/java/org/jabref/logic/search/GroupSearchQuery.java b/src/main/java/org/jabref/logic/search/GroupSearchQuery.java index 520084120ec..3aef5070fbf 100644 --- a/src/main/java/org/jabref/logic/search/GroupSearchQuery.java +++ b/src/main/java/org/jabref/logic/search/GroupSearchQuery.java @@ -3,10 +3,10 @@ import java.util.EnumSet; import java.util.Objects; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.rules.SearchRule; import org.jabref.logic.search.rules.SearchRules; import org.jabref.logic.search.rules.SearchRules.SearchFlags; +import org.jabref.model.entry.BibEntry; public class GroupSearchQuery implements SearchMatcher { diff --git a/src/main/java/org/jabref/logic/search/SearchQuery.java b/src/main/java/org/jabref/logic/search/SearchQuery.java index 1871da18501..6cb3eada56a 100644 --- a/src/main/java/org/jabref/logic/search/SearchQuery.java +++ b/src/main/java/org/jabref/logic/search/SearchQuery.java @@ -10,12 +10,12 @@ import java.util.stream.Stream; import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.rules.ContainsBasedSearchRule; import org.jabref.logic.search.rules.GrammarBasedSearchRule; import org.jabref.logic.search.rules.SearchRule; import org.jabref.logic.search.rules.SearchRules; import org.jabref.logic.search.rules.SentenceAnalyzer; +import org.jabref.model.entry.BibEntry; public class SearchQuery implements SearchMatcher { diff --git a/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java b/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java index 58a1d727301..b395268d34e 100644 --- a/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java +++ b/src/main/java/org/jabref/logic/search/matchers/NotMatcher.java @@ -2,8 +2,8 @@ import java.util.Objects; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.SearchMatcher; +import org.jabref.model.entry.BibEntry; /** * Inverts the search result. diff --git a/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java index e11b18e981d..ee1c1bce56b 100644 --- a/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/ContainsBasedSearchRule.java @@ -5,9 +5,9 @@ import java.util.List; import java.util.Locale; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; /** * Search rule for a search based on String.contains() diff --git a/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java index 8658af21808..53a90dff842 100644 --- a/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java @@ -3,8 +3,8 @@ import java.util.EnumSet; import java.util.concurrent.ExecutionException; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.rules.SearchRules.SearchFlags; +import org.jabref.model.entry.BibEntry; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; diff --git a/src/main/java/org/jabref/model/groups/AbstractGroup.java b/src/main/java/org/jabref/model/groups/AbstractGroup.java index 84b88dfde66..08d3aca08b5 100644 --- a/src/main/java/org/jabref/model/groups/AbstractGroup.java +++ b/src/main/java/org/jabref/model/groups/AbstractGroup.java @@ -8,8 +8,8 @@ import javafx.beans.property.StringProperty; import javafx.scene.paint.Color; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.SearchMatcher; +import org.jabref.model.entry.BibEntry; import org.jabref.model.strings.StringUtil; /** diff --git a/src/main/java/org/jabref/model/groups/GroupTreeNode.java b/src/main/java/org/jabref/model/groups/GroupTreeNode.java index 30724119f1c..9fe2509cb1f 100644 --- a/src/main/java/org/jabref/model/groups/GroupTreeNode.java +++ b/src/main/java/org/jabref/model/groups/GroupTreeNode.java @@ -8,13 +8,13 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jabref.logic.search.SearchMatcher; +import org.jabref.logic.search.matchers.MatcherSet; +import org.jabref.logic.search.matchers.MatcherSets; import org.jabref.model.FieldChange; import org.jabref.model.TreeNode; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; -import org.jabref.logic.search.SearchMatcher; -import org.jabref.logic.search.matchers.MatcherSet; -import org.jabref.logic.search.matchers.MatcherSets; /** * A node in the groups tree that holds exactly one AbstractGroup. diff --git a/src/main/java/org/jabref/model/groups/SearchGroup.java b/src/main/java/org/jabref/model/groups/SearchGroup.java index 655d0de758c..b2456b086c6 100644 --- a/src/main/java/org/jabref/model/groups/SearchGroup.java +++ b/src/main/java/org/jabref/model/groups/SearchGroup.java @@ -3,9 +3,9 @@ import java.util.EnumSet; import java.util.Objects; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.GroupSearchQuery; import org.jabref.logic.search.rules.SearchRules.SearchFlags; +import org.jabref.model.entry.BibEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 1e40d1970f4..bf987482e69 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -93,6 +93,7 @@ import org.jabref.logic.protectedterms.ProtectedTermsLoader; import org.jabref.logic.protectedterms.ProtectedTermsPreferences; import org.jabref.logic.remote.RemotePreferences; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.logic.shared.prefs.SharedDatabasePreferences; import org.jabref.logic.util.OS; import org.jabref.logic.util.Version; @@ -111,7 +112,6 @@ import org.jabref.model.metadata.SaveOrderConfig; import org.jabref.model.pdf.search.SearchFieldConstants; import org.jabref.model.push.PushToApplicationConstants; -import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.strings.StringUtil; import com.tobiasdiez.easybind.EasyBind; diff --git a/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java b/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java index 092730d8a77..4fe4957a314 100644 --- a/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java +++ b/src/test/java/org/jabref/logic/exporter/GroupSerializerTest.java @@ -9,6 +9,7 @@ import javafx.scene.paint.Color; import org.jabref.logic.auxparser.DefaultAuxParser; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.field.StandardField; import org.jabref.model.groups.AllEntriesGroup; @@ -25,7 +26,6 @@ import org.jabref.model.groups.TexGroup; import org.jabref.model.groups.WordKeywordGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.util.DummyFileUpdateMonitor; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java b/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java index a311e541a1e..05de48b741e 100644 --- a/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java +++ b/src/test/java/org/jabref/logic/importer/util/GroupsParserTest.java @@ -9,6 +9,7 @@ import org.jabref.logic.auxparser.DefaultAuxParser; import org.jabref.logic.importer.ParseException; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.field.StandardField; import org.jabref.model.groups.AbstractGroup; @@ -21,7 +22,6 @@ import org.jabref.model.groups.SearchGroup; import org.jabref.model.groups.TexGroup; import org.jabref.model.metadata.MetaData; -import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.model.util.FileUpdateMonitor; diff --git a/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java b/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java index c861a8bee7c..cafe249aa2e 100644 --- a/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java +++ b/src/test/java/org/jabref/logic/search/DatabaseSearcherTest.java @@ -4,11 +4,11 @@ import java.util.EnumSet; import java.util.List; +import org.jabref.logic.search.rules.SearchRules; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.StandardEntryType; -import org.jabref.logic.search.rules.SearchRules; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/logic/search/SearchQueryTest.java b/src/test/java/org/jabref/logic/search/SearchQueryTest.java index 66138f65aab..92c1c748602 100644 --- a/src/test/java/org/jabref/logic/search/SearchQueryTest.java +++ b/src/test/java/org/jabref/logic/search/SearchQueryTest.java @@ -4,11 +4,11 @@ import java.util.Optional; import java.util.regex.Pattern; +import org.jabref.logic.search.rules.SearchRules; +import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.StandardEntryType; -import org.jabref.logic.search.rules.SearchRules; -import org.jabref.logic.search.rules.SearchRules.SearchFlags; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java b/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java index a5af05dc00c..2d5ff918a69 100644 --- a/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java +++ b/src/test/java/org/jabref/logic/search/matchers/MatcherSetsTest.java @@ -1,7 +1,7 @@ package org.jabref.logic.search.matchers; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.rules.MockSearchMatcher; +import org.jabref.model.entry.BibEntry; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java b/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java index 45888fce895..75dbd3e713c 100644 --- a/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java +++ b/src/test/java/org/jabref/logic/search/rules/MockSearchMatcher.java @@ -1,7 +1,7 @@ package org.jabref.logic.search.rules; -import org.jabref.model.entry.BibEntry; import org.jabref.logic.search.SearchMatcher; +import org.jabref.model.entry.BibEntry; /** * Mock search rule that returns the values passed. Useful for testing. diff --git a/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java b/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java index 75961b9dde9..81f2151c1b6 100644 --- a/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java +++ b/src/test/java/org/jabref/model/groups/GroupTreeNodeTest.java @@ -7,13 +7,13 @@ import java.util.List; import java.util.Optional; -import org.jabref.model.FieldChange; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.field.StandardField; import org.jabref.logic.search.matchers.AndMatcher; import org.jabref.logic.search.matchers.OrMatcher; import org.jabref.logic.search.rules.SearchRules; import org.jabref.logic.search.rules.SearchRules.SearchFlags; +import org.jabref.model.FieldChange; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.StandardField; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From 9c8e6399eaaef33499f5016b342bacf59f0986fc Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 17 Jan 2022 21:08:42 +0100 Subject: [PATCH 08/10] Fix missing imports --- .../jabref/logic/importer/fileformat/EndnoteXmlImporter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java index 1a9f4668b70..168fc291bbc 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/EndnoteXmlImporter.java @@ -31,9 +31,11 @@ import org.jabref.logic.importer.fileformat.endnote.Keywords; import org.jabref.logic.importer.fileformat.endnote.Label; import org.jabref.logic.importer.fileformat.endnote.Notes; +import org.jabref.logic.importer.fileformat.endnote.Number; import org.jabref.logic.importer.fileformat.endnote.Pages; import org.jabref.logic.importer.fileformat.endnote.PdfUrls; import org.jabref.logic.importer.fileformat.endnote.Publisher; +import org.jabref.logic.importer.fileformat.endnote.Record; import org.jabref.logic.importer.fileformat.endnote.RefType; import org.jabref.logic.importer.fileformat.endnote.RelatedUrls; import org.jabref.logic.importer.fileformat.endnote.SecondaryTitle; From 9ab3ae68d70573e1ba90aaacf463630e336ba01e Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 7 Jul 2022 23:52:52 +0200 Subject: [PATCH 09/10] Add some comments --- .../org/jabref/logic/search/rules/BibQueryVisitor.java | 3 +++ .../jabref/logic/search/rules/LuceneBasedSearchRule.java | 4 +++- .../java/org/jabref/logic/search/rules/SearchRule.java | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java index 326deb0a944..672954363a5 100644 --- a/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java +++ b/src/main/java/org/jabref/logic/search/rules/BibQueryVisitor.java @@ -23,6 +23,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Implements a Lucene-syntax based search on BibEntries + */ public class BibQueryVisitor { public static final String NO_EXPLICIT_FIELD = "default"; private static final Logger LOGGER = LoggerFactory.getLogger(BibQueryVisitor.class); diff --git a/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java index 148827fb907..4766e04df20 100644 --- a/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/LuceneBasedSearchRule.java @@ -24,8 +24,10 @@ public class LuceneBasedSearchRule extends FullTextSearchRule { private static final Logger LOGGER = LoggerFactory.getLogger(LuceneBasedSearchRule.class); // We use SyntaxParser to be consistent with org.jabref.logic.importer - // We do not use "PrecedenceQueryParser", because this parser keeps the term "AND" + // We do not use "PrecedenceQueryParser", because StandardSyntaxParser parser keeps the term "AND" private SyntaxParser parser = new StandardSyntaxParser(); + + // We cache the mapping from the plain query string to the parsed Lucene query to avoid parsing private LoadingCache cache = CacheBuilder.newBuilder() .maximumSize(100) .build( diff --git a/src/main/java/org/jabref/logic/search/rules/SearchRule.java b/src/main/java/org/jabref/logic/search/rules/SearchRule.java index c56f0a73e80..e0372681136 100644 --- a/src/main/java/org/jabref/logic/search/rules/SearchRule.java +++ b/src/main/java/org/jabref/logic/search/rules/SearchRule.java @@ -5,8 +5,16 @@ public interface SearchRule { + /** + * This method applies the rule to the given BibEntry. + * + * @return true iff there is a match + */ boolean applyRule(String query, BibEntry bibEntry); + /** + * Executes a search on the linked PDF file(s) of the given BibEntry. + */ PdfSearchResults getFulltextResults(String query, BibEntry bibEntry); boolean validateSearchStrings(String query); From 59c0d8ffe12845b53f2b9855ed97b98a389400c0 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 7 Jul 2022 23:53:31 +0200 Subject: [PATCH 10/10] Fix checkstyle --- src/main/java/org/jabref/gui/search/SearchResultsTable.java | 1 - .../org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java | 1 - src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java | 1 - 3 files changed, 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/search/SearchResultsTable.java b/src/main/java/org/jabref/gui/search/SearchResultsTable.java index 09083921f7a..548b117b1c7 100644 --- a/src/main/java/org/jabref/gui/search/SearchResultsTable.java +++ b/src/main/java/org/jabref/gui/search/SearchResultsTable.java @@ -73,4 +73,3 @@ public SearchResultsTable(SearchResultsTableDataModel model, database.getDatabase().registerListener(this); } } - diff --git a/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java index 3c682bc1b09..2702e188cbc 100644 --- a/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java +++ b/src/test/java/org/jabref/logic/search/rules/LuceneBasedSearchRuleTest.java @@ -107,5 +107,4 @@ public void findsCaseInSensitive(String query) { assertTrue(luceneBasedSearchRuleCaseInsensitive.validateSearchStrings(query)); assertTrue(luceneBasedSearchRuleCaseInsensitive.applyRule(query, bibEntry)); } - } diff --git a/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java b/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java index 1ab8115da3e..ad36c170194 100644 --- a/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java +++ b/src/test/java/org/jabref/logic/search/rules/SearchRulesTest.java @@ -25,5 +25,4 @@ void simpleFieldedLuceneQueryReturnsLuceneBasedSearchRule() { SearchRule searchRule = SearchRules.getSearchRuleByQuery("title:test", EnumSet.noneOf(SearchRules.SearchFlags.class)); assertInstanceOf(LuceneBasedSearchRule.class, searchRule); } - }